Plus and Times、Ones and Nines


18

この繰り返し関係を、負でない整数を入出力する関数またはプログラムとして実装します。

  • F(0)= 0

  • F(N)= 10を底とする数字の和および/または積がNになるようなF(N-1)より大きい最小の整数

Nはプログラムの入力であり、F(N)はその出力です。

明確にするために、913などの数字の合計は9 + 1 + 3 = 13です。積は9×1×3 = 27です。1桁の数値の場合、合計と積は同じ数値です。もちろん、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
正しくないシーケンス。
カルバンの趣味

回答:


4

05AB1E20 12バイト

Osableのおかげで8バイト節約

µNSDOsP‚¾>å½

CP-1252エンコードを使用します。オンラインでお試しください!


長さテストは必要ですか?私は思いついたµNSDOsP‚¾>å½。ランダムに選択された番号で機能するようです。
2016

@Osable Ahhもちろん、あなたは天才です!なぜそれを含めたのかさえ分かりません。
アドナン

あなたが突然... 40%20バイトのプログラムを減らすことができる方法アメージング
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)

後者のバージョンでは、あなたが評価する前に±nPlusMinus2つのダウンの値を持つことになります。

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

これは劇的にMathematicaがもはや間の値を計算しませんので、将来の計算を高速化0し、20再帰的に。節約される時間は、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 16

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!


for with for(;;)とforeach を置き換える-2バイトforeach(var c in++i+"")。交換する-22バイトint.Parse(c+"")c-48
ミルク


1

R、124 112バイト

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は10.000を1e + 05として書き込むことを要求しているため、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おっと、読み間違え:P
LegionMammal978

1

JavaScriptの(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

JavaScript(ES6)、84 86

編集:2バイト保存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")

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
edc65

唯一の要件は、が実際にの約数であるp /= dときに正確な結果を生成することdですp。誤解しない限り、これはすべてに当てはまりますd <= p <= Number.MAX_SAFE_INTEGER。の場合p % d != 0、浮動小数点の丸めエラーが発生しますが、これは安全なはずです。
アーナルド

@darrylyeoはあなた自身(試してみてくださいませんでした提案を与えることはありませんeval`1+1` (なぜここだ)codegolf.stackexchange.com/a/52204/21348は:最初のコメントを読んで)
edc65は

1

Mathematica、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各反復実行A、forループ。

forループの条件がかかり$lATEST数を、文字列に"$l"は、キャストとchar-array、及び記憶する一時変数に配列$b。次に、-joinこれらの数字を一緒に+パイプし、それをパイプしますiex(略しInvoke-Expression、同様ですeval)。さらに、同様のことを行い*ます。これらの2つの数値は括弧でカプセル化され、外側のループの-notin現在の番号に対する演算子の配列引数として扱われ$_ます(つまり、forループはいずれかで+あり、で*ある限り実行されます$_)。forループの本体は増加します$l++

内側のforループから抜けたら$l、の新しい要素としてon を追加します$i。範囲ループを完全に完了したら$i[$n]、パイプラインに配置するだけで、出力は暗黙的になります。

NB- 20ループ構造のため、上記の実行がかなり遅くなります。たとえば、N=40私のマシンでは約2分かかりますが、テストさえ気にしませんでしたN>50




0

ワンダー、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.