Plus i Times, One and Nines


18

Zaimplementuj tę relację powtarzalności jako funkcję lub program, który wprowadza i wyprowadza nieujemną liczbę całkowitą:

  • F (0) = 0

  • F (N) = najmniejsza liczba całkowita większa niż F (N-1), tak że suma i / lub iloczyn jej 10 cyfr podstawowych to N

N jest wejściem programu, a F (N) wyjściem.

Dla jasności suma cyfr w liczbie takiej jak 913 wynosi 9 + 1 + 3 = 13. Produkt ma wymiary 9 × 1 × 3 = 27. W przypadku liczb jednocyfrowych suma i iloczyn są takie same. Liczby zawierające 0 oczywiście mają iloczyn 0.

Wyniki za pomocą F (70) to:

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

Najkrótszy kod w bajtach wygrywa. Uznanie, jeśli potrafisz pokazać, że Twój kod korzysta z pewnej wydajności.



1
Niezupełnie właściwa sekwencja.
Calvin's Hobbies,

Odpowiedzi:


4

05AB1E , 20 12 bajtów

Zaoszczędź 8 bajtów dzięki Osable !

µNSDOsP‚¾>å½

Wykorzystuje kodowanie CP-1252 . Wypróbuj online!


Czy wymagany jest test długości? Wymyśliłem µNSDOsP‚¾>å½. Wydaje się, że działa na losowo wybrane liczby.
Osable,

@Osable Ahh, oczywiście, jesteś geniuszem! Nie wiem nawet, dlaczego to zawarłem.
Adnan,

Niesamowite, jak można nagle zmniejszyć program o 20 bajtów o 40% ...
NikoNyrh,

3

Mathematica, 71 bajtów, 68 znaków

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

Jeszcze tylko 4 bajty, oto wersja, która przechowuje wartości ±n:

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

W tej ostatniej wersji, zanim ocenisz ±n, PlusMinusbędą miały dwie wartości spadkowe:

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

Teraz jeśli ocenimy ±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)}

To znacznie przyspiesza przyszłe obliczenia, ponieważ Mathematica nie będzie już obliczać wartości pomiędzy 0i 20rekurencyjnie. Oszczędność czasu jest bardziej dramatyczna w miarę nwzrostu:

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}

Zaczyna się to od F (N - 1) zamiast F (N - 1) + 1; nawrót musi być ściśle rosnący.
LegionMammal978,

2

C #, 155 159 135 bajtów

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 nieefektywny, zajmuje dużo czasu N>=14. Spróbuję uzyskać bardziej wydajne, ale dłuższe rozwiązanie.

Okej, teraz znacznie lepiej, ale 4 bajty dłużej. No cóż, teraz mogę zrobić N<=50dość szybko. Dziękuję @milk za uratowanie 24 bajtów!


-2 bajty, aby zastąpić for za for(;;)i foreach na foreach(var c in++i+""). -22 bajtów zastąpienia int.Parse(c+"")z c-48.
mleko

2

Pyth - 18 17 bajtów

Jeden bajt zapisany dzięki @Jakube!

Używa redukcji, aby wykonać rekurencyjną czynność.

uf}HsM*FBjT;hGSQZ

Pakiet testowy .


sM*FBjT;generuje również sumę cyfr i iloczyn i jest o 1 bajt krótszy.
Jakube,

@Jakube ooh nice trick
Maltysen

1

R, 124 112 bajtów

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}

Nie działa przy N = 45, ponieważ R nalega na zapisanie 10.000 jako 1e + 05, co nie jest doceniane as.numeric(), można to naprawić za pomocą as.integer()kosztu 12 bajtów:

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}

Jako statystyczny język programowania R ma denerwująco trudne sposoby dzielenia liczb na wektor cyfr. Zwłaszcza, że ​​wszystko trzeba jawnie przekonwertować z ciągów znaków na wartości liczbowe.

12 bajtów zapisanych dzięki billywob.


1
Możesz użyć, as.double(el(strsplit(c(x,""),"")))aby podzielić liczbę całkowitą na wektor jej cyfr. Jednak nadal as.integer()
napotykasz

O, sprytny sposób na wtłaczanie x do łańcucha: o
JAD

Zamiast tego możesz również użyć sprintf()do sformatowania liczby całkowitej w ciągu bez zer końcowych: as.double(el(strsplit(sprintf("%1.f",x),"")))i pomiń użycieas.integer()
Billywob

@ LegionMammal978 Pierwszą rzeczą, jaką robi w pętli while, jest x=x+1to gwarantowane, że zostanie ocenione raz, ponieważ na początku y=F(N-1)zdecydowanie nie jest równe N.
JAD,

