pengantar
Forte adalah bahasa esoterik yang sangat aneh berdasarkan konsep memodifikasi nilai-nilai angka. Dalam Forte angka bukan konstanta tetapi variabel, Anda bisa menggunakan LET
instruksi untuk memberikan nilai baru kepada mereka.
Misalnya, setelah mengeksekusi LET 2=4-1
dari sekarang 2
mengasumsikan nilai 3
, yang berarti bahwa setiap kali nilai 2
muncul dalam ekspresi itu malah "diganti" oleh 3
. Ekspresi (1+1)*2
sekarang akan dievaluasi menjadi 9
.
Instruksi ini di Forte digunakan baik untuk menyimpan informasi dan untuk kontrol aliran (garis diberi nomor dan dengan mengubah nilai nomor mereka Anda dapat menentukan urutan pelaksanaannya). Dalam tantangan ini kita tidak akan berurusan dengan aspek kedua ini.
Tantangan
Anda diharuskan untuk menulis juru bahasa untuk subset LET
ekspresi Forte yang disederhanakan .
Anda akan menerima sebagai masukan serangkaian garis mengikuti tata bahasa ini:
<line>::= <number>=<expression>
<expression>::= <number>|<expression>+<number>
Catatan: tata bahasa ini tidak sahih Forte karena tidak memiliki nomor baris, LET, dan tanda kurung (yang selalu wajib)
Artinya, Anda hanya perlu berurusan dengan penjumlahan komputasi dan menetapkan nilai ke angka. Tanda kurung tidak akan ada dalam input, dan setiap ekspresi perlu dievaluasi dari kiri ke kanan: berhati-hatilah bahwa sebagian hasil dipengaruhi oleh redefinisi!
Angka akan selalu berupa bilangan bulat non-negatif, hingga batas jenis bilangan bulat asli bahasa Anda (atau 2 ^ 32, mana yang lebih tinggi).
Untuk setiap baris Anda harus menampilkan hasil dari ekspresi dan menetapkan hasil ini ke nilai (mungkin ditugaskan kembali) dari angka pertama, yang akan mempengaruhi bagaimana baris berikut akan ditafsirkan.
Ini adalah kode-golf , kode terpendek (dalam byte) menang!
Aturan lainnya
- Format input fleksibel, misalnya Anda dapat mengambil string tunggal dengan baris baru, daftar string, daftar daftar angka ... Hal yang sama berlaku untuk output, selama jelas apa hasil dari setiap ekspresi di input.
- Anda dapat mengirimkan fungsi, program lengkap, atau solusi untuk dijalankan dalam lingkungan REPL yang memanggilnya sekali untuk setiap baris.
- Celah standar dilarang, khususnya Anda tidak bisa memanggil juru bahasa Forte eksternal dalam kode Anda.
Contohnya
Ini semua adalah bagian dari input yang sama. Setelah setiap baris, output yang diharapkan relatif terhadap baris tersebut ditampilkan, kadang-kadang dengan komentar yang menunjukkan penugasan kembali yang relevan (bukan bagian dari output yang diperlukan).
5=4
4
6=5
4 # 5 -> 4
7=1+2+5
7
7=5+2+1
4 # Order of operations matters! 5+2 -> 4+2 -> 6 -> 4
18=5+6+7
12
5=3
3 # Remember: 5 -> 4
10=6+4
3 # 6 -> 4 -> 3, 3+3 = 6 -> 3
0
nomor itu valid?0
valid ("Angka akan selalu bilangan bulat non-negatif")Jawaban:
Jelly , 28 byte
Cobalah online!
Ini adalah salah satu dari beberapa program Jelly yang sepertinya terser untuk mengambil input dari input standar. Ini adalah program lengkap (menulis fungsi akan lebih pendek tetapi dilarang oleh aturan PPCG, karena itu tidak akan berjalan dengan benar untuk kedua kalinya). Format input terlihat seperti ini:
Penjelasan
Fungsi pembantu
1Ŀ
(menerjemahkan bilangan bulat ke nilainya)Agak nyaman, fungsi pembantu ini akan bekerja dengan benar baik pada nilai tunggal, atau daftar nilai, karena cara
y
didefinisikan Jika lebih dari satu pemetaan diberikan untuk nilai tunggal, kami mengambil pemetaan pertama dari tabel. Tabel pemetaan disimpan dalam register (yang pada dasarnya hanya variabel; Jelly hanya memiliki satu variabel).Fungsi pembantu
2Ŀ
(mengevaluasi satu instruksi LET)Kami tidak benar-benar menginginkan nilai pengembalian di sini; kami hanya menjalankan ini untuk efek sampingnya (memperbarui register dan mengeluarkan nilai yang ditugaskan). Fungsi Jelly selalu mengembalikan nilai, jadi kami hanya membiarkan tabel pemetaan dikembalikan, karena itu tersest.
Program utama
Biasanya,
⁸
akan memberi kita argumen command-line pertama ketika dijalankan dalam konteks ini, tetapi tidak ada satu (kita mengambil input dari input standar), jadi itu berjalan dalam mode alternatif yang memberi kita string nol. Kebutuhan untuk menginisialisasi register (dari nilai default-nya0
, yang crashy
) berarti bahwa kita tidak dapat menyebutkan input pengguna secara implisit, artinya lebih murah untuk mengambilnya dari input standar (Ɠ
) seperti mengambilnya dari argumen baris perintah (³
atau⁸
), dan dapat mengakses penggunaan alternatif⁸
berarti bahwa bentuk input yang tidak biasa (untuk Jelly) sebenarnya satu byte lebih pendek.Mungkin ini bisa diperbaiki. Saya masih belum tahu mengapa baris kedua perlu diucapkan
⁸Ǥ;
daripada hanya;@Ç
- keduanya harus setara, sejauh yang saya mengerti Jelly, mengingat kurangnya penggunaanµ
/ð
/ø
- tetapi yang terakhir crash karena beberapa alasan. Demikian juga, ada berbagai cara lain untuk mengatur ulang program tanpa kehilangan byte, jadi ada kemungkinan saya telah melewatkan cara untuk membuat segalanya sedikit lebih pendek.Kebetulan, mengubah
ḷ
baris terakhir untuk;
memberi Anda pandangan menarik ke dalam cara kerja internal program, karena kemudian akan menampilkan "sejarah register" yang secara implisit dihasilkan oleh nilai pengembalian dari2Ḷ
.sumber
Perl 5 , 92 byte
90 byte kode +
-pl
bendera.Cobalah online!
Saya menggunakan hashtable
%h
untuk menyimpan pemetaan antar angka.Fungsi (
sub
)f
mengembalikan nomor yang peta inputnya (atau inputnya jika dipetakan ke nomor):$h{$a=pop}
mengambil nomor ke arah mana input peta. Jika tidak ada, terima kasih kepada//$a
, nilai($b=$h{$a=pop}//$a)
inputnya adalah ($a
). Kami memastikan bahwa nilai-nilai ini bukan input itu sendiri untuk tidak berulang (!=$a
). Kemudian, kami memanggilf
atau mengembalikan input secara rekursif .Program utama terdiri dari dua langkah:
-
s%(\d+)\+(\d+)%f($1)+f$2%e&&redo
mengevaluasi penambahan pertama di sisi kanan, sementara masih ada tambahan: ia menggantikanx+y
dengan hasil evaluasif(x)+f(y)
.-
/=/;$_=$h{f$`}=f$'
melakukan penugasan:/=/
memungkinkan untuk mengakses sisi kiri dengan$`
dan sisi kanan dengan$'
, kemudian$h{f$`}=f$'
melakukan penugasan. Dan kami juga menugaskannya untuk$_
yang dicetak secara implisit setelah setiap baris.sumber
JavaScript (Node.js) , 81 byte
Cobalah online!
Menerima input dengan memanggil f dengan nilai untuk ditugaskan, lalu memanggil hasilnya dengan array nilai untuk ditambahkan bersama. (Yaitu
f(5)([4])
) Ulangi untuk beberapa baris.v
digunakan sebagai fungsi untuk menghitung nilai aktual suatu angka, dan juga sebagai objek untuk menyimpan nilai aktual. Pertama,v[x]=v[x]||x
pastikan halv[x]
itu didefinisikan.v[x]-x
melakukan perbandingan untuk menentukan apakah ini angka yang sebenarnya atau tidak. Jika nomor tidak memetakan ke dirinya sendiri,v(v[x])
secara berulang coba lagi, jika tidak kembalix
.f
melakukan perhitungan dan penugasan, mencari satu byte, di mana panggilan kedua mengembalikan nilai yang dihitung.sumber
Haskell ,
116 113 108106 byteCobalah online! Setiap persamaan
4=3+1+5
dinotasikan sebagai tuple(4,[3,1,5])
. Fungsi anonim(id?)
mengambil daftar tupel tersebut dan mengembalikan daftar semua hasil antara.#
adalah fungsi untuk menemukan titik fokus dari fungsi yang diberikane
dan nilai awalx
.Fungsi ini
?
mengambil fungsi evaluasie
dan memecahkan setiap persamaan secara rekursif.foldl1(\a b->e#(e#a+e#b))s
mengevaluasi sisi kanan persamaan dan menyimpan hasilnyam
, misalnya untuk4=3+1+5
menghitungnyaeval(eval(eval 3 + eval 1) + eval 5)
, di mana masingeval
- masing merupakan aplikasi titik perbaikane
. Kemudian fungsi eval dimodifikasi untuk mempertimbangkan penugasan barun
:(\x->last$m:[e#x|x/=e#n])
yang sama dengan\x -> if x == eval n then m else eval x
.Fungsi evaluasi awal adalah
id
memetakan setiap bilangan bulat ke dirinya sendiri.Terima kasih kepada Ørjan Johansen untuk fungsi fixpoint yang lebih pendek, menghemat 2 byte!
sumber
last.
(#)e=until((==)=<<e)e
atau(#)=until=<<((==)=<<)
lebih pendek.OK, 48 byte
Pemakaian:
f[5;1 2 3] / 5=1+2+3
Cobalah online!
Jika Anda tidak keberatan memiliki batas atas untuk angka-angka yang dapat Anda gunakan, seperti hanya menggunakan angka
0
melalui998
, maka yang berikut sudah cukup ( 41 byte ± beberapa tergantung pada maksimum):Penjelasan:
;
memisahkan tiga definisi.a
adalah kamus / peta angka. Dalam kasus pertama, ini adalah kamus kosong yang sebenarnya[]
, dalam kasus kedua adalah daftar angka-angka0
untuk998
.s
adalah fungsi yang menemukan nomor "dihasilkan" ketika diberi nomor. Di/
akhir fungsi berarti bahwa ia akan menerapkan sendiri ke output sendiri sampai output berhenti berubah.Bit terakhir
f
,, berarti bahwa:sumber
Python 3,
146132130 byte14 byte disimpan berkat @Dada
2 byte disimpan berkat @ mbomb007
Cobalah online!
Menerima input sebagai tupel persamaan [
x = y + z + w
sebagai(x, (y, z, w))
], output melalui generator.sumber
g
mungkin bisa ditulisg=lambda x:d.get(x)and d[x]!=x and g(d[x])or x
. Dan saya pikir Anda bisa menggunakan 1 spasi untuk indentasi daripada 2. Itu seharusnya membuat Anda [132 byte] ( Coba online! ).