Effondrement des nombres

23

Définissons la fonction a sur les nombres naturels n , écrite en base 10 chiffres dkdk1d1d0 , comme suit:

Tant qu'il y a des chiffres adjacents égaux didi1 , remplacez-les par leur sommedi+di1 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
ბიმო
la source

Réponses:

6

Python 3 , 128 octets

def t(z):j=z and(z[0]==z[1:2])+1;return[str(int(z[0])*j),*t(z[j:])]if j else''
def c(n):r="".join(t(n));return r!=n and c(r)or r

Essayez-le en ligne!

anon3128
la source
5
Bienvenue chez PPCG! Bon premier post!
Rɪᴋᴇʀ
1
108 octets
Jo King
5

Python 2 , 97 96 93 octets

def f(n):r=re.sub(r'(.)\1',lambda m:`int(m.group(1))*2`,n);return r!=n and f(r)or r
import re

Essayez-le en ligne!


Version non regex:

Python 2 , 133 130 122 112 112 98 octets

def f(n):
 r='';s=n
 while s:a=1+(s[0]==s[1:2]);r+=`int(s[0])*a`;s=s[a:]
 return r!=n and f(r)or r

Essayez-le en ligne!

TFeld
la source
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.

Dennis
la source
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!

nimi
la source
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
Hirsute
la source
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.

Sean
la source
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.)

Neil
la source
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!

Destroigo
la source
2
174 avant utilisation
Embodiment of Ignorance
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/ÏÑ
Hirsute
la source
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
Kevin Cruijssen
la source
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.

DavidC
la source
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!

Incarnation de l'ignorance
la source
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].

Οurous
la source
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 
]
Galen Ivanov
la source
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;
}
dana
la source
139
ASCII uniquement le
134
ASCII uniquement le
@ASCIIOnly - Good move :) (s[i++]-48)*2=>s[i++]*2-96
dana
131
ASCII uniquement
1
114
ASCII uniquement le