Plus và Times, Ones và Nines


18

Thực hiện mối quan hệ lặp lại này dưới dạng hàm hoặc chương trình nhập và xuất số nguyên không âm:

  • F (0) = 0

  • F (N) = số nguyên nhỏ nhất lớn hơn F (N-1) sao cho tổng và / hoặc tích của 10 chữ số cơ sở của nó là N

N là đầu vào của chương trình của bạn và F (N) đầu ra của nó.

Để rõ ràng, tổng các chữ số trong một số như 913 là 9 + 1 + 3 = 13. Sản phẩm có kích thước 9 × 1 × 3 = 27. Đối với các số có một chữ số, tổng và sản phẩm là cùng một số. Các số có chứa 0 tất nhiên có sản phẩm 0.

Các kết quả thông qua F (70) là:

N F(N)
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
10 19
11 29
12 34
13 49
14 59
15 69
16 79
17 89
18 92
19 199
20 225
21 317
22 499
23 599
24 614
25 799
26 899
27 913
28 1147
29 2999
30 3125
31 4999
32 5999
33 6999
34 7999
35 8999
36 9114
37 19999
38 29999
39 39999
40 41125
41 59999
42 61117
43 79999
44 89999
45 91115
46 199999
47 299999
48 311128
49 499999
50 511125
51 699999
52 799999
53 899999
54 911116
55 1999999
56 2111147
57 3999999
58 4999999
59 5999999
60 6111125
61 7999999
62 8999999
63 9111117
64 11111188
65 29999999
66 39999999
67 49999999
68 59999999
69 69999999
70 71111125

Mã ngắn nhất tính bằng byte thắng. Kudos nếu bạn có thể chỉ ra rằng mã của bạn tận dụng một số hiệu quả.



1
Trình tự không hoàn toàn đúng.
Sở thích của Calvin

Câu trả lời:


4

05AB1E , 20 12 byte

Đã lưu 8 byte nhờ Osable !

µNSDOsP‚¾>å½

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến!


Là bài kiểm tra độ dài cần thiết? Tôi nghĩ ra µNSDOsP‚¾>å½. Nó dường như làm việc cho các số được chọn ngẫu nhiên.
Osable

@Osable Ahh tất nhiên, bạn là một thiên tài! Tôi thậm chí không biết tại sao tôi bao gồm điều đó.
Ad Nam

Thật
ngạc

3

Mathicala, 71 byte, 68 ký tự

