บวกกับเวลาคนและเก้า


18

ใช้ความสัมพันธ์ที่เกิดซ้ำนี้เป็นฟังก์ชันหรือโปรแกรมที่อินพุตและเอาต์พุตเป็นจำนวนเต็มที่ไม่เป็นลบ:

  • F (0) = 0

  • F (N) = จำนวนเต็มที่น้อยที่สุดที่มากกว่า F (N-1) เช่นผลรวมและ / หรือผลิตภัณฑ์ของตัวเลขฐาน 10 คือ N

N คืออินพุตของโปรแกรมของคุณและ F (N) เอาต์พุต

เพื่อให้ชัดเจนผลรวมของตัวเลขในจำนวนเช่น 913 คือ 9 + 1 + 3 = 13 ผลิตภัณฑ์นี้คือ 9 × 1 × 3 = 27 สำหรับตัวเลขหลักเดียวผลรวมและผลิตภัณฑ์จะเป็นหมายเลขเดียวกัน ตัวเลขที่มี 0 แน่นอนมีผลิตภัณฑ์ 0

ผลลัพธ์ผ่าน F (70) คือ:

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

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ รุ่งโรจน์ถ้าคุณสามารถแสดงให้เห็นว่ารหัสของคุณใช้ประโยชน์จากประสิทธิภาพบางอย่าง



1
ลำดับไม่ถูกต้องนัก
งานอดิเรกของ Calvin

คำตอบ:


4

05AB1E , 20 12 ไบต์

บันทึกแล้ว 8 ไบต์ขอบคุณOsable !

µNSDOsP‚¾>å½

ใช้การเข้ารหัสCP-1252 ลองออนไลน์!


จำเป็นต้องทำการทดสอบความยาวหรือไม่? µNSDOsP‚¾>å½ฉันมาด้วย ดูเหมือนว่าจะทำงานกับตัวเลขที่เลือกแบบสุ่ม
Osable

@Oableable อ่าแน่นอนคุณเป็นอัจฉริยะ! ฉันไม่รู้ด้วยซ้ำว่าทำไมรวมถึงสิ่งนั้นด้วย
Adnan

น่าประหลาดใจที่คุณสามารถลดขนาดโปรแกรม 20 ไบต์ลง 40% ...
NikoNyrh

3

Mathematica, 71 ไบต์, 68 ตัวอักษร

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

สำหรับอีก 4 ไบต์นี่เป็นรุ่นที่เก็บค่าของ±n:

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

กับรุ่นหลังก่อนที่คุณจะประเมิน±n, PlusMinusจะมีสองค่าลง:

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

ตอนนี้ถ้าเราประเมิน±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)}

สิ่งนี้จะช่วยเร่งการคำนวณในอนาคตได้อย่างรวดเร็วเนื่องจาก Mathematica จะไม่คำนวณค่าระหว่าง0และ20แบบวนซ้ำอีกต่อไป ประหยัดเวลาได้อย่างน่าทึ่งเมื่อnเพิ่มขึ้น:

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}

สิ่งนี้เริ่มต้นที่ F (N - 1) แทน F (N - 1) + 1; การเกิดซ้ำจะต้องเพิ่มขึ้นอย่างเคร่งครัด
LegionMammal978

2

C #, 155 159 135 ไบต์

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

N>=14ซูเปอร์ไม่มีประสิทธิภาพใช้เวลานานเพียง เธอจะพยายามให้มีประสิทธิภาพมากขึ้น แต่ก็แก้ปัญหาได้นานกว่า

โอเคดีกว่ามากตอนนี้ แต่ยาวกว่า 4 ไบต์ โอ้ดีฉันสามารถทำได้N<=50อย่างรวดเร็วในขณะนี้ ขอบคุณ @milk สำหรับการบันทึก 24 ไบต์!


-2 ไบต์เพื่อแทนที่ด้วยfor(;;)และ foreach foreach(var c in++i+"")ด้วย -22 ไบต์เพื่อแทนที่ด้วยint.Parse(c+"") c-48
นม

