Pazartesi Mini Golf # 4: JARVIS (Tam Sayı Dizilerinin Sıra Dışı Bir Başka Seti)


22

Pazartesi Mini Golf: Her pazartesi (umarım!) Yayınlanan bir dizi kısa sorusu.
(Üzgünüm yine geciktim; temelde dün ve bugün bilgisayarımdan uzak durdum.)

Biz programcılar (özellikle kod tutucular) kesinlikle rastgele tamsayı dizilerini severiz. Şu anda yaklaşık 200.000 girişe sahip olan bu dizilere adanmış bir sitemiz bile var . Bu mücadelede, bu dizilerin bir başka setini daha uygulayacağız.

Meydan okuma

Buradaki zorluk, bir N tamsayısı alan ve bir sonraki 10 tamsayının bu şekilde belirlendiği bir 10 tamsayısı dizisi çıktısı veren bir program veya işlev yazmaktır :

  • 1'den başla.
  • Bir önceki tamsayının tabanındaki 10 D gösterimi için:

    • Eğer D 0 olduğunda, mevcut tamsayıya bir ekleyin.
    • Aksi takdirde, geçerli tamsayıyı D ile çarpın .

ayrıntılar

  • 0 < N <2 31 olduğunu varsayabilirsiniz .
  • Her tam sayıyı, 10'dan daha küçük bir sayıya ulaşana kadar giriş numarasından başlayarak sırayla çıkarmalısınız.
  • Çıktı, bir dizi veya boşluk, virgül, yeni satır veya bunların bir kombinasyonu ile ayrılmış bir dize olabilir.
  • Bir arka alan ve / veya yeni satır izin verilmekte, fakat olmayan bir arka virgül.
  • Hiçbir zaman baştaki sıfır olmamalıdır.

Örnekler

Örnek 1: 77

Bu örnek oldukça basittir:

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

Böylece uygun çıktı 77 49 36 18 8.

Örnek 2: 90

İşte biz var:

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

Yani çıktı olacaktı 90 10 2.

Örnek 3: 806

Soldan sağa denklemleri okuyun:

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

Çıktı olmalı 806 54 20 3.

Test-vakalar

Her satırdaki ilk sayı giriş, tam satır beklenen çıktıdır.

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

Referans olarak, işte 10'dan 100'e kadar olan sonraki tam sayılar:

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

Burada 10000'e genişletilmiş bu listeyi bulabilirsiniz .

puanlama

Bu , bayt cinsinden geçerli en kısa koddur. Tiebreaker ilk önce son bayt sayısına ulaşan gönderime gidiyor. Kazanan, 19 Ekim Pazartesi günü seçilecek. İyi şanslar!

Düzenleme: Kazanan, @isaacg , 14 byte için yine Pyth kullanarak tebrikler !

Yanıtlar:


10

Pyth, 15 14 bayt

.uu|*GHhGjNT1Q

Dennis'e 1 bayt teşekkürler

Test odası

Bu meydan okuma Pyth'in azaltma işlevlerinde olduğu gibi hissediyor. Biri rakamları düşürür, biri değişmeyi bırakıncaya kadar azalır ve biz iyiyiz.


2
|*GHhGbir bayttan tasarruf eder ?H*GHhG.
Dennis,

4

PowerShell, 92 91 90 88 87 bayt

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

1
Bu oldukça kaygan, (...)otomatik çıktılardan yararlanarak ... Gelecekte bunu hatırlamaya ihtiyacım olacak.
AdmBorkBork,

3

Pip , 28 25 23 bayt

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

Komut satırı argümanı olarak bir sayı alır ve ardışık satırlara sırayı verir.

Açıklama:

                         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

Şimdi Pbir açıklamadan operatöre birkaç revizyondan önce değiştiğime sevindim . değerini Padeğerlendiren aancak çıktı veren bir ifadedir , bu yüzden aondan daha az kullanıp kullanmadığını yazıp aynı anda test edebilirim t>Pa.


3

CJam, 26 25 24 22 bayt

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

veya

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

Çevrimiçi deneyin.

Nasıl çalışır

Her iki program da esas olarak aynısını yapar; Birincisi özyinelemeli bir yaklaşım, ikincisi yinelemeli bir yaklaşımdır. Daha ilginç olduğunu düşündüğüm ilkini açıklayacağım.

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 bayt

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

Woohoo iç içe geçmiş döngüler!

açıklama

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 bayt

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

2

Python 3, 74, 76 bayt

Burada zaten azaltılmış bir Python cevabı vardı, bu yüzden onsuz bir tane yapmak istedim. Bir int ile çağrılmalıdır.

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 bayt

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

Bu, yalnızca ilk değer yerine tüm listeyi düzgün bir şekilde yazdırır.


Adsız bir lambda kullanarak, yani atlayarak iki bayttan tasarruf edebilirsiniz g=.
Alex A.

1

K5 , 24 bayt

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

Sabit bir noktaya yineleme yaparken bir öğe listesi toplamak tam olarak tarama operatörünün \yaptığı şeydir . Her yinelemede, önce numarayı bir dizgeye çeviririm ve sonra her karakteri değerlendiririm ( .:'$:). Sonra /1 ile başlayan ve lambda kullanarak bir azalma ( ) yapıyorum {(x*y;x+1)@~y}. Bu durumda x, indirgeyici değerdir ve ydizinin her ardışık terimidir.

Eylemde:

  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 bayt

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

Bu f, dizi öğelerini ayrı satırlara basan özyinelemeli bir işlev oluşturur .

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

Çevrimiçi deneyin

Dennis sayesinde 6 bayt kaydedildi!


n>9İkinci örneğe uymak gerekir . Ayrıca, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)biraz daha kısa.
Dennis,

@Dennis Mükemmel fikirler, teşekkürler!
Alex A.

1

Yakut 83 , 72 bayt

orijinal bir işlev olarak ilan edildi:

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

Kullanmaya çalıştım Enumerator.new ama çok fazla bayt kullanıyor:

Özyineleme kullanılarak geliştirildi :

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 # ve LINQ, 165 146 bayt

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 (jarvis için) özyinelemeli işlevdir. r sonucun int listesidir.

LINQPAD’de test edilmiştir:

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

Operatörleri çevreleyen alanları kaldırarak bazı baytları kaydedebilirsiniz, örneğin , vb. int n = 1Olabilirint n=1
Alex A.

@AlexA'yı yakalamak iyi.
146.'ye

A.tostring () yerine + "" yaparak da biraz kazanabilirsiniz :)
Alex Carlsen

0

Haskell, 71 bayt

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

Kullanım: 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 Bayt

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

biçimlendirilmiş

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.