Thứ hai Mini-Golf # 4: JARVIS (Chỉ là một chuỗi các số nguyên khá lớn)


22

Thứ hai Mini-Golf: Một loạt các câu hỏi ngắn , được đăng (hy vọng!) Vào mỗi thứ Hai.
(Xin lỗi tôi lại trễ một lần nữa; tôi đã rời khỏi máy tính của tôi về cơ bản cả ngày hôm qua và hôm nay.)

Chúng tôi lập trình viên (đặc biệt là những người chơi golf mã) chắc chắn thích các chuỗi số nguyên tùy ý. Chúng tôi thậm chí có toàn bộ trang web dành riêng cho các chuỗi này hiện có khoảng 200.000 mục. Trong thử thách này, chúng tôi sẽ triển khai một loạt các chuỗi này.

Thử thách

Thử thách của bạn là viết một chương trình hoặc hàm lấy một số nguyên N và xuất ra một chuỗi các số nguyên cơ sở 10, trong đó mỗi số nguyên tiếp theo được xác định theo cách này:

  • Bắt đầu từ 1.
  • Đối với mỗi chữ số D trong biểu diễn cơ sở 10 của số nguyên trước đó:

    • Nếu D bằng 0, thêm một vào số nguyên hiện tại.
    • Nếu không, nhân số nguyên hiện bởi D .

Chi tiết

  • Bạn có thể giả sử rằng 0 < N <2 31 .
  • Bạn phải xuất từng số nguyên trong chuỗi, bắt đầu bằng số đầu vào, cho đến khi đạt được số nhỏ hơn 10.
  • Đầu ra có thể là một mảng hoặc một chuỗi được phân tách bằng dấu cách, dấu phẩy, dòng mới hoặc kết hợp cả hai.
  • Không gian dấu và / hoặc dòng mới được cho phép, nhưng không là dấu phẩy.
  • Không bao giờ nên có bất kỳ số 0 hàng đầu.

Ví dụ

Ví dụ 1: 77

Ví dụ này khá đơn giản:

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

Vì vậy, đầu ra thích hợp là 77 49 36 18 8 .

Ví dụ 2: 90

Ở đây chúng tôi có:

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

Vì vậy, đầu ra sẽ là 90 10 2 .

Ví dụ 3: 806

Đọc các phương trình từ trái sang phải:

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

Đầu ra nên 806 54 20 3 .

Các trường hợp thử nghiệm

Số đầu tiên trong mỗi dòng là đầu vào và dòng đầy đủ là đầu ra dự kiến.

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

Để tham khảo, đây là số nguyên tiếp theo thích hợp từ 10 đến 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

Bạn có thể tìm thấy danh sách này được mở rộng đến 10000 tại đây .

Chấm điểm

Đây là , vì vậy mã hợp lệ ngắn nhất tính bằng byte thắng. Tiebreaker đi đến trình mà đạt đến số byte cuối cùng của nó đầu tiên. Người chiến thắng sẽ được chọn vào thứ Hai tới, ngày 19 tháng 10. Chúc may mắn!

Chỉnh sửa: Xin chúc mừng người chiến thắng của bạn, @isaacg , sử dụng Pyth một lần nữa cho 14 byte !

Câu trả lời:


10

Bình thường, 15 14 byte

.uu|*GHhGjNT1Q

1 byte nhờ Dennis

Phòng thử nghiệm

Thử thách này có cảm giác như nó được tạo ra cho các chức năng giảm của Pyth. Một giảm trên các chữ số, một giảm cho đến khi giá trị ngừng thay đổi, và chúng tôi tốt.


2
|*GHhGtiết kiệm một byte hơn ?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)}

1
Điều đó khá hấp dẫn, sử dụng (...)để thúc đẩy đầu ra tự động ... Tôi sẽ cần phải nhớ điều đó trong tương lai.
admBorkBork

3

Đường ống , 28 25 23 byte

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

Lấy một số làm đối số dòng lệnh và xuất chuỗi trên các dòng liên tiếp.

Giải trình:

                         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

Bây giờ tôi rất vui vì tôi đã thay đổi Ptừ một tuyên bố thành một nhà điều hành một vài lần sửa đổi trước đây. Palà một biểu thức ước tính giá atrị của nó nhưng cũng xuất ra nó, vì vậy tôi có thể in avà đồng thời kiểm tra xem nó có ít hơn mười hay không t>Pa.


3

CJam, 26 25 24 22 byte

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

hoặc là

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

Hãy thử trực tuyến.

Làm thế nào nó hoạt động

Cả hai chương trình về cơ bản đều làm như vậy; cách thứ nhất là cách tiếp cận đệ quy, cách thứ hai là cách lặp. Tôi sẽ giải thích đầu tiên, mà tôi cho là thú vị hơn.

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

Chồn 0,7 , 52 46 byte

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

Woohoo lồng vòng!

Giải trình

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

Toán học, 66 byte

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

2

Python 3, 74, 76 byte

Đã có một câu trả lời Python ở đây với giảm, vì vậy tôi muốn làm một câu trả lời mà không có nó. Nó nên được gọi với một 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 byte

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

Điều này bây giờ in đúng ra toàn bộ danh sách, thay vì chỉ giá trị đầu tiên.


Bạn có thể lưu hai byte bằng cách sử dụng lambda chưa được đặt tên, tức là bỏ qua g=.
Alex A.

1

K5 , 24 byte

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

Thu thập danh sách các mục trong khi lặp đến một điểm cố định chính xác là những gì toán tử quét \thực hiện. Trên mỗi lần lặp đầu tiên, trước tiên tôi chuyển số thành một chuỗi và sau đó đánh giá từng ký tự ( .:'$:), làm nổ số thành các chữ số của nó. Sau đó, tôi thực hiện giảm ( /) bắt đầu bằng 1 và sử dụng lambda {(x*y;x+1)@~y}. Trong trường hợp xnày là giá trị giảm vày là mỗi số hạng liên tiếp của chuỗi.

Trong hành động:

  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 byte

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

Điều này tạo ra một hàm đệ quy f in các thành phần chuỗi trên các dòng riêng biệt.

Ung dung:

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

Dùng thử trực tuyến

Đã lưu 6 byte nhờ Dennis!


Nó phải là n>9để tuân thủ ví dụ thứ hai. Ngoài ra, f(n)=(println(n);if(d=n>9)for i=reverse(digits(n)) i<1?d+=1:d*=i end;f(d)end)là một chút ngắn hơn.
Dennis

@Dennis Ý tưởng tuyệt vời, cảm ơn!
Alex A.

1

Ruby 83 , 72 byte

Bản gốc được khai báo là một hàm:

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

Tôi đã cố gắng sử dụng Enumerator.newnhưng nó sử dụng rất nhiều byte :-(

Cải thiện sử dụng đệ quy:

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 # & 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 (đối với jarvis) là hàm đệ quy. r là Danh sách int của kết quả.

đã thử nghiệm trong 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);}

Bạn có thể tiết kiệm một số byte bằng cách loại bỏ các không gian khai thác xung quanh, ví dụ như int n = 1có thể int n=1, vv
Alex A.

Bắt tốt @AlexA. giảm xuống 146.
ồn ào2

Bạn cũng có thể tiết kiệm một chút bằng cách thực hiện + "" thay vì 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

Cách sử dụng: 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 byte

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

được định dạng

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.