Mon jeu Diffy est-il dégénéré?

23

Récemment, j'ai posté une question sur les jeux Diffy qui est restée sans réponse. C'est très bien, la question est vraiment difficile, mais je voudrais poser une question plus facile sur les jeux Diffy afin que nous puissions faire bouger les choses.


Comment fonctionne Diffy

Copié à partir de Find Diffy Games

Le jeu Diffy fonctionne comme suit: Vous commencez avec une liste d'entiers non négatifs, dans cet exemple, nous utiliserons

3 4 5 8

Ensuite, vous prenez la différence absolue entre les nombres adjacents

 (8)  3   4   5   8
    5   1   1   3

Ensuite, vous répétez. Vous répétez jusqu'à ce que vous réalisiez que vous êtes entré dans une boucle. Et puis généralement le jeu recommence depuis le début.

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 plupart des jeux se terminent par une chaîne de tous les zéros, ce qui est considéré comme un état de perte, mais quelques rares jeux sont bloqués dans des boucles plus grandes.


Tâche

Étant donné l'état de départ d'un jeu Diffy, déterminez si le jeu atteint ou non un état de tous les zéros. Vous devez générer une valeur Truthy ou Falsy pour chacun des deux états. Ce qui correspond à ce qui n'a pas d'importance.

L'objectif est de minimiser le nombre d'octets dans votre source.

Assistant de blé
la source
1
Le libellé de la tâche semble impliquer que tout jeu qui n'atteint pas un état de tous les zéros est donc périodique. Plus tôt, périodique est défini comme incluant l'état initial dans la séquence répétée. Est-ce à dire que toute séquence atteint finalement tous les zéros ou l'état initial?
trichoplax
3
Non: l'ajout d'une constante positive à tout état périodique différent de zéro entraîne un état qui ne revient ni à lui-même ni à tous les zéros. Par exemple, 1 1 0est périodique, tout 42 42 41comme un tel état.
Greg Martin
3
En effet, pour la question spécifique posée, on n'a même pas besoin d'une notion de "périodique". "Atteint finalement un état de tous les zéros" est autonome et clair.
Greg Martin
2
J'ai prouvé une caractérisation partielle: si la longueur de la liste nest impaire, le jeu ne passe à zéro que si tous les nombres sont égaux. Si la longueur est une puissance de 2, elle va toujours à zéro.
2017
3
Une limite du nombre d'étapes pour atteindre zéro: Une liste avec des néléments et un maximum mprend au plus des n * bit_length(m)étapes. Donc, n*mc'est aussi une limite supérieure. Une limite supérieure plus forte est t(n) * bit_length(m), où t(n)est la plus grande puissance de 2 qui est un facteur de n.
xnor

Réponses:

27

Pyth, 6 octets

suaV+e

Suite de tests

Ce programme est très suave. 0 (faux) signifie tous les zéros, tout le reste (véridique) ne signifie pas tous les zéros.

Comment ça marche:

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
la source
6
c'est une solution suave
Martijn Vissers
14

Mathematica, 52 octets

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

Fonction pure prenant une liste d'entiers non négatifs en entrée et retournant True ou False.

