На самом деле, 58 байт
73*8╙:13542├`≈"÷≥"E`M"«%s₧ªn%s6û"7*%"♠n≥6û"+¿├`' +`M╪♂Σ♂Ri
Попробуйте онлайн!
объяснение
Здесь есть три основные части, поэтому я собираюсь разбить их соответствующим образом.
Часть 1. Построение строки base-256
На самом деле мы собираемся построить двоичную строку в обратном порядке, чтобы воспользоваться структурой на основе стека (LIFO) и избежать сложностей с ведущими нулями в двоичной строке. Таким образом, целевой двоичной строкой является 110011011101111001000110110100101101010111011110010100111101010011001101110111100100011011010010110101011101111011010011110101001100110111011110010001101101001011010101110111101101001111010100110011011101111011000110110100101101010111011110010100111101010011001101110111100100011011010010110101011101111001010011110101001100110111011110110001101101001011010101110111101101001111010100110011011101111001000110110100101101010111011110010100111101010011001101110111101100011011010010110
, что эквивалентно 20083405242288679348048842451418880256193335738939042905519679590571514414673488599852759703515507690399267425671627412178904636115120346432419478
десятичному. В base-256 ( для преобразования используется таблица символов CP437 ) соответствующая строка имеет вид ♠n≥6û«≥₧ªn≥6û«÷₧ªn≥6û«÷₧ªn÷6û«≥₧ªn≥6û«≥₧ªn÷6û«÷₧ªn≥6û«≥₧ªn÷6û
. Чтобы создать исходную двоичную строку, мы создаем строку base-256 (используя преимущества шаблона в ней) и выполняем базовые преобразования в десятичную и двоичную.
Строка base-256 имеет следующий формат (для ясности добавлены пробелы и символы новой строки):
♠n≥6û
« (either ≥ or ÷) ₧ªn (either ≥ or ÷) 6û
(7 times)
Таким образом, каждая из 7 средних секций может быть сформирована с помощью каркаса «%s₧ªn%s6û
и заменой %s
частей либо на, ≥
либо на ÷
.
Конкретная последовательность ≥
s и ÷
s нам нужна ≥≥÷≥÷÷≥≥≥÷÷≥≥÷
. Так как нам нужно это как список строк длиной 1, наивным способом представления этого будет "≥≥÷≥÷÷≥≥≥÷÷≥≥÷"#
(нажать строку, превратить ее в список). Тем не менее, мы можем сделать немного лучше. Интерпретируя эту строку как двоичное число (где ≥
представляет 1
и ÷
представляет 0
), мы получаем 13542
в десятичном виде. Преобразовав это обратно в двоичный файл (используя традиционные 1
s и 0
s) и индексировав в строку длины 2, мы можем получить список, используя на один байт меньше, чем простой метод.
:13542├`≈"÷≥"E`M"«%s₧ªn%s6û"7*%"♠n≥6û"+
:13542├ push 13542, convert to binary
`≈"÷≥"E`M for each bit:
≈ convert to integer (from string)
"÷≥"E index into "÷≥"
"«%s₧ªn%s6û"7* push the scaffold for the middle section
% old-style Python string formatting to fill in the scaffold
"♠n≥6û"+ prepend the beginning piece
Часть 2. Преобразование в двоичный файл
Эта часть намного проще. Если бы на самом деле была возможность напрямую конвертировать base-256 в двоичный файл, мы бы использовали это. К сожалению, это не так, поэтому нам придется использовать десятичный формат в качестве промежуточного формата.
В ,
следующем коде представлен код из Части 1 - для пояснения я заменил код Части 1 на, ,
чтобы прочитать вывод из Части 1 из STDIN. Это не часть фактического окончательного кода.
8╙,¿├
, Part 1 result
8╙ ¿ convert from base-256 to decimal
├ convert to binary
Часть 3: Форматирование
Если бы задача состояла в том, чтобы просто вывести двоичную строку как есть, мы были бы готовы. Тем не менее, у нас еще есть некоторое форматирование, чтобы получить двоичную строку в прямоугольнике 21 x 23.
Как и во второй части, ,
представляет собой результат предыдущей части и не является частью реального кода.
73*,`' +`M╪♂Σ♂Ri
, output from Part 2
`' o`M insert a space after every character
73* ╪ chunk into 21 pieces
♂Σ concatenate each piece
♂R reverse each piece
i flatten
(implicitly print)
Для тех, кто следит за домом, это эквивалентный код Python 3 (481 байт):
print('\n'.join([''.join(' '+c for c in bin(sum('\x00☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼ !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~⌂ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■\xa0'.index(c)*256**i for i,c in enumerate(("♠n≥6û"+("«%s₧ªn%s6û"*7)%tuple("÷≥"[int(b)]for b in bin(13542)[2:]))[::-1])))[2:])[i*42:-~i*42][::-1]for i in range(23)][::-1]))