Effondrement des nombres


23

Définissons la fonction a sur les nombres naturels n , écrite en base 10 chiffres dkdk−1…d1d0 , comme suit:

Tant qu'il y a des chiffres adjacents égaux didi−1 , remplacez-les par leur sommedi+di−1 de gauche à droite. S'il y avait de tels chiffres, répétez la même procédure.

En d'autres termes, à chaque itération, nous prenons avidement toutes les paires de chiffres adjacents égaux et les remplaçons par leur somme en même temps (en utilisant la paire la plus à gauche si elles se chevauchent).

Exemple

Prenons 9988 par exemple:

  1. Les premiers chiffres adjacents qui sont égaux sont les deux 9
  2. On les remplace donc par 9 + 9=18 ce qui nous donne 1888
  3. Puisque nous sommes encore dans la première traversée gauche-droite et qu'il y avait encore deux 8 s, nous devons d'abord les remplacer
  4. Nous obtenons donc 1816
  5. Quelque chose a changé, nous devons donc refaire une itération
  6. Mais il n'y a pas de tels chiffres, alors nous nous arrêtons

Par conséquent, le 9988th nombre dans cette séquence est 1816 .

Défi

Les 200 premiers termes sont:

0,1,2,3,4,5,6,7,8,9,10,2,12,13,14,15,16,17,18,19,20,21,4,23,24,25,26,27,28,29,30,31,32,6,34,35,36,37,38,39,40,41,42,43,8,45,46,47,48,49,50,51,52,53,54,10,56,57,58,59,60,61,62,63,64,65,12,67,68,69,70,71,72,73,74,75,76,14,78,79,80,81,82,83,84,85,86,87,16,89,90,91,92,93,94,95,96,97,98,18,10,101,102,103,104,105,106,107,108,109,20,21,4,23,24,25,26,27,28,29,120,121,14,123,124,125,126,127,128,129,130,131,132,16,134,135,136,137,138,139,140,141,142,143,18,145,146,147,148,149,150,151,152,153,154,20,156,157,158,159,160,161,162,163,164,165,4,167,168,169,170,171,172,173,174,175,176,24,178,179,180,181,182,183,184,185,186,187,26,189,190,191,192,193,194,195,196,197,198,28

Votre tâche consiste à générer cette séquence, soit

  • étant donné n , retourner le nth nombre dans cette séquence,
  • étant donné n , retourne les n premiers nombres de cette séquence
  • ou générer la séquence indéfiniment.

Vous pouvez choisir votre soumission pour utiliser 0 - ou 1 indexation , mais veuillez préciser laquelle.

Cas de test

Vous pouvez utiliser les termes ci-dessus, mais en voici quelques-uns plus grands:

222 -> 42
1633 -> 4
4488 -> 816
15519 -> 2019
19988 -> 2816
99999 -> 18189
119988 -> 21816
100001 -> 101
999999 -> 181818

Réponses:




5

Gelée , 11 octets

DŒg+2/€FVµ¡

Il s'agit d'un programme complet inutilement lent.

Essayez-le en ligne!

Version alternative, 12 octets

DŒg+2/€FVµƬṪ

Un octet de plus, mais beaucoup plus rapide. Fonctionne comme un programme ou une fonction.

Essayez-le en ligne!

Comment ça marche

DŒg+2/€FVµƬṪ  Main link. Argument: n (integer)

         µ    Combine the previous links into a chain. Begin a new one.
D               Decimal; yield n's digit array in base 10.
 Œg             Group adjacent, identical digits into subarrays.
   +2/€         Map non-overlapping, pairwise sum over the subarrays.
                If there is an odd number of digits in a subarray, the
                last digit will remain untouched.
       F        Flatten; dump all sums and digits into a single array.
        V       Eval; turn the result into an integer.
          Ƭ   Execute the chain 'til the results are no longer unique.
              Return all unique results.
           Ṫ  Tail; extract the last result.

La version à 11 octets fait de même, sauf qu'elle appelle le lien n fois pour l'entrée n , au lieu de l'appeler jusqu'à ce qu'un point fixe soit atteint.


3
Ce n'est pas inutile s'il enregistre 1 octet :-)
— Luis Mendo

4

Haskell, 70 octets

until((==)=<<f)f
f(a:b:c)|a==b=show(2*read[a])++f c|1<2=a:f(b:c)
f a=a

L'entrée est considérée comme une chaîne.

Essayez-le en ligne!