2

Pyth - 18 17 ไบต์

บันทึกหนึ่งไบต์ต้องขอบคุณ @Jakube!

ใช้การลดเพื่อทำสิ่งที่วนซ้ำ

uf}HsM*FBjT;hGSQZ

Test Suite


sM*FBjT;สร้างผลรวมหลักและผลิตภัณฑ์และสั้นลง 1 ไบต์
Jakube

@Jakube ooh nice trick
Maltysen

1

R, 124 112 ไบต์

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}

ล้มเหลวที่ N = 45 เพราะ R ยืนยันในการเขียน 10.000 เป็น 1e + 05 ซึ่งไม่ได้รับความนิยมas.numeric()สิ่งนี้สามารถแก้ไขได้โดยใช้as.integer()ที่ราคา 12 ไบต์:

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}

ในฐานะที่เป็นภาษาโปรแกรมเชิงสถิติ R มีวิธีการแยกตัวเลขออกเป็นเวกเตอร์ของตัวเลข โดยเฉพาะอย่างยิ่งเพราะทุกอย่างจะต้องถูกแปลงกลับจากสตริงเป็นค่าตัวเลขอย่างชัดเจน

บันทึกได้ 12 ไบต์ด้วย billywob


1
คุณสามารถใช้as.double(el(strsplit(c(x,""),"")))เพื่อแบ่งจำนวนเต็มเป็นเวกเตอร์ของตัวเลข อย่างไรก็ตามคุณยังคงพบปัญหาการจัดรูปแบบ แต่สามารถแก้ไขได้ตามที่คำตอบของคุณโดยas.integer()
Billywob

Ooh วิธีที่ฉลาดในการบังคับให้ x เข้าสู่สตริง: o
JAD

นอกจากนี้คุณยังสามารถใช้sprintf()แทนการจัดรูปแบบจำนวนเต็มเป็นสตริงที่ไม่มีศูนย์ต่อท้ายได้โดยตรงas.double(el(strsplit(sprintf("%1.f",x),"")))และข้ามการใช้งานas.integer()
Billywob

@ LegionMammal978 สิ่งแรกที่มันไม่ในขณะที่ห่วงคือx=x+1และนี่คือการรับประกันว่าจะได้รับการประเมินครั้งเพราะในช่วงเริ่มต้นซึ่งแน่นอนไม่เท่ากับy=F(N-1) N
JAD

@JarkoDubbeldam อ๊ะเข้าใจผิด: P
LegionMammal978


1

JavaScript (ES6), 84 86

แก้ไข: บันทึก 2 ไบต์ขอบคุณ @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")

หมายเหตุทดสอบด้านบน 50 จะใช้ CPU ของคุณมากเกินไปคลิก 'ซ่อนผลลัพธ์' เพื่อหยุดก่อนที่จะสายเกินไป

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>


ฉันคิดว่าfor(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);vควรบันทึก 2 ไบต์ ฉันคิดว่ามันสั้นลงได้อีก แต่ฉันไม่สามารถเข้าใจได้
Arnauld

@Arnauld ฉันคาดหวังว่าจะมีปัญหากับการแบ่ง
จุดทศนิยม

ข้อกำหนดเพียงอย่างเดียวของเราคือว่าp /= dก่อให้เกิดผลที่แน่นอนเมื่อเป็นจริงหารของd pถ้าฉันเข้าใจผิดนี่เป็นเรื่องจริงสำหรับทุกd <= p <= Number.MAX_SAFE_INTEGERคน เราจะได้รับข้อผิดพลาดในการปัดเศษทศนิยมเมื่อp % d != 0แต่ควรจะปลอดภัย
Arnauld

@darrylyeo ไม่ได้ให้คำแนะนำคุณไม่ได้ลองด้วยตัวคุณเอง (ลองeval`1+1` ) (นี่คือเหตุผลที่codegolf.stackexchange.com/a/52204/21348 : อ่านความคิดเห็นแรก)
edc65

1

Mathematica, 67 ไบต์

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

