Tulis program yang menggunakan string panjang ganjil yang hanya berisi karakter .
dan :
. Dengan bantuan tumpukan yang awalnya kosong , buat angka dari string ini sebagai berikut:
Untuk setiap karakter c dalam string (dari kiri ke kanan) ...
- Jika c adalah
.
dan tumpukan memiliki kurang dari 2 elemen, tekan 1 pada tumpukan. - Jika c adalah
.
dan tumpukan memiliki 2 atau lebih elemen, pop dua nilai teratas dari tumpukan dan dorong jumlah mereka ke tumpukan. - Jika c adalah
:
dan tumpukan memiliki kurang dari 2 elemen, tekan 2 pada tumpukan. - Jika c adalah
:
dan tumpukan memiliki 2 elemen atau lebih, pop dua nilai teratas dari tumpukan dan dorong produk mereka ke tumpukan.
Angka yang dihasilkan adalah nilai di bagian atas tumpukan. Program Anda harus mencetak nomor ini ke stdout (dengan baris tambahan tambahan opsional).
(Analisis kecil menunjukkan bahwa hanya ada satu angka yang tersisa kecuali string memiliki panjang genap, itulah sebabnya kami mengabaikannya. Faktanya, stack tidak pernah memiliki lebih dari 2 elemen.)
Misalnya, nomor untuk ::...:.:.
adalah 9:
2 1 2 2 /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9 \
: : . . . : . : . <-- string, one character at a time
Sebagai pemeriksaan kewarasan, berikut adalah angka untuk semua string dengan panjang 1, 3, dan 5:
. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8
Program terpendek dalam byte menang. Tiebreaker adalah posting sebelumnya.
- Anda dapat mengasumsikan input selalu valid, yaitu string yang hanya berisi
.
dan:
yang panjangnya ganjil. - Alih-alih menulis program, Anda dapat menulis fungsi yang mengambil string yang valid dan mencetak atau mengembalikan nomor yang dihasilkan.
Jawaban:
CJam,
27 24 2322 byteCukup lurus ke depan. Saya menggunakan tumpukan CJam sebagai tumpukan yang disebutkan dalam pertanyaan;)
Algoritma
Pertama mari kita lihat kode ASCII untuk
.
dan:
.Karena di CJam, indeks membungkus, mari kita lihat apakah kita dapat menggunakan nilai-nilai ini secara langsung untuk mendapatkan operasi yang diinginkan ..
Jadi saya tidak bisa begitu saja menggunakan kode ASCII dalam string operasi 4 panjang. Mari kita coba beberapa nilai lainnya
yang pada string 4 panjang bermuara ke
Saya dapat menggunakan operasi mod 10 ini, tetapi biayanya 2 byte. Mari kita coba yang lain
Bagus !, sekarang kita cukup kurangi 1 untuk kondisi ukuran tumpukan untuk mendapatkan indeks
0, 1, 2 and 3
dan menggunakan5
array panjang ("1+2* "
) sebagai sakelar. Ruang terakhir hanyalah pengisi untuk membuatnya dengan panjang 5. Ini hanya 1 byte tambahan dibandingkan dengan operasi modding.Cobalah online di sini
1 byte disimpan berkat cosechy
sumber
> <> (Ikan) , 33 byte
Cukup mudah dengan sedikit trik / optimisasi.
Penjelasan:
i
= codepoint input char selanjutnya,-1
jika akhir input tercapai;a
= 10;b
= 11;)
=>
i
codepoint input char pertama,b%1-
top_of_stack mod 11 - 1
topeng48 ('.') , 56 (':')
untuk1 , 2
i:1+?\~n;
jika akhir input tercapai cetak hasil terakhir dan hentikanb%1-
mask input ke1 , 2
0@
tekan di0
bawah dua nomori5a*)
baca input selanjutnya dan tutup untuk0 , 1
dibandingkan50
1
(':'
) kalikan dua elemen teratas menciptakan tumpukan [0 produk][0 sum]
atau[0+product=product]
40.
melompat (loop) kembali ke posisi(4,0)
, titik kami4
,i:1+?\~n;
sumber
Haskell,
7365 byteSolusi mudah, menggunakan fakta bahwa tumpukan tidak pernah memiliki lebih dari 2 elemen.
sumber
C, 104 byte
Yah, ini terlalu panjang.
sumber
Pyth,
2524 bytePunya ide dengan mempelajari solusi @ isaacg. Tapi saya menggunakan tumpukan.
Demonstrasi Online atau Test Suite
Penjelasan
Hal pertama yang saya lakukan adalah mengubah string input menjadi 0s dan 1s. A
"."
akan dikonversi menjadi0
, a":"
menjadi1
.Lalu saya mengurangi daftar angka ini:
sumber
JavaScript (ES6), 65
Kami hanya menggunakan 2 sel tumpukan kami.
Mulai memasukkan nilai dalam s [0].
Kemudian, pada setiap posisi ganjil (dihitung dari 0) dalam string input, masukkan nilai dalam s [1].
Pada setiap posisi genap, jalankan calc (tambah atau kalikan) dan simpan hasil dalam s [0].
Jadi lupakan stack dan gunakan hanya 2 variabel, a dan b.
Tes cepat
Keluaran
sumber
f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
Pyth, 27 byte
Tumpukan? Siapa yang butuh tumpukan.
Demonstrasi.
sumber
Retina ,
1057573 byteProgram Retina pertama saya! (Terima kasih kepada Martin Büttner karena telah menghemat 2 byte, belum lagi menciptakan bahasa di tempat pertama.)
Setiap baris harus dalam file terpisah; atau, Anda bisa meletakkan semuanya dalam satu file dan menggunakan
-s
bendera. The<empty>
notasi merupakan file kosong / line.Terinspirasi oleh jawaban mbomb007 , tapi saya mengambil pendekatan yang agak berbeda. Salah satu perbedaan utama adalah bahwa saya membangun tumpukan di depan string dotty (dengan bagian atas tumpukan menghadap ke kanan). Ini membuatnya mudah untuk mengkonversi simbol ke angka yang sesuai di tempat. Saya juga menggunakan
a
alih-alih1
, menukar hanya di akhir, untuk menghindari penguraian ambiguitas dalam urutan seperti$1a
. Jika jawaban sukaaaaaaa
diterima sebagai angka unary, dua baris / file terakhir dapat dihilangkan untuk menghemat 4 byte.Penjelasan:
Cocok jika ada 0 atau 1 item pada stack (
(a+;)?
) diikuti oleh titik (\.
); jika demikian, itu mengganti periode dengana;
(yaitu mendorong 1).Cocok jika ada 0 atau 1 item pada tumpukan diikuti oleh titik dua. Jika demikian, itu menggantikan titik dua dengan
aa;
(yaitu mendorong 2).Cocok jika ada dua item pada tumpukan yang diikuti oleh titik. Menghapus titik dan titik koma di antara item, sehingga menambahkannya.
Cocok jika ada dua item pada tumpukan, yang atasnya adalah 2, diikuti oleh titik dua. Hapus tanda titik dua dan angka 2 dan ulangi angka lainnya dua kali, dengan demikian mengalikannya dengan angka 2.
Regex cocok jika ada dua item pada tumpukan, yang atasnya adalah 1, diikuti oleh titik dua. Menghapus titik dua dan angka 1, meninggalkan angka lainnya tidak berubah (yaitu dikalikan dengan 1).
)`
menunjukkan akhir dari satu loop. Jika ada perubahan pada string, kontrol kembali ke atas program dan menjalankan substitusi lagi. Jika string telah berhenti berubah, kami telah mengganti semua periode dan titik dua, dan yang tersisa hanyalah pembersihan ...Menghapus titik koma yang tersisa.
Mengubah semua a menjadi 1's. Sekali lagi, jika nomor unary diizinkan untuk menggunakan simbol apa pun, langkah ini tidak perlu.
sumber
Karat, 170 karakter
Lebih banyak bukti bahwa Rust benar-benar mengerikan dalam bermain golf. Kode lengkap ungolfed:
Berikut adalah trik menarik yang saya gunakan dalam hal ini. Anda dapat memotong karakter dalam pernyataan if / else dengan meminta mereka mengembalikan nilai yang segera dibuang, yang berarti Anda hanya perlu satu titik koma alih-alih dua.
Sebagai contoh,
dapat diubah menjadi
yang menyimpan karakter dengan mencukur titik koma.
sumber
Haskell,
888179 BytesTampaknya seseorang mengalahkan saya sampai tandai pada solusi Haskell, tidak hanya itu, solusi mereka lebih pendek daripada milik saya. Itu buruk tapi, saya tidak melihat alasan untuk tidak memposting apa yang saya hasilkan.
sumber
APL (50)
Saya sangat dirugikan di sini, karena APL bukan bahasa berbasis tumpukan. Saya akhirnya harus mengurangi pengurangan untuk mempersingkat program.
Fungsi bagian dalam mengambil 'perintah' di sebelah kiri dan tumpukan di sebelah kanan, dan menerapkannya, mengembalikan tumpukan. Fungsi luar menguranginya di atas string, dimulai dengan tumpukan kosong.
Penjelasan:
(⌽⍵),⊂⍬
: daftar awal untuk mengurangi.⊂⍬
adalah daftar kosong kotak, yang mewakili tumpukan,(⌽⍵)
adalah kebalikan dari input. (Pengurangan diterapkan kanan-ke-kiri pada daftar, sehingga string akan diproses dari kanan ke kiri. Membalik input sebelumnya membuatnya menerapkan karakter dalam urutan yang benar.){
...}
: fungsi dalam. Dibutuhkan tumpukan di sebelah kanan, karakter di sebelah kiri, dan mengembalikan tumpukan yang dimodifikasi.F←'.:'⍳⍺
: indeks karakter dalam string.:
, ini akan menjadi 1 atau 2 tergantung pada nilainya.2>⍴⍵:F,⍵
: Jika 2 lebih besar dari ukuran tumpukan saat ini, tambahkan saja nilai saat ini ke tumpukan.⋄
: jika tidak,2↓⍵
: hapus dua item teratas dari tumpukan(
...)/2↑⍵
: kurangi fungsi yang diberikan di atasnya, dan tambahkan ke tumpukan.⍎F⌷'+×'
: fungsinya adalah+
(penambahan) atau×
(perkalian), dipilih olehF
.⊃
: akhirnya, kembalikan item paling atas di tumpukansumber
Ruby - 96 karakter
Bagian yang agak menarik di sini adalah
eval
.Selain itu, saya membuat asumsi bahwa setelah karakter pertama, tumpukan akan selalu menjadi 2, matematika, 2, matematika, .... Ini memungkinkan saya menggunakan lebih sedikit kode dengan meraih dua karakter sekaligus - saya tidak pernah harus mencari apakah karakter adalah matematika atau angka. Itu posisi.
Tidak Disatukan:
sumber
TI-BASIC,
7873706966 byteTI-BASIC bagus dalam satu kalimat, karena tanda kurung penutup adalah opsional; sebaliknya, itu adalah bahasa yang buruk di mana menyimpan banyak nilai diperlukan karena menyimpan ke variabel membutuhkan dua hingga empat byte ruang. Karena itu, tujuannya adalah menulis sebanyak mungkin pada setiap baris. TI-BASIC juga mengerikan (untuk bahasa yang tokenized) pada manipulasi string apa pun; bahkan membaca substring itu panjang.
Trik meliputi:
int(e^([boolean]
dari pada1+(boolean
; menghemat satu bytesumber
".:.":prgmDOTTY
, menghemat 4 byte.1+(":"=sub(Ans,1,1
Pergi,
129115112 byte(agak) tidak berbulu:
Cobalah online di sini: http://play.golang.org/p/B3GZonaG-y
sumber
Python 3, 74
Pertama mengubah daftar input menjadi urutan 1 dan 2, mengambil nilai pertama sebagai nilai awal
x
. Kemudian, lepaskan dua elemen sekaligus dari depans
, ambil angka pertama dan tambahkan atau gandakan dengan nomor saat ini berdasarkan apakah yang kedua adalah 1 atau 2.sumber
nah ini adalah operasi yang sangat mudah, canggih oleh op (sengaja)
hanya saja ...
Kode: C (80 byte)
memasukkan
panjang = 2n + 1 vektor V dari tipe char '.' atau ':'
Keluaran
bilangan bulat k
Fungsi
Simulasi:
coba di sini
sumber
*(V-1)
) adalah nol?Retina,
181135129 byteSetiap baris harus dalam file terpisah.
<empty>
mewakili file kosong. Outputnya di Unary.Ketika${0}1
digunakan, kawat gigi terpisah$0
dari1
, jika tidak$01
, kelompok pencocokan 1. Saya mencoba menggunakan$001
, tetapi ini tampaknya tidak berfungsi dalam .NET rasa regex.Sunting: Ditemukan yang
$&
sama dengan$0
.Dalam pseudo-code, ini pada dasarnya akan menjadi loop do-while, seperti yang terlihat di bawah ini. Saya menekan angka pertama, lalu loop: mendorong angka kedua, menghapus operasi (instruksi), melakukan matematika, menghapus op. Lanjutkan perulangan. Perhatikan bahwa ketika sebuah operasi muncul, ini juga akan menghapus ruang setelah semua instruksi dilakukan.
Berkomentar:
sumber
(:)(.*)
->$1$2
, yang saya yakin bisa(:.*)
->$1
(karena Anda menjaga kedua grup dalam urutan yang sama dan tidak melakukan hal lain dengan mereka) ).Python 3, 122 byte
Tidak Disatukan:
Dengan python, Anda mereferensikan indeks daftar seperti ini:
Anda dapat memasukkan nilai boolean ke dalamnya,
True
apakah1
danFalse
sekarang0
.Cobalah online di sini
sumber
Perl, 77 byte
diperluas:
The
@o
Array peta Angka operator. Kemudian kami mengganti pasangan digit dengan operator yang sesuai, disusun ulang untuk infiks. Regexp dimulai dengan\B
jadi kami tidak cocok dengan karakter pertama. Hasil daris///g
memberitahukan berapa banyak paren terbuka yang kita butuhkan di awal. Kemudian, ketika kami telah mengumpulkan ekspresi infiks penuh, kami dapat mengevaluasinya. (Hapuseval
jika Anda ingin melihat ekspresi sebagai gantinya).Inilah test harness yang saya gunakan untuk memverifikasi hasil:
Input adalah daftar ekspresi titik dan nilainya (disediakan dalam pertanyaan) dan output adalah pasangan {aktual, diharapkan}.
sumber