Monday Mini-Golf # 4: JARVIS (Solo otro conjunto bastante extenso de secuencias enteras)

22

Minigolf de lunes: una serie de preguntas breves de , publicadas (¡ojalá!) Todos los lunes.
(Lo siento, llego tarde otra vez; básicamente estuve lejos de mi computadora ayer y hoy).

Nosotros, los programadores (especialmente los golfistas de código), amamos las secuencias enteras arbitrarias. Incluso tenemos un sitio completo dedicado a estas secuencias que actualmente tiene alrededor de 200,000 entradas. En este desafío, implementaremos otro conjunto de estas secuencias.

Reto

Su desafío es escribir un programa o función que tome un entero N y genere una secuencia de enteros de base 10, donde cada entero siguiente se determina de esta manera:

  • Comience en 1.
  • Para cada dígito D en la representación de base 10 del entero anterior:

    • Si D es 0, agregue uno al entero actual.
    • De lo contrario, se multiplica el número entero actual por D .

Detalles

  • Puede suponer que 0 < N <2 31 .
  • Debe generar cada número entero en la secuencia, comenzando con el número de entrada, hasta alcanzar un número menor que 10.
  • El resultado puede ser una matriz o una cadena separada por espacios, comas, líneas nuevas o una combinación de estos.
  • Se permite un espacio final y / o una nueva línea, pero no una coma final.
  • Nunca debe haber ceros a la izquierda.

Ejemplos

Ejemplo 1: 77

Este ejemplo es bastante sencillo:

77 = 1*7*7 = 49
49 = 1*4*9 = 36
36 = 1*3*6 = 18
18 = 1*1*8 = 8

Por lo tanto, la salida adecuada es 77 49 36 18 8.

Ejemplo 2 90

Aquí tenemos:

90 = 1*9+1 = 10
10 = 1*1+1 = 2

Entonces la salida sería 90 10 2.

Ejemplo 3: 806

Lea las ecuaciones de izquierda a derecha:

806 = 1*8+1*6 = 54 (((1*8)+1)*6)
 54 = 1*5*4   = 20
 20 = 1*2+1   = 3

La salida debería ser 806 54 20 3.

Casos de prueba

El primer número en cada línea es la entrada, y la línea completa es la salida esperada.

77 49 36 18 8
90 10 2
249 72 14 4
806 54 20 3
1337 63 18 8
9999 6561 180 9
10000 5
8675309 45369 3240 25 10 2
9999999 4782969 217728 1568 240 9
1234567890 362881 2304 28 16 6

Como referencia, aquí están los siguientes enteros del 10 al 100:

Current | Next
--------+-----
     10 |  2
     11 |  1
     12 |  2
     13 |  3
     14 |  4
     15 |  5
     16 |  6
     17 |  7
     18 |  8
     19 |  9
     20 |  3
     21 |  2
     22 |  4
     23 |  6
     24 |  8
     25 | 10
     26 | 12
     27 | 14
     28 | 16
     29 | 18
     30 |  4
     31 |  3
     32 |  6
     33 |  9
     34 | 12
     35 | 15
     36 | 18
     37 | 21
     38 | 24
     39 | 27
     40 |  5
     41 |  4
     42 |  8
     43 | 12
     44 | 16
     45 | 20
     46 | 24
     47 | 28
     48 | 32
     49 | 36
     50 |  6
     51 |  5
     52 | 10
     53 | 15
     54 | 20
     55 | 25
     56 | 30
     57 | 35
     58 | 40
     59 | 45
     60 |  7
     61 |  6
     62 | 12
     63 | 18
     64 | 24
     65 | 30
     66 | 36
     67 | 42
     68 | 48
     69 | 54
     70 |  8
     71 |  7
     72 | 14
     73 | 21
     74 | 28
     75 | 35
     76 | 42
     77 | 49
     78 | 56
     79 | 63
     80 |  9
     81 |  8
     82 | 16
     83 | 24
     84 | 32
     85 | 40
     86 | 48
     87 | 56
     88 | 64
     89 | 72
     90 | 10
     91 |  9
     92 | 18
     93 | 27
     94 | 36
     95 | 45
     96 | 54
     97 | 63
     98 | 72
     99 | 81
    100 |  3

Puede encontrar esta lista ampliada a 10000 aquí .

Tanteo

Este es el , por lo que gana el código válido más corto en bytes. Tiebreaker va a la presentación que alcanzó su conteo final de bytes primero. El ganador será elegido el próximo lunes 19 de octubre. ¡Buena suerte!

Editar: ¡ Felicidades a tu ganador, @isaacg , usando Pyth una vez más por 14 bytes !

ETHproducciones
fuente

