Plus dan Times, Ones and Nines

18

Menerapkan hubungan perulangan ini sebagai fungsi atau program yang menginput dan mengeluarkan integer non-negatif:

  • F (0) = 0

  • F (N) = bilangan bulat terkecil lebih besar dari F (N-1) sehingga jumlah dan / atau produk dari basis-10 digitnya adalah N

N adalah input program Anda dan F (N) hasilnya.

Agar jelas, jumlah digit dalam angka seperti 913 adalah 9 + 1 + 3 = 13. Produk ini 9 × 1 × 3 = 27. Untuk angka satu digit, jumlah dan produk adalah angka yang sama. Angka yang mengandung 0 tentu saja memiliki produk 0.

Hasil melalui F (70) adalah:

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

Kode terpendek dalam byte menang. Kudos jika Anda dapat menunjukkan bahwa kode Anda memanfaatkan efisiensi.

Hobi Calvin
sumber
1
Urutan OEIS
MildlyMilquetoast
1
Urutan tidak tepat.
Hobi Calvin

Jawaban:

4

05AB1E , 20 12 byte

Disimpan 8 byte berkat Osable !

µNSDOsP‚¾>å½

Menggunakan pengkodean CP-1252 . Cobalah online!

Adnan
sumber
Apakah tes panjang diperlukan? Saya datang dengan µNSDOsP‚¾>å½. Tampaknya berfungsi untuk angka yang dipilih secara acak.
Osable
@ Ahh tentu saja, Anda jenius! Saya bahkan tidak tahu mengapa saya memasukkan itu.
Adnan
Luar biasa bagaimana Anda bisa tiba-tiba mengurangi program 20 byte sebesar 40% ...
NikoNyrh
3

Mathematica, 71 byte, 68 karakter

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

Untuk hanya 4 byte lagi, inilah versi yang menyimpan nilai-nilai ±n:

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

Dengan versi yang terakhir, sebelum Anda mengevaluasi ±n, PlusMinusakan ada dua nilai turun:

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

Sekarang jika kita mengevaluasi ±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)}

Ini secara dramatis mempercepat perhitungan di masa depan karena Mathematica tidak akan lagi menghitung nilai antara 0dan 20secara rekursif. Waktu yang dihemat lebih dramatis dengan nmeningkatnya:

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}
ngenisis
sumber
Ini dimulai dari F (N - 1) bukannya F (N - 1) + 1; pengulangan harus meningkat secara ketat.
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;}};

Super tidak efisien, butuh waktu lama untuk adil N>=14. Akan mencoba untuk mendapatkan solusi yang lebih efisien, tetapi lebih lama.

Oke, jauh lebih baik sekarang, tetapi 4 byte lebih lama. Oh well, aku bisa melakukannya N<=50dengan cepat sekarang. Terima kasih @milk karena telah menghemat 24 byte!

Yodle
sumber
-2 byte untuk menggantikan for for(;;)dan foreach with foreach(var c in++i+""). -22 byte untuk menggantikan int.Parse(c+"")dengan c-48.
susu
2

Pyth - 18 17 byte

Satu byte disimpan berkat @Jakube!

Penggunaan mengurangi untuk melakukan hal yang rekursif.

uf}HsM*FBjT;hGSQZ

Test Suite .

Maltysen
sumber
sM*FBjT;juga menghasilkan jumlah digit dan produk dan 1 byte lebih pendek.
Jakube
@Jakube ooh trik yang bagus
Maltysen
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}

Gagal pada N = 45 karena R bersikeras menulis 10.000 sebagai 1e + 05, yang tidak dihargai oleh as.numeric(), ini dapat diperbaiki dengan menggunakan as.integer()dengan biaya 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}

Sebagai bahasa pemrograman statistik, R memiliki cara bertele-tele yang menjengkelkan dalam membagi angka menjadi vektor angka. Terutama karena semuanya harus dikonversi kembali dari string ke nilai numerik secara eksplisit.

12 byte disimpan berkat billywob.

JAD
sumber
1
Anda dapat menggunakan as.double(el(strsplit(c(x,""),"")))untuk membagi integer menjadi vektor digit-digitnya. Namun, Anda masih mengalami masalah pemformatan tapi itu bisa seperti dalam jawaban Anda dipecahkan olehas.integer()
Billywob
Ooh, cara pintar memaksa x menjadi string: o
JAD
Anda juga dapat menggunakan sprintf()format bilangan bulat menjadi string tanpa nol tambahan langsung: as.double(el(strsplit(sprintf("%1.f",x),"")))dan lewati penggunaanas.integer()
Billywob
@ LegionMammal978 Hal pertama yang dilakukannya di loop sementara adalah x=x+1dan ini dijamin akan dievaluasi sekali, karena pada awal y=F(N-1)yang pasti tidak sama dengan N.
JAD
@JarkoDubbeldam Whoops, salah baca: P
LegionMammal978
1

