¿Se ha degenerado mi juego Diffy?

23

Recientemente publiqué una pregunta sobre los juegos de Diffy que no ha recibido respuesta. Está bien, la pregunta es realmente difícil, pero me gustaría hacer una pregunta más fácil sobre los juegos de Diffy para que podamos poner la pelota en marcha.


¿Cómo funciona Diffy?

Copiado de Find Diffy Games

El juego Diffy funciona de la siguiente manera: comienzas con una lista de enteros no negativos, en este ejemplo usaremos

3 4 5 8

Luego tomas la diferencia absoluta entre números adyacentes

 (8)  3   4   5   8
    5   1   1   3

Entonces repites. Repite hasta que se da cuenta de que ha entrado en un bucle. Y luego, en general, el juego comienza desde el principio nuevamente.

3 4 5 8
5 1 1 3
2 4 0 2
0 2 4 2
2 2 2 2
0 0 0 0
0 0 0 0

La mayoría de los juegos terminan en una cadena de todos los ceros, lo que se considera un estado perdido, pero algunos juegos raros se atascan en bucles más grandes.


Tarea

Dado el estado inicial de un juego Diffy, determine si el juego finalmente alcanza o no un estado de todos ceros. Debe generar un valor de Verdad o Falsía para cada uno de los dos estados. Lo que corresponde a lo que no importa.

El objetivo es minimizar el número de bytes en su fuente.

Asistente de trigo
fuente
1
La redacción de la tarea parece implicar que cualquier juego que no alcanza un estado de todos los ceros es, por lo tanto, periódico. Anteriormente, periódico se define como la inclusión del estado inicial en la secuencia repetida. ¿Significa esto que alguna secuencia eventualmente alcanza todos los ceros o el estado inicial?
trichoplax
3
No: agregar una constante positiva a cualquier estado periódico que no sea cero da como resultado un estado que no vuelve a sí mismo ni va a todos los ceros. Por ejemplo, 1 1 0es periódico, también lo 42 42 41es ese estado.
Greg Martin
3
De hecho, para la pregunta específica que se hace, uno ni siquiera necesita una noción de "periódico". "Eventualmente alcanza un estado de todos los ceros" es autocontenido y claro.
Greg Martin
2
He demostrado una caracterización parcial: si la longitud de la lista nes impar, el juego no llega a cero a menos que todos los números sean iguales. Si la longitud es una potencia de 2, siempre va a cero.
xnor
3
Un límite de la cantidad de pasos para llegar a cero: una lista con nelementos y máximo mtoma en la mayoría de los n * bit_length(m)pasos. Entonces, n*mtambién es un límite superior. Un límite superior más fuerte es t(n) * bit_length(m), donde t(n)es la mayor potencia de 2 que es un factor de n.
xnor

Respuestas:

27

Pyth, 6 bytes

suaV+e

Banco de pruebas

Este programa es muy suave. 0 (falso) significa todos los ceros, cualquier otra cosa (verdad) significa no todos los ceros.

Cómo funciona:

suaV+e
suaV+eGGGQ    Variable introduction.
 u       Q    Apply the following function repeatedly to its previous result,
              starting with the input. Stop when a value occurs which has
              occurred before.
  aV          Take the absolute differences between elements at the same indices of
        G     The previous list and
    +eGG      The previous list with its last element prepended.
s             The repeated value is returned. Sum its entries. This is zero (falsy)
              if and only if the entries are all zero.
isaacg
fuente
66
esa es una solución suave
Martijn Vissers
14

Mathematica, 52 bytes

