Monday Mini-Golf # 4: JARVIS (Just Another Rast Set of Integer Sequences)


22

Minigolf w poniedziałek: seria krótkich pytań do , opublikowanych (mam nadzieję!) W każdy poniedziałek.
(Przepraszam, że się spóźniłem; praktycznie nie było mnie z komputerem wczoraj i dziś.)

My, programiści (szczególnie golfiści kodu), z pewnością uwielbiamy dowolne sekwencje liczb całkowitych. Mamy nawet całą witrynę poświęconą tym sekwencjom, która ma obecnie około 200 000 wpisów. W tym wyzwaniu będziemy wdrażać kolejny zestaw tych sekwencji.

Wyzwanie

Wyzwanie polega na napisaniu programu lub funkcji, która przyjmuje liczbę całkowitą N i generuje sekwencję liczb całkowitych podstawowych 10, w której każda następna liczba całkowita jest określana w następujący sposób:

  • Zacznij od 1.
  • Dla każdej cyfry D w reprezentacji 10 poprzedniej liczby całkowitej:

    • Jeśli D wynosi 0, dodaj jedną do bieżącej liczby całkowitej.
    • W przeciwnym razie, należy pomnożyć liczbę całkowitą przez obecną D .

Detale

  • Możesz założyć, że 0 < N <2 31 .
  • Musisz wypisać każdą liczbę całkowitą w sekwencji, zaczynając od liczby wejściowej, aż do osiągnięcia liczby mniejszej niż 10.
  • Dane wyjściowe może być tablicą lub łańcuchem oddzielonym spacjami, przecinkami, znakami nowej linii lub ich kombinacją.
  • Końcowe spacje i / lub znaki nowej linii są dozwolone, ale nie przecinki końcowe.
  • Nigdy nie powinno być żadnych zer wiodących.

Przykłady

Przykład 1: 77

Ten przykład jest dość prosty:

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

Tak więc właściwym wyjściem jest 77 49 36 18 8.

Przykład 2: 90

Mamy tutaj:

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

Więc wynik byłby 90 10 2.

Przykład 3: 806

Przeczytaj równania od lewej do prawej:

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

Wyjście powinno być 806 54 20 3.

Przypadki testowe

Pierwsza liczba w każdym wierszu to dane wejściowe, a pełna linia to oczekiwany wynik.

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

Jako odniesienie, oto odpowiednie następne liczby całkowite od 10 do 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

Listę tę można rozszerzyć do 10000 tutaj .

Punktacja

To jest , więc wygrywa najkrótszy prawidłowy kod w bajtach. Tiebreaker przechodzi do przesyłania, które jako pierwsze osiągnęło końcową liczbę bajtów. Zwycięzca zostanie wybrany w poniedziałek, 19 października. Powodzenia!

Edycja: Gratulacje dla twojego zwycięzcy, @isaacg , używając Pyth jeszcze raz dla 14 bajtów !

Odpowiedzi:


10

Pyth, 15 14 bajtów

.uu|*GHhGjNT1Q

1 bajt dzięki Dennisowi

Pakiet testowy

To wyzwanie wydaje się być zrobione dla funkcji redukcji Pytha. Jedna redukuje ponad cyfry, druga redukuje, dopóki wartość nie przestaje się zmieniać, a my jesteśmy dobrzy.


2
|*GHhGoszczędza bajt ?H*GHhG.
Dennis

4

PowerShell, 92 91 90 88 87 bajtów

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

1
To całkiem sprytne, używając (...)do automatycznego wykorzystania wyjścia ... Będę musiał pamiętać o tym w przyszłości.
AdmBorkBork,

3

Pip , 28 25 23 bajtów

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

Pobiera liczbę jako argument wiersza polecenia i wyświetla sekwencję w kolejnych wierszach.

Wyjaśnienie:

                         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

Teraz cieszę się, że Pkilka wersji temu zmieniłem z instrukcji na operatora. Pajest wyrażeniem, które ocenia awartość, ale również ją wyprowadza, dzięki czemu mogę drukować ai jednocześnie testować, czy używa mniej niż dziesięć t>Pa.


3

CJam, 26 25 24 22 bajtów

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

lub

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

Wypróbuj online.

Jak to działa

Oba programy zasadniczo robią to samo; pierwsze to podejście rekurencyjne, drugie iteracyjne. Wytłumaczę pierwsze, które uważam za bardziej interesujące.

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 bajtów

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

Woohoo zagnieżdżone pętle!

Wyjaśnienie

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 bajtów

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

2

Python 3, 74, 76 bajtów

Tutaj była już odpowiedź Pythona z redukcją, więc chciałem zrobić ją bez niej. Powinien zostać wywołany z 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 bajtów

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

To teraz poprawnie drukuje całą listę, a nie tylko pierwszą wartość.


Możesz zapisać dwa bajty, używając nienazwanej lambda, tzn g=. Pomijając .
Alex A.,

1

K5 , 24 bajty

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

Zebranie listy elementów podczas iteracji do stałego punktu jest dokładnie tym, co \robi operator skanowania . Przy każdej iteracji najpierw rzucam liczbę na ciąg, a następnie oceniam każdy znak ( .:'$:), rozbijając liczbę na cyfry. Następnie wykonuję redukcję ( /) zaczynając od 1 i używając lambda {(x*y;x+1)@~y}. W tym przypadku xjest wartością redukującą i yjest każdym kolejnym terminem sekwencji.

W akcji:

  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 bajtów

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

Tworzy to funkcję rekurencyjną, fktóra drukuje elementy sekwencji na osobnych liniach.

Nie golfowany:

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

Wypróbuj online

Zaoszczędź 6 bajtów dzięki Dennisowi!


Powinno być n>9zgodne z drugim przykładem. Ponadto, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)jest nieco krótszy.
Dennis

@Dennis Doskonałe pomysły, dzięki!
Alex A.

1

Rubinowy 83 , 72 bajty

Oryginał zadeklarowany jako funkcja:

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

Próbowałem użyć, Enumerator.newale używa tak wielu bajtów :-(

Ulepszono za pomocą rekurencji:

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 # i LINQ, 165 146 bajtów

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 (dla jarvis) to funkcja rekurencyjna. r jest listą liczb całkowitych wyniku.

testowane w 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);}

Możesz zaoszczędzić niektóre bajty, usuwając spacje otaczające operatorów, np. int n = 1Mogą być int n=1itp.
Alex A.

Dobry połów @AlexA. zmniejszono do 146.
noisyass2

Możesz także trochę zaoszczędzić, wykonując znak „+” zamiast a.tostring () :)
Alex Carlsen,

0

Haskell, 71 bajtów

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

Zastosowanie: 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 bajtów

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

sformatowany

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.