Biarkan saya memberi tahu Anda tentang sistem bilangan sederhana. (yang saya buat hanya untuk tantangan ini)
Sistem ini berisi fungsi ()
, []
, {}
, dan <>
.
1. ()
Ketika ()
tidak diberikan argumen, itu dievaluasi untuk 0
.
Ketika ()
diberikan satu atau lebih argumen, itu mengevaluasi jumlah argumen.
2. []
Ketika []
tidak diberikan argumen, itu dievaluasi untuk -1
.
Ketika []
diberikan satu atau lebih argumen, ia mengevaluasi argumen pertama dikurangi jumlah argumen lainnya.
3. {}
Ketika {}
tidak diberikan argumen, itu dievaluasi untuk 1
.
Ketika {}
diberikan satu atau lebih argumen, ia mengevaluasi produk dari argumen tersebut.
4. <>
Ketika <>
tidak diberikan argumen, itu dievaluasi untuk 1
.
Ketika <>
diberikan satu atau lebih argumen, itu mengevaluasi ke integer argumen pertama dibagi dengan produk dari argumen lain.
Tugas Anda
Diberikan string yang berisi angka yang valid (itu berarti tanda kurung seimbang, tidak ada pembagian dengan 0s, dll.) Dalam sistem angka sederhana ini, cetak nilainya.
Uji kasus
() -> 0
(()()) -> 0
([][]) -> -2
({}<>) -> 2
({}[]) -> 0
[] -> -1
[[][]] -> 0
[()<>] -> -1
{()} -> 0
{([]<>)} -> 0
Ingat, ini adalah kode-golf , jadi kode dengan byte paling sedikit menang.
sumber
5/3
,5/-3
,-5/3
dan-5/-3
?Jawaban:
Dyalog APL , 94 byte
o←{(⊂(1⊃⍵),⍺⍺⊃⍵),2↓⍵}⋄u←{(⊃⍵,⍺⍺1)⍺⍺⍵⍵/1↓⍵}⋄⍎⍕'+/o' '-u+o' '×/o' '÷u×o' '(⊂⍬),'[')]}>'⍳⌽⍞],'⊂⍬'
menggunakan
⎕IO←0
menggantikan
)]}>
dengan pemanggilan fungsi yang mengambil tumpukan, menerapkan operasi pada frame atasnya, menghapusnya, dan menambahkan hasilnya ke frame berikutnya (operator monadiko
digunakan untuk itu; operator dyadicu
menangani kasus yang lebih rumit dari-
dan÷
)diganti
([{<
dengan kode yang menambahkan bingkai ke tumpukan ((⊂⍬),
)mengeksekusi ekspresi yang dihasilkan (terbalik, agar sesuai dengan urutan eksekusi APL) dengan tumpukan awal dari satu frame kosong (
⊂⍬
)sumber
Haskell,
357306277251228224188185180 byteParser berbasis token dengan tumpukan eksplisit.
(%)
mengambil token stack dan karakter dan mendorong (opcode, defaultnumber) atau (0, number) untuk({[<
, atau muncul nomor paling atas dan satu opcode dan mendorong jawaban untuk)}]>
. Opcode dikodekan oleh peretas enumerasi ascii.Salam kepada @ChristianSievers atas jawaban besarnya yang saya pinjam dari beberapa ide.
Satu garis!
Sekarang dengan lebih sedikit penanganan kesalahan! Pemakaian:
Terima kasih @ChristianSievers untuk menghemat 14 + 3 byte!
Terima kasih @Zgarb untuk menghemat +4 byte!
sumber
(0,[0,0,1,-1,1]!!o):s
di baris kelima?!
, sehingga Anda dapat melakukan(s:_)!_=d s
sebagai kasus kedua. Juga, saya pikir Anda bisa mengikatx<-p$d<$>init a,y<-d$last a
dalam kasus terakhir%
.%
Anda bisa meletakkan parens di sekitar_:b
dang c
.Python 2,
292265248235223206204 byteMengganti semua tanda kurung dengan lambda yang melakukan apa yang dilakukan braket, kemudian mengevaluasi kode Python yang dihasilkan. Membutuhkan inputnya dikelilingi oleh tanda kutip, seperti
'[<><>([]{})]'
.Program ini menyimpan jenis braket sebagai karakter pertama di setiap string di
for
, dan semuanya setelah kata kuncilambda
sebagai sisanya. Kemudian menggunakan karakter pertama untuk menggantikan; sisanya digabung menjadi seperti lambda(lambda*x:sum(x))()
.Cobalah di Ideone!
sumber
PEG.js (ES6) , 132 byte
Harus diperbaiki sekarang.
Penjelasan
Lebih mudah dibaca:
PEG.js adalah versi Javascript tambahan yang dibuat khusus untuk parsing. Ini SANGAT ketat, itulah sebabnya saya harus menggunakan
var
. Selain itu, tampaknya ada bug dengan tanda kurung di dalam string, yang membengkak kode secara signifikan.Untuk memulai, kami menetapkan aturan
x
yang cocok dengan braket apa puna
yang mungkin atau mungkin tidak mengandung banyak ekspresi yang cocok dengan aturanx
.Agar setiap kecocokan berkuasa
x
, kami mendorong 0 ke deretan kecocokan dalamb
jikab
panjangnya adalah 1.Jika
b
panjang> 0, maka kita menemukan indeksa
dalam([<
dan mendapatkan karakter dari+-/
menggunakan indeks itu. Jika hasilnya tidak terdefinisi (artinyaa
dulu{
), maka kami mengubah hasilnya menjadi*
. Akhirnya, kami memasang spasi dan bergabungb
dengan hasilnya.Jika
b
panjang = 0, maka kami menemukan indeksa
masuk([<
dan mendapatkan karakter dari10
menggunakan indeks itu. Jika hasilnya tidak terdefinisi (artinyaa
itu{
atau<
), maka kami mengubah hasilnya menjadi 2. Akhirnya, kami hanya mengurangi.Pada akhirnya, kita bisa mengevaluasi ekspresi dan mengukur hasilnya.
sumber
Perl, 113 + 2 = 115 byte
Jalankan dengan
-lp
(penalti 2 byte).Lebih mudah dibaca (catatan: "versi yang lebih mudah dibaca" ini tidak akan benar-benar berjalan, karena saya memberikan komentar di tempat yang tidak diizinkan secara sintaksis):
Ide dasarnya adalah bahwa kita mengubah input seperti
[()<>]
ke program Perlb(a(0),d(0),0),
melalui pemrosesan teks; Perl baik-baik saja dengan koma yang tertinggal. Sebelumnya, kita mendefinisikan fungsia
,b
,c
,d
memiliki efek yang sama seperti()
,[]
,{}
,<>
konstruksi dari bahasa kita menerapkan; mereka masing-masing mengabaikan argumen terakhir mereka (0 di akhir), yang disertakan untuk memastikan bahwa semua input diurai dengan benar, dan bekerja menggunakan implementasi yang biasa terlihat dalam pemrograman fungsional di mana kepala dan ekor diproses secara terpisah. Karenab(e,f,g,0)
carae-f-g
, yaitu memperlakukan argumen pertamanya secara khusus, sedangkana
memperlakukan argumennya secara simetris (a(e,f,g,0)
berartie+f+g
), kami terapkana
secara rekursif danb
melalui panggilana
.c
dand
memiliki hubungan yang serupa. Keempat fungsi ini sangat mirip, jadi kami membuatnya pada saat runtime daripada mengimplementasikannya secara terpisah; kami menyimpan templat yang berlaku untuk keempat fungsi dalam sebuah string, lalu menghasilkan fungsi dengan mengganti karakter ke dalam templat.Karena Perl
/
melakukan pembagian floating-point, yang diterapkan{}
juga. Saya berasumsi bahwa ini bukan masalah dalam dirinya sendiri, atau-Minteger
(memilih varian bahasa di mana semua operasi aritmatika adalah operasi integer) adalah gratis, karena kalau tidak saya harus menghabiskan byte ekstra menulis divisi integer di Perl, yang tampaknya tidak menjadi masalah pada dasarnya. (Saya pikir Anda harus menghabiskan empat byte(shift)
untuk menggantiint+(shift)
; Saya belum menguji ini.)sumber
Oktaf,
215206198 bytecoba online
sumber
PHP,
315300285258250244 bytemenggantikan sub-ekspresi dengan nilai garis bawah +; loop terputus ketika iterasi tidak membuat penggantian.
19 tahun sejak saya pertama kali bertemu C, 17 tahun bekerja dengan PHP;
ini adalah pertama kalinya
strtok
masuk akal ... membantu menyelamatkan 24 byte!kerusakan
sumber
ES6 (Javascript),
250,171,154,149, 147 byteVersi Javascript murni.
"Metaprogramming" (seperti kebanyakan jawaban lain di sini), mengubah teks program input menjadi program Javascript yang sesuai, dengan menerapkan sejumlah substitusi teks langsung padanya (yaitu menjaga struktur program seperti apa adanya).
Mungkin bisa bermain golf lebih lanjut.
PEMBARUAN (v2.1)
PEMBARUAN (v2)
Baru menyadari bahwa koma yang tertunda dalam array ES benar-benar valid, sehingga seluruh kode normalisasi koma dapat dihapus. Juga mengikuti saran yang sangat baik dari @Titus, tentang mengoptimalkan pencarian alfabet.
PEMBARUAN (v1)
Duplikat "ganti" alias dihapus.
PEMBARUAN (v1)
Gunakan alfabet yang lebih baik: () => 1+ [] => 0 {} => 2 * <> => 2 / (masing-masing karakter dapat langsung digunakan kembali sebagai nilai atau operator)
Diganti reduksi () dengan replace () (pemetaan alfabet)
Penggabungan braket inline, buka dan tutup yang konstan menjadi satu langkah
Golf (v2.1)
Golf (v1)
Golf (v0)
Dijelaskan (v0)
Uji
Output Uji
sumber
s.reduce((r,c)=>r+="abcdefgh"["()[]{}<>".indexOf(c)],'')
(-5)? jika demikian, Anda bisa mengingatindexOf
dalam variabel dan mengambil operator dari string literal ketiga.Haskell,
184 179 172 161 160 159 151 148145 byteTurunnya rekursif, memasukkan input karena Haskell. Seperti biasa, baris terakhir bukan definisi, tetapi menyatakan fungsi yang memecahkan masalah. Jadi untuk menguji, letakkan baris kecuali yang terakhir dalam file, muat dan lakukan sesuatu seperti ini:
Terima kasih kepada @Zgarb untuk inspirasi dan banyak petunjuk terperinci, dan untuk @Angs atas inspirasi dari solusi dan petunjuk selanjutnya.
Tidak ditentukan bagaimana pembagian harus berperilaku dengan bilangan bulat negatif. Lagi pula, berulang kali menggunakan
div
tampaknya salah, karena tidak sama dengan menggunakandiv
satu kali dengan produk dari nilai yang tersisa. Sekarang menggunakanquot
, saya mendapatkan hasil yang sama untuk<{}([][])[]>
dan<{}{([][])[]}>
.Untuk kode yang bagus dan mudah dibaca lihatlah pada versi pertama. Versi perantara berisi semua jenis kode yang bagus dan mengintimidasi dan membantu memahami versi ini.
sumber
(!)=(,)
dan menggunakan!
alih-alih tuple eksplisit.m x
dand x
sebagai1#x
dan0#x
, Anda dapat menggabungkan kasusm[x]
dand[x]
menjadi satu, yang saya pikir menyimpan beberapa byte juga.!
trik itu tidak membuahkan hasil. Saran kedua Anda adalah jahat, hilang kode saya yang hampir dapat dibaca ... Pintar!s%(c:i)=(s?c,i)
dans?')'=sum s
lain - lain akan jauh lebih pendek, karena Anda dapat menyingkirkani
s berulang . ..Tidak Tunggu, itu mungkin tidak akan berhasil karenas%(_:i)
kasus ini.elem
dandiv
, yang seharusnya menghemat lebih banyak byte.JavaScript (ES6), tidak
eval
, 156 bytePenjelasan: Regexp menemukan braket penutup yang belum diproses pertama, dan cocok dengan (mungkin) braket pembuka yang sesuai dan argumen di antaranya. Argumen dibagi dan dikurangi sesuai dengan operasi (sayangnya '(' dan '[' bukan pasangan yang optimal untuk
+
dan-
), atau jika tidak ada argumen maka nilai yang sesuai dihitung (lagi-lagi pencocokan karakter dengan nilai-nilai adalah suboptimal dari sudut pandang saya). Hasilnya kemudian diganti dengan ruang terdepan untuk memisahkannya dari hasil lainnya. Fungsi ini kemudian memanggil dirinya secara rekursif sampai tidak ada lagi perubahan untuk dibuat, dalam hal ini mengembalikan nilai yang dihasilkan. Contoh:sumber