Lundi Mini-Golf # 4: JARVIS (juste un autre ensemble assez vaste de séquences entières)


22

Lundi mini-golf: une série de courtes questions sur le , affichées (avec un peu de chance!) Tous les lundis.
(Désolé, je suis encore en retard; j'étais loin de mon ordinateur hier et aujourd'hui.)

Les programmeurs américains (en particulier les golfeurs de code) adorent les séquences entières arbitraires. Nous avons même un site entier dédié à ces séquences qui compte actuellement environ 200 000 entrées. Dans ce défi, nous allons implémenter un autre ensemble de ces séquences.

Défi

Votre défi consiste à écrire un programme ou une fonction qui accepte un entier N et génère une séquence d'entiers de base 10, où chaque entier suivant est déterminé de cette manière:

  • Commencez à 1.
  • Pour chaque chiffre D dans la représentation en base 10 de l'entier précédent:

    • Si D est 0, ajoutez un à l'entier courant.
    • Dans le cas contraire, il faut multiplier le nombre entier courant par D .

Détails

  • Vous pouvez supposer que 0 < N <2 31 .
  • Vous devez sortir chaque entier de la séquence, en commençant par le numéro d'entrée, jusqu'à ce qu'un nombre inférieur à 10 soit atteint.
  • La sortie peut être un tableau ou une chaîne séparée par des espaces, des virgules, des sauts de ligne ou une combinaison de ceux-ci.
  • Un espace de fin et / ou une nouvelle ligne est autorisé, mais pas une virgule de fin.
  • Il ne doit jamais y avoir de zéros non significatifs.

Exemples

Exemple 1: 77

Cet exemple est assez simple:

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

Ainsi, la sortie appropriée est 77 49 36 18 8.

Exemple 2: 90

Ici nous avons:

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

Ainsi, la sortie serait 90 10 2.

Exemple 3: 806

Lisez les équations de gauche à droite:

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

La sortie devrait être 806 54 20 3.

Cas de test

Le premier nombre de chaque ligne est l'entrée et la ligne complète est la sortie attendue.

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

À titre de référence, voici les prochains entiers appropriés de 10 à 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

Vous pouvez trouver cette liste étendue à 10000 ici .

Notation

Il s'agit de , donc le code valide le plus court en octets l'emporte. Tiebreaker va à la soumission qui a atteint son nombre d'octets final en premier. Le gagnant sera choisi lundi 19 octobre prochain. Bonne chance!

Edit: Félicitations à votre gagnant, @isaacg , en utilisant encore Pyth pour 14 octets !

Réponses:


10

Pyth, 15 14 octets

.uu|*GHhGjNT1Q

1 octet merci à Dennis

Suite de tests

Ce défi semble avoir été fait pour les fonctions de réduction de Pyth. Une réduction sur les chiffres, une réduction jusqu'à ce que la valeur cesse de changer, et nous sommes bons.


2
|*GHhGenregistre un octet de plus ?H*GHhG.
Dennis

4

PowerShell, 92 91 90 88 87 octets

($n=$args);while($n-gt9){$x=1;[char[]]"$n"|%{$x=if($y=$_-48){$x*$y}else{$x+1}};($n=$x)}

1
C'est assez simple, utiliser (...)pour tirer parti de la sortie automatique ... Je vais devoir m'en souvenir à l'avenir.
AdmBorkBork du

3

Pip , 28 25 23 octets

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

Prend un nombre comme argument de ligne de commande et sort la séquence sur des lignes successives.

Explication:

                         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

Maintenant, je suis content d'avoir changé Pde déclaration en opérateur il y a plusieurs révisions. Paest une expression qui évalue ala valeur de mais la génère également, donc je peux imprimer aet tester simultanément si elle est inférieure à dix en utilisant t>Pa.


3

CJam, 26 25 24 22 octets

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

ou

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

Essayez-le en ligne.

Comment ça marche

Les deux programmes font essentiellement la même chose; la première est une approche récursive, la seconde une approche itérative. Je vais expliquer le premier, que je considère plus intéressant.

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 octets

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

Boucles imbriquées Woohoo!

Explication

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 octets

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

2

Python 3, 74, 76 octets

Il y avait déjà une réponse Python ici avec réduire, donc je voulais en faire une sans. Il doit être appelé avec 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)

2

Python, 85 80 octets

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

Cela imprime maintenant correctement la liste entière, au lieu de seulement la première valeur.


Vous pouvez enregistrer deux octets en utilisant un lambda sans nom, c'est-à-dire en omettant g=.
Alex A.

1

K5 , 24 octets

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

Rassembler une liste d'éléments tout en itérant vers un point fixe est précisément ce que fait l'opérateur de numérisation \. À chaque itération, je commence par convertir le nombre en une chaîne, puis j'évalue chaque caractère ( .:'$:), en éclatant le nombre en ses chiffres. Ensuite, j'exécute une réduction ( /) commençant par 1 et utilisant le lambda {(x*y;x+1)@~y}. Dans ce cas, xc'est la valeur réductrice et yest chaque terme successif de la séquence.

En action:

  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 octets

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

Cela crée une fonction récursive fqui imprime les éléments de séquence sur des lignes distinctes.

Non 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

Essayez-le en ligne

6 octets enregistrés grâce à Dennis!


Ce devrait être n>9pour se conformer au deuxième exemple. En outre, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)est un peu plus court.
Dennis

@Dennis Excellentes idées, merci!
Alex A.

1

Ruby 83 , 72 octets

Original déclaré en fonction:

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

J'ai essayé d'utiliser Enumerator.newmais il utilise tellement d'octets :-(

Amélioration en utilisant la récursivité:

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 # et LINQ, 165 146 octets

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 (pour jarvis) est la fonction récursive. r est la liste des int du résultat.

testé dans 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);}

Vous pouvez enregistrer quelques octets en supprimant les espaces environnants opérateurs, par exemple , int n = 1peut être int n=1, etc.
Alex A.

Bonne prise @AlexA. réduit à 146.
noisyass2

Vous pouvez également économiser un peu en faisant un + "" au lieu d'un a.tostring () :)
Alex Carlsen

0

Haskell, 71 octets

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

Utilisation: 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 octets

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

formaté

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

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.