1>Max@Nest[Abs[#-RotateLeft@#]&,#,Max[1+#]^Tr[1^#]]&

Función pura que toma una lista de enteros no negativos como entrada y retorno Trueo False.

Abs[#-RotateLeft@#]&es una función que ejecuta una ronda del juego de diferencia. (Técnicamente debería serlo RotateRight, pero la respuesta final no se ve afectada, y bueno, byte libre). Entonces se Nest[...,#,R]ejecutaR rondas del juego de diferencia y luego 1>Max@detecta si el resultado es todo ceros.

¿Cómo sabemos cuántas rondas de juego de diferencia Rhacer? Si mes el valor más grande en la entrada, observe que nunca produciremos un número entero mayor que mno importa cuántas rondas hagamos. El número total de listas de longitud lde enteros no negativos todos delimitados por mes (m+1)^l. Entonces, si llevamos a cabo (m+1)^lrondas del juego de diferencia, estamos garantizados de haber visto alguna lista dos veces para entonces, y así estaremos en la parte periódica del juego. En particular, el juego termina en todos los ceros si y solo si el resultado de las (m+1)^lrondas del juego es la lista de todos los ceros. Esa expresión es lo que Max[1+#]^Tr[1^#]calcula.

Greg Martin
fuente
6

Jalea , 13 bytes

Ṁ‘*L
ṙ1ạ
ÇÑ¡Ṁ

Emite 0 (falsey) si se alcanzará el estado cero, de lo contrario se devuelve un valor verdadero (un entero positivo).

Pruébalo en línea!

Utiliza la primera observación hecha por Greg Martin de que los números dentro de la matriz nunca pueden abandonar el dominio [0, m] donde m es el elemento máximo en la entrada, por lo que realizar (m + 1) l redondea donde l es la longitud de la entrada satisfacer.

¿Cómo?

Ṁ‘*L - Link 1, number of rounds to perform: list a
Ṁ    - maximum of a
 ‘   - incremented
   L - length of a
  *  - exponentiate

ṙ1ạ - Link 2, perform a round: list x
ṙ1  - rotate x left by 1
  ạ - absolute difference (vectorises) with x

ÇÑ¡Ṁ - Main link: list a
  ¡  - repeat:
Ç    -     the last link (2) as a monad
 Ñ   -     the next link (1) as a monad times
   Ṁ - return the maximum of the resulting list
Jonathan Allan
fuente
¿Podría mejorarse esto con el límite de xnor ?
Wheat Wizard
@WheatWizard Creo que costaría un byte. (Es posible obtener un método más corto recopilando todos los resultados hasta que no sean únicos, pero no lo he encontrado).
Jonathan Allan
2

PHP, 144 bytes

imprima 0 para todo cero y cualquier valor entero positivo para verdadero

<?for($r[]=$_GET[0];!$t;){$e=end($r);$e[]=$e[$c=0];for($n=[];++$c<count($e);)$n[]=abs($e[$c-1]-$e[$c]);$t=in_array($n,$r);$r[]=$n;}echo max($n);

Versión en línea

Expandido

for($r[]=$_GET;!$t;){
    $e=end($r);  # copy last array
    $e[]=$e[$c=0]; # add the first item as last item
    for($n=[];++$c<count($e);)$n[]=abs($e[$c-1]-$e[$c]); # make new array
    $t=in_array($n,$r); # is new array in result array
    $r[]=$n; # add the new array
}
echo max($n); # Output max of last array
Jörg Hülsermann
fuente
1
array_push? Pero por qué ?
Christoph
1
Además, si se usa $_GETcomo entrada, debe suponer que contiene una cadena.
Christoph
1
@ Christoph ?0[0]=1&0[1]=1&0[2]=0o ?0[]=1&0[]=1&0[]=0es una matriz de cadenas, pero esto no importa. Pero tiene razón, podría ?0=1&1=1&2=0acortarlo con por qué no àrray_push` Estoy seguro de que usted o Titus encuentran mejores formas de acortar esto.
Jörg Hülsermann
1
array_push($e,$e[$c=0]);es exactamente igual $e[]=$e[$c=0];e incluso ya usa la sintaxis ( $r[]=$n). Ya utiliza maxahora lo que también debe reemplazar end($r)con $nporque $nes siempre igual a end($r)cuando el eco se ejecuta.
Christoph
@ Christoph Parece que ayer no fue mi día. Gracias. Me has traído a mi idea una nueva entrada en la sección de consejos
Jörg Hülsermann
2

R (3.3.1), 87 bytes

Devuelve cero para un juego que termina en todos ceros, y un número positivo de lo contrario.

z=scan();sum(Reduce(function(x,y)abs(diff(c(x,x[1]))),rep(list(z),max(z+1)^length(z))))

aprovecha el mismo hecho de Greg Martin y usa el diff incorporado para hacer la diferencia

Giuseppe
fuente
siempre que el límite de xnor sea correcto (de los comentarios), esto podría ser dos bytes más corto usando max (z) * length (z) pero no estoy convencido de la corrección
Giuseppe
1

Röda , 80 bytes

f l...{x=[{peek a;[_];[a]}()|slide 2|abs _-_];[sum(x)=0]if[x in l]else{x|f*l+x}}

Pruébalo en línea!

Sin golf:

function f(l...) { /* function f, variadic arguments */
    x := [ /* x is a list of */
        { /* duplicate the first element of the stream to the last position */
            peek a /* read the first element of the stream */
            [_]    /* pull all values and push them */
            [a]    /* push a */
        }() |
        slide(2) | /* duplicate every element except first and last */
        abs(_-_)   /* calculate the difference of every pair */
    ]
    /* If we have already encountered x */
    if [ x in l ] do
        return sum(x) = 0 /* Check if x contains only zeroes */
    else
        x | f(*l+x) /* Call f again, with x appended to l */
    done
}
fergusq
fuente
1

05AB1E , 13 bytes

Devuelve 1 si termina en ceros y 0 en caso contrario.

Z¹g*F¤¸ì¥Ä}_P

Pruébalo en línea!

Explicación

Utiliza el límite superior de rondas: max(input)*len(input)explicado por xnor en la sección de comentarios.

Z              # get max(input)
 ¹g            # get length of input
   *           # multiply
    F          # that many times do:
     ¤         # get the last value of the current list (originally input)
      ¸        # wrap it
       ì       # prepend to the list
        ¥      # calculate deltas
         Ä     # calculate absolute values
          }    # end loop
           _   # negate each (turns 0 into 1 and everything else to 0)
            P  # calculate product
Emigna
fuente
1

J, 22 bytes

Devuelve 0(que está efectivamente falseen J) para un juego degenerado que termina en todos ceros. Devuelve 1( true) si la enésima iteración contiene un número distinto de cero, donde n es igual al número entero más grande en la secuencia original multiplicado por la longitud de la lista. Vea la respuesta de Greg Martin explicando por qué esto es cierto.

*>./|&(-1&|.)^:(#*>./)

Traducción:

  • Cual es el signo *
  • del mayor valor >./
  • cuando iteras lo siguiente tantas veces como ^:( )
  • la longitud de la lista #multiplicada por *el mayor valor en la lista >./:
    • tomar el valor absoluto |&de
    • la diferencia entre la lista (- )y
    • la lista rota por uno 1&|.

Ejemplos:

   *>./|&(-1&|.)^:(#*>./) 1 1 0
1
   *>./|&(-1&|.)^:(#*>./) 42 42 41
1
   *>./|&(-1&|.)^:(#*>./) 3 4 5 8
0
   *>./|&(-1&|.)^:(#*>./) 0 0 0 0 0 0 0 0 0 0 0 0 0 1 2 1
0
danés
fuente
1
Esa no es la afirmación de Greg Martin. Sin embargo, xnor tiene mejores límites en los comentarios anteriores (pero aún no es solo el número entero más grande). Lo más simple es multiplicar el mayor valor con la longitud.
Ørjan Johansen el
Buena atrapada. No estaba prestando suficiente atención. Arreglaré la solución.
Dane
1

JavaScript (ES6), 95 92 90 bytes

f=(a,b=(Math.max(...a)+1)**(c=a.length))=>b?f(a.map((v,i)=>v-a[++i%c]),b-1):a.every(v=>!v)

Explicación

La función recursiva que se llama a sí misma siempre que el contador (que comienza en el valor máximo en la lista más uno a la potencia de la longitud de la lista [ = (max + 1)**length]) no sea cero. En cada llamada, el contador disminuye, y cuando llega a cero, todos los elementos de la lista se comparan con cero. Si todos son iguales a cero, el programa vuelve true, y de lo falsecontrario.

Luke
fuente
1

PHP, 123 115

for($a=$_GET,$b=[];!in_array($a,$b);){$b[]=$c=$a;$c[]=$c[0];foreach($a as$d=>&$e)$e=abs($e-$c[$d+1]);}echo!max($a);

tomar entrada a través de HTTP get, por ejemplo, ?3&4&5&8guarda algunos bytes.

Imprime 1 si alcanza todos los ceros o nada de lo contrario.


for($e=$argv,$r=[];!in_array($e,$r);$q=$e[0]){$e[0]=end($e);$r[]=$e;foreach($e as$k=>&$q)$q=abs($q-$e[$k+1]);}echo!max($e);

toma la lista de argumentos a través de la línea de comando. Tengo la sensación de que esto se puede jugar aún más (mirando a @Titus).

Christoph
fuente
1

Python 3.6, 101 bytes

def f(t):
 x={}
 while x.get(t,1):x[t]=0;t=(*(abs(a-b)for a,b in zip(t,t[1:]+t[:1])),)
 return any(t)

Toma una tupla de números y devuelve False si termina en ceros y True si se repite.

RootTwo
fuente
0

JavaScript (ES6), 84 83 bytes

Devuelve truepara un juego que termina en todos ceros, de lo falsecontrario.

f=(a,k=a)=>k[b=a.map((n,i)=>Math.abs(n-a[(i||a.length)-1]))]?!+b.join``:f(k[b]=b,k)

Prueba

Arnauld
fuente