Respuestas:

10

Pyth, 15 14 bytes

.uu|*GHhGjNT1Q

1 byte gracias a Dennis

Banco de pruebas

Este desafío parece hecho para las funciones de reducción de Pyth. Una reducción sobre los dígitos, una reducción hasta que el valor deja de cambiar y estamos bien.

isaacg
fuente
2
|*GHhGguarda un byte encima ?H*GHhG.
Dennis
4

PowerShell, 92 91 90 88 87 bytes

($n=$args);while($n-gt9){$x=1;[char[]]"$n"|%{$x=if($y=$_-48){$x*$y}else{$x+1}};($n=$x)}
Andrés
fuente
1
Eso es bastante hábil, usar (...)para aprovechar la salida automática ... Voy a necesitar recordar eso en el futuro.
AdmBorkBork
3

Pip , 28 25 23 bytes

Tt>Pa{Y1FdaYy*d|y+1a:y}

Toma un número como argumento de línea de comando y genera la secuencia en líneas sucesivas.

Explicación:

                         a is cmdline arg; t is 10 (implicit)
Tt>Pa{                }  Loop till a<10, printing it each time the test is made:
      Y1                   Yank 1 into variable y
        Fda                For each digit d in a:
           Yy*d|y+1          If y*d is truthy (nonzero), yank it; otherwise, yank y+1
                   a:y     Assign value of y back to a

Ahora me alegro de haber cambiado Pde una declaración a un operador hace varias revisiones. Paes una expresión que evalúa ael valor de 'pero también lo genera, por lo que puedo imprimir ay probar simultáneamente si es menos de diez usando t>Pa.

DLosc
fuente
3

CJam, 26 25 24 22 bytes

riA,{_pAb{_2$*@)?}*j}j

o

ri{_pAb{_2$*@)?}*_9>}g

Pruébalo en línea.

Cómo funciona

Ambos programas esencialmente hacen lo mismo; el primero es un enfoque recursivo, el segundo es iterativo. Explicaré el primero, que considero más interesante.

ri                     Read an integer from STDIN and push it on the stack.
  A,{               }j Initialize a memoized, recursive function j with the array
                       [0 ... 9] as "base cases". If j is called on an integer
                       below 10, it returns the element at that index of the base
                       cases (which is same integer) and does not execute the code
                       block. The base case array is filled with new values as j is
                       called again and again, but we do not use this feature.
     _p                Copy and print the integer on the stack.
       Ab              Convert it into its base-10 digits.
         {       }*    Fold; push the first digit, for each remaining digit:
          _2$*         Multiply copies of the accumulator and the current digit.
              @)       Increment the original accumulator.
                ?      Select the product if the digit is non-zero, else the sum.
                   j   Call j on the result.
                       If the result was less than 10, it is retrieved from the
                       base cases and pushed on the stack. CJam prints it before
                       exiting the program.
Dennis
fuente
2

Minkolang 0.7 , 52 46 bytes

ndN((d25*%1R25*:)r11(x2~gd4&x1+!*I1-)dNd9`,?).

¡Bucles anidados de Woohoo!

Explicación

ndN     Takes integer input and outputs it
(       Starts overall loop

 (        Starts loop that separates top of stack into digits
  d25*%   Modulus by 10
  1R      Rotates stack 1 unit to the right
  25*:    Divides by 10
 )

 r11   Reverses stack and pushes two 1s; 1 for the dump and 1 for the multiply
 (     Starts the multiply/add loop
  x    Dumps top value

      -This top-of-stack dump is because
       while loops end when the stack is
       empty or the top of stack is 0. The
       top of stack is *not* popped for
       this conditional check, so if the loop
       continues, I need to dump the left-over
       from the previous iteration.

  2~gd    Gets next-to-last stack value and duplicates for the conditional
  4&      Jumps 4 spaces if top of stack is positive
   x1+!   Dumps the 0 leftover, adds 1 to top of stack, and jumps the multiply
   *      Multiplies the top two elements of stack
  I1-     Pushes length of stack - 1
 )        Exits the loop if top of stack is 0 (i.e., len(stack)=1)
 dN       Outputs as integer
 d9`,?    Jumps out of the loop if top of stack <=9
)
.    Stop.
El'endia Starman
fuente
2

Mathematica, 66 bytes

