数学をする時間です


14

前書き

これは私のお気に入りの数学パズルの1つです。

数字(3など)とその数字を使用する回数(5など)を指定して、+のみを使用して1、2、3、4、5、6、7、8、9、10になる10個の式を生成します。 −、×、÷、^、および√(ルート)(グループは操作をグループ化できます)。

例えば:

(3^3 + 3)/(3 + 3) = (33 - 3)/(3 + 3) = 3 + 3/3 + 3/3 = 5

上記のすべてが5つの3を使用し、数学演算と結果が5になることに注意してください。√の前に3を使用して、立方根を表すこともできます。4番目のルートを示すために、√の前に4を使用する場合も同様です。

また、2つの3を使用して33を形成したり、3つの3を使用して333を形成したりできることにも注意してください。

チャレンジ

  • 関数の引数、STDIN、またはコマンドライン引数として2つの数字(両方とも1〜5)が与えられます。
  • 最初の数字は使用する数字を示し、2番目の数字はその数字が式で使用される回数を示します。
  • プログラムは、サイズ10(またはスペースで区切られた10個の数値)の配列を出力する必要があります。各要素は、(index + 1)数値を生成する数式(許可演算子のみを使用)が可能かどうかを示します。

たとえば、入力が

1 3

次に、出力は

[1, 1, 1, 0, 0, 0, 0, 0, 0, 1]

なぜなら、1、2、3、および10のみが3つの1を使用して表現できるからです。

スコア

ボーナス

Print-em-all [−50]

出力配列要素が妥当な組み合わせの合計数に等しい場合は、スコアから50 (index + 1)を引いて、真の値または偽の値ではなく値を取得します。

たとえば、5になる5つの3の可能な組み合わせが3つしかない場合、出力配列の4 番目のエントリは3になります。

エクストリーム数学[−100]

出力配列要素に、(index + 1)値になる結果の実際の式が少なくとも1つ含まれている場合は、スコアから100を引きます。

たとえば、5つの3を使用する場合、出力配列の4 番目のエントリは(3^3 + 3)/(3 + 3)(33 - 3)/(3 + 3)または3 + 3/3 + 3/3

オーバーキル[−200]

出力配列要素に可能なすべての組み合わせが含まれている場合は、スコアから200を引きます(で区切られます|)。このボーナスはExtreme Mathsボーナスに追加されるため、合計で-300が得られます。

たとえば、5つの3を使用する場合、出力配列の4 番目の要素は次のようになります。(3^3 + 3)/(3 + 3)|(33 - 3)/(3 + 3)|3 + 3/3 + 3/3

注:同じ結果を得るための2つの式は、論理的に異なり、両方のアプローチが異なります。

例えば、5 3のを使用して5を取得するには、3 + 3/3 + 3/3同じである3/3 + 3 + 3/3か、3/3 + 3/3 + 3同じアプローチは、それらのそれぞれのために取られているので。分子の30は異なるアプローチで達成されるため(3^3 + 3)/(3 + 3)(33 - 3)/(3 + 3)異なります。

更新:すべての回答を調べた後、すべての回答に単項-および√のエッジケースによる不完全性があることがわかりました。したがって、回答の完全性が関係する限り、これらのエッジケースが欠落していても問題ありません。

これは難しい質問ですが、かなり興味深い質問です。

ハッピーゴルフ!


1
すみません、これは馬鹿げているかもしれませんが、たった3 1秒で10を得るにはどうすればいいですか?
FryAmTheEggman 14

3
@FryAmTheEggman 11-1
オプティマイザー14

1
ああ、だから私は愚かだった:p
FryAmTheEggman 14

4
それは非常に曖昧なルールです。1の平方根、1の平方根の平方根などはすべて異なるアプローチであり、無限の数の回答があると判断する場合があります。a + bはb + aと異なりますか?(-a)*(-b)はb * aと異なりますか?
feersum 14