±0=0;±n_:=(For[x=±(n-1),FreeQ[{+##,1##}&@@IntegerDigits@x,n],x++];x)

Chỉ thêm 4 byte, đây là phiên bản lưu trữ các giá trị của ±n:

±0=0;±n_:=(For[x=±(n-1),FreeQ[{+##,1##}&@@IntegerDigits@x,n],x++];±n=x)

Với phiên bản sau, trước khi bạn đánh giá ±n, PlusMinussẽ có hai giá trị giảm:

In[2]:= DownValues@PlusMinus
Out[2]= {HoldPattern[±0] :> 0, HoldPattern[±n_] :> (For[x=±(n-1),FreeQ[{+##,1##}&@@IntegerDigits@x,n],x++];±n=x)}

Bây giờ nếu chúng ta đánh giá ±20:

In[3]:= ±20
In[3]:= 225

In[4]:= DownValues@PlusMinus
Out[4]= {HoldPattern[±0] :> 0, HoldPattern[±1] :> 1, HoldPattern[±2] :> 2, HoldPattern[±3] :> 3, HoldPattern[±4] :> 4, HoldPattern[±5] :> 5, HoldPattern[±6] :> 6, HoldPattern[±7] :> 7, HoldPattern[±8] :> 8, HoldPattern[±9] :> 9, HoldPattern[±10] :> 19, HoldPattern[±11] :> 29, HoldPattern[±12] :> 34, HoldPattern[±13] :> 49, HoldPattern[±14] :> 59, HoldPattern[±15] :> 69, HoldPattern[±16] :> 79, HoldPattern[±17] :> 89, HoldPattern[±18] :> 92, HoldPattern[±19] :> 199, HoldPattern[±20] :> 225, HoldPattern[±n_] :> (For[x=±(n-1),FreeQ[{+##,1##}&@@IntegerDigits@x,n],x++];±n=x)}

Điều này tăng tốc đáng kể các tính toán trong tương lai vì Mathematica sẽ không còn tính toán các giá trị giữa 020đệ quy. Thời gian tiết kiệm được nhiều hơn khi ntăng:

In[5]:= Quit[]

In[1]:= ±0=0;±n_:=(For[x=±(n-1),FreeQ[{+##,1##}&@@IntegerDigits@x,n],x++];±n=x)

In[2]:= AbsoluteTiming[±60]
Out[2]= {23.0563, 6111125}

In[3]:= AbsoluteTiming[±60]
Out[3]= {9.89694*10^-6, 6111125}

Điều này bắt đầu tại F (N - 1) thay vì F (N - 1) + 1; sự tái phát phải tăng nghiêm ngặt.
LegionMammal978

2

C #, 155 159 135 byte

a=n=>{if(n<1)return 0;int i=n,s=0,p=1,N=a(n-1);for(;;){s=0;p=1;foreach(var c in++i+""){s+=c-48;p*=c-48;}if(i>N&(s==n|p==n))return i;}};

Siêu không hiệu quả, mất nhiều thời gian cho chỉ N>=14. Gonna cố gắng để có được một giải pháp hiệu quả hơn, nhưng lâu hơn.

Được rồi, tốt hơn nhiều bây giờ, nhưng dài hơn 4 byte. Oh tốt, tôi có thể làm N<=50khá nhanh bây giờ. Cảm ơn bạn @milk đã tiết kiệm 24 byte!


-2 byte để thay thế cho for for(;;)và foreach bằng foreach(var c in++i+""). -22 byte để thay thế int.Parse(c+"")bằng c-48.
sữa


1

R, 124 112 byte

f=function(N){y=x=`if`(N-1,f(N-1),0);while(N!=prod(y)&N!=sum(y)){x=x+1;y=as.double(el(strsplit(c(x,""),"")))};x}

Thất bại ở N = 45 vì R khăng khăng viết 10.000 là 1e + 05, điều này không được đánh giá cao as.numeric(), điều này có thể sửa được bằng cách sử dụng as.integer()với chi phí 12 byte:

f=function(N){y=x=`if`(N-1,f(N-1),0);while(N!=prod(y)&N!=sum(y)){x=x+1;y=as.double(el(strsplit(c(as.integer(x),""),"")))};x}

Là một ngôn ngữ lập trình thống kê, R có những cách khó hiểu khi chia số thành một vectơ chữ số. Đặc biệt bởi vì mọi thứ phải được chuyển đổi trở lại từ chuỗi thành giá trị số một cách rõ ràng.

12 byte được lưu nhờ billywob.


1
Bạn có thể sử dụng as.double(el(strsplit(c(x,""),"")))để chia một số nguyên thành một vectơ các chữ số của nó. Tuy nhiên, bạn vẫn gặp phải vấn đề định dạng nhưng điều đó có thể như trong câu trả lời của bạn được giải quyết bằng cáchas.integer()
Billywob 6/12/2016

Ôi, cách thông minh để buộc x thành một chuỗi: o
JAD

sprintf()Thay vào đó, bạn cũng có thể sử dụng để định dạng số nguyên thành một chuỗi không có số 0 ở cuối: as.double(el(strsplit(sprintf("%1.f",x),"")))và bỏ qua việc sử dụngas.integer()
Billywob

@ LegionMammal978 Điều đầu tiên nó làm trong vòng lặp while là x=x+1và điều này được đảm bảo để được đánh giá một lần, bởi vì khi bắt đầu y=F(N-1), điều này chắc chắn không bằng N.
JAD

@JarkoDubbeldam Rất tiếc, đã đọc sai: P
LegionMammal978 7/12/2016

1

JavaScript (ES6) 109 107 105 91 89 byte

f=n=>n&&eval(`for(i=f(n-1);++i,${x="[...i+''].reduce((r,v)=>"}+r+ +v)-n&&${x}r*v)-n;);i`)



console.log(f.toString().length + 2); 
console.log(f(25));
console.log(f(13));
console.log(f(8));                                  


1

JavaScript (ES6), 84 86

Chỉnh sửa: 2 byte đã lưu thx @Arnauld

f=n=>eval("for(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);v")

Kiểm tra Lưu ý trên 50, nó sẽ sử dụng quá nhiều CPU của bạn, nhấp vào 'Ẩn kết quả' để dừng trước khi quá muộn

f=n=>eval("for(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);v")

out=x=>O.textContent=x+'\n'+O.textContent

i=0
step=_=>out(i+' '+f(i),++i,setTimeout(step,i*10))

step()
<pre id=O></pre>


Tôi nghĩ for(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);vnên tiết kiệm 2 byte. Tôi nghi ngờ nó có thể được rút ngắn thêm một số, nhưng tôi không thể tìm ra nó cho đến nay.
Arnauld

@Arnauld Tôi mong đợi một số vấn đề với phân chia điểm nổi lặp đi lặp lại
edc65

Yêu cầu duy nhất của chúng tôi là p /= dtạo ra một kết quả chính xác khi dthực sự là một ước số của p. Trừ khi tôi nhầm, điều này đúng với bất kỳ d <= p <= Number.MAX_SAFE_INTEGER. Khi nào chúng ta sẽ gặp lỗi làm tròn điểm trôi nổi p % d != 0, nhưng điều đó sẽ an toàn.
Arnauld

@darrylyeo không đưa ra lời đề nghị bạn không thử cho mình (thử eval`1+1` ) (đây là lý do tại sao codegolf.stackexchange.com/a/52204/21348 : đọc những nhận xét đầu tiên)
edc65

1

Toán học, 67 byte

a@0=0;a@b_:=NestWhile[#+1&,a[b-1]+1,+##!=b&&1##!=b&@*IntegerDigits]

Chức năng, được đặt tên a. Lấy một số làm đầu vào và trả về một số làm đầu ra. Lấy cảm hứng từ giải pháp Mathicala trước đó, nhưng sử dụng một cơ chế lặp khác nhau.


1

C, 240 byte

int f(char n){int q[19],i=19,r=n%9,j=9,*p=q,c=n/9;while(i)q[--i]=0;if(c){if(!r){r=9;c--;}q[9]=c;if(!(n%r)){n/=r;while((j-1)*(n-1)*c){if(n%j)j--;else{c--;q[9+j]++;n/=j;}}q[10]=c;if(1==n)p+=9;}while(++i<10){while(p[i]--)r=r*10+i;}}return(r);}

Cố gắng khai thác một số tính chất toán học của chuỗi.


0

PowerShell v3 +, 114 byte

param($n)$i=,0;$l=1;1..$n|%{for(;$_-notin((($b=[char[]]"$l")-join'+'|iex)),(($b-join'*'|iex))){$l++}$i+=$l};$i[$n]

Giải pháp lặp, không có cách dễ dàng để biến một số thành tổng / sản phẩm của các chữ số của nó, vì vậy nó dài hơn một chút so với các câu trả lời JavaScript.

Đưa đầu vào $n, đặt $ithành một mảng chỉ 0(đây là tập hợp củaF() và đặt $lbằng 1(đây là mới nhất F). Sau đó, chúng tôi lặp lại từ trên 1xuống $n, mỗi lần lặp thực hiện một forvòng lặp.

Điều forkiện của vòng lặp lấy $lsố ít nhất, trong một chuỗi "$l", sau đó biến nó thành một char-array và lưu mảng đó vào biến temp $b. Chúng tôi sau đó -joinnhững chữ số đó cùng với +và chuyển sang iex(viết tắt Invoke-Expressionvà tương tự eval). Ngoài ra, chúng tôi cũng làm tương tự với *. Hai số đó được gói gọn trong parens và được coi là đối số mảng cho -notintoán tử so với số hiện tại$_ của vòng lặp bên ngoài (nghĩa là forvòng lặp chạy miễn là một trong hai +*khác nhau $_). Cơ thể của forvòng lặp chỉ tăng lên $l++.

Khi chúng tôi ra khỏi forvòng lặp bên trong đó , chúng tôi thêm $lvào như là một yếu tố mới $i. Khi chúng tôi đã hoàn thành vòng lặp phạm vi, chúng tôi chỉ cần đặt $i[$n]trên đường ống và đầu ra là ẩn.

NB - Nhận được khá chậm để thực hiện ở trên 20, đơn giản là do cấu trúc vòng lặp. Ví dụ: N=40mất khoảng hai phút trên máy của tôi và tôi thậm chí không bận tâm đến việc thử nghiệm N>50.


0

Pyke, 17 byte

t.fY'Bs]~ohR{Io(e

Hãy thử nó ở đây!

Hoặc 13 byte không cạnh tranh

first_nbây giờ đặt số lượng vật phẩm đã tìm thấy cộng với một trong inếu được sử dụng.

Q.fY'Bs]iR{)e

Hãy thử nó ở đây!

Q.f        )  -  first_n(input, start=1)
   Y          -   digits(^)
    'Bs]      -   [sum(^), product(^)]
         R}   -   V in ^
        i     -    len(results)+1
            e - ^[-1]


0

Kỳ quan , 49 byte

f\.{0\0@(:>@(| =#1sum#0)=#1prod#0)(dp +1f -#0 1)N

Phù hợp với mô hình ftw! Sử dụng:

f\.{0\0@(:>@(| =#1sum#0)=#1prod#0)(dp +1f -#0 1)N}; f 10

Dễ đọc hơn:

f\.{
  0\0
  @(
    find @(or = #1 sum #0) = #1 prod #0
  ) (dp + 1 (f -#0 1)) N
}

Điều này về cơ bản chỉ là một triển khai từng từ của thông số kỹ thuật.


0

BASH, 107 byte

với nếp gấp + dán + bc

for ((;n<=$1;z++)){
p(){ fold -1<<<$z|paste -sd$1|bc;}
[ `p +` = $n -o `p \*` = $n ]&&((z-->n++))
}
echo $z

0

Befunge, 101 byte

&20p>:000pv
>\1+^vp011<
| >.@>:55+%:00g+00p10g*v>10g-*
::\$_^#!:/+55p01*!`"~":<^\-g00
< |!-g02
+1< v\

Hãy thử trực tuyến! Nhưng lưu ý rằng nó sẽ trở nên rất chậm khi bạn bước vào tuổi bốn mươi. Nếu bạn muốn kiểm tra toàn bộ phạm vi, bạn thực sự cần phải sử dụng trình biên dịch Befunge.

Giải trình

&20p           Read N and save for later.

>              Start of main loop; current target and test number on stack, initially 0.
:              Duplicate the test number so we can manipulate it.
000p           Initialise the sum to 0.
110p           Initialise the product to 1.

>              Start of inner loop.
:55+%:         Modulo 10 of the test number to get the first digit.
00g+00p        Add to the sum.
10g*           Multiply by the product.
:"~"`!*        If greater than 126, set to 0 to prevent overflows - it'll never match.
10p            Update the product variable.
55+/           Divide the test number by 10 to get the next digit.
:!_            If not zero, repeat the inner loop

$              Drop the zero left over from the loop.
\::00g-\10g-   Compare the sum and product with the current target.
*|             Multiply the two diffs and branch; up if no match, down if either match.
\1+^           On no match, we increment the test number and repeat the main loop.
:>20g-!|       With a match, we compare the current target with the saved N.
1+\v           If that doesn't match, increment the current target and restart main loop.
\>.@           If it does match, we've got our result; output it and exit.

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.