Crollare i numeri


23

Definiamo la funzione a sui numeri naturali n , scritta come base 10 cifre , come segue:dkdk1d1d0

Finché ci sono cifre adiacenti uguali , sostituiscile con la loro somma da sinistra a destra. Se erano presenti tali cifre, ripetere la stessa procedura.didi1di+di1

In altre parole, in ogni iterazione prendiamo avidamente tutte le coppie di cifre adiacenti uguali e le sostituiamo con la loro somma allo stesso tempo (usando la coppia più a sinistra se si sovrappongono).

Esempio

Prendiamo ad esempio :9988

  1. Le prime cifre adiacenti uguali sono le due9
  2. Quindi li sostituiamo con che ci dà9 + 9=181888
  3. Dato che siamo ancora nella prima traversata sinistra-destra e c'erano ancora due s, dobbiamo prima sostituirli8
  4. Quindi otteniamo1816
  5. Qualcosa è cambiato, quindi dobbiamo fare un'altra iterazione
  6. Ma non ci sono cifre del genere, quindi ci fermiamo

Pertanto il numero in quella sequenza è .9988th1816

Sfida

I primi 200 termini sono:

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

Il tuo compito è anche quello di generare quella sequenza

  • dato n , restituire il nth numero in quella sequenza,
  • dato n , restituisce i primi n numeri in quella sequenza
  • o generare la sequenza indefinitamente.

Puoi scegliere il tuo invio per usare 0 - o 1 indicando, ma per favore specifica quale.

Casi test

È possibile utilizzare i termini sopra indicati, tuttavia eccone alcuni più grandi:

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

Risposte:



5

Python 2 , 97 96 93 byte

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

Provalo online!


Versione non regex:

Python 2 , 133 130 122 112 98 byte

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

Provalo online!


5

Gelatina , 11 byte

DŒg+2/€FVµ¡

Questo è un programma inutilmente lento e completo.

Provalo online!

Versione alternativa, 12 byte

DŒg+2/€FVµƬṪ

Un byte in più, ma molto più veloce. Funziona come un programma o una funzione.

Provalo online!

Come funziona

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 versione a 11 byte fa lo stesso, tranne per il fatto che chiama il collegamento n volte per l'ingresso n , invece di chiamarlo fino al raggiungimento di un punto fisso.


3
Non è necessario se si salva 1 byte :-)
Luis Mendo il

4

Haskell, 70 byte

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'input è preso come una stringa.

Provalo online!


Finora non ti fa risparmiare nulla, ma con la stessa lunghezza puoi sostituire la seconda clausola con |x<-b:c=a:f xo anche f(a:c)=a:f c, nel caso in cui l'una o l'altra potrebbe effettivamente portare a un miglioramento :)
flawr

4

JavaScript, 48 47 46 byte

Input e output come stringhe. Restituisce il nthtermine della sequenza.

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

Provalo online

  • 1 byte salvato grazie ad Arnauld
  • 1 byte salvato grazie a tsh

1
x[0]*2->x/5.5
TSH

Grazie @tsh. Non ci avrei pensato.
Shaggy

3

Perl 6 , 37 byte

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

Provalo online!

Questa è una funzione che genera l'ennesimo termine della sequenza, dato n come argomento.

($_, { ... } ... * == *)è la sequenza di successive modifiche al numero di input, generata dall'espressione tra parentesi (una semplice sostituzione regex) e si interrompe quando * == *, cioè quando gli ultimi due numeri nella sequenza sono uguali. Quindi [*-1]prende solo l'ultimo elemento di quella sequenza come valore di ritorno.


È possibile salvare byte rimuovendo ==*e sostituendo *-1con $_, poiché ci sono sempre meno di nsostituzioni per un numero n. 33 byte
Jo King

3

Retina , 16 byte

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

Provalo online! Il link include casi di test. Spiegazione:

+`

Ripetere fino a quando l'ingresso smette di cambiare.

(.)\1

Sostituisci coppie di cifre adiacenti ...

$.(2*$1*

... con il doppio della cifra. ( $1*genera una stringa di $1 _s, la 2*duplica e ne $.(prende la lunghezza. In realtà, il motore Retina è più intelligente di quello e raddoppia $1.)


3

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

EDIT: la funzione è ora a 185 byte più 18 per using System.Linq;

Grazie a BMO (per 1> 0 uguale a true più la rimozione della nuova riga) e Mr. XCoder (per le dichiarazioni f =! F)!

EDIT2: fino a 182 byte più 18 per using System.Linqgrazie a Dana per aver condiviso alcuni consigli sul golf!

EDIT3: Grazie a Embodiment of Ignorance per int [] -> var, rimozione del corto circuito && -> & e modifica ToArray -> ToList! (178 byte + 18 utilizzando)

EDIT4: l'incarnazione dell'ignoranza ha perso 4 byte modificando un compito. Manichino che avrei dovuto contare! Grazie ancora: 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;};

Provalo online!




2

Japt v2.0a0 -h, 15 14 byte

Restituisce il nthtermine della sequenza.

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

Provalo

Questo dovrebbe funzionare per 10 byte ma sembra esserci un bug nel metodo di sostituzione ricorsiva di Japt.

e/(.)\1/ÏÑ


2

05AB1E , 11 byte

Δγε2ôSO}˜J

Provalo online o verifica tutti i casi di test .

Spiegazione:

Δ             # 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

Lingua Wolfram 108 byte

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

Spiegazione

IntegerDigits trasforma il numero di input in un elenco delle sue cifre.

Split raggruppa cifre ripetute consecutive.

Partition[#, UpTo@2]&/@ suddivide le serie di cifre simili in elenchi di, al massimo, lunghezze di 2.

Flatten[...,1] elimina le parentesi graffe eccessivamente annidate occasionali, ad esempio {{2,2}} diventa {2,2}

Total/@somma i totali delle cifre associate. Le cifre isolate non devono essere sommate.

ToString converte i totali (e le cifre isolate) in stringhe.

""<> unisce tutte le stringhe nell'elenco.

ToExpression converte il risultato in un numero intero.

...~FixedPoint~#& applica la funzione fino a quando il risultato non cessa di cambiare.


2

C # (compilatore interattivo Visual C #) con flag /u:System.Text.RegularExpressions.Regex, 70 byte

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

Emette modificando l'ingresso. Comprende un elenco contenente una stringa per l'input.

Grazie a @dana per aver giocato a golf per un totale di 23 byte!

Provalo online!


95 + 34 - 33 + 1 per lo spazio extra necessario nella riga di comando args, iirc
ASCII-solo il

Le funzioni anonime ricorsive devono essere definite per prime e la definizione è inclusa nel conteggio dei byte.
Incarnazione dell'ignoranza il

Oh, è ricorsivo
solo ASCII il

1
Bello! Penso di poterlo abbattere un po 'di più
Incarnazione dell'ignoranza il

È un punteggio abbastanza buono considerando che è C # :)
dana il

1

Pulito , 118 byte

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

Provalo online!

Prende il primo valore ripetuto ( limit) dall'elenco infinito di applicazioni ( iterate) di un lambda che esegue una singola fase del processo di compressione. Input preso come a [Char].


1

Rosso , 84 83 80 byte

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

Provalo online!

Restituisce il nthtermine della sequenza.

Spiegazione:

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 # (compilatore interattivo Visual C #) , 111 byte

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

Provalo online!

Enorme credito a @ASCIIOnly per il golf ~ 30;) All'inizio stavamo entrambi postando simultaneamente aggiornamenti, ma a un certo punto è andato chiaramente in città!

-2 grazie a @EmbodimentOfIgnorance!

Meno codice 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,


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.