Bayangkan Anda memiliki dua kotak B(x)
dan B(y)
, masing-masing berisi bit yang tidak diketahui - 0 atau 1, dan sebuah mesin F
yang dapat melakukan rontgen dan menghasilkan kotak ketiga untuk B(x^y)
( xor ). F
juga dapat menghitung B(x*y)
( dan ). Bahkan, itu hanya kasus-kasus khusus dari operasi tunggal yang dapat dilakukan mesin - masing-masing produk dalam , dilambangkan dengan di F()
bawah ini.
Untuk dua array dengan panjang yang sama
[B(x[0]), B(x[1]), ..., B(x[n-1])]
[B(y[0]), B(y[1]), ..., B(y[n-1])]
produk dalam didefinisikan sebagai
B(x[0]*y[0] ^ x[1]*y[1] ^ ... ^ x[n-1]*y[n-1])
" Setiap " berarti F()
dapat memproses beberapa pasang x[]
, y[]
dalam satu pergi. Pasangan dari x[]
dan y[]
harus memiliki panjang yang sama; x[]
-s dan y[]
-s dari pasangan yang berbeda tidak perlu.
Kotak diwakili oleh id integer unik.
Implementasi produk dalam masing-masing dalam JavaScript mungkin terlihat seperti
var H=[0,1]; // hidden values, indexed by boxId
function B(x) { // seal x in a new box and return the box id
return H.push(x)-1;
}
function F(pairs) { // "inner product each"
return pairs.map(function (pair) {
var r = 0, x = pair[0], y = pair[1];
for (var i = 0; i < x.length; i++) r ^= H[x[i]] * H[y[i]];
return B(r);
})
}
(Silakan terjemahkan di atas ke bahasa pilihan Anda.)
Diberikan akses ke F()
implementasi yang sesuai untuk bahasa Anda (tetapi tidak ada akses ke H
atau B()
) dan diberi dua larik kotak id yang merupakan representasi biner 16-bit dari dua bilangan bulat a
dan b
, tugas Anda adalah menghasilkan id kotak untuk representasi biner 16-bit of a+b
(discarding overflow) dengan jumlah F()
panggilan minimum .
Solusi yang memanggil F()
waktu paling sedikit menang. Ikatan akan rusak dengan menghitung jumlah total x[],y[]
pasangan F()
yang dipanggil - lebih sedikit lebih baik. Jika masih terikat, ukuran kode Anda (tidak termasuk implementasi F()
dan pembantunya) menentukan pemenang dengan cara golf kode tradisional. Silakan gunakan judul seperti "MyLang, 123 panggilan, 456 pasangan, 789 byte" untuk jawaban Anda.
Tulis fungsi atau program lengkap. Input / output / argumen / hasil adalah array int dalam format apa pun yang masuk akal. Representasi biner mungkin sedikit atau big-endian - pilih satu.
Lampiran 1: Untuk membuat tantangan sedikit lebih mudah, Anda dapat mengasumsikan bahwa kotak dengan id 0 dan 1 berisi nilai 0 dan 1. Ini memberi Anda konstanta, misalnya berguna untuk negasi ( x^1
"tidak"). Tentu saja ada beberapa cara untuk mengatasi kekurangan konstanta, tetapi tantangan lainnya cukup sulit, jadi mari kita hilangkan gangguan ini.
Lampiran 2: Untuk memenangkan hadiah, Anda harus melakukan salah satu dari yang berikut:
memposting skor Anda (panggilan, pasangan, byte) dan kode Anda sebelum batas waktu
memposting skor Anda dan hash kode Anda sha256 sebelum batas waktu; kemudian posting kode aktual dalam waktu 23 jam setelah batas waktu
F
hanya sekali. Itu pasti kecurangan, tapi saya tidak yakin apakah itu kecurangan yang baik atau buruk.y=f(x)
dan biarkanx
tergantung paday
.data Box = B Int deriving (Show); f :: [[[Box]]] -> [Box]
Saya akan membutuhkan lebih banyak waktu untuk mencari tahu bagaimana mengimplementasikanf
(pasukan Haskell huruf kecil di sini) - Saya akan mencobanya besok.Jawaban:
Python 3 , 5 panggilan, 92 pasangan, 922 byte
Python 3 , 5 panggilan, 134 pasangan, 3120 bytePython 3 , 6 panggilan, 106 pasangan, 2405 byte[JavaScript (Node.js)], 9 panggilan, 91 pasangan, 1405 byteJavaScript (Node.js), 16 panggilan, 31 pasangan, 378 byteCobalah online!
VERSI PERTAMA Oke itu bukan golf. Itu hanya adaptasi dari kode @ ngn.
Satu-satunya ide di sini adalah bahwa Anda tidak perlu menghitung carry terakhir karena Anda membuang overflow. Juga, panggilan
F
dikelompokkan berdasarkan dua. Mungkin mereka dapat dikelompokkan dengan cara lain, tetapi saya ragu Anda dapat mengurangi jumlah pasangan secara signifikan, karena sifat dari algoritma penambahan dasar.EDIT : Masih tidak golf. Jumlah pasangan pasti dapat dikurangi, dan mungkin jumlah panggilan juga. Lihat https://gist.github.com/jferard/864f4be6e4b63979da176bff380e6c62 untuk "bukti" dengan sympy.
EDIT 2 Beralih ke Python karena lebih mudah dibaca untuk saya. Sekarang saya sudah mendapatkan formula umum, saya pikir saya dapat mencapai batas 5 (mungkin 4) panggilan.
EDIT 3 Berikut adalah batu bata dasar:
Rumus umum adalah:
Versi yang diperluas adalah:
5 panggilan sepertinya batas bagi saya. Sekarang saya punya sedikit pekerjaan untuk menghilangkan pasangan dan golf itu!
EDIT 4 Saya bermain golf yang ini.
Versi tidak disatukan:
Cobalah online!
sumber
F()
. Saya jamin ada cara untuk mengurangi mereka secara signifikan (itu bagian tersulit dari tantangan ini), dan kemudian akan ada ruang untuk mengoptimalkan jumlah pasangan, dan akhirnya tentu saja golf kode (tapi itu kriteria paling tidak penting).... + x * y * z + ...
. Kami tidak dapat menggunakannyaF
untuk mengevaluasinya, tetapi jika kami telah menghitungx * y
denganF
panggilan sebelumnya , kami hanya perlu melakukannya:... + (x * y) * z + ...
(itu cocok dengan formatF
). Bermain dengan sympy, saya berhasil melakukan panggilan (step1: compute r0, c0, r1; step2: compute c1 dan beberapa nilai aux; step3: compute r2, c2, r3, c3), dan sekarang saya sedang mencari seorang jenderal larutan.Haskell, 1 panggilan (selingkuh ???), 32 pasang (dapat ditingkatkan), 283 byte (sama)
Tolong jangan marah dengan saya, saya tidak ingin menang dengan ini, tetapi saya didorong dalam komentar untuk tantangan untuk menjelaskan apa yang saya bicarakan.
Saya mencoba menggunakan monad negara untuk menangani menambahkan kotak dan menghitung panggilan dan pasangan, dan itu berhasil, tetapi saya tidak berhasil membuat solusi saya bekerja di pengaturan itu. Jadi saya melakukan apa yang disarankan dalam komentar: sembunyikan saja data di belakang konstruktor data dan jangan mengintip. (Cara bersihnya adalah dengan menggunakan modul terpisah dan tidak mengekspor konstruktor.) Versi ini memiliki keuntungan menjadi lebih sederhana.
Karena kita berbicara tentang kotak bit, saya memberikan
Bool
nilai ke dalamnya. Saya mendefinisikanzero
sebagai kotak yang diberikan dengan bit nol - aone
tidak diperlukan.Kami menggunakan fungsi debugging
trace
untuk melihat seberapa seringf
dipanggil, dan dengan berapa pasangan.&&&
melihat ke dalam kotak dengan pencocokan pola, ketidaksetaraan yang/=
digunakan padaBool
nilai adalahxor
.The
test
fungsi mengambil penambah biner buta sebagai argumen pertama, dan kemudian dua angka yang Selain diuji. Ini mengembalikan yangBool
menunjukkan apakah tes berhasil. Pertama, kotak input dibuat, kemudian penambah dipanggil, hasilnya tanpa kotak (denganunB
) dan dibandingkan dengan hasil yang diharapkan.Saya menerapkan dua adders, solusi sampel
simple
, sehingga kita dapat melihat bahwa output debug berfungsi dengan benar, dan solusi saya menggunakan rekursi nilaivalrec
.Lihat bagaimana saya mendefinisikannya
res
sendiri? Itu juga dikenal sebagai ikatan .Sekarang kita dapat melihat bagaimana
f
hanya dipanggil sekali:Atau ganti
valrec
dengansimple
untuk melihatf
dipanggil 32 kali.Cobalah online! (output penelusuran muncul di bawah "Debug")
sumber
f
adalah daftar malas yang berpotensi tak terbatas yang muncul saat Anda mengulanginya? Saya khawatir itu bertentangan dengan semangat tantangan - ini memungkinkan Anda untuk menunda keputusan tentang apa yang harus disampaikan sebagaii+1
argumen pertama sampai setelah Anda mendapatkan hasil yang sesuai dengani
-th. Jauh lebih menarik untuk mengetahui berapa banyak panggilanf
yang akan Anda perlukan dengan argumen yang sepenuhnya terwujud dan tidak dapat diubah :)f
dapat mengambil input tanpa batas (tambahkan bit stream tanpa batas, yay!), Bukan itu intinya. Oh, dan sebenarnyatrace
pesannya memastikan bahwa panjangnya terbatas dan diketahui di awal. Juga, saya tidak akan mengatakan bahwa ada keputusan yang ditangguhkan: semuanya sudah direncanakan sebelumnya, karena menuntut saya hanya kotak pengacak yang membabi buta. Dan perhatikan ini bukan tentang urutan argumen: Saya bisa mengubahnya sehinggares
berisi pertama hasilnya dan kemudian carry bits.f
; apakah Anda memberi makan kotak itu sebagai argumen lain dalam panggilan yang samaf
?JavaScript, 32 panggilan, 32 pasangan, 388 byte
Dyalog APL, 32 panggilan, 32 pasangan, 270 byte
Ini adalah solusi sampel naif yang dapat berfungsi sebagai templat.
Perhatikan bahwa jumlah byte hanya mencakup bagian yang dikelilingi dengan "BEGIN / END SOLUTION".
Penjelasan:
Saya memilih urutan bit little-endian (
x[0]
adalah bit paling signifikan).Amati bahwa penambahan 2-bit mod 2 dapat direalisasikan sebagai
F([[[x,y],[x,y]]])
(yaitu:x*x ^ y*y
- perkalian mod 2 idempoten) dan perkalian biner sebagaiF([[[x],[y]]])
.Kami melintasi bit dari paling tidak signifikan ke paling signifikan dan pada setiap langkah menghitung bit hasil dan carry.
Hal yang sama di Dyalog APL (tetapi menggunakan id kotak acak):
sumber