Most@FixedPointList[Fold[If[#2<1,#+1,1##]&,1,IntegerDigits@#]&,#]&
alephalpha
fuente
2

Python 3, 74, 76 bytes

Ya había una respuesta de Python aquí con reduce, así que quería hacer una sin ella. Debe llamarse con un int.

def j(n,m=1):
 print(n)
 if n>9:
  for d in str(n):m=m*int(d)or m+1
  j(m)
Morgan Thrapp
fuente
2

Python, 85 80 bytes

def g(n):y=reduce(lambda i,x:i*int(x)or i+1,`n`,1);return[n]+(g(y)if n>9else[])

Esto ahora imprime correctamente toda la lista, en lugar de solo el primer valor.

Mego
fuente
Puede guardar dos bytes utilizando una lambda sin nombre, es decir, omitiendo g=.
Alex A.
1

K5 , 24 bytes

(1{(x*y;x+1)@~y}/.:'$:)\

Recopilar una lista de elementos mientras se itera a un punto fijo es precisamente lo que hace el operador de escaneo \. En cada iteración primero lanzo el número a una cadena y luego evalúo cada carácter ( .:'$:), explotando el número en sus dígitos. Luego realizo una reducción (/ ) comenzando con 1 y usando la lambda {(x*y;x+1)@~y}. En este caso xes el valor reductor y yes cada término sucesivo de la secuencia.

En acción:

  f: (1{(x*y;x+1)@~y}/.:'$:)\

  f'77 90 249 806 1337 9999 10000 8685309 9999999 1234567890
(77 49 36 18 8
 90 10 2
 249 72 14 4
 806 54 20 3
 1337 63 18 8
 9999 6561 180 9
 10000 5
 8685309 51849 1440 17 7
 9999999 4782969 217728 1568 240 9
 1234567890 362881 2304 28 16 6)
JohnE
fuente
1

Julia, 93 89 88 86 83 77 bytes

f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)

Esto crea una función recursiva f que imprime los elementos de secuencia en líneas separadas.

Sin golf:

function f(n::Int)
    println(n)
    if (d = n > 9)
        for i in reverse(digits(n))
            i < 1 ? d += 1 : d *= i
        end
        f(d)
    end
end

Pruébalo en línea

¡Guardado 6 bytes gracias a Dennis!

Alex A.
fuente
Debe ser n>9para cumplir con el segundo ejemplo. Además, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)es un poco más corto.
Dennis
@Dennis Excelentes ideas, ¡gracias!
Alex A.
1

Rubí 83 , 72 bytes

Original declarado como una función:

def f(d)loop{p d;break if d<10;d=d.to_s.bytes.inject(1){|r,i|i>48?r*(i-48):r+1}}end

Traté de usar Enumerator.newpero usa tantos bytes :-(

Mejorado usando recursividad:

def f(d)p d;f(d.to_s.bytes.inject(1){|r,i|i>48?r*(i-48):r+1})if d>10 end
cpt_peter
fuente
0

C # y LINQ, 165 146 bytes

void j(int a){r.Add(a);var l=a.ToString().Select(d=>int.Parse(d.ToString()));int n=1;foreach(int i in l)n=i==0?n+1:n*i;if(n>9)j(n);else r.Add(n);}

j (para jarvis) es la función recursiva. r es la lista de int del resultado.

probado en LINQPAD:

void Main()
{
    j(806);
    r.Dump();
}
List<int> r = new List<int>();

void j(int a){r.Add(a);var l=a.ToString().Select(d=>int.Parse(d.ToString()));int n=1;foreach(int i in l)n=i==0?n+1:n*i;if(n>9)j(n);else r.Add(n);}
noisyass2
fuente
Puede guardar algunos bytes eliminando los espacios que rodean a los operadores, por ejemplo, int n = 1puede ser int n=1, etc.
Alex A.
Buena captura @AlexA. reducido a 146.
noisyass2
También puede ahorrar un poco haciendo un + "" en lugar de a.tostring () :)
Alex Carlsen
0

Haskell, 71 bytes

x!'0'=x+1
x!c=x*read[c]
g x|h>9=x:g h|1<2=[x,h]where h=foldl(!)1$show x

Uso: g 8675309-> [8675309,45369,3240,25,10,2].

nimi
fuente
0

Matlab, 108

N=input('');disp(N)
k=1;while k
x=1;for n=num2str(N)-48
if n
x=x*n;else
x=x+1;end
end
disp(x)
N=x;k=x>9;
end
Luis Mendo
fuente
0

Java 8, 148 bytes

String f(int j){String s="";Function r=i->(""+i).chars().map(x->x-48).reduce(1,(x,y)->y>0?x*y:x+1);while((j=(int)r.apply(j))>9)s+=j+" ";return s+j;}

formateado

String f(int j) {
    String s = "";
    Function r = i -> ("" + i).chars().map(x -> x - 48).reduce(1, (x, y) -> y>0 ? x*y : x+1);
    while ((j = (int)r.apply(j)) > 9) s += j+" ";
    return s+j;
}
Rnet
fuente