Cuenta las verdades finales


59

Inspirado y en memoria de mi querido amigo y colega,

Dan Baronet

Dan Baronet , 1956 - 2016. RIP

Encontró la solución APL más corta posible para esta tarea:

Tarea

Dada una lista booleana, cuente el número de valores de verdad finales.

Casos de ejemplo

{}0

{0}0

{1}1

{0, 1, 1, 0, 0}0

{1, 1, 1, 0, 1}1

{1, 1, 0, 1, 1}2

{0, 0, 1, 1, 1}3

{1, 1, 1, 1, 1, 1}6


¿Podemos tomar la lista como una cadena de ceros y unos? por ejemplo 01100?
Adnan el

@Adnan solo si esa es la forma más normal para que su idioma represente listas booleanas.
Adám

71
Lo siento por su pérdida.
Martin Ender

66
@ MartinDender Gracias. Será difícil seguir adelante. Dan me enseñó todo lo que necesitaba saber para trabajar para Dyalog.
Adám el

55
Adiós a Dan. RIP ...
Erik the Outgolfer

Respuestas:


36

Dyalog APL, 6 2 bytes

⊥⍨

Pruébelo en TryAPL .

Cómo funciona

(uptack, dyadic: decode) realiza la conversión de base. Si el operando izquierdo es un vector, realiza una conversión de base mixta , lo cual es perfecto para esta tarea.

Para un vector base b = b n , ⋯, b 0 y un vector de dígitos a = a n , ⋯, un 0 , b ⊥ un convierte una a la base mixta b , es decir, calcula b 0 ⋯ b n-1 una n + ⋯ + b 0 b 1 a 2 + b 0 a 1 + a 0 .

Ahora, (tilde dieresis, conmutar) modifica el operador a la izquierda de la siguiente manera. En un contexto monádico, llama al operador con argumentos iguales de izquierda y derecha.

Por ejemplo, ⊥⍨ a se define como a ⊥ a , que calcula a 0 ⋯ a n + ⋯ + a 0 a 1 a 2 + a 0 a 1 + a 0 , la suma de todos los productos acumulativos de derecha a izquierda .

Para k finales, los k productos más a la derecha son 1 y todos los demás son 0 , por lo que su suma es igual a k .


14
Sugerencia: Dan lo hizo en solo dos bytes.
Adám

3
Conversión de base mixta! Eso es inteligente.
Dennis

1
Oh. Conversión de base mixta, cómo ataca de nuevo.
Conor O'Brien el

¡Bravo! De hecho, a causa de Dan, que especial con carcasa b⊥by ⊥⍨brenunciar a infinita velocidad de marcha.
Adám

19

JavaScript (ES6), 21 bytes

f=l=>l.pop()?f(l)+1:0

Casos de prueba


¿Como funciona esto? ¿Cómo f(l)+1devuelve un valor > 2?
Oliver

@Oliver Este es un proceso recursivo, evaluado como l.pop()?(l.pop()?(l.pop()?(...etc...)+1:0)+1:0)+1:0.
Arnauld

Veo. Gracias por la explicación.
Oliver

11

Jalea , 4 bytes

ŒrṪP

Pruébalo en línea! o Verificar todos los casos de prueba.

Para el caso donde la lista está vacía, hay algunas observaciones curiosas. Primero, la codificación de longitud de ejecución de la lista vacía []devuelve otra lista vacía []. Luego, recuperando el último elemento de ese uso de retornos de cola en 0lugar de un par [value, count]que son los elementos regulares de una matriz codificada de longitud de ejecución. Luego, el producto Pregresa 0cuando se le solicita 0cuál es el resultado esperado.

Explicación

ŒrṪP  Main link. Input: list M
Œr    Run-length encode
  Ṫ   Tail, get the last value
   P  Product, multiply the values together

Alternativamente, ŒgṪS¡también funciona!
Lynn el

Da la salida correcta para la lista vacía como entrada, pero me sorprende dada la disección. ¿Te importaría caminar por ese caso especial?
Peter Taylor

