Monday Mini-Golf # 4: JARVIS (Sekadar Sekuens Bilangan Integer Yang Lain)

22

Monday Mini-Golf: Serangkaian pertanyaan pendek , diposting (mudah-mudahan!) Setiap hari Senin.
(Maaf saya terlambat lagi; saya jauh dari komputer saya pada dasarnya kemarin dan hari ini.)

Kami programmer (terutama pegolf-kode) pasti suka urutan bilangan bulat sewenang-wenang. Kami bahkan memiliki seluruh situs yang didedikasikan untuk urutan ini yang saat ini memiliki sekitar 200.000 entri. Dalam tantangan ini, kami akan menerapkan serangkaian rangkaian ini lagi.

Tantangan

Tantangan Anda adalah menulis sebuah program atau fungsi yang menggunakan bilangan bulat N , dan mengeluarkan urutan bilangan bulat 10, di mana setiap bilangan bulat berikutnya ditentukan dengan cara ini:

  • Mulai dari 1.
  • Untuk setiap digit D dalam representasi basis 10 integer sebelumnya:

    • Jika D adalah 0, tambahkan satu ke integer saat ini.
    • Jika tidak, kalikan bilangan bulat saat ini dengan D .

Detail

  • Anda dapat berasumsi bahwa 0 < N <2 31 .
  • Anda harus mengeluarkan setiap bilangan bulat dalam urutan, mulai dengan nomor input, hingga angka kurang dari 10 tercapai.
  • Outputnya bisa berupa array, atau string yang dipisahkan oleh spasi, koma, baris baru, atau kombinasi dari semuanya.
  • Ruang trailing dan / atau baris baru diizinkan, tetapi bukan tanda koma.
  • Seharusnya tidak pernah ada nol terkemuka.

Contohnya

Contoh 1: 77

Contoh ini cukup mudah:

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

Dengan demikian, output yang tepat adalah 77 49 36 18 8.

Contoh 2: 90

Di sini kita memiliki:

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

Jadi hasilnya akan 90 10 2.

Contoh 3: 806

Baca persamaan dari kiri ke kanan:

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

Output seharusnya 806 54 20 3.

Kasus uji

Angka pertama di setiap baris adalah input, dan baris penuh adalah output yang diharapkan.

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

Sebagai referensi, inilah bilangan bulat berikutnya yang tepat dari 10 hingga 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

Anda dapat menemukan daftar ini diperluas menjadi 10.000 di sini .

Mencetak gol

Ini adalah , jadi kode terpendek yang valid dalam byte menang. Tiebreaker pergi ke pengiriman yang mencapai jumlah byte terakhirnya terlebih dahulu. Pemenang akan dipilih Senin depan, 19 Oktober. Semoga beruntung!

Sunting: Selamat kepada pemenang Anda, @isaacg , menggunakan Pyth lagi untuk 14 byte !

Produksi ETH
sumber

Jawaban:

10

Pyth, 15 14 byte

.uu|*GHhGjNT1Q

Terima kasih 1 byte untuk Dennis

Test Suite

Tantangan ini terasa seperti dibuat untuk fungsi pengurangan Pyth. Satu mengurangi atas angka, satu mengurangi sampai nilainya berhenti berubah, dan kami baik-baik saja.

isaacg
sumber
2
|*GHhGmenghemat satu byte lebih ?H*GHhG.
Dennis
4

PowerShell, 92 91 90 88 87 byte

($n=$args);while($n-gt9){$x=1;[char[]]"$n"|%{$x=if($y=$_-48){$x*$y}else{$x+1}};($n=$x)}
Andrew
sumber
1
Itu cukup apik, gunakan (...)untuk meningkatkan output otomatis ... Saya perlu mengingatnya di masa depan.
AdmBorkBork
3

Pip , 28 25 23 byte

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

Mengambil nomor sebagai argumen baris perintah dan menampilkan urutan pada baris yang berurutan.

Penjelasan:

                         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

Sekarang saya senang saya berubah Pdari pernyataan ke operator beberapa revisi yang lalu. Paadalah ekspresi yang mengevaluasi anilai tetapi juga mengeluarkannya, jadi saya dapat mencetak adan secara bersamaan menguji apakah menggunakan kurang dari sepuluh t>Pa.

DLosc
sumber
3

CJam, 26 25 24 22 byte

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

atau

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

Cobalah online.

Bagaimana itu bekerja

Kedua program pada dasarnya melakukan hal yang sama; yang pertama adalah pendekatan rekursif, yang kedua adalah pendekatan berulang. Saya akan jelaskan dulu, yang menurut saya lebih menarik.

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
sumber
2

Minkolang 0.7 , 52 46 byte

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

Woohoo bersarang loop!

Penjelasan

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
sumber
2

Mathematica, 66 byte

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

Python 3, 74, 76 byte

Sudah ada jawaban Python di sini dengan mengurangi, jadi saya ingin melakukannya tanpa itu. Itu harus disebut dengan 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
sumber
2

Python, 85 80 byte

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

Ini sekarang dengan benar mencetak seluruh daftar, bukan hanya nilai pertama.

Mego
sumber
Anda dapat menyimpan dua byte dengan menggunakan lambda yang tidak disebutkan namanya, yaitu menghilangkan g=.
Alex A.
1

K5 , 24 byte

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

Mengumpulkan daftar item saat beriterasi ke titik tertentu adalah tepat yang dilakukan oleh operator pemindaian \. Pada setiap iterasi, saya pertama-tama melemparkan nomor ke string dan kemudian mengevaluasi setiap karakter ( .:'$:), dan meledak nomor ke dalam digit-nya. Lalu saya melakukan pengurangan ( /) dimulai dengan 1 dan menggunakan lambda {(x*y;x+1)@~y}. Dalam hal ini xadalah nilai yang mengurangi dan ymasing-masing istilah urutan.

Dalam aksi:

  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
sumber
1

Julia, 93 89 88 86 83 77 byte

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

Ini menciptakan fungsi rekursif fyang mencetak elemen urutan pada garis yang terpisah.

Tidak Disatukan:

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

Cobalah online

Disimpan 6 byte berkat Dennis!

Alex A.
sumber
Seharusnya n>9sesuai dengan contoh kedua. Juga, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)sedikit lebih pendek.
Dennis
@ Dennis Ide bagus, terima kasih!
Alex A.
1

Ruby 83 , 72 byte

Asli dinyatakan sebagai fungsi:

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

Saya mencoba menggunakan Enumerator.newtetapi menggunakan banyak byte :-(

Ditingkatkan menggunakan rekursi:

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
sumber
0

C # & LINQ, 165 146 byte

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 (untuk jarvis) adalah fungsi rekursif. r adalah Daftar int dari hasilnya.

diuji dalam 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
sumber
Anda dapat menyimpan beberapa byte dengan menghapus spasi di sekitar operator, misalnya int n = 1bisa int n=1, dll.
Alex A.
Tangkapan yang bagus @AlexA. dikurangi menjadi 146.
noisyass2
Anda juga dapat menghemat sedikit dengan melakukan + "" alih-alih a.tostring () :)
Alex Carlsen
0

Haskell, 71 byte

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

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

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

diformat

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
sumber