JavaScript (ES6) 109 107 105 91 89 Bytes

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

Lmis
sumber
1

JavaScript (ES6), 84 86

Sunting: 2 byte disimpan 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")

Uji Catatan di atas 50 itu akan menggunakan CPU Anda terlalu banyak, klik 'Sembunyikan hasil' untuk berhenti sebelum terlambat

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>

edc65
sumber
Saya pikir for(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);vharus menyimpan 2 byte. Saya menduga itu bisa dipersingkat lagi, tapi saya tidak bisa mengetahuinya sejauh ini.
Arnauld
@Arnauld Saya mengharapkan beberapa masalah dengan pembagian floating point berulang
edc65
Satu-satunya persyaratan kami adalah yang p /= dmenghasilkan hasil yang tepat ketika dsebenarnya adalah pembagi p. Kecuali saya salah, ini berlaku untuk semua d <= p <= Number.MAX_SAFE_INTEGER. Kami akan mendapatkan kesalahan pembulatan titik mengambang kapan p % d != 0, tetapi itu harus aman.
Arnauld
@darrylyeo tidak memberikan saran Anda tidak mencoba sendiri (coba eval`1+1` ) (inilah mengapa codegolf.stackexchange.com/a/52204/21348 : baca komentar pertama)
edc65
1

Mathematica, 67 byte

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

Fungsi, dinamai a. Mengambil nomor sebagai input dan mengembalikan nomor sebagai output. Terinspirasi oleh solusi Mathematica sebelumnya, tetapi menggunakan mekanisme pengulangan yang berbeda.

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

Mencoba mengeksploitasi beberapa properti matematika dari urutan.

bernaf
sumber
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]

Solusi berulang, tanpa cara mudah untuk mengubah angka menjadi jumlah / produk dari digitnya, jadi ini sedikit lebih lama dari jawaban JavaScript.

Mengambil input $n, set $ike array dengan just 0(ini adalah kumpulan F(), dan set $lsama dengan 1(ini adalah yang terbaru F) .Kami kemudian loop ke atas dari 1ke $n, setiap iterasi mengeksekusi forloop.

The forbersyarat loop mengambil $lnomor atest, dalam sebuah string "$l", maka melemparkan bahwa sebagai char-array, dan toko yang array menjadi variabel temp $b. Kami kemudian -joinangka-angka bersama dengan +dan pipa itu ke iex(kependekan dari Invoke-Expressiondan mirip dengan eval). Selain itu, kami juga melakukan hal serupa *. Kedua angka tersebut dienkapsulasi dalam parens dan diperlakukan sebagai argumen array untuk -notinoperator terhadap jumlah saat ini $_dari loop luar (yaitu, forloop berjalan selama salah satu +dan *berbeda dari $_). Tubuh forloop hanya bertambah $l++.

Setelah kami keluar dari forlingkaran dalam itu , kami menambahkan kami $lsebagai elemen baru $i. Setelah kami sepenuhnya menyelesaikan rentang loop, kami hanya menempatkan $i[$n]di pipeline, dan output tersirat.

NB - Mendapat cukup lambat untuk mengeksekusi di atas 20, hanya karena struktur loop. Sebagai contoh, N=40membutuhkan sekitar dua menit pada mesin saya, dan saya bahkan tidak pernah repot pengujian N>50.

AdmBorkBork
sumber
0

Pyke, 17 byte

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

Coba di sini!

Atau 13 byte tidak kompetitif

first_nsekarang menempatkan jumlah item yang sudah ditemukan ditambah satu ijika digunakan.

Q.fY'Bs]iR{)e

Coba di sini!

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

Python 2 , 77 byte

f=lambda n,k=0,r=0:-(k>n)or-~f(n,k+(k in[eval(c.join(`r`))for c in'+*']),r+1)

Cobalah online!

Dennis
sumber
0

Bertanya-tanya , 49 byte

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

Pencocokan pola ftw! Pemakaian:

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

Lebih mudah dibaca:

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

Ini pada dasarnya hanyalah implementasi spesifikasi kata demi kata.

Mama Fun Roll
sumber
0

BASH, 107 byte

dengan lipat + tempel + bc

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

Befunge, 101 byte

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

Cobalah online! Tetapi perhatikan bahwa itu akan menjadi sangat lambat begitu Anda memasuki usia empat puluhan. Jika Anda ingin menguji jangkauan penuh, Anda benar-benar harus menggunakan kompiler Befunge.

Penjelasan

&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.
James Holderness
sumber
0

PHP , 110 byte

for(;$c<=$a=$argn;$c=count($r))array_product($s=str_split($n++))!=$c&&array_sum($s)!=$c?:$r[]=~-$n;echo$r[$a];

Cobalah online!

Jörg Hülsermann
sumber