@ PeterTaylor También me sorprende que haya funcionado. Además, acabo de notar que el primer enlace tiene el código incorrecto.
millas

@PeterTaylor Jelly se implementa como: lambda z: iterable(z).pop() if iterable(z) else 0. iterablecuando se le llama en una lista solo devuelve la lista, y la lista vacía es, por supuesto, falsa.
FryAmTheEggman

10

Brachylog , 7 6 5 bytes

@]#=+

Pruébalo en línea!

Explicación

@]        A suffix of the Input...
  #=      ...whose elements are all equal
    +     Sum its elements

Dado que @] - Suffixcomienza desde el sufijo más grande hasta el más pequeño, primero encontrará la carrera más larga.


10

CJam (8 bytes)

{W%0+0#}

Conjunto de pruebas en línea

Disección

{    e# begin a block
  W%  e# reverse the array
  0+  e# append 0 so there's something to find
  0#  e# find index of first 0, which is number of nonzeros before it
}

10

Haskell, 26 25 bytes

a%b|b=1+a|0<3=0
foldl(%)0

Uso:

Prelude> foldl(%)0 [True,False,True,True]
2

Versión sin puntos (26 bytes):

length.fst.span id.reverse

Usando una lista entera en lugar de una lista bool (21 bytes, gracias a Christian Sievers):

a%b=b*(a+1)
foldl(%)0

Uso:

Prelude> foldl(%)0 [1,0,1,1]
2

Versión sin puntos (25 bytes)

sum.fst.span(==1).reverse

Para listas enteras con las que foldlfunciona la ideaa%b=b*(a+1)
Christian Sievers

9

Retina , 7 5 bytes

r`1\G

Pruébalo en línea! (La primera línea habilita un conjunto de pruebas separado por salto de línea).

Definir el formato de entrada para Retina no es del todo inequívoco. Dado que Retina no tiene ningún concepto de ningún tipo, excepto cadenas (y tampoco ningún valor que pueda usarse para nuestra definición habitual de verdad y falsedad), generalmente uso 0y 1(o algo positivo en general) para corresponder a verdad y falsedad, ya que representan cero o algunos partidos, respectivamente.

Con las representaciones de un solo carácter, tampoco necesitamos un separador para la lista (que, en cierto modo, es más la representación de la lista más natural para un lenguaje que solo tiene cadenas). Adám confirmó que este es un formato de entrada aceptable.

En cuanto a la expresión regular en sí, coincide de right a izquierda y \Gancla cada coincidencia a la anterior. Por lo tanto, esto cuenta cuántos 1s podemos igualar desde el final de la cadena.


"Sí, para Retina, dado que maneja solo cadenas, creo que una cadena" 01 "o" FT "está en orden.
Adám

9

05AB1E , 12 10 6 5 bytes

Guardado 1 byte gracias a carusocomputing .

Î0¡¤g

Pruébalo en línea!

Explicación

Î      # push 0 and input
 0¡    # split on 0
   ¤   # take last item in list
    g  # get length

0¡¤ges de cuatro bytes.
Urna mágica del pulpo

@carusocomputing: ¡Qué bueno! Todavía no se aclaró si la entrada de cadena estaba bien cuando escribí esto, pero ahora veo que es :)
Emigna

J0¡¤gtambién es aún más corto;).
Urna de pulpo mágico

@carusocomputing: Desafortunadamente, necesitamos Îmanejar la entrada vacía, pero aún es un byte guardado gracias :)
Emigna




7

Mathematica, 25 24 bytes

Fold[If[#2,#+1,0]&,0,#]&

3
Simplemente grabando un puerto de la genial solución de base mixta de Dan: FromDigits[b=Boole@#,MixedRadix@b]&(35 bytes).
Greg Martin

5

Pyth, 6 bytes

x_+0Q0

Pruébalo aquí!

Agrega un 0, invierte y encuentra el índice del primer 0


@Jakube solucionado ahora - algoritmo diferente
Azul

5

C90 (gcc), 46 bytes

r;main(c,v)int**v;{while(0<--c&*v[c])r++;c=r;}

La entrada es a través de argumentos de línea de comandos (un número entero por argumento), la salida a través del código de salida .

Pruébalo en línea!

Cómo funciona

r es una variable global. Su tipo predeterminado es int y, al ser global, su valor predeterminado es 0 .

El argumento de la función c por defecto también es int . Retendrá el número entero n + 1 para matrices de n booleanos; El primer argumento de main es siempre la ruta del ejecutable.

El argumento de la función v se declara como int**. El tipo real de v será char**, pero dado que solo examinaremos el bit menos significativo de cada argumento para distinguir los caracteres 0 (punto de código 48 ) y 1 (punto de código 49 ), esto no importará en little-endian maquinas.

El ciclo while disminuye c y lo compara con 0 . Una vez que c alcanza 0 , saldremos del bucle. Esto es necesario solo si la matriz no contiene 0 's.

Siempre que 0<--cdevuelva 1 , tomamos el argumento de línea de comando c th ( v[c]) y extraemos su primer carácter desreferenciando el puntero ( *). Tomamos el AND bit a bit del Booleano 0<--cy el punto de código del carácter (y los tres bytes de basura que lo siguen), por lo que la condición devolverá 0 una vez que se encuentre un 0 , rompiendo el bucle.

En el caso restante, mientras que los argumentos de la línea de comando son 1 , r++incrementa r en 1 , contando así el número de 1 's posteriores .

Finalmente, c=ralmacena el valor calculado de r en c . Con la configuración predeterminada, el compilador optimiza y elimina la asignación; En realidad genera la movl %eax, -4(%rbp)instrucción. Como retdevuelve el valor del registro EAX, esto genera la salida deseada.

Tenga en cuenta que este código no funciona con C99, que devuelve 0 desde main si se alcanza el final de main .


¿No es argcal menos 1(con argv[0]contener el nombre del archivo)? Podría guardar un byte con en --c&&lugar de 0<--c&. ¿Se toma el código de salida de gcc argc? Ordenado.
Titus

@Titus Eso no funcionará. *v[c]es el punto de código de 1 o 0 , por lo que es 49 o 48 y, por lo tanto, siempre es verdadero.
Dennis

Con C89 y C90, gcc devuelve lo que esté en RAX en ese momento. C99 siempre devuelve 0 desde main si se alcanza el final.
Dennis

4

k, 6 bytes

+/&\|:

Esta composición de funciones se traduce en sum mins reversein q, el hermano más legible del lenguaje, donde min es un mínimo continuo.


¿Se puede dejar caer el?
Callejero

4

J, 9 3 bytes

#.~

Esta es una conversión reflexiva de base mixta. Porque esto es lo mismo que la conversión de base mixta. De nuevo.

Casos de prueba

   v =: #.~
   ]t =: '';0;1;0 1 1 0 0;1 1 1 0 1;1 1 0 1 1;0 0 1 1 1;1 1 1 1 1 1
++-+-+---------+---------+---------+---------+-----------+
||0|1|0 1 1 0 0|1 1 1 0 1|1 1 0 1 1|0 0 1 1 1|1 1 1 1 1 1|
++-+-+---------+---------+---------+---------+-----------+
   v&.> t
+-+-+-+-+-+-+-+-+
|0|0|1|0|1|2|3|6|
+-+-+-+-+-+-+-+-+
   (,. v&.>) t
+-----------+-+
|           |0|
+-----------+-+
|0          |0|
+-----------+-+
|1          |1|
+-----------+-+
|0 1 1 0 0  |0|
+-----------+-+
|1 1 1 0 1  |1|
+-----------+-+
|1 1 0 1 1  |2|
+-----------+-+
|0 0 1 1 1  |3|
+-----------+-+
|1 1 1 1 1 1|6|
+-----------+-+

2
Sugerencia: Esto se puede hacer en solo 3 bytes, utilizando la traducción J de la solución de Dan.
Adám

1
@ Adám Intenté buscar una solución. No pensé en la conversión de base. ¡Eso es muy inteligente de su parte!
Conor O'Brien el

1
Si. Ese fue Dan. :-(
Adám

4

R, 40 39 25 bytes

Solución completamente reelaborada gracias a @Dason

sum(cumprod(rev(scan())))

Lea la entrada de stdin, invierta el vector y, si el primer elemento de !=0, emite la primera longitud de la codificación de longitud de ejecución ( rle), de lo contrario 0.


1
Puede guardar un byte cambiando la segunda línea a ifelse(r$v,r$l,0)[1]. (Vectorizado si, y luego tomar el primer elemento.)
rturnbull

1
no es necesario el iflelse: simplemente multiplique r $ v y r $ l.
Dason

Pero la ruta de la suma (cumprod (rev (.))) Debería ahorrar muchos bytes de todos modos
Dason

3

Haskell, 24 bytes

foldl(\a b->sum[a+1|b])0

Itera sobre la lista, agregando uno para cada elemento, reiniciando 0después de que golpea a False.

16 bytes con entrada 0/1:

foldl((*).(+1))0

Si se garantizara que la lista no está vacía, podríamos obtener 14 bytes:

sum.scanr1(*)1

Esto calcula el producto acumulativo desde la parte posterior, luego los suma. El producto acumulativo permanece 1 hasta que se alcanza un 0, y luego se convierte en 0. Entonces, los 1 corresponden a los 1 finales.



3

C # 6, 103 72 bytes

using System.Linq;
int a(bool[] l)=>l.Reverse().TakeWhile(x=>x).Count();

El uso de la lista no genérica supera la lista genérica por 1 byte lol

-31 bytes gracias a Scott


Si usa una variedad de ints, puede salirse con la suyaint a(int[] l)=>l.Reverse().TakeWhile(i=>i>0).Sum();
Scott

@ Scott Por supuesto, ¿qué estaba pensando? Sin embargo, me quedaré con bool. La pregunta especifica una lista booleana y no es C.
Enlace del

Compilar a a Func<bool[], int>para 57 bytes, es decirusing System.Linq;l=>l.Reverse().TakeWhile(x=>x).Count();
TheLethalCoder

2

Python, 37 bytes

f=lambda l:len(l)and-~f(l[:-1])*l[-1]

2

GUIÓN, CORRER PRECIPITADAMENTE, PRECIPITARSE, IR DE PRISA , 16 bytes

@len mstr"1+$"#0

No es la solución DASH más corta posible, pero la solución DASH más corta posible me está molestando. Estoy publicando este enfoque novedoso en su lugar.

Uso:

(@len mstr"1+$"#0)"100111"

Explicación

@(                 #. Lambda
  len (            #. Get the length of the array after...
    mstr "1+$" #0  #. ... matching the argument with regex /1+$/
  )                #. * mstr returns an empty array for no matches
)

2

Scala, 25 bytes

l=>l.reverse:+0 indexOf 0

Sin golf:

l=>(l.reverse :+ 0).indexOf(0)

Invierte la lista, agrega un 0 y encuentra el primer índice de 0, que es el número de elementos antes del primer 0


2

Lote, 57 bytes

@set n=0
@for %%n in (%*)do @set/an=n*%%n+%%n
@echo %n%

Toma datos como parámetros de línea de comandos. Funciona multiplicando el acumulador por el valor actual antes de agregarlo, para que los ceros en la línea de comando restablezcan el conteo. Tenga en cuenta que %%nno es lo mismo que la variable no %n%.



2

Java 7, 62 bytes

int c(boolean[]a){int r=0;for(boolean b:a)r=b?r+1:0;return r;}

Ungolfed y código de prueba:

Pruébalo aquí.

class M{
  static int c(boolean[] a){
    int r = 0;
    for (boolean b : a){
      r = b ? r+1 : 0;
    }
    return r;
  }

  public static void main(String[] a){
    System.out.print(c(new boolean[]{}) + ", ");
    System.out.print(c(new boolean[]{ false }) + ", ");
    System.out.print(c(new boolean[]{ true }) + ", ");
    System.out.print(c(new boolean[]{ false, true, true, false, false }) + ", ");
    System.out.print(c(new boolean[]{ true, true, true, false, true }) + ", ");
    System.out.print(c(new boolean[]{ true, true, false, true, true }) + ", ");
    System.out.print(c(new boolean[]{ false, false, true, true, true }) + ", ");
    System.out.print(c(new boolean[]{ true, true, true, true, true, true }));
  }
}

Salida:

0, 0, 1, 0, 1, 2, 3, 6

2

Perl 5.10, 22 bytes

21 bytes + 1 byte para -abandera. Dado que se realizó la expresión basada en expresiones regulares ...: p

Los valores de entrada para la matriz deben estar separados por un espacio.

$n++while pop@F;say$n

Pruébalo en línea!


1
Un poco más corto si toma argumentos a través de la línea de comando: perl -E '$_++while pop;say' 0 1 1 0 1 1 1pero esto no genera nada 0(¡aunque no estoy seguro si eso es un problema!)
Dom Hastings

2

Perl, 22 bytes

21 bytes de código + 1 byte para -pbandera.

s/.(?=.*0)//g;$_=y;1;

Para ejecutarlo:

perl -pE 's/.(?=.*0)//g;$_=y;1;' <<< "0 1 1 0 1 1 1"

(En realidad, el formato de la entrada no importa mucho: 0110111, 0 1 1 0 1 1 1, [0,1,1,0,1,1,1]etc haría todo el trabajo)


Versión de 18 bytes de @Dom Hastings pero requiere suministrar la entrada como una cadena de 0 y 1, lo cual no está permitido:

perl -pE '/1*$/;$_=length$&' <<< '0110111'

Me encanta ese ;truco :) Si el formato es una cadena continua: perl -pE '/1*$/;$_=length$&' <<< '0110111'para 18, no estoy seguro de si eso está doblando las reglas o no ...
Dom Hastings

@DomHastings sí, yo también! (¡Gracias Ton por mostrarme eso!) El primer y el segundo comentario de la pregunta no permiten el formato de entrada que necesita para su solución ... Pero editaré mi publicación para sugerir su versión si el formato de entrada fue más gratis.
Dada

2

PHP, 50 bytes

<?=strlen(preg_filter('/.*[^1]/','',join($argv)));

Extrañamente, mi primer intento con una expresión regular resultó más corto que mi intento con matrices ...
Use como:

php tt.php 1 1 0 1 1

2

Ruby 37 32 bytes

->n{n.size-1-(n.rindex(!0)||-1)}

Crea una función anónima que encuentra la instancia más a la derecha de un valor falso y cuenta el tamaño de la submatriz a partir de ese valor.

Se usa !0como falso, ya que 0 son valores verdaderos en Ruby. rindexencuentra el último índice de un valor en una matriz.

Uso :

boolean_list = [true, false, false, true]
->n{n.size-1-(n.rindex(!0)||-1)}[boolean_list]

Devuelve 1


Si se me permitiera pasar una cadena de 0 y 1 como parámetros de línea de comando (que no es cómo Ruby representa listas de booleanos), podría reducirlo a 24:

$*[0]=~/(1*)\z/;p$1.size

Esto usa expresiones regulares e imprime la longitud de la cadena devuelta por la expresión regular /(1*)\z/, donde \zes el final de la cadena. $*[0]es el primer argumento pasado y es una cadena de 0s y 1s.

Uso:

trailing_truths.rb 011101

Devuelve 1.


1
Una vez que tenga el índice del último valor falso, ¿por qué necesita recuperar elementos de la matriz nuevamente?
Lee W

Tienes razón, yo no. Gracias. ¡5 bytes de descuento!
IMP1
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.