Deadfish adalah salah satu bahasa pemrograman non-Turing-lengkap yang paling terkenal. Ini hanya memiliki satu akumulator (yang dimulai pada 0) untuk menyimpan data, dan hanya empat perintah:
i - Increment the accumulator
s - Square the accumulator
d - Decrement the accumulator
o - Output the accumulator
Program Deadfish mungkin terlihat seperti:
iiisdo
Dan itu akan mencetak:
8
Tantangan
Buat sebuah program yang akan memasukkan nomor dan output Deadfish kode untuk menampilkan nomor. (Atau membuat fungsi yang mengambil nomor sebagai parameter dan kembali kode.) Ini harus bekerja untuk integer apapun dari 0
ke255
Tujuan
Cobalah untuk membuat kode Anda membuat kode sesingkat mungkin untuk menghasilkan nomor yang diberikan. Sebagai contoh:
iiiiiiiiio
dan
iiiso
setiap cetak 9
, tetapi yang kedua lebih pendek.
Mencetak gol
Nilaimu adalah:
The number of characters in your source code +
The sum of the lengths of your output for all numbers from 1-255
-100 if the language you chose is Deadfish :)
Skor terendah menang!
Dalam tantangan asli saya hanya memiliki jumlah 6 angka (9,17,99,100 dan 123). Ini dari saya yang ingin tidak membuat semua orang menguji untuk setiap nomor, dan saya ingin kode terpendek menjadi relevan. Kemudian saya menyadari bahwa pemrogram mahir membuat skrip untuk menguji hal-hal seperti itu, dan saya lebih suka ini menjadi kontes untuk algoritma terbaik dengan golf sebagai tiebreak.
Untuk itu saya mengubah ini, seperti yang disarankan oleh Martin Büttner.
sumber
16^2 = 0
atau16^2 = 256
atau16^2 = error
?-1
ATAU256
, maka akan diatur ulang ke0
. Tetapi jika Anda menekan angka lebih besar dari256
dengan mengkuadratkan maka itu tidak berubah, misalnya17^2 = 289
. (lihat halaman esolang)Jawaban:
Perl,
132131 bytes + 2036 bytes = 2167Termasuk +2 untuk
-lp
Jalankan dengan nomor target di STDIN, mis
deadfish.pl:
Grep adalah filter untuk membatasi ledakan eksponensial (meskipun program ini masih membutuhkan 2 GB untuk hard case). Ini juga berfungsi tanpa tetapi saya tidak bisa menjalankannya pada perangkat keras saya kecuali untuk kasus yang mudah. Tetapi pada prinsipnya
110=108+2
program byte ini juga berfungsi:Daftar output:
sumber
ES6 JavaScript 2126 + 311 = 2437 skor
Semi-komentar:
Ini mengambil keuntungan dari fakta bahwa dalam ikan mati, Anda dapat mencetak lebih dari satu karakter.
Contoh:
10
mengkompilasiiodo
yang merupakan "print one, decrement, print zero."Pemakaian:
Inilah data keluaran json:
Itu dihasilkan oleh kode ini:
yang mencetak
result = (the result)
danc =
hal di atas.Ini mendapat skor sangat tinggi meskipun cukup sederhana. Ini mencari kuadrat sempurna terdekat, menghitung akar kuadrat dari kuadrat sempurna itu, menambahkan 's', dan kenaikan / penurunan tepat.
Versi lama yang tidak menggunakan fakta bahwa "10" = "cetak satu, cetak nol"
sumber
d
operasi yang salah - jika berkurang-1
, maka akan disetel ulang menjadi0
tidak255
.o
dilakukan; ini mengeluarkan akumulator dan baris baru.iodo
output1\n0\n
, bukan10
.o
. Banyak kompiler (dalam bahasa yang berbeda) juga tidak mencetak baris baru dengano
Mathematica,
254165 karakter + 3455 = 3620Lebih sedikit golf:
Saya percaya angka yang dihasilkan optimal. Ini melakukan pencarian pertama yang luas atas semua 256 angka, melacak cara terpendek yang ditemukan untuk mewakili setiap angka. Pencarian sedang membangun semacam tabel pencarian dalam fungsi
g
yang kemudian diterapkan pada input.Untuk referensi, berikut adalah 255 hasil:
sumber
n > 256
tidakn ≥ 256
. Dan itu juga sejalan dengan halaman esolang: "Meskipun komentar dalam implementasi C menyatakan/* Make sure x is not greater then [sic] 256 */
, implementasi menetapkan nilai ke nol jika dan hanya jikavalue == -1 || value == 256
."d
, sehingga harus mencetak 0.C, 433 kode + 3455 output = 3888
C ++, kode 430 + 3455 output = 3885
Dan sekarang untuk sesuatu yang sama sekali berbeda.
Saya menggunakan output dari jawaban Mathematica Martin (diperbarui pada 23 Oktober karena salah untuk 240+ sebelumnya). Output saya adalah 3455 karakter yang sama. Saya menganalisis pola dalam output dan menemukan bahwa [0,255] dapat diwakili oleh urutan ini:
i
dtks
dtki
dtk ataud
dtks
dtki
atau 0-16d
dtko
Langkah selanjutnya adalah membangun dengan hati-hati lima kolom ini (
c
melaluig
kode di bawah ini). Saya menggunakan angka negatif untuk menunjukkan,d
bukani
dalam kolome
dang
. Kemudian, ternyata hasilnya bekerja sebagian besar seperti penghitung dig
kolom, karena setiap barisu
biasanya menghapus satud
atau menambahkan satui
relatif ke baris sebelumnya (v
). Ada 15 pengecualian, yang disimpan dalamx
(indeks) danb
(lima kolom, dikemas ke dalam bilangan bulat yang hanya membutuhkan 14 bit untuk menyimpan maksimum10832
).Misalnya, "pengecualian" pertama adalah baris paling pertama, di mana kami ingin nol karakter terpisah dari terminating
o
. Begitux[0]
juga0
, danb[0]
ini544
, yang ketika dibongkar adalah gaya ("little endian", karenag
adalah kolom penghitungan){ 32, 0, 4, 0, 0 }
. Kami selalu mengurangi 32 darig
dan 4 darie
untuk membuat bit-field yang tidak ditandatangani berfungsi (yaitu kedua kolom tersebut mewakili angka negatif secara konseptual saatd
diperlukan alih-alihi
, tetapi dalam penerapannya nilai diimbangi untuk menghindari angka negatif aktual).Berikut adalah tabel yang menunjukkan cara kerja sepuluh angka pertama (kosong adalah nol):
Anda dapat melihat bahwa
g
sebagian besar hanya kenaikan satu per satu untuk setiap baris baru, tetapi beberapa baris (0, 4, 8, ..., yang secara singkat saya harapkan temukan di OEIS) "setel ulang" urutannya, artinyag
mengambil beberapa nilai baru dan setidaknya satu kolom lainnya juga dimodifikasi.Jumlah karakter kode tidak termasuk spasi putih kecuali baris wajib baru sebelum masing
#
- masing dan spasi setelahunsigned
danint
. Anda dapat menyimpan 3 karakter dengan mengkompilasi sebagai C ++ alih-alih C, mengganti<stdio.h>
dengan<cstdio>
, dan*(int*)&u
dengan(int&)u
.Fakta menyenangkan tentang kode ini: versi sebelumnya menggunakan array 256 serikat pekerja, bukan hanya
u
danv
. Versi itu menyebabkan GCC 4.7.2 untuk menghasilkan kesalahan kompiler internal! Namun, GCC 4.9 memperbaikinya, dan kode di atas berfungsi dengan salah satu versi.sumber
for(...)
denganscanf
- ini akan mengurangi jumlah karakter).#include
, dan mungkin Anda bisa membuat bagianstruct
dalam yangunion
tidak disebutkan namanya.for
Loop masih diperlukan karena cara saya menghitung hasilnya. Ini ditambah tanpa nama struct yang disimpan 5 karakter; 2 lain diselamatkan dengan mengubah==
ke>
dan menghapus baris tertinggal. :) Program ini hanya sepenuhnya valid di C99, karenamain
tidak secara eksplisit mengembalikan nilai; menghapus#include
hasil dalam kesalahan karenascanf()
sekarang.256
.Haskell,
220021772171 = 2036 + 135ini bekerja dengan memiliki daftar tak terbatas semua program ikan mati, diurutkan berdasarkan panjangnya, disertai dengan keadaan internal dan hasilnya. fungsi
f
mencari daftar dan mengembalikan entri pertama yang cocok.pendekatan ini memungkinkan untuk multiple
o
dalam setiap kode yang dihasilkan, tetapi tidak membatasi untuk mencetak semua digit secara terpisah, atau mencetak seluruh nomor sekaligus. misalnya, di sini 216 memiliki kodeiiosso
.Sunting:
sesuai dengan spesifikasi, ketika negara adalah 256 (tetapi tidak 257) itu dibuat menjadi 0. sekarang kode saya memperhitungkan ini. misalnya, 160 adalah
iissoso
.ini memiliki beberapa masalah efisiensi; karena
l
merupakan daftar level atas, semua elemenl
yang telah dievaluasi tetap berada dalam memori, dan karena itu runtime mungkin akan kehabisan memori di beberapa titik.untuk menghitung skor, saya membuat versi yang setara tetapi tidak terlalu banyak memori.
kode saya yang lebih efisien bekerja dengan menghitung ulang daftar pada setiap aplikasi
f
, sehingga pemulung dapat membuang bagian yang sudah dicari dari daftar. dalam arti, ini adalah pencarian pertama dengan menggunakan kemalasan.kode yang lebih efisien juga menambahkan beberapa kendala pada elemen daftar - ini memfilter semua kode yang mengandung
id
ataudi
, atau berisis
ketika keadaan lebih kecil dari 2.Sunting:
Saya memindahkan
g
fungsi dari tingkat atas menjadi fungsi pembantuf'
, jadi sekarangg
filter kode yang mencetak sesuatu yang bukan awalan dari angka yang kita inginkan. sekarang kodenya jauh lebih cepat.kode yang lebih efisien:
perhatikan kode yang lebih efisien tidak akan memiliki hasil yang sama karena program melintasi semua kode yang mungkin dalam urutan berbeda. Namun, mereka akan menampilkan kode dengan panjang yang sama. juga, beralih
c:x
denganx++[c]
membuat program setara.dengan kode ini saya dapat menghitung semua program dalam
520,81 detik.Sunting:
tampaknya ini adalah jawaban terbaik! Saya memperhatikannya sekarang, sangat jauh dari saat ini diminta ...
hasil:
sumber
Picat 516 + 2060 = 2576
Ini adalah versi modifikasi dari program Sergey Dymchenko . Versi ini menghasilkan program ikan mati yang lebih ringkas.
Sejauh yang saya mengerti kalimat "panjang output", itu berarti bahwa saya harus menjumlahkan output tanpa karakter baris baru.
Menggunakan:
1-255 Kode:
Kinerja:
Versi program untuk mengukur waktu:
Hasil:
Output penuh:
sumber
ioio
akan mencetak"12"
dan tidak"11"
JavaScript (E6) 141 + 3455 = 3596
Fungsi rekursif mencari akar kuadrat terdekat, tetapi menghindari 16 karena 16 * 16 = 256 akan diubah menjadi 0. Banyak jawaban lain tidak mendapatkan poin ini.
Uji di konsol FireFox / FireBug
Keluaran
sumber
Picat, kode 242 + 3455 output = 3697
Lihat http://picat-lang.org/ untuk info tentang Picat.
Lebih sedikit golf:
sumber
Python 3 - 4286 + 168 = 4454
Bukan yang terlalu serius, tapi sangat sederhana. Hanya menemukan yang terbaik untuk menambah 0, kuadrat, kekuatan ke- 4
dan kekuatan ke- 8.EDIT: Golf 75 byte, kekuatan ke- 8 tidak melakukan apa-apa
EDIT 2: Menghapus beberapa byte agar dapat diimplementasikan dengan benar
d
. Namun, skor meningkat.Python 3 - 2594 + 201 = 2795
Yang ini menggunakan semacam pencarian mendalam-pertama untuk menemukan program terpendek. Saya menambahkan beberapa (tidak perlu?) Optimasi untuk itu, sehingga saya bisa mendapatkan hasilnya; dengan cara ini tidak harus menjalankan banyak jalur. Mungkin coba untuk menghapus beberapa dari mereka. Tidak mengalahkan JS yang menggunakan trik pintar seperti banyak
o
.EDIT: Golf off 93 byte, saya tampaknya memiliki kode tidak berguna yang ditinggalkan oleh pengembangan. Juga menghapus semua yang saya temukan tidak perlu sejauh ini. Aku datang, JS.
EDIT 2: Bermain golf dengan 8 byte lainnya. Itu
return
tidak perlu.EDIT 3: Golf 5 byte tambahan. Sekarang kita sudah menyingkirkan yang satu hanya bisa menempatkan yang
elif
lainreturn
.EDIT 4: Memperbaiki fungsi dari
d
. Ukuran bertambah 1 byte, skor beberapa byte.sumber
APL: 80 + 3456 = 3536
Penjelasan: (dikoreksi setelah edc65, terima kasih)
⍵ <4: ⍵⍴'i 'Jika argumen kurang dari 3, ulangi "i" itu berkali-kali
(⌈, ⌊) ⍵ * .5 ⍵ adalah argumennya, ambil akar kuadrat dan ambil langit-langit dan lantai
| ⍵-2 * ⍨ meninggikan langit-langit dan lantai itu menjadi 2, menghapus argumen, dan menjadikannya positif
b ← ⊃ (>, <, =) / dapatkan vektor boolean dengan a> b, a
(⍵> 240) ⌽ Untuk menghindari ke 256, lakukan "i" untuk angka di atas 240, alih-alih ^ 2
b / 'id' gunakan boolean itu untuk mengambil i, d atau s dan menambahkannya ke solusi dengan,
, ∇ (-⊃b) + b [2] + ⍵ * ÷ 1 + 3⊃b Secara rekursif memanggil fungsi dengan argumen -b 1 + b [2] dinaikkan ke daya (kebalikan dari b [3] +1))
Dapat menghitung output dengan:
¨ menerapkan fungsi ke setiap angka 0-255
+ / ⊃, / ⍴¨ menghitung jumlah total elemen
Sekali lagi, Anda dapat mencoba semua hal di atas di TryApl.org
BTW: Ini 3456 dan bukan 3455 karena saya mempertimbangkan 0 juga, karena saya pikir masalahnya bertanya. Jika 1-255 maka skornya adalah 80 + 3455 = 3535
sumber
Python 2712 = 2608 + 104
Kode:
Menggunakan:
0-255 Kode:
sumber
CJam,
2436 2392 22962173 ( 74 karakter + 2099)Yang diterjemahkan menjadi:
Berusaha mengoptimalkan panjang kode Deadfish dengan memilih jalur terpendek untuk mencapai setiap digit angka.
Terima kasih Martin untuk terjemahan Unicode
Ini daftar kode lengkap
Cobalah online di sini:
sumber
o
mencetak baris baru. Semua kompiler juga hanya mencetak tanpa baris baru.C printf("%d\n",x);
C# Console.WriteLine(x)
GO fmt.Println(x)
pascal WRITELN(val);
python print accumulator (no comma)
bash echo $no;; (no -n)