@JarkoDubbeldam Ups, źle odczytałem: P
LegionMammal978

1

JavaScript (ES6) 109 107 105 91 89 bajtów

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

Edycja: zapisane 2 bajty x @ 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")

Uwaga testowa powyżej 50 zużyje zbyt dużo procesora, kliknij „Ukryj wyniki”, aby zatrzymać, zanim będzie za późno

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>


Myślę, że for(v=n&&f(n-1),p=s=n+1;s&&p-1;)[...++v+''].map(d=>(p/=d,s-=d),p=s=n);vpowinien zaoszczędzić 2 bajty. Podejrzewam, że można to jeszcze trochę skrócić, ale jak dotąd nie mogłem tego rozgryźć.
Arnauld,

@Arnauld Spodziewam się problemu z powtarzającym się podziałem zmiennoprzecinkowym
edc65

Naszym jedynym wymaganiem jest to, aby p /= duzyskać dokładny wynik, gdy dfaktycznie jest dzielnikiem p. O ile się nie mylę, dotyczy to każdego d <= p <= Number.MAX_SAFE_INTEGER. Kiedy wystąpią błędy zaokrąglania zmiennoprzecinkowego p % d != 0, ale to powinno być bezpieczne.
Arnauld,

@ Darrylyeo nie dawaj sugestii, których sam nie próbowałeś (spróbuj eval`1+1` ) (oto dlaczego codegolf.stackexchange.com/a/52204/21348 : przeczytaj pierwszy komentarz)
edc65

1

Mathematica, 67 bajtów

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

Funkcja o nazwie a. Pobiera liczbę jako dane wejściowe i zwraca liczbę jako dane wyjściowe. Zainspirowany poprzednim rozwiązaniem Mathematica, ale wykorzystuje inny mechanizm zapętlania.


1

C, 240 bajtów

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

Próba wykorzystania niektórych właściwości matematycznych sekwencji.


0

PowerShell v3 +, 114 bajtów

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

Iteracyjne rozwiązanie, bez łatwego sposobu przekształcenia liczby w sumę / iloczyn jej cyfr, więc jest to nieco dłużej niż odpowiedzi JavaScript.

Pobiera dane wejściowe $n, ustawia $itablicę za pomocą just 0(jest to zbiór F()i ustawia wartość $lrówną 1(jest to najnowsza wersja F). Następnie zapętlamy w górę od 1do $n, a każda iteracja wykonuje forpętlę.

Na forwarunkowym Loop przybiera $lATEST numer, w ciągu znaków "$l", a następnie rzuca, że jako char-array i sklepów, które tablicę do zmiennej temp $b. Następnie -joinłączymy te cyfry +i potokujemy to iex(skrót od Invoke-Expressioni podobne do eval). Ponadto robimy podobnie z *. Te dwie liczby są enkapsulowane w pareny i traktowane jako argument tablicowy dla -notinoperatora względem bieżącej liczby $_zewnętrznej pętli (tj. forPętla działa tak długo, jak długo jest inna +i *jest inna niż $_). Ciało forpętli powiększa się$l++ .

Kiedy wyjdziemy z tej wewnętrznej forpętli, dodajemy naszą $ljako nowy element $i. Po pełnym zakończeniu pętli zasięgu po prostu umieszczamy$i[$n] w potoku, a dane wyjściowe są niejawne.

NB - Powolne wykonywanie powyżej 20, po prostu ze względu na strukturę pętli. Na przykład N=40zajmuje to około dwóch minut na moim komputerze i nawet nie zawracałem sobie głowy testowaniem N>50.


0

Pyke, 17 bajtów

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

Wypróbuj tutaj!

Lub 13 bajtów niekonkurencyjnych

first_nodkłada teraz liczbę znalezionych przedmiotów plus jeden w, ijeśli jest używany.

Q.fY'Bs]iR{)e

Wypróbuj tutaj!

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


0

Zastanawiam się , 49 bajtów

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

Dopasowane wzorce ftw! Stosowanie:

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

Bardziej czytelny:

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

Jest to w zasadzie tylko implementacja specyfikacji słowo w słowo.


0

BASH, 107 bajtów

ze składaniem + wklej + pne

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

0

Befunge, 101 bajtów

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

Wypróbuj online! Pamiętaj jednak, że po osiągnięciu lat czterdziestych będzie bardzo wolno. Jeśli chcesz przetestować pełny zakres, naprawdę potrzebujesz kompilatora Befunge.

Wyjaśnienie

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.