Plus und Zeiten, Eins und Neun

18

Implementieren Sie diese Wiederholungsrelation als Funktion oder Programm, das eine nicht negative Ganzzahl eingibt und ausgibt:

  • F (0) = 0

  • F (N) = die kleinste ganze Zahl, die größer als F (N-1) ist, so dass die Summe und / oder das Produkt seiner 10-stelligen Basis N ist

N ist die Eingabe Ihres Programms und F (N) die Ausgabe.

Um es klar auszudrücken, die Summe der Ziffern in einer Zahl wie 913 ist 9 + 1 + 3 = 13. Das Produkt ist 9 × 1 × 3 = 27. Bei einstelligen Zahlen sind Summe und Produkt gleich. Zahlen, die eine 0 enthalten, haben natürlich das Produkt 0.

Die Ergebnisse bis F (70) sind:

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

Der kürzeste Code in Bytes gewinnt. Ein dickes Lob, wenn Sie zeigen können, dass Ihr Code eine gewisse Effizienz ausnutzt.

Calvins Hobbys
quelle
1
OEIS-Sequenz
MildlyMilquetoast
1
Nicht ganz richtige Reihenfolge.
Calvins Hobbys

Antworten:

4

05AB1E , 20 12 Bytes

8 Bytes gespart dank Osable !

µNSDOsP‚¾>å½

Verwendet die CP-1252- Codierung. Probieren Sie es online!

Adnan
quelle
Ist der Längentest erforderlich? Ich habe es mir ausgedacht µNSDOsP‚¾>å½. Es scheint für zufällig ausgewählte Zahlen zu funktionieren.
Osable
@Osable Ahh natürlich, du bist ein Genie! Ich weiß nicht einmal, warum ich das aufgenommen habe.
Adnan
Erstaunlich, wie Sie ein 20-Byte-Programm plötzlich um 40% reduzieren können ...
NikoNyrh
3

Mathematica, 71 Bytes, 68 Zeichen

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

Für nur 4 weitere Bytes ist hier eine Version, die die Werte von speichert ±n:

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

Bei der letztgenannten Version, bevor Sie bewerten ±n, PlusMinuswerden zwei unten Werte haben:

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

Wenn wir nun auswerten ±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)}

Dies beschleunigt zukünftige Berechnungen erheblich, da Mathematica die Werte zwischen 0und nicht mehr 20rekursiv berechnet . Die Zeitersparnis nimmt dramatisch nzu:

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}
Genisis
quelle
Dies beginnt bei F (N - 1) anstelle von F (N - 1) + 1; Die Wiederholung muss streng zunehmen.
LegionMammal978
2

C #, 155 159 135 Bytes

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 ineffizient, dauert halt lange N>=14. Ich werde versuchen, eine effizientere, aber längere Lösung zu finden.

Okay, jetzt viel besser, aber 4 Bytes länger. Na ja, ich kann es jetzt N<=50ziemlich schnell machen. Vielen Dank an @milk, dass Sie 24 Bytes gespart haben!

Jodler
quelle
-2 Bytes zum Ersetzen von for mit for(;;)und foreach mit foreach(var c in++i+""). -22 Bytes zum Ersetzen int.Parse(c+"")durch c-48.
Milch
2

Pyth - 18 17 Bytes

Ein Byte gespart dank @Jakube!

Verwendet reduzieren, um die rekursive Sache zu tun.

uf}HsM*FBjT;hGSQZ

Test Suite .

Maltysen
quelle
sM*FBjT;Erzeugt auch die Ziffernsumme und das Produkt und ist 1 Byte kürzer.
Jakube
@ Jakube ooh schönen Trick
Maltysen
1

R, 124 112 Bytes

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}

Ausfällt bei N = 45 , da R besteht auf dem Schreiben als 10.000 1e + 05, die durch geschätzt isnt as.numeric(), ist dies durch die Verwendung fixierbar as.integer()auf Kosten von 12 Bytes

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}

Als statistische Programmiersprache hat R ärgerlich wortreiche Möglichkeiten, Zahlen in einen Vektor von Ziffern aufzuteilen. Vor allem, weil alles explizit von Strings auf numerische Werte zurückkonvertiert werden muss.

Dank billywob werden 12 Bytes gespart.

JAD
quelle
1
Mit können Sie as.double(el(strsplit(c(x,""),"")))eine Ganzzahl in einen Vektor ihrer Ziffern aufteilen. Sie haben zwar immer noch as.integer()
Probleme mit
Oh, eine clevere Art, x in einen String zu zwingen: o
JAD
Sie können sprintf()stattdessen auch verwenden, um die Ganzzahl direkt in eine Zeichenfolge ohne nachfolgende Nullen zu formatieren: as.double(el(strsplit(sprintf("%1.f",x),"")))und die Verwendung vonas.integer()
Billywob
@ LegionMammal978 Das erste, was es in der while-Schleife macht, ist x=x+1und dies wird garantiert einmal ausgewertet, denn zu Beginn y=F(N-1)ist das definitiv nicht gleich N.
JAD
@ JarkoDubbeldam Whoops, falsch verstanden: 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
quelle
1