Abs[#-RotateLeft@#]&est une fonction qui exécute un tour du jeu diffy. (Techniquement, cela devrait l'être RotateRight, mais la réponse ultime n'est pas affectée, et bon, octet libre.) DoncNest[...,#,R] Exécute Rtours du jeu diffy, puis 1>Max@détecte si le résultat est des zéros.

Comment savons-nous combien de tours de jeu diffy Rfaire? Si mest la plus grande valeur dans l'entrée, notez que nous ne produirons jamais un entier plus grand que mle nombre de tours que nous faisons. Le nombre total de listes de longueur ld'entiers non négatifs tous bornés par mest (m+1)^l. Donc, si nous effectuons des (m+1)^ltours du jeu diffy, nous sommes assurés d'avoir vu une liste deux fois d'ici là, et nous serons donc dans la partie périodique du jeu. En particulier, le jeu se termine par tous les zéros si et seulement si le résultat des (m+1)^ltours du jeu est la liste des zéros. Cette expression est ce qui Max[1+#]^Tr[1^#]calcule.

Greg Martin
la source
6

Gelée , 13 octets

Ṁ‘*L
ṙ1ạ
ÇÑ¡Ṁ

Sorties 0 (falsey) si l'état tout zéro sera atteint, sinon une valeur véridique (un entier positif) est retournée.

Essayez-le en ligne!

Utilise l'observation d'abord faite par Greg Martin que les nombres dans le tableau ne peuvent jamais quitter le domaine [0, m]m est l'élément maximal dans l'entrée, donc effectuer (m + 1) l tours où l est la longueur de l'entrée sera suffire.

Comment?

Ṁ‘*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
la source
Cela pourrait-il être amélioré avec xnor lié ?
Wheat Wizard
@WheatWizard Je pense que cela coûterait un octet. (Il pourrait être possible d'obtenir une méthode plus courte en collectant tous les résultats jusqu'à ce qu'ils ne soient pas uniques, mais je ne les ai pas trouvés).
Jonathan Allan
2

PHP, 144 octets

affiche 0 pour tout zéro et toute valeur entière positive pour vrai

<?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);

Version en ligne

Étendu

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
la source
1
array_push? Mais pourquoi ?
Christoph
1
aussi si vous utilisez $_GETcomme entrée, vous devez supposer qu'il contient une chaîne.
Christoph
1
@Christoph ?0[0]=1&0[1]=1&0[2]=0ou ?0[]=1&0[]=1&0[]=0est un tableau de chaînes mais cela n'a pas d'importance. Mais vous avez raison, je pourrais le raccourcir avec ?0=1&1=1&2=0pourquoi pas àrray_push` Je suis sûr que vous ou Titus trouvez de meilleures façons de raccourcir cela.
Jörg Hülsermann
1
array_push($e,$e[$c=0]);est tout simplement identique à $e[]=$e[$c=0];et vous utilisez même déjà la syntaxe ( $r[]=$n). Vous l'utilisez déjà maxmaintenant, vous devez donc également le remplacer end($r)par $ncar $nest toujours égal à end($r)l'exécution de l'écho.
Christoph
@Christoph Il semble que hier n'était pas ma journée. Merci. Vous m'avez amené à mon idée d'une nouvelle entrée dans la section des conseils
Jörg Hülsermann
2

R (3.3.1), 87 octets

Renvoie zéro pour un jeu se terminant par tous les zéros et un nombre positif sinon.

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

exploite le même fait par Greg Martin et utilise le diff intégré pour faire la diff

Giuseppe
la source
à condition que la limite de xnor soit correcte (d'après les commentaires), cela pourrait être deux octets plus court en utilisant max (z) * longueur (z) mais je ne suis pas convaincu de l'exactitude
Giuseppe
1

Röda , 80 octets

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

Essayez-le en ligne!

Non 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
la source
1

05AB1E , 13 octets

Renvoie 1 s'il se termine par des zéros et 0 sinon.

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

Essayez-le en ligne!

Explication

Utilise la limite supérieure des arrondis : max(input)*len(input)expliquée par xnor dans la section des commentaires.

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
la source
1

J, 22 octets

Renvoie 0(qui est effectivement falseen J) pour un jeu dégénéré se terminant par tous les zéros. Renvoie 1( true) si la nième itération contient un nombre non nul, où n est égal au plus grand entier de la séquence d'origine multiplié par la longueur de la liste. Voir la réponse de Greg Martin expliquant pourquoi cela est vrai.

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

Traduction:

  • Quel est le signe *
  • de la plus grande valeur >./
  • lorsque vous répétez autant de fois que ^:( )
  • la longueur de la liste #multipliée par* la plus grande valeur de la liste>./ :
    • prendre la valeur absolue |& de
    • la différence entre la liste (- ) et
    • la liste a tourné d'un 1&|.

Exemples:

   *>./|&(-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
Danois
la source
1
Ce n'est pas ce que prétend Greg Martin. Cependant, xnor a de meilleures limites dans les commentaires ci-dessus (mais pas seulement le plus grand entier). Le plus simple est de multiplier la plus grande valeur par la longueur.
Ørjan Johansen
Bonne prise. Je ne faisais pas assez attention. Je vais réparer la solution.
Danois
1

JavaScript (ES6), 95 92 90 octets

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)

Explication

Fonction récursive qui s'appelle tant que le compteur (qui commence à la valeur maximale dans la liste plus un à la puissance de la longueur de la liste [ = (max + 1)**length]) n'est pas nul. À chaque appel, le compteur est décrémenté et lorsqu'il atteint zéro, tous les éléments de la liste sont vérifiés par rapport à zéro. S'ils sont tous égaux à zéro, le programme retourne trueetfalse sinon.

Luc
la source
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);

prendre une entrée via HTTP obtenir par exemple ?3&4&5&8 enregistre quelques octets.

Imprime 1 s'il atteint tous les zéros ou rien d'autre.


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);

prend la liste des arguments via la ligne de commande. J'ai l'impression que cela peut être joué encore plus loin (en regardant @Titus).

Christoph
la source
1

Python 3.6, 101 octets

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)

Prend un tuple de nombres et retourne False s'il se termine par des zéros et True s'il boucle.

RootTwo
la source
0

JavaScript (ES6), 84 83 octets

Retourne truepour un jeu se terminant par tous les zéros, falsesinon.

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)

Tester

Arnauld
la source