Monday Mini-Golf # 4: JARVIS (apenas mais um vasto conjunto de sequências inteiras)


22

Mini-golfe de segunda-feira: Uma série de perguntas curtas sobre , postadas (espero!) Toda segunda-feira.
(Desculpe, estou atrasado novamente; eu estava longe do meu computador basicamente ontem e hoje.)

Nós programadores (especialmente os jogadores de código) certamente adoram seqüências inteiras arbitrárias. Temos até um site inteiro dedicado a essas sequências que atualmente possui cerca de 200.000 entradas. Neste desafio, implementaremos mais um conjunto dessas seqüências.

Desafio

Seu desafio é escrever um programa ou função que receba um número inteiro N e produza uma sequência de números inteiros de base 10, onde cada próximo número inteiro é determinado da seguinte maneira:

  • Comece em 1.
  • Para cada dígito D na representação base 10 do número anterior:

    • Se D for 0, adicione um ao número inteiro atual.
    • Caso contrário, multiplicar o número inteiro corrente por D .

Detalhes

  • Você pode assumir que 0 < N <2 31 .
  • Você deve gerar cada número inteiro na sequência, começando com o número de entrada, até que um número menor que 10 seja alcançado.
  • A saída pode ser uma matriz ou uma sequência separada por espaços, vírgulas, novas linhas ou uma combinação delas.
  • Um espaço à direita e / ou nova linha é permitido, mas não uma vírgula à direita.
  • Nunca deve haver zeros à esquerda.

Exemplos

Exemplo 1: 77

Este exemplo é bastante direto:

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

Assim, a saída adequada é 77 49 36 18 8.

Exemplo 2: 90

Aqui temos:

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

Então a saída seria 90 10 2.

Exemplo 3: 806

Leia as equações da esquerda para a direita:

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

A saída deve ser 806 54 20 3.

Casos de teste

O primeiro número em cada linha é a entrada e a linha completa é a saída 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 referência, aqui estão os próximos inteiros adequados de 10 a 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

Você pode encontrar esta lista expandida para 10000 aqui .

Pontuação

Este é o , pelo que o código válido mais curto em bytes vence. O desempatador vai para o envio que atingiu sua contagem final de bytes primeiro. O vencedor será escolhido na próxima segunda-feira, 19 de outubro. Boa sorte!

Edit: Parabéns ao seu vencedor, @isaacg , usando Pyth novamente por 14 bytes !

Respostas:


10

Pitão, 15 14 bytes

.uu|*GHhGjNT1Q

1 byte graças a Dennis

Suíte de teste

Parece que esse desafio foi feito para as funções de redução do Pyth. Uma redução acima dos dígitos, uma redução até que o valor pare de mudar e nós estamos bem.


2
|*GHhGsalva um byte ?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)}

1
Isso é muito liso, usando (...)para alavancar a saída automática ... Vou precisar lembrar disso no futuro.
AdmBorkBork 14/10

3

Pip , 28 25 23 bytes

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

Pega um número como argumento da linha de comando e gera a sequência em linhas sucessivas.

Explicação:

                         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

Agora, fico feliz por ter mudado Pde uma declaração para um operador várias revisões atrás. Paé uma expressão que avalia ao valor de mas também o gera, para que eu possa imprimir ae testar simultaneamente se é menor que dez usando t>Pa.


3

CJam, 26 25 24 22 bytes

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

ou

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

Experimente online.

Como funciona

Ambos os programas fazem essencialmente o mesmo; a primeira é uma abordagem recursiva, a segunda é iterativa. Vou explicar o primeiro, que considero mais interessante.

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.

2

Minkolang 0.7 , 52 46 bytes

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

Woohoo loops aninhados!

Explicação

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.

2

Mathematica, 66 bytes

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

2

Python 3, 74, 76 bytes

Já havia uma resposta em Python aqui com redução, então eu queria fazer uma sem ela. Deve ser chamado com um 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)

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[])

Isso agora imprime corretamente a lista inteira, em vez de apenas o primeiro valor.


Você pode salvar dois bytes usando uma lambda sem nome, ou seja, omitindo g=.
Alex A.

1

K5 , 24 bytes

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

Reunir uma lista de itens enquanto itera para um ponto fixo é exatamente o que o operador de digitalização \faz. Em cada iteração, primeiro converto o número em uma sequência e depois avalio cada caractere ( .:'$:), explodindo o número em seus dígitos. Então eu executo uma redução ( /) começando com 1 e usando o lambda {(x*y;x+1)@~y}. Nesse caso, xé o valor redutor e ycada termo sucessivo da sequência.

Em ação:

  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)

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)

Isso cria uma função recursiva fque imprime os elementos de sequência em linhas separadas.

Ungolfed:

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

Experimente online

Economizou 6 bytes graças a Dennis!


Deveria estar n>9em conformidade com o segundo exemplo. Além disso, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)é um pouco menor.
Dennis

@ Dennis Excelentes idéias, obrigado!
Alex A.

1

Ruby 83 , 72 bytes

Original declarado como uma função:

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

Eu tentei usar, Enumerator.newmas ele usa tantos bytes :-(

Melhorado usando recursão:

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

0

C # e 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) é a função recursiva. r é a lista de int do resultado.

testado no 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);}

Você pode salvar alguns bytes, removendo os espaços envolventes operadores, por exemplo, int n = 1pode ser int n=1, etc.
Alex A.

Boa captura @AlexA. reduzido para 146.
noisyass2 14/10

Você também pode economizar um pouco, fazendo um + "" em vez 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].


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

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

formatado

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.