Ini dulu, tetapi saat ini semua orang telah beralih ke IPv6 . (Baik?)
Tugas Anda adalah menulis program yang mencetak semua alamat IPv6 .
Anda harus menulis program lengkap yang tidak mengambil input dan mencetak alamat IPv6, satu per baris, dan tidak ada output lainnya. Program Anda harus mencetak semua 128 alamat yang mungkin, termasuk yang tidak valid. Setiap alamat harus dicetak tepat sekali. Anda dapat mencetak alamat dengan urutan apa pun.
Setiap alamat dapat dicetak secara penuh, dengan 8 grup dengan 4 digit heksadesimal yang dipisahkan oleh titik dua, misalnya
2001:0db8:85a3:0000:0000:8a2e:0370:7334
Anda dapat, atas kebijakan Anda, menggunakan singkatan standar dari RFC 5952 :
- Angka nol di grup dapat dihilangkan, kecuali yang
0
tidak dapat disingkat lebih lanjut. ::
dapat digunakan paling banyak sekali per alamat untuk menyingkat urutan satu atau lebih grup yang semuanya nol.- Digit heksadesimal dapat menggunakan huruf kecil atau huruf besar.
Jika Anda mencapai rekomendasi representasi dari RFC 5952 (hanya huruf kecil, representasi sesingkat mungkin, dengan ::
digunakan sedini mungkin jika ada beberapa tempat di mana ia dapat digunakan), Anda mendapatkan bonus -20% .
Karena ukuran output, program Anda tidak diharapkan selesai saat kami duduk di sana. Program Anda mungkin terganggu oleh sarana eksternal di beberapa titik ( Ctrl+ C, mengeluarkan daya, ...). Program Anda harus menghasilkan output sebagai aliran, sehingga setelah menunggu "masuk akal", itu akan menghasilkan beberapa baris. Pada dasarnya, membangun string raksasa di memori hanya untuk mencetaknya di akhir tidak diperbolehkan. Program apa pun yang kehabisan memori pada PC "standar" didiskualifikasi. (Meskipun demikian, jika program Anda dibiarkan berjalan cukup lama, ia harus mencetak semua alamat IPv6 dan kemudian keluar.)
(Jika kondisi ini merupakan masalah bagi juru bahasa yang menjalankan program sampai selesai dan kemudian membiarkan Anda melihat hasilnya, dan Anda tidak memiliki juru bahasa yang di-host, ujilah program Anda pada versi masalah yang lebih kecil, lalu sesuaikan dengan hati-hati ke 2 128 penuh .)
Skor Anda adalah panjang program Anda dalam byte, dikalikan dengan 0,8 jika Anda mendapatkan bonus. Ini golf kode, jadi skor terendah menang.
sumber
Jawaban:
Pyth, 21 byte
Menggunakan loop sementara dengan
J
sebagai variabel iterator. Menginisialisasi penggunaan maksimum8^chr(' ')
. Pads dengan menambahkan nilai awal itu, mengonversi ke hex, lalu menghapus karakter pertama.sumber
Python 3, 65 byte · 0.8 = 52.0
sumber
ipaddress
hanya python3.Pyth,
272524 byteCatatan: kode memiliki bug sebelumnya, memperbaikinya menyimpan 1 byte
Mencetak alamat seperti
Versi sebelumnya (lebih rumit) menggunakan operator pad (juga 24 byte):
Penjelasan
Pyth, 21 byte (tidak valid)
Ini tidak dapat dijalankan karena 1) ia akan mengkonsumsi setidaknya 2 132 byte (2 52 yobibytes) memori dan 2) penerjemah tidak menyukainya (2 128 tidak cocok
ssize_t
, jadi tidak adalist
ukuran sebesar itu) . Itu akan mencetak alamat dalam urutan leksikografis. Anda dapat mencoba algoritme dengan mengubah angka pada akhirnya menjadi sesuatu yang dapat digunakan.sumber
C (dengan ekstensi GCC), 76 byte * 0,8 = 60,8
Ini menggunakan ekstensi GCC 128-bit integer untuk sekadar menghitung dari
::
hinggaffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
.inet_ntop()
memformat setiap alamat dengan benar sehingga bonus -20% dapat diklaim.Keluaran
Menggunakan
sed
untuk menghasilkan setiap garis sepersejuta hingga 10 juta:Catatan Saya menggunakan mesin x86_64 little-endian, dan bahwa alamat jaringan biasanya selalu dalam urutan jaringan (big-endian), sehingga endianness secara efektif ditukar dengan menggunakan
inet_ntop()
. Ini tidak masalah - semua alamat masih (pada akhirnya) akan ditampilkan.sumber
CJam,
3627 byte-9 byte terima kasih kepada @Dennis (saya lupa bahwa CJam memiliki pemformatan string). Mencetak alamat huruf kecil dan turun.
Untuk alasan yang jelas, gunakan penerjemah Java, bukan penerjemah online. Anda dapat mengganti
G32#
dengan sesuatu yang lebih kecil untuk pengujian online, misalnya, inilah 100 yang terakhir .Penjelasan
sumber
0000:0000:0000:0000:0000:0000:ffff:ffff
. Sepertinya pemformatan string mungkin bekerja secara online berbeda. Saya mengkonfirmasi bahwa ini berfungsi baik dengan versi offline.n
sama sepertioNo
di TIO .Python 2.7, 67 byte
Sebagai efek samping dari metode yang digunakan untuk memasukkan titik dua, alamat dicetak dengan kolom paling kanan muncul di sebelah kiri:
sumber
[printing] the addresses in any order
. ;)Verilog, 335
Pengajuan Verilog pertama saya, mungkin bisa menggunakan lebih banyak golf tetapi saya tidak punya energi untuk melakukannya sekarang.
c
adalah clock,o
adalah output ASCII. Tidak memenuhi syarat untuk memformat bonus karena zero-padding alih-alih menyingkat.Ini adalah iterasi sederhana yang diikuti oleh sedikit twiddling untuk membuat output ASCII. Saya memotong usus setelah kelompok terakhir dengan hack kecil. Mensintesis dan tampaknya berfungsi untuk xc3s500e-4ft256-4 pada ISE 13.7 lin64.
sumber
C, 91-126 byte
Versi asli saya, 119 byte.
Versi portable-ish golf terbaik, 103 byte (terima kasih @Dennis untuk beberapa konsep ini)
Penjelasan: Algoritme itu sendiri cukup mudah. Saya menggunakan int lama daripada unsigned karena lebih pendek. Mendeklarasikan mereka di tingkat file berarti semuanya diinisialisasi dengan nol. The
f
fungsi adalah kenaikan sederhana dengan membawa yang beroperasi pada rendah 16 bit dari setiap kata. Loop berakhir ketika membawa ke bit ke-129.Iterasi mundur untuk printf berarti bahwa kita mencetak alamat dalam urutan "tepat" dan juga memeriksa untuk mencetak baris baru adalah beberapa karakter lebih pendek.
Ini memang menggunakan beberapa konstruksi non-portabel. Paling baik dianggap sebagai dialek K&R dari C, karena menggunakan jenis pengembalian int implisit dan tidak termasuk stdio.h. Dan penggunaan saya lama diinformasikan oleh ini - pada kebanyakan sistem modern int sudah cukup karena 32 bit. Ini mungkin dapat dijalankan tanpa modifikasi pada PDP-11 Unix.
Namun, bisa lebih pendek. Jika kita berasumsi bahwa kita dapat menggunakan int (baik sebagai tipe yang lebih luas dari 16 bit, atau tipe tepat 16 bit dengan berbagai properti yang ternyata benar pada banyak sistem seperti komplemen dua dan rollover aritmatika), kita dapat menyingkirkan hal-hal terkait penggunaan panjang.
Versi untuk int lebih luas dari 16 bit, 97 byte.
Versi untuk sistem 16-bit, 91 byte.
Anehnya, kompiler K&R asli tidak benar-benar mendukung deklarasi tanpa int (itu mengkompilasi dengan baik, tetapi memperlakukan variabel sebagai eksternal dan karenanya tidak terdefinisi pada waktu tautan), sehingga diperlukan tiga byte tambahan untuk mengubah deklarasi menjadi
int*p,a[9];
untuk total 94.Juga, jika asumsi bahwa itu terganggu sebelum menyelesaikan output adalah kendala yang sulit, kita bisa menghapus cek akhir, menghemat lima byte.
Bonus: versi portabel ANSI sepenuhnya, 126 byte:
Baris baru di semua versi dimasukkan untuk dibaca dan di lokasi di mana spasi tidak diperlukan, dan dikeluarkan dari jumlah byte, kecuali baris baru setelah
#include
baris dalam versi ANSI.Semua versi kecuali versi ANSI jatuh pada akhir utama dan karenanya dapat mengembalikan kode keluar palsu ke sistem operasi.
sumber
a[9];f(int*x){if(++*x>>16)*x=f(x+1);}main(i){for(;!a[8];f(a))for(i=8;i--;)printf(i?"%x:":"%x\n",a[i]);}
i--
pemeriksaan kondisi.a[0]
dan bungkusa[1]
AutoIt3,
142231 BytesPenjelasan
For $a=0 To 2^32-1
: Iterasi 4 kali lebih dari 0-2 ^ 32 ((2 ^ 32) ^ 4 = 2 ^ 128) kemungkinan kombinasi.$s=StringFormat("%08x%08x%08x%08x",$a,$b,$c,$d)
: Konversi angka menjadi string heksadesimal dengan panjang 32 (4 * 32).For $j=0 To 8
: Iterate atas semua 8 bagian dari string.ConsoleWrite(StringMid($s,$j*4+1,4)&($j<7?":":""))
: Ekstrak 4 karakter berikutnya dari string dan tambahkan tanda titik dua (:
) di bagian akhir, jika kita belum mencapai bagian terakhir, maka output semuanya ke konsolNext
: Akhiri for-loop dalamConsoleWrite(@LF)
: Tambahkan umpan baris di akhir barisNext
: Akhiri loop luar untukUkuran output yang diharapkan: (Satu baris (39 byte) + feed baris) (= 40 byte) * 2 ^ 128 = 1,361 * 10 ^ 16 YB (yottabytes)
sumber
4^64 - 1
?Cinnamon Gum, 16 byte
Cobalah online. (TIO membatasi output)
Penjelasan
The
g
menempatkan modus Cinnamon Gum di menghasilkan modus . Sisa string mendekompresi ke regex ini:Itu kemudian menciptakan generator dari semua string yang mungkin cocok dengan regex dan beralih melalui itu, mencetak masing-masing.
Agak mengherankan, regex golfier
([0-9a-f]{4,4}:){7,7}[0-9a-f]{4,4}
sebenarnya kompres ke string yang lebih panjang daripada regex di atas.sumber
Commodore BASIC 2.0, 339 byte
Untuk mendapatkan digit hex dengan huruf kecil, program ini ditulis dalam "mode bergeser" (tekan
<SHIFT>+<C=>
)Membuat pekerjaan ini di Commodore 64 adalah sebuah tantangan, karena memori, ukuran layar, ukuran data, dan batasan lainnya. Saya mempertimbangkan untuk menerapkan representasi yang disingkat, tetapi keterbatasan lain (seperti ketidakmampuan tidak berdokumen untuk menggunakan elemen array sebagai indeks loop) berarti akan menambah panjang program dengan sekitar 1000 byte.
Baris 7 adalah implementasi dari
HEX$()
, yang kurang Commodore BASIC 2.0. Saya tidak bisa menggunakan aDEF FN
untuk ini karena mereka hanya bisa mengembalikan angka, bukan string. Baris 6 adalah subrutin yang berlaku untuk sekelompok empat digit, yang akan jauh lebih pendek jika fungsi dapat mengembalikan string.Baris 2 dan 5 adalah delapan loop bersarang, diimplementasikan sebagai tujuh "untuk" loop dan goto bersyarat karena delapan "untuk" loop, ketika dikombinasikan dengan dua "gosub" untuk mencetak alamat, akan meluap tumpukan kecil C64.
C64 dapat mencetak sekitar 1,2 alamat per detik, untuk perkiraan waktu kerja 1,3 * 10 ^ 31 tahun.
sumber
PowerShell (v4),
193 166 162 145103 byteVersi no-bonus TimmyD pada 103 byte:
Versi sebelumnya dengan bonus 145 * 0,8 = 116 byte
Dengan bantuan dari TimmyD dan TomKandy , yang menunjukkan itu
0 -eq $false
tetapi([bigint]0) -eq $true
. Jadi semua versi saya sebelumnya tidak akan berakhir.Sebelumnya di 162, sebelum beberapa perubahan regex:
"Sebuah tantangan di mana PowerShell seharusnya cukup kompetitif!" - saya, sebelum saya mencobanya.
Penjelasan
sumber
for($g=[bigint]::pow(2,128);$g;$g-=1){'{0:X32}'-f$g-replace'(?=(.{4})+$)',':'-replace'^0+:',''}
for($g=[bigint]::pow(2,120);$g;$g-=1){'{0:X32}'-f$g-replace'(?=(.{4})+$)',':'-replace'^0*:',''}
for($g=[bigint]::pow(2,128);$g-gt0;$g-=1){'{0:X32}'-f$g-replace'(?=(.{4})+$)',':'-replace'^\d*:',''}
Ya, alamat pertama salah tetapi tidak diulangi pada akhirnya. Juga perhatikan bahwawhile($i)
di dalam kamu tidak akan berhenti di nol -[boolean][bigint]0
mengevaluasi sebagai benar0:
lagi: /)$i=[bigint]::Pow(4,64);while($i-gt0){('{0:X32}'-f($i-=1)-replace'0(?=.{32})'-replace'.{4}(?!$)','$0:')}
di 103 ...AutoIt3, 137 Bytes
sumber
4^64 - 1
?Python 2, 95 byte
Cukup melalui setiap angka dari 0 hingga 2 ^ 128. Pertama-tama ia mengubah angka saat ini menjadi string heksadesimal, kemudian menghapus
'0x'
yang diberikan fungsi tersebut. Selanjutnya menyesuaikan string untuk memiliki 32 nol di depan dan kemudian memecahnya menjadi kelompok empat. Akhirnya ia bergabung dengan kelompok empat dengan titik dua, mencetak yang keluar dan menambahkan 1 ke nomor saat ini. Memiliki bonus tambahan yang dapat Anda mulai dengan nilai apa pun jika Anda memberikannya, tetapi tidak diperlukan input.sumber
Haskell 111
Dengan fungsi urutan saya sendiri
s
, memori tidak lagi bocor, tetapi tidak terasa golf lagi.sumber
CBM BASIC v7.0 (166 karakter)
Jawaban Mark adalah untuk Commodore 64's BASIC 2.0, yang tidak memiliki perintah bawaan untuk mencetak angka dalam heksadesimal. Namun, berkat
HEX$()
fungsi di BASIC 7.0, versi Commodore 128 jauh lebih pendek. Itu tidak muat pada satu baris logis (yang pada C128 terbatas hingga 160 karakter) tetapi masih dapat dimasukkan sebagai dua baris terpisah dalam mode langsung.sumber
Ruby 75
Ini adalah solusi rekursif yang mengambil setiap awalan dan menemukan setiap sufiks yang mungkin. Secara rekursif.
sumber
x=->s,n{...};x['',8]
Tcl
341318301sumber