더하기와 시간, 1과 9


18

음이 아닌 정수를 입력 및 출력하는 함수 또는 프로그램 으로이 되풀이 관계 를 구현하십시오 .

  • F (0) = 0

  • F (N) = 밑 (10) 자릿수의 합 및 / 또는 곱이 N이되도록 F (N-1)보다 큰 가장 작은 정수

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 's Hobbies

답변:


4

05AB1E , 20 12 바이트

Osable 덕분에 8 바이트 절약 !

µNSDOsP‚¾>å½

CP-1252 인코딩을 사용합니다 . 온라인으로 사용해보십시오!


길이 테스트가 필요합니까? 나는 생각해 냈습니다 µNSDOsP‚¾>å½. 무작위로 선택한 숫자에서 작동하는 것 같습니다.
Osable

물론 @Osable Ahh, 당신은 천재입니다! 내가 왜 그것을 포함했는지조차 모르겠습니다.
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)}

매스 매 티카가 더 이상 사이의 값을 계산하지 않습니다 때문에 극적으로 미래의 계산 속도 020재귀. 시간이 절약 될수록 절약되는 시간이 더 극적으로 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) + 1 대신 F (N-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지금 꽤 빨리 할 수 있습니다 . 24 바이트를 절약 해 주신 @milk 님 감사합니다!


-2와의를 대체 할 바이트 for(;;)로하고 foreach는 foreach(var c in++i+""). 대체 -22 바이트 int.Parse(c+"")c-48.
우유

2

Pyth- 18 17 바이트

@Jakube 덕분에 1 바이트가 절약되었습니다!

recursive 일을 줄이기 위해 사용합니다.

uf}HsM*FBjT;hGSQZ

테스트 스위트 .


sM*FBjT;또한 숫자 합과 곱을 생성하며 1 바이트 더 짧습니다.
Jakube

@Jakube 우 멋진 트릭
Maltysen

1

R, 124112 바이트

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}

R은 1e + 05로 10.000을 쓸 것을 고집하기 때문에 N = 45에서 실패합니다 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은 숫자를 벡터로 나누는 성가신 방법입니다. 특히 모든 것이 문자열에서 숫자 값으로 명시 적으로 변환되어야하기 때문입니다.

billywob 덕분에 12 바이트가 절약되었습니다.


1
as.double(el(strsplit(c(x,""),"")))정수를 숫자의 벡터로 나누는 데 사용할 수 있습니다 . 그러나 여전히 형식 문제가 발생하지만 답변에서와 같이 해결할 수 있습니다.as.integer()
Billywob

x를 문자열로 강제하는 영리한 방법 : o
JAD

당신은 또한 사용할 수 있습니다 sprintf()직접 후행 제로와 문자열로 정수를 포맷 대신 : as.double(el(strsplit(sprintf("%1.f",x),"")))및 사용 건너as.integer()
Billywob

@ LegionMammal978 while 루프 x=x+1에서 가장 먼저 y=F(N-1)하는 작업은 시작 과 반드시 ​​같지 않기 때문에 한 번 평가되는 것이 보장 됩니다 N.
JAD

@JarkoDubbeldam Whoops, 오해 : P
LegionMammal978

1

자바 스크립트 (ES6) 109 107 105 91 89 바이트

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

자바 스크립트 (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);v2 바이트를 절약해야 한다고 생각 합니다. 나는 그것이 더 짧아 질 수 있다고 생각하지만, 지금까지 그것을 알아낼 수 없었습니다.
Arnauld

@Arnauld 반복 된 부동 소수점 나누기에 약간의 문제가있을 것으로 예상됩니다
edc65

우리의 유일한 요구 사항은 실제로의 제수 일 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

수학, 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단지와 배열 0(이 컬렉션이다 F()한 세트가 $l동일 1(이것은 최신 F). 그러면 루프 위쪽에서1 으로 $n, 각 반복 실행하는for 루프.

for루프의 조건이 얻어 $lATEST 번호 문자열에서 "$l"다음과 같은 캐스팅하는 char-array 및 저장하는 임시 변수에 배열 $b. 그런 다음 -join해당 숫자를 함께 사용 +하고 iex(을 짧게 Invoke-Expression및 유사하게 eval) 파이프합니다 . 또한와 유사합니다 *. 이 두 숫자는 Parens로 캡슐화되고 -notin현재 $_외부 루프 수 에 대해 연산자 의 배열 인수로 처리됩니다 (즉, for루프는 길이만큼 실행 +되고)와 *다릅니다 $_. for루프 의 본문은 증가 $l++합니다.

내부 for루프에서 벗어나면에 $l새로운 요소로 추가합니다 $i. 범위 루프를 완전히 완료 $i[$n]하면 파이프 라인에 배치하기 만하면 출력이 암시됩니다.

NB- 20단순히 루프 구조로 인해에 대해 실행 속도가 느려집니다 . 예를 들어, N=40내 컴퓨터에서 약 2 분이 걸리며 테스트를 방해하지도 않았습니다 N>50.


0

파이크, 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

Wonder , 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

BASH, 107 바이트

접기 + 붙여 넣기 + bc 포함

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

0

Befunge, 101 바이트

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

온라인으로 사용해보십시오! 그러나 40 대가되면 정말 느려질 것입니다. 전체 범위를 테스트하려면 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.