Penjelasan
Befunge adalah program dua dimensi yang menggunakan tumpukan .
Itu berarti, untuk melakukan 5 + 6, Anda menulis 56+
, yang berarti:
56+
5 push 5 into stack
6 push 6 into stack
+ pop the first two items in the stack and add them up, and push the result into stack
(to those of you who do not know stacks, "push" just means add and "pop" just means take off)
Namun, seperti yang diamati oleh kecerdasan Anda, kami tidak dapat mendorong nomornya 56
langsung ke tumpukan.
Untuk melakukannya, kita harus menulis 78*
sebaliknya, yang mengalikan 7
dan 8
dan mendorong produk ke dalam stack.
Detail
Input dapat diambil dalam format apa pun, artinya bisa STDIN atau tidak, atas kebijakan programmer.
Input akan berupa bilangan bulat positif (tidak ada bonus untuk menyertakan 0
atau bilangan bulat negatif).
Outputnya akan berupa string yang hanya terdiri dari karakter-karakter ini: 0123456789+-*/
(Saya tidak akan menggunakan %
modulo.)
Tujuannya adalah untuk menemukan string terpendek yang dapat mewakili input, menggunakan format yang dijelaskan di atas.
Misalnya, jika inputnya adalah 123
, maka outputnya adalah67*99*+
. Keluaran harus dievaluasi dari kiri ke kanan.
Jika ada lebih dari satu output yang dapat diterima (mis. 99*67*+
Juga dapat diterima), ada yang bisa dicetak (tidak ada bonus untuk mencetak semuanya).
Penjelasan lebih lanjut
Jika Anda masih tidak mengerti bagaimana cara 67*99*+
mengevaluasi 123
, berikut adalah penjelasan terperinci.
stack |operation|explanation
67*99*+
[6] 6 push 6 to stack
[6,7] 7 push 7 to stack
[42] * pop two from stack and multiply, then put result to stack
[42,9] 9 push 9 to stack
[42,9,9] 9 push 9 to stack
[42,81] * pop two from stack and multiply, then put result to stack
[123] + pop two from stack and add, then put result to stack
TL; DR
Program perlu menemukan string terpendek yang dapat mewakili input (angka), menggunakan format yang ditentukan di atas.
Catatan
Ini adalah tantangan kode-golf , jadi kode terpendek dalam byte menang.
Disambiguasi
The -
baik dapat x-y
atau y-x
, kebijaksanaan programmer. Namun, pilihannya harus konsisten dalam solusi. Demikian juga untuk/
.
Program sampel
Lua, 1862 bytes ( coba online )
Karena saya penulis, saya tidak akan golf sama sekali.
Penjelasan:
This uses the depth-first search method.
Lebih lanjut tentang pencarian mendalam-pertama: di sini .
Program:
local input = (...) or 81
local function div(a,b)
if b == 0 then
return "error"
end
local result = a/b
if result > 0 then
return math.floor(result)
else
return math.ceil(result)
end
end
local function eval(expr)
local stack = {}
for i=1,#expr do
local c = expr:sub(i,i)
if c:match('[0-9]') then
table.insert(stack, tonumber(c))
else
local a = table.remove(stack)
local b = table.remove(stack)
if a and b then
if c == '+' then
table.insert(stack, a+b)
elseif c == '-' then
table.insert(stack, b-a)
elseif c == '*' then
table.insert(stack, a*b)
elseif c == '/' then
local test = div(b,a)
if test == "error" then
return -1
else
table.insert(stack, a+b)
end
end
else
return -1
end
end
end
return table.remove(stack) or -1
end
local samples, temp = {""}, {}
while true do
temp = {}
for i=1,#samples do
local s = samples[i]
table.insert(temp, s..'0')
table.insert(temp, s..'1')
table.insert(temp, s..'2')
table.insert(temp, s..'3')
table.insert(temp, s..'4')
table.insert(temp, s..'5')
table.insert(temp, s..'6')
table.insert(temp, s..'7')
table.insert(temp, s..'8')
table.insert(temp, s..'9')
table.insert(temp, s..'+')
table.insert(temp, s..'-')
table.insert(temp, s..'*')
table.insert(temp, s..'/')
end
for i=1,#temp do
if input == eval(temp[i]) then
print(temp[i])
return
end
end
samples = temp
end
Bonus
Kue untuk Anda jika Anda menggunakan Befunge (atau varian lainnya) untuk menulis kode.
sumber
Jawaban:
Python 2, 278 byte
Solusi terbaik saya, yang setiap saat memberikan jawaban terpendek. (tapi sangat lambat)
Python 2, 437 byte
Solusi ini lebih panjang, tetapi sangat cepat (bukan kekerasan). Dan saya cukup yakin, itu selalu mengembalikan hasil sesingkat mungkin.
sumber
f(6551)
mengembalikan25*8*9*7+9*8+
(13 karakter), sedangkan9999***52*-
(11 karakter) adalah yang lebih baik. Diverifikasi denganeval
fungsi saya sendiri di atas (dalam pertanyaan).while c:
;
untuk memisahkan tugas ke variabel (yang menyimpan byte dalam blok indentasi), tip ven, menyingkirkan spasi putih antara simbol dan apa pun, dant
bisa pergi.Perl,
134133132128 byteTermasuk +5 untuk
-Xlp
(2 tambahan karena mengandung kode'
)Jalankan dengan nomor target di STDIN:
befour.pl
:Ini tidak memiliki batas buatan dan secara konseptual agak efisien tetapi memiliki waktu menjalankan yang mengerikan meskipun saya mengorbankan beberapa byte untuk mempercepatnya. Menghasilkan solusi panjang 11 (mis. Nomor target 6551) membutuhkan waktu sekitar 5 jam pada sistem saya.
Mengorbankan 7 byte lebih banyak membuat kecepatannya lebih tertahankan.
17 menit untuk solusi panjang 11, sekitar 5 jam untuk solusi panjang 13. Nomor pertama yang membutuhkan panjang 15 adalah 16622 yang memakan waktu sekitar 2 hari. Angka pertama yang membutuhkan panjang 17 adalah 73319.
Perhatikan bahwa ia mengasumsikan bahwa divisi mengembalikan integer dengan memotong menuju 0 (sesuai spesifikasi befunge 93)
sumber
$
mengakses nilai skalar. Di mana di sebagian besar bahasa yang Anda tulisa=4
, perl akan digunakan$a=4
. Tetapi juga digunakan untuk akses skalar dari variabel yang lebih kompleks. Misalnya$a{$b}
mengambil dari hash (peta, kamus)%a
nilai skalar yang dikunci$b
C,
550545 byte550545 byte setelah menghapus baris baru yang tidak perlu (semua kecuali tiga baris baru setelah arahan preprocessing).@ Kenny Lau - Dapat menerima input integer antara 1 dan 9998, tapi saya pikir rentang input yang solusi optimalnya dihitung lebih kecil dari 9998. Di sisi lain, kedua rentang dapat diperpanjang, jika memori memungkinkan itu.
Program tidak dapat mendorong ke tumpukan nomor lebih tinggi dari 9998. (9998 dapat dimodifikasi.) Saya menjalankan program dalam versi yang berbeda, iterasi di atas loop luar (yang dengan k) selama ada perbaikan untuk nomor apa pun antara 1 dan 9998 (seperti dalam algoritma Dijkstra). Setelah tiga iterasi tidak ada perbaikan. Jadi untuk menghemat byte, saya hardcode k = 3.
Untuk memperluas jangkauan, dua hal diperlukan - memodifikasi konstanta 9999 dan 9998, menjalankannya dengan sejumlah variabel iterasi di atas loop outter selama ada perbaikan, untuk melihat berapa lama waktu sampai tidak ada peningkatan, kemudian ubah konstanta k = 3 ke nilai itu.
sumber
i
,j
dank
sebelummain()
.Python 2, 284 byte
Penafian: Mengalami ketakutan selamanya untuk beberapa nilai ... tetapi harus dijamin untuk selalu mengembalikan string terpendek, dan tidak memiliki batas rentang yang diberlakukan secara artifisial ... bahkan bekerja pada nilai negatif. :)
Algoritma:
i = 0
i
, dan gantiabcd
dengan+-*/
masing - masing, dan hapusef
i
dan coba lagi.sumber
f(i)
dari0 <= i <= 6551
(untuk menangkap6551
nilai yang Anda gunakan untuk membatalkan pengajuan asli @pbochniak). Saat ini, sudah berjalan hanya beberapa menit, dan inilah output terakhir dari tes ini:91 : 49+7* 3.020 s (total 108.174 s, worst 89: 5.827 s)
Pembaruan - baru saja selesai dengan nilai 92:92 : 149+7*+ 258.761 s (total 366.935 s, worst 92: 258.761 s)
113
... lihat hasil tes lengkap di sini (pastebin) jika Anda tertarik ...Python 2, 182 byte
Sangat lambat, saya membiarkannya berjalan selama satu jam pada input
221
dan masih belum dihentikan. Sebagian besar kelambatan adalah karena saya menggunakan daftar sebagai antrian untuk pencarian pertama kali, dan.pop(0)
memang demikianO(n)
untuk daftar.L
hanyalah sebuah antrian yang berisi(stack, code to reach stack)
pasangan. Pada setiap langkah, angka selalu ditambahkan, dan operator dilakukan jika tumpukan memiliki setidaknya dua elemen. Pembagian hanya dilakukan jika elemen terakhir bukan 0, meskipun saya memiliki kecurigaan kuat bahwa pembagian tidak perlu (walaupun saya tidak punya cara untuk membuktikannya, tetapi saya telah memeriksa ini adalah kasus hingga 500).Program berakhir melalui
NameError
setelah mencetak hasilnya (akhirnya).sumber
;E
pada akhirnya dilakukan?NameError
untuk penghentian, karenaE
tidak ditentukan di tempat lainCJam, 79
Cobalah online
Ini sangat tidak efisien, tetapi mengingat ingatan dan waktu yang cukup, akhirnya bekerja. Memori kehabisan 123 dengan 16GB, tetapi 120 dan 125 baik-baik saja.
sumber
Pyth - 35 byte
Paksaan. Yang aneh adalah bahwa input implisit baru benar-benar menyakiti skor saya karena tampaknya juga berfungsi untuk
.v
pyth_eval.Cobalah online di sini .
sumber
Python 3, 183 byte
Kecepatan tidak sepenuhnya tidak masuk akal (123, 221, 1237, 6551 selesai dalam urutan detik atau menit). Mengubah
if
pernyataan untukif j<=i and <k<2*n
mempercepatnya lebih banyak, dengan biaya 9 byte lebih banyak. Saya meninggalkan divisi (/
), karena saya tidak dapat melihat bagaimana itu akan diperlukan.sumber