2
私はこれを知っていますが、4 ^(4 ^(4 ^(4 ^ 4)))を通常の数値形式で表すことはできません。宇宙に原子があるよりも)。そのため、そのような数値を処理できるコンピューター代数システム(存在する場合)を使用しない限り、これらを特別なケースとして扱う必要があります。しかし、これはほぼ間違いなく、私がやりすぎで勝つよりも多くのキャラクターを必要としますしたがって、これらの賞は、複数の平方根をいくらか除外しない限り意味がありません。
Wrzlprmft 14

回答:


1

Python 3(不完全)、449-300 = 149

KSabのソリューションと同じ欠点に悩まされています。完全に括弧で囲まれた単項演算子には、(1+1)+1andなどの同等の式が含まれていません1+(1+1)。結果をに渡すことで、正確な重複を排除しましたset()。出力は数バイト節約するために少しbitいかもしれませんが、私はこの方法が好きです。また、この問題であなたをあまり買わないように見えるので、私はn番目のルートをしませんでした。

R=range
E=lambda z:eval(z.replace("^","**"))
def m(d,n):_=R(1,11);s={i:[]for i in _};r=R(1,n);n<2 and s[d].append(str(d));d=str(d);t=[[(d*i,i)for i in r]]+[[]]*n;h=[];[(h.append("("+A+o+B+")"),t[l].append((h[0],a+b))if a+b<n else E(*h)in _ and s[E(*h)].append(h[0]),h.pop())for l in r for j in R(l)for A,a in t[j]for k in R(l)for B,b in t[k]if a+b<=n for o in"+-*/^"if(o=="^"and-~-(0<E(B)<9)or 0==E(B)and"/"==o)-1];[print(i,set(s[i])or'')for i in _]

2番目の引数は呼び出すことによって5.テストしている場合、これは実行に数分かかりますm(digit, number)

>>> m(1,3)
1 {'((1*1)^1)', '(1^(1+1))', '((1-1)+1)', '((1/1)/1)', '((1*1)*1)', '((1^1)/1)', '(1*(1*1))', '(1^(1*1))', '(1+(1-1))', '(1^(1^1))', '((1^1)*1)', '(1^(1/1))', '((1/1)*1)', '(1-(1-1))', '(1/(1^1))', '(1/(1*1))', '(1/(1/1))', '(1*(1^1))', '((1+1)-1)', '((1*1)/1)', '((1^1)^1)', '(1*(1/1))', '((1/1)^1)'}
2 {'(1*(1+1))', '((1^1)+1)', '((1+1)/1)', '((1*1)+1)', '((1+1)^1)', '(1+(1*1))', '((1/1)+1)', '(1+(1^1))', '(1+(1/1))', '((1+1)*1)'}
3 {'((1+1)+1)', '(1+(1+1))'}
4 
5 
6 
7 
8 
9 
10 {'(11-1)'}
>>> m(3,3)
1 {'((3/3)^3)'}
2 {'(3-(3/3))', '((3+3)/3)'}
3 {'(3-(3-3))', '((3-3)+3)', '((3/3)*3)', '(3*(3/3))', '(3/(3/3))', '((3+3)-3)', '(3^(3/3))', '(3+(3-3))', '((3*3)/3)'}
4 {'((3/3)+3)', '(3+(3/3))'}
5 
6 {'((3*3)-3)'}
7 
8 
9 {'(3+(3+3))', '((3+3)+3)', '((3^3)/3)'}
10 

4

Python(不完全)493 474-300 = 174

このソリューションにはかなりの数の問題があります。まず、大きすぎる指数(指数が100を超える指数)を無視します。実際、これにより5以下の入力の可能性が排除されるとは思いませんが、100%確信はありません。

別のことは、複雑になるため、単項平方根を考慮しないことです(0または1に等しい項を持つ解は無限の数の解を生成します)。また、同じ理由で単項否定(「-」記号)を考慮していません。また、質問がそれを要求したかどうか実際にはわからないという事実も考慮しません。

また、2つの式が同等であるかどうかを判断する基準を検討しましたが、直感的に理解できる方法で厳密に定義する方法を見つけることができなかったため、(少なくとも今のところ)そのようなものは実装しませんでした。これは、かなりの数の結果を出力することを意味し、括弧もかなり単純な方法で使用します。

