Artı ve Times, Olanlar ve Dokuzlar


18

Bu yineleme ilişkisini , negatif olmayan bir tamsayı girip çıkaran bir işlev veya program olarak uygulayın :

  • F (0) = 0

  • F (N) = F (N-1) 'den büyük olan en küçük tam sayı, taban-10 basamaklarının toplamı ve / veya ürünü N olacak şekilde

N, programınızın girişi ve F (N) çıktısıdır.

Açık olmak gerekirse, 913 gibi bir sayıdaki rakamların toplamı 9 + 1 + 3 = 13'tür. Ürün 9 × 1 × 3 = 27'dir. Tek haneli sayılar için, toplam ve ürün aynı sayıdır. 0 içeren sayılar elbette 0 ürüne sahiptir.

F (70) ile elde edilen sonuçlar şunlardır:

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

Bayt cinsinden en kısa kod kazanır. Kudos, kodunuzun bir miktar verimlilikten faydalandığını gösterebilirseniz.


1
OEIS

1
Pek doğru sıra değil.
Calvin'in Hobileri

Yanıtlar:


4

05AB1E , 20 12 bayt

Osable sayesinde 8 bayt tasarruf !

µNSDOsP‚¾>å½

CP-1252 kodlamasını kullanır . Çevrimiçi deneyin!


Uzunluk testi gerekli mi? Ben geldim µNSDOsP‚¾>å½. Rastgele seçilen sayılar için çalışıyor gibi görünüyor.
Osable

@ Muhtemelen Ahh tabii ki sen bir dahisin! Bunu neden dahil ettiğimi bile bilmiyorum.
Adnan

20 baytlık bir programı aniden% 40 azaltabileceğiniz inanılmaz ...
NikoNyrh

3

Mathematica, 71 bayt, 68 karakter

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

Sadece 4 bayt daha, şu değerleri saklayan bir sürüm ±n:

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

İkincisi sürümü ile, değerlendirmek önce ±n, PlusMinusiki aşağı değerlere sahip olacaktır:

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

Şimdi değerlendirirsek ±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 artık değerleri arasındaki 0ve 20özyinelemeli olarak hesaplamayacağı için bu, gelecekteki hesaplamaları önemli ölçüde hızlandırır . Tasarruf süresi narttıkça daha dramatiktir :

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}

Bu, F (N - 1) + 1 yerine F (N - 1) 'de başlar; nüks kesinlikle artmalıdır.
LegionMammal978

2

C #, 155 159 135 bayt

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

Süper verimsiz, sadece uzun zaman alıyor N>=14. Daha verimli, ancak daha uzun bir çözüm elde etmeye çalışacağım.

Tamam, şimdi çok daha iyi, ama 4 bayt daha uzun. Ah, N<=50şimdi oldukça çabuk yapabilirim . 24 bayt kaydettiğiniz için teşekkürler!


For ile for(;;)ve foreach ile değiştirilecek -2 bayt foreach(var c in++i+""). Yerine -22 bayt int.Parse(c+"")ile c-48.
süt

2

Pyth - 18 17 bayt

@ Jakube sayesinde bir bayt kurtarıldı!

Yinelemeli şeyi yapmak için azaltmayı kullanır.

uf}HsM*FBjT;hGSQZ

Test Takımı .


sM*FBjT;ayrıca rakam toplamını ve ürünü oluşturur ve 1 bayt daha kısadır.
Jakube

Jakube ooh güzel hile
Maltysen

1

R, 124 bayt

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'te başarısız olur, çünkü R 10.000'i 1e + 05 olarak yazmakta ısrar ediyor, ki as.numeric()bu takdir edilmiyor, bu kullanılarak düzeltilebiliras.integer() 12 bayt maliyetiyle :

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}

İstatistiksel bir programlama dili olarak R, sayıları bir rakam vektörüne bölmenin rahatsız edici derecede garip yollarına sahiptir. Özellikle her şeyin dizelerden tekrar sayısal değerlere dönüştürülmesi gerektiğinden.

Billywob sayesinde 12 bayt kaydedildi.


1
as.double(el(strsplit(c(x,""),"")))Bir tamsayıyı basamaklarının bir vektörüne bölmek için kullanabilirsiniz . Ancak, hala biçimlendirme sorunuyla karşılaşıyorsunuz, ancak cevabınızdaki gibi çözülebiliras.integer()
Billywob

Ooh, x'i bir dizeye zorlamanın akıllı yolu: o
JAD

Bunun sprintf()yerine, tamsayıyı doğrudan sıfır as.double(el(strsplit(sprintf("%1.f",x),"")))as.integer()
içermeyen

