Tulis program yang mencetak baris 80 karakter berikut:
Program ini dari codegolf.stackexchange.com memungkinkan dirinya untuk menyandikan string.
kemudian menerima satu baris input, lalu mencetak kode sumbernya dengan titik kode yang mungkin disusun ulang (tidak ada yang ditambahkan dan tidak ada yang dihapus). Ketika kode itu dieksekusi, hal yang sama harus terjadi, kecuali baris yang dicetak akan menjadi jalur input terbaru.
Regex-style Perl ^[A-Za-z0-9. ]{80}$
akan cocok dengan semua input. Anda tidak dapat membuat asumsi tambahan.
Skor pengajuan adalah jumlah poin kode dalam kode sumbernya kurang dari 94 . Lebih rendah lebih baik.
Kode tidak boleh melakukan apa pun yang tidak dapat diterima dalam quine ( mis . Pembacaan file). Khususnya, setiap pengajuan dengan skor negatif harus curang entah bagaimana, seperti 93! kurang dari 64 80 .
Ditambahkan 2014-04-21: Seluruh kode sumber program Anda harus terbentuk dengan baik dalam pengkodean karakter tempat Anda menghitung poin kode. Misalnya, Anda tidak dapat menggunakan 80 byte berturut-turut dalam rentang byte trailing UTF-8 (80..BF) dan menghitung masing-masing sebagai satu KARAKTER PENGGANTIAN U + FFFD (atau lebih buruk, karena bukan titik kode sama sekali).
Selain itu, jika penyandian memungkinkan beberapa cara untuk menyandikan titik kode ( misalnya SCSU ), program Anda, serta semua program yang dihasilkan secara langsung atau tidak langsung, hanya boleh menggunakan salah satunya (atau setidaknya semua harus diperlakukan secara setara di seluruh kode) ).
Jawaban:
GolfScript,
231162131Bagaimana itu bekerja
Kami mulai dengan memilih 94 karakter berbeda yang akan diizinkan untuk menyandikan string. 94 karakter apa pun akan berfungsi, tetapi kami memilih yang berikut untuk tujuan bermain golf:
Sebut saja larik karakter ini "&".
Baris input akan selalu berisi 81 karakter (termasuk LF). Semua karakter tersebut hadir dalam 65 karakter pertama "&". Ini adalah satu-satunya alasan untuk memilih karakter dalam 128 byte atas.
Kami mengganti setiap karakter string dengan indeksnya di "&", jadi LF menjadi 0, spasi menjadi 1, dll.
Kami menganggap 81 nomor yang diperoleh sebagai digit dari satu nomor basis 65. Sebut saja nomor ini "N".
Sekarang, kami menghitung semua kemungkinan permutasi "&" dan mengambil permutasi yang sesuai dengan nomor dari atas. Ini dicapai dengan cara berikut:
c = 1
danA = []
.N % c
untukA
.N = N / c
danc = c + 1
.c < 95
, kembali ke 2.i = 0
dans = ""
.&[A[i]]
, tambahkan ke "s" dan hapus dari "&".i = i + 1
.i < 94
kembali ke 6.Misalkan kita memiliki blok kode "E" dan "D" yang menyandikan dan mendekode string seperti dijelaskan di atas.
Sekarang, kita membutuhkan pembungkus untuk blok kode yang memenuhi persyaratan pertanyaan:
Ini melakukan hal berikut:
{…}.~
mendefinisikan sebuah blok, menggandakannya dan mengeksekusi salinan kedua. Salinan pertama akan tetap di tumpukan.\.$
menukar string yang disandikan dengan blok dan membuat salinan dari string yang disandikan, dengan karakter yang diurutkan.[{}/]:&;
mengubah string dari atas menjadi sebuah array, menyimpannya di "&" dan membuangnya.D puts
mendekodekan string yang disandikan dan mencetak hasilnya.'"#{`head -1`}"'~
membaca satu baris input dengan mengeksekusihead -1
di shell.E "'".@+\+
mengkodekan string dan menambahkan dan menambahkan satu kutipan.\'.~'
menukar string yang disandikan dan blok dan menambahkan string'.~'
.Setelah blok telah dieksekusi, GolfScript mencetak isi stack (string yang dikodekan, blok,
'.~'
) dan keluar."E" dapat didefinisikan sebagai berikut:
"D" dapat didefinisikan sebagai berikut:
Golf terakhir:
Ganti
\.$[{}/]:&;0&@
dengan0@.$[{}/]:&\
untuk menyimpan dua karakter.Tentukan fungsi
{;65base}:b
untuk menyimpan satu karakter.Hapus semua spasi putih kecuali LF tertinggal dan LF dalam string.
Contoh
sumber
Perl,
14281099Ini memiliki 1193 karakter ASCII (termasuk 960 digit biner yang diijinkan). 1193 - 94 = 1099
Desain pertama saya
Sebelum saya mengambil saran dari Dennis untuk beralih ke biner, program saya mengijinkan digit oktal.
Desain pertama saya mengkodekan setiap string dalam 160 digit oktal, dengan 2 digit per karakter. Pengkodean ini memiliki 100 8 = 64 karakter yang berbeda. Sistem oktal memiliki 8 digit berbeda. Program harus memiliki 160 salinan dari setiap digit, sehingga memungkinkan 8 × 160 = 1280 digit.
Saya menyimpan 160 digit
$s
dan 1.120 digit lainnya masuk$t
. Saya mulai dengan program yang bukan quine, tetapi hanya mencetak tugas untuk$s
dan$t
untuk menjalankan selanjutnya. Ini dia:(() = $s =~ /$_/g))
adalah penugasan ke daftar variabel yang kosong. Saya mengambil trik ini dari tutorial konteks di PerlMonks . Ini memaksa konteks daftar pada operator pertandingan=~
. Dalam konteks skalar, kecocokan akan benar atau salah, dan saya akan memerlukan loop ingin$i++ while ($s =~ /$_/g)
menghitung kecocokan. Dalam konteks daftar,$s =~ /$_/g
adalah daftar kecocokan. Saya menempatkan daftar ini dalam konteks skalar pengurangan, jadi Perl menghitung elemen daftar.Untuk membuat quine, saya mengambil formulir
$_=q{print"\$_=q{$_};eval"};eval
dari quines Perl di Rosetta Code . Yang ini memberikan sebuah stringq{...}
ke$_
dan kemudian memanggileval
, jadi saya dapat memiliki kode saya dalam sebuah string dan juga menjalankannya. Program saya menjadi quine ketika saya membungkus baris ketiga ke terakhir di$_=q{
dan};eval
, dan mengubah yang terakhirprint
keprint "\$s = '$s';\n\$t = '$t';\n\$_=q{$_};eval"
.Akhirnya, saya mengubah program saya dengan mengubah tugas pertama
$t
menjadi komentar, dan dengan menghapus karakter tambahan.Ini memiliki 1522 karakter ASCII (termasuk 1280 digit oktal yang diijinkan).
1522 - 94 = 1428
Beralih ke biner
Dalam komentar, Dennis memperhatikan bahwa 960 digit biner yang diijinkan akan kurang dari 1280 digit oktal. Jadi saya membuat grafik jumlah digit yang diijinkan untuk setiap basis dari 2 hingga 16.
Meskipun basis 8 adalah minimum lokal, basis 2 dan 3 dan 4 mengikat untuk basis terbaik, pada 960 digit yang diijinkan. Untuk golf kode, base 2 adalah yang terbaik karena Perl memiliki konversi untuk base 2.
Mengganti 1280 digit oktal dengan 960 digit biner menghemat 320 karakter.
Mengubah kode dari oktal ke biner menghabiskan 8 karakter:
oct
keoct'0b'.$_
biaya 7./../g
ke/.{6}/g
biaya 2."%02o"
ke "% 06b" `biaya 0.160
ke480
biaya 0.0..7
untuk0,1
menyimpan 1.Saya belajar beberapa tips golf Perl . Mereka menyimpan 14 karakter:
'A'..'Z','a'..'z','0'..'9'
keA..Z,a..z,0..9
, menggunakan kata kunci dan angka telanjang, menyimpan 12 karakter."\n"
untuk$/
menyimpan 2 karakter.Saya menyimpan 3 karakter dengan memindahkan
#$t
komentar ke akhir file. Ini menghapus baris baru yang mengakhiri komentar, dan literal\n
di quine.Perubahan ini menyimpan total 329 karakter, dan mengurangi skor saya dari 1428 menjadi 1099.
sumber