サイドノートでは、これは、特に完全にゴルフされる前に、私が書いたコードの最長の単一行を含むかもしれないと思います。

R=range
F=lambda s:lambda a,b:eval(s)
L=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)|(b>99)else a**b")),('v',F("b**(1./a)if a and(a>=0 or b)and(b>=0 or int(1./a)==1./a)&(1./a<99)else''"))]if o(u,v)!='']
A=L(*input())
for i in R(11):
 for v,s in A:
    if v==i:print i,s[1:-1]

例:(「v」は「√」を表します)

2,3

0 2*(2-2)
0 2v(2-2)
0 (2-2)*2
0 (2-2)/2
0 (2-2)^2
1 2^(2-2)
1 2-(2/2)
1 2v(2/2)
1 (2/2)^2
2 2v(2+2)
2 2+(2-2)
2 2-(2-2)
2 2v(2*2)
2 2*(2/2)
2 2/(2/2)
2 2^(2/2)
2 2v(2^2)
2 (2+2)-2
2 (2+2)/2
2 (2-2)+2
2 (2*2)-2
2 (2*2)/2
2 (2/2)*2
2 (2/2)v2
2 (2^2)-2
2 (2^2)/2
3 2+(2/2)
3 (2/2)+2
6 2+(2+2)
6 2+(2*2)
6 2+(2^2)
6 (2+2)+2
6 (2*2)+2
6 (2^2)+2
8 2*(2+2)
8 2*(2*2)
8 2*(2^2)
8 (2+2)*2
8 (2*2)*2
8 (2^2)*2

私はあなたが短縮するために行うことができますカップルの事を発見したLL=lambda D,N:[(int(str(D)*N),str(D)*N)]+[(o(u,v),"(%s%s%s)"%(s,c,t))for p in R(1,N)for u,s in L(D,p)for v,t in L(D,N-p)for c,o in[('+',F('a+b')),('-',F('a-b')),('*',F('a*b')),('/',F("1.*a/b if b else''")),('^',F("''if(a<0 and int(b)!=b)|(a and b<0)or b>100 else a**b")),('v',F("''if a==0 or(b<0 and int(1./a)!=(1./a))or(b or a<0)or(1./a)>100 else b**(1./a)"))]if o(u,v)!='']
FryAmTheEggman

すみません、そのコメントのルックスは本当に悪い:(とにかく、説明する:と比較するとき0、私はその後、結果を入れ替える、声明を否定しようとした私はまた、使用にいくつかの場所を発見した|&の代わりに、orandこれらのトリックの両方。 Fへの最後の呼び出しを短縮するために使用できますが、そのためにはいくつかのDemorganが必要になり、くちばしの時間を使い果たしました; p
FryAmTheEggman 14

@FryAmTheEggmanそれは良いキャッチです、あなたの投稿で答えを更新しました。時間があるときに最後のものを見ていきます。入力の有効性をチェックするこれらの条件は、予想より少し多めになりました:/
KSab 14

入れ子になったラムダの素晴らしさのために+10とeval-2行目を理解するのにかなり時間がかかりました!ただし、「最長の単一行」で勝つことができたと思います。;)大きな指数を無視することに同意します。実際、9より大きい指数は役に立たないと思います(基数が1の場合の操作なしを除く)。
DLosc 14

@DLoscまあ、あなたが持つことができる1つのシナリオは次のようなものです3 = 33 √ (3 ^ 33)。実際、これを書いているとき、私の答えが見逃している2つの(おそらく2つだけですか?)組み合わせ4 = (4^4) √ (4 ^ (4^4))5sを持つ同等の式に気付きます。明らかに、ルートは問題にあまり追加されないようです。なぜなら、それらの大部分は0または1でノーオペレーションとして使用されるか、ルートが1のときにノーオペレーションであるか、単にパワーをキャンセルするためです。
KSab 14

3

Python 3 – 349 346