@ LegionMammal978 while döngüsünde yaptığı ilk şey budur x=x+1ve bunun bir kez değerlendirilmesi garanti edilir, çünkü başlangıçta y=F(N-1)kesinlikle eşit değildir N.
JAD

@JarkoDubbeldam Whoops, yanlış okudum: P
LegionMammal978

1

JavaScript (ES6) 109 107 105 91 89 Bayt

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

Düzenle: 2 bayt kaydedildi 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")

Test Notu 50'nin üzerinde CPU'nuzun çok fazla kullanacağını, çok geç olmadan durdurmak için 'Sonuçları gizle'yi tıklayı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>


Sanırım for(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);v2 bayt tasarruf etmeli. Biraz daha kısaltılabileceğinden şüpheleniyorum, ancak şu ana kadar çözemedim.
Arnauld

@Arnauld tekrarlanan kayan nokta bölümü ile ilgili bir sorun bekliyorum
edc65

Tek ihtiyacımız, aslında bir bölen p /= dolduğunda kesin bir sonuç üretmesidir . Yanılmıyorsam, bu herkes için geçerlidir . Ne zaman kayan nokta yuvarlama hataları alırız , ancak bu güvenli olmalıdır. dpd <= p <= Number.MAX_SAFE_INTEGERp % d != 0
Arnauld

@darrylyeo kendiniz denemediğiniz önerilerde bulunmayın (deneyin eval`1+1` ) (işte neden codegolf.stackexchange.com/a/52204/21348 : ilk yorumu okuyun)
edc65

1

Mathematica, 67 bayt

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

İşlev, adlandırılmış a. Sayıyı girdi olarak alır ve sayıyı çıktı olarak döndürür. Önceki Mathematica çözümünden esinlenilmiştir, ancak farklı bir döngü mekanizması kullanır.


1

C, 240 bayt

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

Dizinin bazı matematik özelliklerinden yararlanmaya çalışmak.


0

PowerShell v3 +, 114 bayt

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

Sayıyı rakamlarının toplamına / ürününe dönüştürmenin kolay bir yolu olmayan yinelemeli çözüm, bu nedenle JavaScript'in cevaplarından biraz daha uzun.

Girişi alır $n, setleri $isadece bir diziye 0(bu koleksiyon F()ve setleri $liçin eşit 1(bu sonuncusu F). Daha sonra döngü yukarı gelen 1için $nbir yürütme her yineleme, fordöngü.

forDöngünün koşullu alır $latest sayı, bir dizede "$l", ardından atmalarını bir şekilde char-array ve mağazalar bu geçici değişkenin içine dizisi $b. Sonra -joinbu rakamlar ile birlikte +ve bunu iex(kısaltmak Invoke-Expressionve benzerlerine) bağlamak eval. Ayrıca, biz de benzer *. Bu iki sayı, çözüm satırları içinde kapsüllenir ve dış döngüdeki -notingeçerli sayıya $_göre işleç için dizi bağımsız değişkeni olarak işlem görür (yani, fordöngü ikisinden biri kadar çalışır +ve *farklıdır $_). forDöngünün gövdesi sadece artar$l++ .

Bu iç fordöngüden çıktığımızda, $lyeni bir öğe olarak ekleriz $i. Menzil döngüsünü tamamen tamamladıktan sonra,$i[$n] boru hattına ve çıktı örtük.

NB - 20Sadece döngü yapısı nedeniyle yukarıda yürütmek oldukça yavaş alır . Örneğin, N=40makinemde yaklaşık iki dakika sürüyor ve testten bile rahatsız olmadım N>50.


0

Pyke, 17 bayt

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

Burada deneyin!

Veya 13 bayt rakipsiz

first_nşimdi bulunan öğelerin miktarını artı ikullanılırsa bir tane koyar .

Q.fY'Bs]iR{)e

Burada deneyin!

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


0

Harika , 49 bayt

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

Desen eşleme ftw! Kullanımı:

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

Daha okunabilir:

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

Bu, temelde, teknik özelliklerin sadece kelimeden kelimeye uygulanmasıdır.


0

BASH, 107 bayt

katlama + yapıştırma + bc ile

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

0

Befunge, 101 bayt

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

Çevrimiçi deneyin! Ancak yüksek kırklı yaşlara girdiğinizde bunun gerçekten yavaşlayacağını unutmayın. Tüm aralığı test etmek istiyorsanız, gerçekten bir Befunge derleyicisi kullanmanız gerekir.

açıklama

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

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.