Jusqu'à présent, cela ne vous sauve rien, mais avec la même longueur, vous pouvez remplacer la deuxième clause par |x<-b:c=a:f x ou même f(a:c)=a:f c, au cas où l'un ou l'autre pourrait réellement conduire à une amélioration :)
— flawr

4

JavaScript, 48 47 46 octets

Entrée et sortie sous forme de chaînes. Renvoie le nthterme de la séquence.

f=s=>s-(s=s.replace(/(.)\1/g,x=>x/5.5))?f(s):s

Essayez-le en ligne

  • 1 octet économisé grâce à Arnauld
  • 1 octet économisé grâce à tsh

1
x[0]*2->x/5.5
— tsh

Merci, @tsh. N'aurais pas pensé à ça.
— Shaggy

3

Perl 6 , 37 octets

{($_,{S:g[(\d)$0]=2*$0}...*==*)[*-1]}

Essayez-le en ligne!

Il s'agit d'une fonction qui génère le nième terme de la séquence, donné n comme argument.

($_, { ... } ... * == *)est la séquence de modifications successives du numéro d'entrée, générée par l'expression entre crochets (une simple substitution d'expression régulière) et s'arrêtant lorsque * == *, c'est-à-dire lorsque les deux derniers nombres de la séquence sont égaux. Ensuite, le [*-1]prend uniquement le dernier élément de cette séquence comme valeur de retour.


Vous pouvez économiser des octets en supprimant le ==*et en le remplaçant *-1par $_, car il y a toujours moins de nremplacements pour un nombre n. 33 octets
— Jo King

3

Rétine , 16 octets

+`(.)\1
$.(2*$1*

Essayez-le en ligne! Le lien inclut des cas de test. Explication:

+`

Répétez jusqu'à ce que l'entrée cesse de changer.

(.)\1

Remplacez les paires de chiffres adjacents ...

$.(2*$1*

... avec deux fois le chiffre. ( $1*génère une chaîne de $1 _s, 2*duplique cela et $.(prend la longueur. En fait, le moteur Retina est plus intelligent que cela et double simplement $1.)


3

C # (.NET Core) , 231 , 203 , 200 , 196 , 192 octets

EDIT: La fonction est maintenant à 185 octets plus 18 pour using System.Linq;

Merci à BMO (pour 1> 0 étant égal à true plus suppression de nouvelle ligne) et à M. XCoder (pour les instructions f =! F)!

EDIT2: jusqu'à 182 octets plus 18 pour using System.Linq remercier Dana d'avoir partagé quelques conseils de golf!

EDIT3: Merci à Embodiment of Ignorance pour l'int [] -> var, la suppression des courts-circuits && -> & et la modification de ToArray -> ToList! (178 octets + 18 en utilisant)

EDIT4: Incarnation de l'ignorance a chuté de 4 octets en modifiant une affectation. Dummy me shoulda counted! Merci encore: D

p=>{var f=1>0;while(f){var t=p.Select(n=>n-48).ToList();p="";f=!f;for(var j=0;j<t.Count;j++){if(j<t.Count-1&t[j]==t[1+j]){p+=t[j]+t[++j];f=!f;continue;}p+=t[j];}};return p;};

Essayez-le en ligne!




2

Japt v2.0a0 -h, 15 14 octets

Renvoie le nthterme de la séquence.

Æ=s_r/(.)\1/ÏÑ

Essayez-le

Cela devrait fonctionner pendant 10 octets, mais il semble y avoir un bogue dans la méthode de remplacement récursif de Japt.

e/(.)\1/ÏÑ


2

05AB1E , 11 octets

Δγε2ôSO}˜J

Essayez-le en ligne ou vérifiez tous les cas de test .

Explication:

Δ             # Continue until the (implicit) input no longer changes:
 γ            #  Split the integer in chunks of the same adjacent digits
              #   i.e. 199999889 → [1,99999,88,9]
  ε     }     #  Map each to:
   2ô         #   Split it into parts of size 2
              #    i.e. 99999 → [99,99,9]
     €S       #   Split each part into digits
              #    i.e. [99,99,9] → [[9,9],[9,9],[9]]
       O      #   And take the sum of each part
              #    i.e. [[9,9],[9,9],[9]] → [18,18,9]
         ˜    #  Flatten the list
              #   i.e. [[1],[18,18,9],[16],[9]] → [1,18,18,9,16,9]
          J   #  Join everything together
              #   i.e. [1,18,18,9,16,9] → 118189169
              # (And output the result implicitly at the end)
              #  i.e. output = 28189169

2

Langue Wolfram 108 octets

ToExpression[""<>ToString/@Total/@Flatten[Partition[#,UpTo@2]&/@Split@IntegerDigits@#,1]]&~FixedPoint~#&

Explication

IntegerDigits transforme le numéro d'entrée en une liste de ses chiffres.

Split regroupe des chiffres répétés consécutifs.

Partition[#, UpTo@2]&/@ décompose des séries de chiffres similaires en listes d'au plus 2 longueurs.

Flatten[...,1] élimine les accolades occasionnellement trop imbriquées - par exemple, {{2,2}} devient {2,2}

Total/@somme les totaux des chiffres appariés. Les chiffres isolés n'ont pas besoin d'être additionnés.

ToString convertit les totaux (et les chiffres isolés) en chaînes.

""<> joint toutes les chaînes de la liste.

ToExpression convertit le résultat en un entier.

...~FixedPoint~#& applique la fonction jusqu'à ce que le résultat cesse de changer.


2

C # (Visual C # Interactive Compiler) avec indicateur /u:System.Text.RegularExpressions.Regex, 70 octets

s=>{for(;s[0]!=(s[0]=Replace(s[0],@"(.)\1",m=>m.Value[0]*2-96+"")););}

Sorties en modifiant l'entrée. Prend une liste contenant une chaîne pour l'entrée.

Merci à @dana d'avoir joué au golf pendant 23 octets!

Essayez-le en ligne!


95 + 34 - 33 + 1 pour l'espace supplémentaire dont vous avez besoin dans les arguments de la ligne de commande, iirc
— ASCII uniquement le

Les fonctions anonymes récursives doivent être définies en premier et la définition est incluse dans le nombre d'octets.
— Incarnation de l'ignorance

Oh, c'est récursif
— ASCII uniquement le

1
Agréable! Je pense que je peux le comprendre un peu plus
— Embodiment of Ignorance

C'est un très bon score étant donné que c'est C # :)
— dana

1

Nettoyer , 118 octets

import StdEnv,Data.List
$[a,b:t]|a==b=[1,(a*2)rem 10]%(1-a/5,1)++ $t=[a: $[b:t]]
$l=l

limit o iterate$o map digitToInt

Essayez-le en ligne!

Prend la première valeur répétée ( limit) de la liste infinie d'applications ( iterate) d'un lambda effectuant une seule étape du processus d'effondrement. Entrée prise comme a [Char].


1

Rouge , 84 83 80 octets

func[n][if parse s: form n[to some change[copy d skip d](2 * do d)to end][f s]s]

Essayez-le en ligne!

Renvoie le nthterme de la séquence.

Explication:

Red[]
f: func [ n ] [
    if parse s: form n [  ; parse the input converted to a string
        to some change [  ; find and change one or more
            copy d skip   ; digit (in fact any character, no predefined character classes)
            d             ; followed by itself
        ] (2 * do d)      ; with its doubled numeric value 
        to end            ; go to the end of the string
    ] [ f s ]             ; call the function with the altered string if parse returned true
    s                     ; finally return the string 
]


1

C # (Visual C # Interactive Compiler) , 111 octets

s=>{var t=s;do{s=t;t="";for(int i=0;i<s.Length;)t+=s[i]%48*(s[i++]!=(s+0)[i]?1:2*++i/i);}while(t!=s);return t;}

Essayez-le en ligne!

ÉNORME crédit à @ASCIIOnly pour avoir joué au golf ~ 30;) Au début, nous publions tous les deux des mises à jour simultanément, mais à un moment donné, il est clairement allé en ville!

-2 grâce à @EmbodimentOfIgnorance!

Moins de code golfé ...

// s is the input as a string
s=>{
  // t is another string used
  // to hold intermediate results
  var t=s;
  // the algorithm repeatedly
  // processes s and saves the
  // result to t
  do{
    // copy the last result to s
    // and blank out t
    s=t;
    t="";
    // iterate over s
    for(int i=0;i<s.Length;)
      // append either 1 or 2 times
      // the current digit to t
      t+=s[i]%48*
        // compare the current digit
        // to the next digit. to prevent
        // an out-of-bounds exception,
        // append a 0 to s which either
        // gets ignored or collapses
        // to 0
        (s[i++]!=(s+0)[i]
          // if they are different, then
          // the multiplier is 1
          ?1
          // if they are the same, then
          // the multiplier is 2, and we
          // have to increment i
          :2*++i/i);
  }
  // continue this until the input
  // and output are the same
  while(t!=s);
  return t;
}



@ASCIIOnly - Good move :) (s[i++]-48)*2=>s[i++]*2-96
— dana


En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.