r=range
l=lambda s:eval("lambda a"+s)
def T(u,f,X,Y):
    try:return u(f(X,Y))
    except:0
c=l(',x:{x}.union(*[{u(int("1"*a)*x)}|{T(u,f,X,Y)for j in r(1,a)for X in c(j,x)for Y in c(a-j,x)for f in[l(",b:a%sb"%o)for o in{"**"}|set("+-*/")]+[l(",b:a**b**-1")]}for u in[l(":-a")]+[l(":a**.5**%i"%k)for k in r(9)]])')
R=l(",i:[{n+1}<c(i,a)for n in r(10)]")

これはかなり未使用のバージョンです。

def R(x,i):
    # Unary Operations
    U = [lambda a:-a] + [eval("lambda a:a**(1/2.**%i)" % j) for j in range(9)]
    # Binary Operations
    F = [eval("lambda a,b:a%sb"%o) for o in ["+","-","*","/","**"]] + [lambda a,b:a**(1./b)]

    def combos(i):
        L = {x}
        for u in U:
            # 3, 33, 333, etc.
            L |= {u(int(str(x)*i))}

            for j in range(1,i):
                for X in combos(j):
                    for Y in combos(i-j):
                        for f in F:
                            # To avoid trouble with division by zero, overflows and similar:
                            try:
                                L |= {u(f(X,Y))}
                            except:
                                pass
        return L

    return [n in combos(i) for n in range(1,11)]

テスト(9)では、これを考慮に入れた複数の平方根の数であり、パフォーマンスに大きな影響を与えるため、より小さなものに変更することをお勧めします。

最後に、これにより、ある場合に単項マイナスが実際に必要かどうか疑問に思いました…


1
単項の「-」についてはおそらく正しいと思います(おそらく、ボーナスなしの基本的な質問には)。私が考えることができる唯一の自明でないシナリオは1 = 3^3 * 3^(-3)、のようなものですが、これらを考慮しても、他に何もない場合にこれが可能な解決策になる数字があるとは思いません。
KSab 14

1
複数の平方根を計算するa**.5**%i代わりにa**(1/2**%i)を使用して、3バイトを節約できます。
DLosc 14

@DLosc:確かに、ありがとう。
Wrzlprmft 14

4スペースのインデントを1スペースに減らすことで、6バイトを節約できます。
ベータ崩壊14

@BetaDecay:4スペースのインデント(震え)は使用せず、タブを使用します。投稿のソースを調べてください。Stack Exchangeは、それらを4つのスペースとしてレンダリングします。
Wrzlprmft 14

2

Mathematica-246文字(ボーナスは請求されません)

f[x_,y_]:=x-y
g[x_,y_]:=x/y
h[x_,y_]:=x^(1/y)
j[x_,y_]:=FromDigits@Join[IntegerDigits@x,{y}]
z[{r_,n_,L_}]:=z[{L[[1]][r,n],n,Rest@L}]
z[{r_,n_,{}}]:=r
a[n_,t_]:=Union@Select[z[{n,n,#}]&/@Tuples[{Plus,f,Times,g,Power,h,j},t-1],IntegerQ@#&&0<#<11&]

説明

関数は、j2つの数字を数字ごとに連結します。

Function zはresult r、number n、およびfunctionのリストを取りL、それぞれが2つの引数で動作します。次に[r,n]、リストが空になるまで再帰を使用して引数に関数のリストを順番に適用し、結果を返します。

関数aは、数nと数のコピーを取りますt。関数のリストから長さ(t-1)のすべてのタプルを作成し、{Plus, f, Times, g, Power, h, j}関数zを介して各タプルを送信し、作成されたすべての数値1〜10のリストを返します。

実行例をa[2,3]返す{1, 2, 3, 6, 8}

制限事項

関数のリストは順番に適用され、そのたびに番号のコピーを1つ消費するため、一部の組み合わせを見逃す可能性があります。たとえば、4つの2で動作する場合、関数のリストを順不同で評価できないため、22/22 = 1になりません。もちろん、2/2 * 2/2 = 1がこのケースをカバーします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.