算術式を評価するゴルフプログラムを生成する


8

あなたの仕事は、次のような入力を取るプログラムを書くことです:

a + b * c + a / 2

そして、ユーザー入力を受け取り、式を評価するプログラムのソースコードを生成します。

式は、演算子を含めることができ+、-、*、/、1文字の小文字の変数。0から32000までの整数。標準の算術優先順位に正しく従う必要があります。式は、26個の一意の変数a〜zに制限されています。ただし、1つの変数が複数回現れることがあります。

入力式は有効であると想定できます(これらの規則に従います)。

生成されたプログラムは、このフォームでユーザー入力を要求する必要があり、変数ごとに1回だけ要求します。

a = 

0から32000までのユーザー入力は正しく処理されます。次に、式と正しい結果を出力します。整数または浮動小数点演算を使用できます。計算は、少なくとも32ビットの精度で実行する必要があります。それ以上であれば、オーバーフローやゼロによる除算を心配する必要はありません。

上記の式に対して生成された非ゴルフ生成Perlプログラムの例:

print "a = ";
my $a = <>;
print "b = ";
my $b = <>;
print "c = ";
my $c = <>;
print "a + b * c + a / 2 = " . ($a + $b * $c + $a / 2); 

上記の式に対して生成されたプログラムの入力と出力の例:

a = 1
b = 2
c = 3
a + b * c + a / 2 = 7.5

スコアは、プログラムの長さ+この式に対して生成されたプログラムの長さとして計算されます。

1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000

最も低いスコアが勝ちます。

更新:上記のように、問題のいくつかの要件を強調するだけです。

  • プログラムの出力は、式を評価する別のプログラムのソースコードである必要があります。
  • プログラムは元の式を印刷する必要があります。おそらくこれにはあいまいさがいくつかありますが(これa+bはと同じ式であると主張することもできますa + b)、明確にするために、空白がそのままの元の式である必要があるとしましょう。これまでのすべての有効な答えは、そのようにしてきました。

回答:


1

Perl、80 + 110 = 190

Rubyの別の(現在は削除済み)回答に直接影響を受けた。Perl≥v5.14が必要です。

コマンドラインスイッチが1文字としてカウントされるという通常のルールに従いました。

#!/usr/bin/perl -n
chomp;print'print $_="',$_,'"," = ",eval(s#\pL#${$&}//=do{print"$& = ";<>}#ger)'

Perl、80 + 231 = 311

出力での評価は安く感じるからです。

#!/usr/bin/perl -p
chomp;print"print '$_ = ',";s/\pL/$s{$&}++?"\$$&":"do{print'$& = ';\$$&=<>}"/ge

プロンプトをサブに移動することで出力を短縮できるようですが、私は熱意を使い果たしました。


これはコードゴルフです。出力の評価は安くはありません!

いくつかの提案:\pLを置き換えることができ[a-z]ます。doブロックの必要はありません。ただ書くことができます:${$&}//=print"$& = "and<>

@ dan1111、ありがとうございました\pL。and優先順位が低すぎるため、どちらのプログラムでも使用できません。andはより優先順位が低くなってい//=ます。
— ケビンリード

1

ルア、202 + 166 = 368

ファイル「generate_code.lua」

F=...
C='function G(v)io.write(v.." = ")_G[v]=io.read"*n"end 'V={}for v in F:gmatch'%l'do V[v]=0 end
for v in pairs(V)do C=C..'G"'..v..'"'end
print(C..'F="'..F..'"print(F.." = "..load("return "..F)())')

使用法:

$ lua generate_code.lua "1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000"

生成されたコード(変数の順序は指定されていません):

function G(v)io.write(v.." = ")_G[v]=io.read"*n"end G"g"G"e"G"d"G"b"G"a"G"h"F="1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000"print(F.." = "..load("return "..F)())

実際に生成されたコード:

g = 4
e = 3
d = 2
b = 1
a = 6.5
h = 4.3
1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000 = 29787.941860465

1

Tcl 198 + 155 = 352

gets stdin i;puts [string map [list @ [lsort -u [regexp -all -inline {[a-z]} $i]] & [regsub -all {[a-z]} [join $i {}] {$\0}] | $i] {foreach va {@} {puts "$va =";gets stdin $va};puts "| = [expr &]"}]

生成する

foreach va {a b d e g h} {puts "$va =";gets stdin $va};puts "1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000 = [expr 1+$a*4*$b+2/$d*$e-$a-3+$g/$h*32000]"

foreach=> lmap; va=>v
— sergiol

0

Python 125 + 151 = 276

>>> t=raw_input();z=sorted(set(filter(str.isalpha,t)));print','.join(z)+'=[input(x+" = ")for x in%r];print"%s =",%s'%(z,t,t[::2])
1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000
a,b,d,e,g,h=[input(x+" = ")for x in['a', 'b', 'd', 'e', 'g', 'h']];print"1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000 =",1+a*4*b+2/d*e-a-3+g/h*300

今それを実行します:

>>> exec"""a,b,d,e,g,h=[input(x+" = ")for x in['a', 'b', 'd', 'e', 'g', 'h']];print"1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000 =",1+a*4*b+2/d*e-a-3+g/h*300"""
a = 1
b = 2
d = 3
e = 4
g = 5
h = 6
1 + a * 4 * b + 2 / d * e - a - 3 + g / h * 32000 = 5

変数をソートする必要はないと思いますし、リストの代わりに文字列リテラルを使用する方が良いことがわかったと思います。つまり、交換してくださいz=sorted(set(filter(str,isalpha,t)))とz=''.join(set(filter(str.isalpha,t)))。
— Geoff Reedy 2013
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.