JavaScript (ES6), 84 86

Edit: 2 Bytes gespeichert dank @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 Note über 50 beansprucht zu viel CPU. Klicken Sie auf "Ergebnisse ausblenden", um den Test zu beenden, bevor es zu spät ist

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
quelle
Ich denke, for(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);vsollte 2 Bytes sparen. Ich vermute, es kann noch etwas gekürzt werden, aber ich konnte es bisher nicht herausfinden.
Arnauld
@ Arnauld Ich erwarte ein Problem mit wiederholter Gleitkommadivision
edc65
Unsere einzige Anforderung ist, dass p /= dein genaues Ergebnis erzeugt wird, wenn dtatsächlich ein Teiler von ist p. Sofern ich mich nicht irre, gilt dies für alle d <= p <= Number.MAX_SAFE_INTEGER. Wir werden Gleitkomma-Rundungsfehler bekommen p % d != 0, aber das sollte sicher sein.
Arnauld
@ Darrylyeo geben Sie keine Vorschläge, die Sie nicht selbst ausprobiert haben (versuchen eval`1+1` ) (hier ist, warum codegolf.stackexchange.com/a/52204/21348 : Lesen Sie den ersten Kommentar)
edc65
1

Mathematica, 67 Bytes

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

Funktion, benannt a. Nimmt eine Zahl als Eingabe und gibt eine Zahl als Ausgabe zurück. Inspiriert von der vorherigen Mathematica-Lösung, verwendet jedoch einen anderen Schleifenmechanismus.

LegionMammal978
quelle
1

C 240 Bytes

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

Versuch, einige mathematische Eigenschaften der Sequenz auszunutzen.

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

Eine iterative Lösung, bei der es nicht einfach ist, eine Zahl in die Summe / das Produkt ihrer Ziffern umzuwandeln. Sie ist also viel länger als die JavaScript-Antworten.

Nimmt Eingaben an $n, setzt $iauf ein Array mit just 0(dies ist die Auflistung von F()und setzt $lgleich 1(dies ist die neueste F). Wir schleifen dann von 1bis aufwärts $n, wobei jede Iteration eine forSchleife ausführt .

Die forBedingung der Schleife nimmt die $lhöchste Zahl in einer Zeichenfolge "$l", charwandelt sie dann in ein -array um und speichert dieses Array in einer temporären Variablen $b. Wir dann -joindiese Ziffern zusammen mit +und leiten das zu iex(kurz für Invoke-Expressionund ähnlich zu eval). Darüber hinaus machen wir auch ähnlich mit *. Diese beiden Zahlen werden in Parens eingekapselt und als Array-Argument für den -notinOperator gegen die aktuelle Nummer $_der äußeren Schleife behandelt (dh die forSchleife läuft so lange wie eine von beiden +und *unterscheidet sich von $_). Der Körper der forSchleife wird nur inkrementiert $l++.

Sobald wir diese innere forSchleife verlassen haben, fügen wir unser $lOn als neues Element von hinzu $i. Sobald wir die Bereichsschleife vollständig abgeschlossen haben, platzieren wir sie einfach $i[$n]in der Pipeline, und die Ausgabe ist implizit.

NB - Wird 20wegen der Schleifenstruktur ziemlich langsam ausgeführt . Zum Beispiel N=40dauert es ungefähr zwei Minuten auf meinem Computer, und ich habe mich nicht einmal um Tests gekümmert N>50.

AdmBorkBork
quelle
0

Pyke, 17 Bytes

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

Probieren Sie es hier aus!

Oder 13 Bytes nicht konkurrenzfähig

first_nStellt nun die Anzahl der bereits gefundenen Gegenstände plus eins ein, ifalls verwendet.

Q.fY'Bs]iR{)e

Probieren Sie es hier aus!

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

Python 2 , 77 Bytes

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

Probieren Sie es online!

Dennis
quelle
0

Wunder , 49 Bytes

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

Pattern Matching ftw! Verwendung:

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

Besser lesbar:

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

Dies ist im Grunde nur eine wörtliche Umsetzung der Spezifikationen.

Mama Fun Roll
quelle
0

BASH, 107 Bytes

mit fold + paste + bc

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

Befunge, 101 Bytes

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

Probieren Sie es online! Aber beachten Sie, dass es sehr langsam wird, sobald Sie in den hohen Vierzigern sind. Wenn Sie die gesamte Bandbreite testen möchten, müssen Sie einen Befunge-Compiler verwenden.

Erläuterung

&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
quelle
0

PHP , 110 Bytes

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

Probieren Sie es online!

Jörg Hülsermann
quelle