aฟังก์ชั่นการตั้งชื่อ รับตัวเลขเป็นอินพุตและส่งคืนตัวเลขเป็นเอาต์พุต แรงบันดาลใจจากโซลูชัน Mathematica ก่อนหน้านี้ แต่ใช้กลไกการวนซ้ำที่แตกต่างกัน


1

C, 240 ไบต์

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

พยายามที่จะใช้ประโยชน์จากคุณสมบัติทางคณิตศาสตร์บางอย่างของลำดับ


0

PowerShell v3 +, 114 ไบต์

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

วิธีแก้ปัญหาแบบวนซ้ำที่ไม่มีวิธีง่ายๆในการเปลี่ยนตัวเลขให้เป็นผลรวม / ผลิตภัณฑ์ของตัวเลขดังนั้นมันจึงค่อนข้างยาวกว่าคำตอบ JavaScript

รับอินพุต$n, ตั้งค่า$iเป็นอาร์เรย์ด้วย just 0(นี่คือชุดสะสมของF(), และตั้ง$lค่าเท่ากับ1(นี่คือล่าสุดF) จากนั้นเราวนขึ้นจาก1ไปสู่$nการวนซ้ำแต่ละครั้งจะดำเนินการforวนรอบ

forเงื่อนไขห่วงของใช้$lจำนวน Atest ในสตริง"$l"แล้วปลดเปลื้องว่าเป็นchar-array และร้านค้าที่เข้ามาในอาร์เรย์ตัวแปรชั่วคราว$bและร้านค้าที่เข้ามาในอาร์เรย์ตัวแปรชั่วคราว จากนั้นเราก็ใส่-joinตัวเลขเหล่านั้นพร้อมกับ+ไปป์ที่iex(สั้นInvoke-Expressionและคล้ายกับeval) *นอกจากนี้เรายังทำคล้ายกับ ทั้งสองตัวเลขจะถูกห่อหุ้มใน parens และถือว่าเป็นอาร์กิวเมนต์อาร์เรย์สำหรับ-notinผู้ประกอบการกับจำนวนปัจจุบัน$_ของวงรอบนอก (เช่นforห่วงทำงานตราบใดอย่างหนึ่ง+และ*มีความแตกต่างกว่า$_) เนื้อความของforลูปเพิ่มขึ้นเพียง$l++ครั้งเดียว

เมื่อเราออกมาจากภายในที่forห่วงเราเพิ่มของเราในฐานะองค์ประกอบใหม่ของ$l $iเมื่อเราเสร็จสิ้นช่วงของวงอย่างสมบูรณ์แล้วเราเพิ่งจะวาง$i[$n]บนไพพ์ไลน์และเอาท์พุทก็เป็นนัย

NB - ได้รับช้าสวยที่จะดำเนินการดังกล่าวข้างต้น20เพียงเพราะโครงสร้างวง ตัวอย่างเช่นใช้เวลาประมาณสองนาทีในเครื่องของฉันและฉันไม่ได้ใส่ใจการทดสอบN=40N>50


0

Pyke ขนาด 17 ไบต์

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

ลองที่นี่!

หรือ 13 ไบต์ที่ไม่สามารถแข่งขันได้

first_nตอนนี้ใส่จำนวนรายการที่พบแล้วบวกหนึ่งรายการiหากใช้

Q.fY'Bs]iR{)e

ลองที่นี่!

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


0

สงสัย 49 ไบต์

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

การจับคู่รูปแบบ ftw! การใช้งาน:

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

อ่านเพิ่มเติมได้:

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

นี่เป็นเพียงการดำเนินการตามข้อกำหนดของคำต่อคำ



0

Befunge ขนาด 101 ไบต์

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

ลองออนไลน์! แต่โปรดทราบว่ามันจะช้าลงจริง ๆ เมื่อคุณเข้าสู่วัยสี่สิบสูง หากคุณต้องการทดสอบเต็มรูปแบบคุณจำเป็นต้องใช้คอมไพเลอร์ Befunge จริงๆ

คำอธิบาย

&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.

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.