Laci pola yang indah
Selamat pagi PPCG!
Suatu hari, ketika saya mencoba untuk membantu seseorang di Stack Overflow, sebagian dari masalahnya memberi saya ide untuk tantangan ini.
Pertama-tama, periksa bentuk berikut:
Di mana semua angka hitam adalah indeks dari titik-titik dalam bentuk dan semua angka biru tua adalah indeks dari hubungan antara titik-titik.
Sekarang, mengingat angka heksadesimal untuk 0x00000 hingga 0xFFFFF, Anda perlu menggambar bentuk di konsol menggunakan hanya ruang karakter dan "■" (menggunakan karakter "o" juga oke).
Berikut adalah beberapa contoh di mana angka heksadesimal adalah input dan bentuk adalah output:
0xE0C25 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
0xC1043 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■
■
■
■
■
■
■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xE4F27 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xF1957 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xD0C67 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0x95E30 :
■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■
0x95622 :
■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■
■
■
■ ■ ■ ■ ■
0xC5463 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xE5975 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xB5E75 :
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xF4C75 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xF5D75 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
Berikut ini beberapa penjelasan tentang cara kerjanya:
0xFFFFF(16) = 1111 1111 1111 1111 1111(2)
Anda di sini memiliki 20 bit, setiap bit mengatakan apakah ada tautan atau tidak.
Indeks Bit Paling Signifikan (MSB) adalah 0 (referensi gambar) atau Bit Paling Signifikan (LSB) adalah 19 (referensi gambar lagi).
Inilah cara kerjanya untuk bentuk pertama yang diberikan sebagai contoh:
0xE0C25(16) = 1110 0000 1100 0010 0101(2)
Berarti Anda akan memiliki tautan yang ada berikut ini: 0,1,2,8,9,14,17,19.
Jika Anda menyorot garis pada gambar referensi dengan angka-angka itu, itu akan memberi Anda bentuk ini:
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
Berikut ini adalah implementasi Python yang sederhana dan tidak ungolfed jika Anda membutuhkan bantuan lebih lanjut:
patterns = [
0xE0C25, 0xC1043, 0xE4F27, 0xF1957,
0xD0C67, 0x95E30, 0x95622, 0xC5463,
0xE5975, 0xB5E75, 0xF4C75, 0xF5D75
]
def printIfTrue(condition, text = "■ "):
if condition:
print(text, end="")
else:
print(" "*len(text), end="")
def orOnList(cube, indexes):
return (sum([cube[i] for i in indexes]) > 0)
def printPattern(pattern):
cube = [True if n == "1" else False for n in str(bin(pattern))[2::]]
for y in range(9):
if y == 0: printIfTrue(orOnList(cube, [0, 2, 3]))
if y == 4: printIfTrue(orOnList(cube, [2, 4, 9, 11, 12]))
if y == 8: printIfTrue(orOnList(cube, [11, 13, 18]))
if y in [0, 4, 8]:
printIfTrue(cube[int((y / 4) + (y * 2))], "■ ■ ■ ")
if y == 0: printIfTrue(orOnList(cube, [0, 1, 4, 5, 6]))
if y == 4: printIfTrue(orOnList(cube, [3, 5, 7, 9, 10, 13, 14, 15]))
if y == 8: printIfTrue(orOnList(cube, [12, 14, 16, 18, 19]))
printIfTrue(cube[int((y / 4) + (y * 2)) + 1], "■ ■ ■ ")
elif y in [1, 5]:
for i in range(7):
if i in [2, 5]:
print(" ", end=" ")
printIfTrue(cube[y * 2 + (1 - (y % 5)) + i])
elif y in [2, 6]:
for i in range(5):
if i in [1, 2, 3, 4]:
print(" ", end=" ")
if i in [1, 3]:
if i == 1 and y == 2:
printIfTrue(orOnList(cube, [3, 4]))
elif i == 3 and y == 2:
printIfTrue(orOnList(cube, [6, 7]))
if i == 1 and y == 6:
printIfTrue(orOnList(cube, [12, 13]))
elif i == 3 and y == 6:
printIfTrue(orOnList(cube, [15, 16]))
else:
printIfTrue(cube[(y * 2 - (1 if y == 6 else 2)) + i + int(i / 4 * 2)])
elif y in [3, 7]:
for i in range(7):
if i in [2, 5]:
print(" ", end="")
ri, swap = (y * 2 - 2) + (1 - (y % 5)) + i, [[3, 6, 12, 15], [4, 7, 13, 16]]
if ri in swap[0]: ri = swap[1][swap[0].index(ri)]
elif ri in swap[1]: ri = swap[0][swap[1].index(ri)]
printIfTrue(cube[ri])
if y == 0: printIfTrue(orOnList(cube, [1, 7, 8]))
if y == 4: printIfTrue(orOnList(cube, [6, 8, 10, 16, 17]))
if y == 8: printIfTrue(orOnList(cube, [15, 17, 19]))
print()
for pattern in patterns:
printPattern(pattern)
Tentu saja itu tidak sempurna dan cukup lama untuk apa yang harus dilakukan, dan itulah alasan mengapa Anda ada di sini!
Membuat program ini sangat singkat :)
Ini kode-golf, jadi jawaban tersingkat menang!
sumber
Jawaban:
JavaScript (ES6),
202188187 byteBagaimana itu bekerja
Kami mengerjakan kisi
g
9 baris 10 karakter. Grid awalnya diisi dengan spasi, dengan LineFeed setiap karakter ke-10.Setiap segmen ditentukan oleh posisi awal dan arah.
Arah disandikan sebagai berikut:
Setiap segmen dikodekan sebagai integer:
Misalnya, segmen # 3 dimulai pada posisi 55 dan menggunakan arah ke-3. Oleh karena itu, ini dikodekan sebagai
(55 << 2) | 3 == 223
.Di bawah ini adalah daftar bilangan bulat yang dihasilkan, dari segmen # 19 ke segmen # 0:
Setelah dikodekan delta, mulai dari 356, itu menjadi:
Yang akhirnya dikodekan sebagai:
sumber
Python 3, 289 byte
Tidak ada yang pintar, hanya hardcoding.
sumber
"trq|t...a|eca".split("|")
menjadi"tqr t...a eca".split()
?.split()
hancurkan||
.Ruby, 116 byte
Ini bergantung pada beberapa pola yang saya amati. Pertama, polanya berulang setiap 9 baris. Kedua, jika titik awal dari garis horizontal dipilih dengan tepat, siklus arah x terus menerus melalui kanan, kiri, lurus.
Tidak digabungkan dalam program uji
Saya percaya ada solusi 112 byte menggunakan string 20-karakter dan beberapa decoding untuk menentukan parameter dari 20 baris. Saya akan mencoba ini nanti jika saya punya waktu.
sumber
PHP,
142150149 bytemencetak bentuk sejauh yang diperlukan; yaitu jika bagian bawah kosong, itu akan dipotong.
Jalankan dengan
php -nr '<code>' <input>
. Jangan awali inputUji secara online
Tambahkan 11 byte tanpa pemotongan: Sisipkan
,$r[80]=" "
setelah$r=""
.pengkodean dijelaskan
Setiap baris dapat dijelaskan dengan titik awal dan satu dari empat arah.
Menggambar pada kisi 9x9, posisi awal berkisar dari
0,0
hingga8,4
; atau, digabungkan, dari0
ke8*9+4=76
. Untungnya, semua poin awal[0,4,8,36,40,44,72,76]
dapat dibagi 4; jadi kode arahnya[0..3]
dapat dipadatkan menjadi bit 0 dan 1 -> tidak perlu bergeser sama sekali.Untuk perhitungan gerakan kursor yang mudah,
0
diambil untuk timur (hanya arah tanpa gerakan vertikal) dan[1,2,3]
untuk barat daya, selatan, tenggara, di mana offset adalah9
(untuk gerakan vertikal) plus[-1,0,1]
->[8,9,10]
->delta=code?code+7:1
.Arah untuk baris pertama dan terakhir adalah timur, yang menghasilkan kode mulai dari 0 hingga 76
[0+0,4+0,0+2,0+3,4+1,4+2,4+3,8+1,8+2,...,44+1,44+2,72+0,76+0]
; dan bitwise xor 96 pada setiap nilai menghasilkan kode ascii yang dapat dicetak dan tidak bermasalah[96,100,98,99,101,102,103,105,106,68, 72,70,71,73,74,75,77,78,40,44]
->`dbcefgijDHFGIJKMN(,
. Kode menggunakan LSB untuk bit 0, sedangkan baris 0 sesuai dengan MSB, jadi string harus dibalik. Finito.kerusakan
beberapa golf menjelaskan
^96
tidak berpengaruh pada dua bit yang lebih rendah, dapat diabaikan ketika mengekstraksi arah; jadi tidak perlu menyimpan nilai dalam variabel, yang menyimpan 5 byte pada kursor init.~3
alih-alih124
menyimpan satu byte dan memungkinkan bermain golf berikutnya:$k=3
di dalam$p
tugas menyimpan dua bytedan tidak merusak kondisi awal (karena nilai atas masih memiliki satu digit).
chunk_split
merupakan cara terpendek untuk memasukkan linebreak.Saya bahkan tidak ingin tahu berapa banyak lagi yang akan diambil.
7+($c&3?:-6)
lebih pendek satu byte dari$c&3?$c%4+7:1
.hexdec()
(8 byte) untuk memenuhi batasan input.sumber
JavaScript,
184183178168167 byteAwalnya 206 byte tetapi jawaban @ Arnauld menginspirasi saya untuk menyelidiki solusi array satu dimensi. Sunting: Disimpan 1 byte berkat @ edc65. Disimpan
515 byte berkat @Arnauld. Menyimpan byte lebih lanjut dengan mengubah pilihan karakter.sumber
[0,1,2,3,4]
lebih pendek[67,65,52,36,51,50,34,49,48,35,33,20,4,19,18,2,17,16,3,1]
dan[0,2,4,6,8].map(i=>a[(e&102)*4+(e&17||15)*i]='o')
[..."ecVFUTDSREC6&54$32%#"]
dan[0,2,4,6,8].map(i=>a[(e&102)*4+(e&17||15)*i]='o',e=e.charCodeAt()-34)
menyimpan 10 byte lebih banyak.~
alih-alih-34
(sayangnya saya jatuh busuk pada `\` itulah sebabnya saya tidak menyimpan 2 byte).Batch, 491 byte
Catatan: Baris terakhir berakhir dengan spasi. Menempatkan
if
bersyarat dengan variabel di dalam afor
loop adalah di luar batch sehingga membutuhkan subrutin sendiri. Karena tidak terlihat apa-apa, saya jatuh ke dalamnya untuk keluar. Tanda~
kutip string dalam loop luar memungkinkan loop dalam untuk mengulangi angka-angka. Angka-angka hanyalah bitmask untuk semua tempat di manao
s harus ditarik.sumber
C,
267262260256 karakterMenghitung lolos sebagai 1 karakter
k adalah sebuah pencarian yang merujuk ke kotak mana untuk menempatkan 'o'.
Cobalah online!
sumber
Befunge, 468 byte
Cobalah online!
Baris pertama membaca string dari stdin, mengevaluasinya sebagai angka heksadesimal. Sisa kode pada dasarnya hanyalah sebuah loop ganda di atas koordinat x / y dari grid, dengan perhitungan boolean besar yang menentukan apakah suatu
o
output harus untuk setiap lokasi.Pada dasarnya ada kondisi terpisah untuk masing-masing dari 20 titik kisi, misalnya (empat yang pertama):
Dan setelah kita menghitung 20 dari semuanya, kita ATAU lot bersama-sama, dan jika hasilnya benar, kita menghasilkan a
o
, kalau tidak kita output spasi.Befunge tidak memiliki apa pun yang menghalangi operasi manipulasi bit, jadi untuk mengekstrak bit dari input, kami hanya berulang kali melakukan evaluasi
n%2
dan kemudiann/=2
saat kami melakukan perhitungan 20 kondisi.sumber