Hasilkan program golf untuk mengevaluasi ekspresi aritmatika

8

Tugas Anda adalah menulis program yang akan menerima input seperti ini:

a + b * c + a / 2

dan akan menghasilkan kode sumber untuk program yang mengambil input pengguna dan kemudian mengevaluasi ekspresi.

Ekspresi dapat berisi operator +, -, *, /; variabel huruf kecil satu huruf; dan bilangan bulat antara 0 dan 32000. Diutamakan aritmatika standar harus diikuti dengan benar. Ekspresi dibatasi hingga 26 variabel unik a hingga z. Namun, satu variabel dapat muncul lebih dari satu kali.

Anda dapat mengasumsikan bahwa ekspresi input valid (mengikuti aturan ini).

Program yang dihasilkan harus meminta input pengguna dalam formulir ini, meminta hanya sekali untuk setiap variabel:

a = 

Input pengguna dari 0 hingga 32000 harus ditangani dengan benar. Kemudian akan mencetak ekspresi dan hasil yang benar. Anda dapat menggunakan bilangan bulat atau aritmatika floating point. Perhitungan harus dilakukan dengan setidaknya 32 bit presisi. Selain itu, Anda tidak perlu khawatir meluap atau membaginya dengan nol.

Contoh program Perl yang dihasilkan bukan golf untuk ekspresi di atas:

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

Contoh input dan output program yang dihasilkan untuk ekspresi di atas:

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

Skor dihitung sebagai panjang program + panjang program yang dihasilkan untuk ungkapan ini:

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

Skor terendah menang.

Pembaruan: Hanya untuk menyoroti beberapa persyaratan masalah, sebagaimana dinyatakan di atas:

  • Output dari program harus berupa kode sumber untuk program lain yang mengevaluasi ekspresi.
  • Program harus mencetak ekspresi asli . Mungkin ada beberapa ambiguitas dalam hal ini (orang dapat berargumen bahwa itu a+badalah ekspresi yang sama dengan a + b), tetapi untuk kejelasan katakanlah itu pasti ekspresi asli dengan ruang putih yang utuh. Semua jawaban yang valid sejauh ini telah melakukannya dengan cara itu.

sumber

Jawaban:

1

Perl, 80 + 110 = 190

Terinspirasi langsung oleh jawaban lain (sekarang dihapus) di Ruby. Membutuhkan Perl ≥ v5.14.

Mengikuti aturan yang biasa saya lihat dari saklar baris perintah menghitung sebagai satu karakter.

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

Perl, 80 + 231 = 311

Karena evaluasi dalam output terasa murah.

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

Sepertinya output bisa dipersingkat dengan memindahkan bisikan ke sub, tapi saya sudah kehabisan antusiasme.

Kevin Reid
sumber
Ini golf kode. Memvalidasi output tidak murah!
Beberapa saran: \pLbisa diganti [a-z]. Tidak perlu dodiblokir. Bisa saja menulis:${$&}//=print"$& = "and<>
@ dan1111 Terima kasih untuk \pL, dilakukan. Tidak dapat digunakan anddalam salah satu program, karena prioritasnya terlalu rendah; andlebih diutamakan daripada //=.
Kevin Reid
1

Lua, 202 + 166 = 368

File "menghasilkan_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)())')

Pemakaian:

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

Kode yang dihasilkan (urutan variabel tidak ditentukan):

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

Kode yang dihasilkan dalam aksi:

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
Egor Skriptunoff
sumber
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 &]"}]

menghasilkan

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]"
Johannes Kuhn
sumber
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

Sekarang sedang menjalankannya:

>>> 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
jamylak
sumber
Saya tidak berpikir ada persyaratan untuk mengurutkan variabel dan saya pikir ternyata lebih baik menggunakan string literal daripada daftar. Artinya, ganti z=sorted(set(filter(str,isalpha,t)))dengan z=''.join(set(filter(str.isalpha,t))).
Geoff Reedy