Введение
Atari ST был довольно популярным персональным компьютером с середины 80 - х до начала 90 -х годов эпохи, питание от Motorola 68000 микропроцессор. На этой машине стандартное поведение операционной системы для неперехваченных исключений ЦП заключалось в отображении ряда бомб на экране, как показано на следующем рисунке:
Источник: https://commons.wikimedia.org/wiki/File:Row_of_bombs.png
NB. В зависимости от версии ОС, изображение бомбы может немного отличаться. Но давайте возьмем это как ссылку.
Количество бомб зависит от вектора исключения, наиболее распространенными из которых являются:
- ($ 008) Ошибка автобуса: 2 бомбы
- ($ 00c) Ошибка адреса: 3 бомбы
- ($ 010) Незаконная инструкция: 4 бомбы
Цель
Ваша цель - написать программу или функцию, которая печатает или выводит искусство ASCII таких бомб Atari ST.
вход
Целое число, представляющее количество бомб для отображения. Ваш код должен поддерживать наиболее распространенные значения: 2, 3 и 4. Поддержка меньшего количества и / или большего количества бомб - это хорошо, но это не требуется и не подлежит бонусу.
Выход
Оригинальная бомба состоит из плитки размером 16x16 пикселей, представленной здесь как в формате ASCII, так и в двоичном виде:
....##.......... 0000110000000000
.#.#..#......... 0101001000000000
.......#........ 0000000100000000
#..#....#....... 1001000010000000
..#...#####..... 0010001111100000
......#####..... 0000001111100000
....#########... 0000111111111000
...###########.. 0001111111111100
...###########.. 0001111111111100
..#############. 0011111111111110
..########.####. 0011111111011110
...#######.###.. 0001111111011100
...######.####.. 0001111110111100
....#########... 0000111111111000
.....#######.... 0000011111110000
.......###...... 0000000111000000
В этом испытании каждая бомба ASCII должна быть увеличена вдвое по сравнению с первоначальной шириной для лучшего рендеринга. Следовательно, он будет состоять из 16 строк по 32 символа с использованием ##
пикселей «ON» и двух пробелов для пикселей «OFF». Все плитки бомбы должны быть положены рядом. Ведущие пробелы запрещены. Замыкающие пробелы также запрещены, кроме тех, которые фактически являются частью плитки бомбы (то есть 31-й и 32-й столбцы), которые должны присутствовать. Вы можете включить не более одного разрыва строки и не более одного разрыва строки.
пример
Ниже приведен эталонный выход для двух бомб, где обязательные разрывы строк отмечены как, \n
а допустимые дополнительные разрывы строк отмечены как (\n)
:
(\n)
#### #### \n
## ## ## ## ## ## \n
## ## \n
## ## ## ## ## ## \n
## ########## ## ########## \n
########## ########## \n
################## ################## \n
###################### ###################### \n
###################### ###################### \n
########################## ########################## \n
################ ######## ################ ######## \n
############## ###### ############## ###### \n
############ ######## ############ ######## \n
################## ################## \n
############## ############## \n
###### ###### (\n)
(Конечно, другие форматы переноса строк, такие как \r
или \r\n
могут быть использованы так же хорошо.)
правила
Это код-гольф, поэтому выигрывает самый короткий ответ в байтах. Стандартные лазейки запрещены.
Ответы:
Желе ,
4344 байта+1 байт - забыл удвоить символы (не то, чтобы кто-то заметил!)
TryItOnline
Как?
Подготовка состояла в том, чтобы сжать данные как кодирование длины серии исходного изображения:
1
s (пробел) или0
s (хеш) в изображении, игнорируя новые строки - выдает список[4,2,11,1,1,...]
:;[0,15]
;v
сi
обратным индексом и суммируйте16**i*v
=19468823747267181273462257760938030726282593096816512166437
);[5,119,249,42,...]
:;¥vẏ)X;ndĊɓ¡ẹ3ċi}Ịɲ¡P
Теперь код вычисляет это число, отображает
1
s и0
s в пробел и хэш-символы *, удваивает каждое, разбивает на строки и повторяет каждое соответствующее количество раз.* на самом деле реализация выполняется по модулю 2 для сохранения байтов, поэтому пробелы нечетные, а хеши четные:
источник
05AB1E ,
57555350 байтИспользует кодировку CP-1252 .
Попробуйте онлайн!
объяснение
Поскольку выходное изображение состоит только из 2 символов, мы можем представить его как двоичное число.
Мы можем игнорировать символы новой строки, поскольку каждая строка имеет одинаковую длину.
Мы можем игнорировать последний символ каждой строки, так как он одинаков для всех строк.
Мы используем более тонкое изображение, так как оно занимает меньше места, и мы можем легко продублировать каждый символ позже.
Используя 1 для представления пробела и 0 для представления # мы получаем двоичное число:
111100111111111101011011111111111111101111111011011110111111110111000001111111111000001111111100000000011111000000000001111000000000001110000000000000110000000010000111000000010001111000000100001111100000000011111110000000111111111100011111
Затем мы конвертируем это в базу-10, а затем сжимаем в базу 214, максимальную базу в 05AB1E. Результат этого:
Мясо программы состоит из следующего:
источник
Pyth,
575654535150 байтКод содержит непечатаемые символы, так что вот обратимый
xxd
hexdump.Попробуйте онлайн.
источник
JavaScript (ES6),
159154140136 байтСохранено много байтов благодаря @Hedi и @Arnauld
Это 104 символа, но (к сожалению) 136 байтов UTF-8. Строка была сгенерирована с помощью этого фрагмента:
Показать фрагмент кода
Использование
.replace
вместо[...string].map
одинаково долго:Как это устроено
Поскольку каждая строка необработанных данных может быть представлена в виде 16-разрядного числа, мы можем сохранить весь файл в 16-символьной строке. Алгоритм сжатия берет каждую двоичную строку, переворачивает ее и переворачивает (поскольку каждая строка в оригинале заканчивается на 0 , каждая строка в измененной версии теперь начинается с 1 ), затем превращает ее в символ и объединяет полученные символы ,
Чтобы распаковать его, нам нужно извлечь код и превратить его двоичное представление в строку хешей и пробелов. Это можно сделать с помощью рекурсивной функции, например так:
f
повторно принимает последний битq
, выбирая два пробела, если он равен 1, или два хэша, если он равен 0, затем объединяет это с результатом выполненияf
в оставшейся частиq
. Это запускаетсяx.charCodeAt()
, превращая char-код в правильную строку пробелов и хэшей.(Раньше здесь было гораздо больше драмы, но техника сохранения 4 байта стерла все это.)
После этого мы можем просто повторить строку
n
времени и добавить новую строку . Это самый короткий метод декомпрессии, который я нашел, но не стесняйтесь предлагать любые более короткие методы.Другие попытки сжатия строки:
Первый из них - 153 байта, поэтому ни один из них не подходит к 136 ...
источник
+x?'##':' '
вместо" #"[x].repeat(2)
x.charCodeAt()
а не преобразовать их в двоичный файл? (Я думаю, это сэкономило бы около 8 байт.)MS-DOS .COM файл, 84 байта
ХОРОШО. Просто ради удовольствия, потому что я не могу побить 50 байтов ...
Пробовал под DOSbox, а также под MS-DOS 6.22 на виртуальной машине.
Под DOSbox программа работает нормально, однако в реальной MS-DOS вывод не будет отображаться правильно, потому что DOS требует CR-LF вместо LF в конце строки.
(Однако вывод правильный.)
88-байтовый вариант будет использовать CR-LF в конце строки.
Вот файл:
Код ассемблера (в синтаксисе AT & T) выглядит следующим образом:
--- Редактировать ---
Я забыл упомянуть: программа должна быть запущена с помощью следующей командной строки:
Имя COM-файла + ровно один пробел + количество бомб (1-9)
источник
objdump -dw
Вывод - это хороший способ показать необработанный двоичный файл, поскольку вы видите, какие байты являются какой инструкцией. Я сделал это для ответов gcd и adler32 . (А также включая закомментированный исходный код для людей, чтобы попробовать себя.)Python,
223179 байтВторой подход:
Попробуйте это на repl.it!
Вместо того, чтобы создавать список строк на лету, существует жестко закодированная шестнадцатеричная строка, которая индексируется и преобразуется в двоичную; затем каждая двоичная цифра превращается в либо,
' '
либо'#'
, которая дублируется и объединяется ... и т. д.Первый подход:
Попробуйте это на repl.it!
Он содержит жестко запрограммированный список строк каждой строки (не включая конечные пробелы), созданный путем дублирования
' '
или'##'
нескольких раз. Для каждой из этих строк они дополняются пробелами до 32 символов, дублируютсяn
, затем объединяются с помощью новых строк.источник
'\n'
. Так,lambda n:print(*(''.join(2*' #'[int(d)]for d in bin(int('0c0052000100908023e003e00ff81ffc1ffc3ffe3fde1fdc1fbc0ff807f001c0'[i:i+4],16))[2:].zfill(16))*n for i in range(0,64,4)))
. Кроме того, вам не нужно считать байты, необходимые для присвоения лямбда-имени. Таким образом, ваш счет может быть 176.C
250240208188 байтПереключитесь на использование функции.
Тест, как это.
main(c,v)char**v; { f(atoi(v[1])); }
источник
0x
./// ,
539532 + нет. байтов бомбПервый /// ответ, отображающий 4 бомбы. Конечные четыре 1 могут быть заменены любым унарным представлением количества бомб, которые вы хотите напечатать (11 для 2, 111 для 3)
Попробуйте онлайн!
Если входное значение должно быть десятичным, следующее имеет
555548 байт (где последняя цифра может быть изменена на 1, 2, 3 или 4):Попробуйте онлайн!
Наиболее важные части кода таковы:
| означает //
ABCDEFGHIJKLMNOP означает каждую линию бомбы соответственно
S означает 2 пробела
s означает 4 пробела
* означает 6 пробелов
q означает 8 пробелов
T означает ## (2)
t означает #### (4)
^ означает ##### # (6)
r означает ######## (8)
и означает ################ (16)
Большая часть кода гарантирует, что бомбы напечатаны бок о бок, а не друг на друга.
источник
CJam , 66 байт
Попробуйте онлайн! (обратите внимание, что в коде есть некоторые непечатаемые символы.)
Бомба, закодированная как двоичное число с использованием 1 для пробелов (начальный пробел как 1 гарантирует, что нам не нужно заполнять двоичные представления), транспонируется, а затем преобразуется в строку в base-136 (что дает самую короткую строку без широких символов). Эти шаги можно сыграть здесь .
Этот ответ затем изменяет кодировку, основной трюк заключается в том, чтобы повторить бомбу перед переносом, эффективно объединяя каждую линию бомбы сразу. Символы в каждой строке можно затем удвоить, добавив символы новой строки для окончательного вывода.
источник
PHP,
138104 + 32 = 136 байтЯ никогда не думал, что
file
это бинарный сейф. Я только хотел бы найти более интересный способ хранения данных; но я ничего не пробовал бить сырой двоичный файл.0
с 2 пробелами,1
с##
,повтор
$argv[1]
раз, результат печати + перевод строкибежать с
-r
двоичные данные в файле
b
:код для создания файла:
источник
\n
.MATL ,
6463605958 байтПопробуйте онлайн!
объяснение
Код использует предварительно сжатую версию двоичной матрицы 16 × 16. Предварительное сжатие (не является частью программы) выполнялось в два этапа:
Сжатая строка,
распаковывается с основания 94 на основание 16:
Полученный вектор пробегов плюс 1 умножается на 2:
выполнить горизонтальное растяжение.
Вектор бегущих длин содержит 49 значений. Исходные числа, которые должны повторяться с такой длиной, должны быть
[0 1 0 1 ... 0]
(49 записей). Но вместо этого короче использовать вектор[1 2 ... 49]
, который будет одинаково действителен благодаря модульной индексации. Таким образом, декодирование по длине прогонаСформированный вектор containis на прогоны
1
,2
...49
, в общей сложности 512 записей. Это преобразовано в матрицу 16 × 32:и используется в качестве модульных индексов в строке
' #'
для производства одной бомбы:Наконец, горизонтальное повторение с помощью коэффициента, заданного входными данными, дает желаемый результат:
источник
Python 2: 143 байта
Это в идеоне
(Я понял, что прямое кодирование исходной бомбы в базе 36 было сделано для более короткого кода в Python.)
Строка была сформирована обработкой пробелов как 1 с и хэшей как 0, а затем преобразованием в основание 36. Затем программа преобразует обратно в двоичный файл и срезы в длину 16 (со смещением 2 для '0b' в начале Python. двоичная строка), преобразует в двойные пробелы и двойные хэши, объединяет их, повторяет строковое
n
время и печатает.Предыдущая: Python 2,
169 166163 байтаЭто в идеоне
Почти порт моего желе ответа .
источник
Python 2,7,
144141 байтБомба написана в двоичном виде с 1 для пробела, ведущий 1 устраняет необходимость дополнения двоичных представлений. Бомба транспонирована (очень похоже на мой ответ CJam ) и хранится в базе 36.
Программа декодирует бомбу в двоичную форму и перебирает биты с шагом 16, эффективно следуя за транспозицией (то есть экономит байты при разрезании заданной строки). Результирующая строка объединяется, биты заменяются на удвоенные
или
#
, и соединяются в одиночную строку.источник
O
по какой-то причине ...C (gcc) ,
216 204 183 165134 байтаПопробуйте онлайн!
Написан как отдельная программа (
201 183151 байт)Попробуйте онлайн!
Это segfaults, если параметр командной строки не указан.
источник
Пакет, 415 байт
Примечание: строка
set s=
заканчивается 5 пробелами. Принимает счет в качестве параметра командной строки. Просто проходит по каждой линии бомбы (сжимается очень немного, удаляя серии из 5 одинаковых символов), затем повторяет бомбу столько раз, сколько необходимо, прежде чем, наконец, дублировать каждый символ.источник
Python 2,
206205203199191188186184160 байтовПосмотрел на Hex список номеров, но, похоже, он не сохранил достаточно, чтобы стоить того. Я надеялся, что смогу сыграть в код, но, похоже, достиг такого уровня, насколько я могу, с этим подходом. Любые дополнительные подсказки с благодарностью получены.
РЕДАКТИРОВАТЬ
-1, изменив
e==1
наe>0
. Я всегда забываю это.-2, игнорируя длину двоичной строки, добавляя 7 0 и принимая только последние 16 элементов. Работает так как никогда не бывает больше 7 ведущих 0.
-4 потому что теперь, когда я потерял вторую ссылку на переменную b, я могу использовать ее
bin(y)[2:]
непосредственно в функции карты, взяв ее ниже магического 200 :-)-8 с помощью назначения среза во втором списке. Узнал что-то новое этим вечером.
-3 с благодарностью @Jonathan
-2 с использованием
c=d=([0]*7+map(int,bin(y)[2:]))[-16:]
вместо того, чтобы иметьc=d;
-2 еще раз благодаря @Jonathan
-24 с благодарностью @Linus
Выход
источник
" #"[e>0]*2
будет работать(...)
тоже могут идти (RE: согласно моему предыдущему комментарию).for y in ...:print"".join(" #"[e>0]*2for e in(([0]*7+map(int,bin(y)[2:]))[-16:]))*z
RProgN ,
210193 байтаСохраняя несколько байтов, переключая 0 = '' 1 = '##' на 1 = '' 0 = '', это означает, что мне не нужно добавлять дополнительные нули обратно. Кроме того, это означает, что теперь строка B64, которая раньше говорила «MAFIA», не делает этого, это печально.
объяснение
Довольно длинный, Расширение, печать и тому подобное сжатой строки составляет 105 байтов. Может быть немного более пригодным для игры в гольф, но по крайней мере это работает.
Ввод неявно в стеке, стек неявно печатается.
Выход
Попробуй!
источник
PHP,
144140139138136 байтПримечание: используется кодировка Windows-1252
Запустите так:
Или используя кодировку IBM-850 (135 байтов и более хороший результат):
объяснение
Это не делает ничего двоичного и не требует внешнего файла.
Каждое 16-битное число переворачивается, затем кодируется как число base-36, дополняется,
0
если необходимо, лидирующим символом, поэтому каждые 16 битов дают 3 байта. Объединяя эти результаты в01c02203k07d1j81j46b4cmwcmwpa4ohobugc8o6b434w0ow
. Код полностью изменяет процесс, поэтому бомбы печатаются правильноN
раз.Tweaks
$j
на ноль на границах строки с помощью%=
. Это избавляет от скобок$argn
источник
GCC C 129 байт
ISO8859 / ASCII
В одну строку:
Бежать с:
Компилировать исходный код как ISO8859-x (ASCII).
NB óÿÿþÿoÜüðààÀÀ! ÀCàCðøþ? должен содержать невидимые коды ASCII, но он был сломан из-за способа, которым StackExchange представляет свое содержимое. Пожалуйста, см. Ссылку ideaone для правильного тестового кодирования. Альтернативно исходная строка ASCII находится по адресу: https://github.com/claydonkey/AtariBombs/blob/master/ISO8859_REPR2.txt
объяснение
Сначала выполняется преобразование шестнадцатеричного представления бомб [f3 ff ad ff fe ff 6f 7f dc 1f fc 1f f0 07 e0 03 e0 03 c0 01 c0 21 c0 43 e0 43 f0 07 f8 0f fe 3f] в UTF-8 (в В версии UTF-8 компилятор сохраняет строку в виде расширенного массива символов - 2 или 4 байта для каждого символа во время выполнения, но это академично). Принимая во внимание, что символы UTF-8 будут храниться как 2-4 байта, все эти значения находятся в пределах ISO-8859-1 (ASCII) и поэтому требуют только 1 байт. Также безопасно храниться как ISO-8859-x (нет значений 0x8_ или 0x9_). Поэтому в ISO-8859 текст занимает 32 байта, а в общей сложности - 135 байтов.
(NB широкие символы хранятся в виде 16-битного целого числа в Windows и 32-битного в Linux, но, опять же, это не имеет отношения к текущей задаче)
Предостережение: не все символы отображаются (контрольные символы ниже 0x20). Они, тем не менее, присутствуют. Большинство веб-страниц имеют вид utf-8 / 8859/1253 ( https://w3techs.com/technologies/overview/character_encoding/all ), поэтому я считаю, что это законно
(смещение всех значений ниже 0x20 в печатаемый ASCII должно исправить это).UTF-8,
Вот версия ближе к оригинальной публикации с кодированным UTF-8 источником. Это потребляет 173 байта. Сама строка составляет 50 байтов источника. Процедура также длиннее, поскольку байты ASCII теперь хранятся с заполнением 0 для 16-битных / 32-битных широких символов и должны быть смещены вместо приведения к uint16_t, как указано выше. Я сохранил это, поскольку это можно проверить с помощью ideone, который использует кодировку UTF-8.
Бежать с:
Если вы можете установить в своем компиляторе неявное значение равным 16-битному целому числу, вы можете опустить объявление типа wchar_t для широкого символа. Ideone не жалуется, поэтому я считаю, что это хорошо.
Попробуйте это на Ideone
источник
Haskell, 155 байт
Как функция с типом
Int -> String
:Печать в IO напрямую будет стоить 5 байт (или 6, если мы предпочитаем возвращать,
IO ()
а неIO [()]
):источник
C 175 байт
конкатенирует каждый x к себе и делает p переполнением для завершения каждой строки.
источник
Java, 228 байт
источник
n->{String s="";for(int x,r=0;r<16*n;s+=(++r%n<1?"\n":""))for(x=16;x-->0;)s+=((new int[]{1536,10496,128,18496,4592,496,2044,4094,4094,8191,8175,4078,4062,2044,1016,224}[r/n])&(1<<x))<1?" ":"##";return s;}
( 205 байт ) Помимо использования лямбды Java 8, я сократил больше байтов, изменив: положениеx=16
(и изменилwhile
наfor
); 2x==0
к<1
; возвратs
вместо печати (импорт также входит в число байтов между прочим ..);--x>=0
кx-->0
. Тем не менее, отличный ответ, так что +1!J, 89 байт
Кодирует строку в виде числа base-95, увеличивает каждую цифру на единицу
32
, затем представляет ее в виде строки ascii.объяснение
Это состоит из двух основных частей. Существует создание бомбы и фактическое повторение. Давайте пока назовем бомбу как
b
. Затем код выглядит так:Когда
k
вызывается с вводом , это эквивалентно:b
является коробчатой бомбой, поэтомуk#b
делаетk
повторенияb
,;
выравнивает ее по вертикали и|:
переносит результат. (Бомбаb
сама построена транспонированной.)Теперь вот бомба:
Последующая строка является строкой в кодировке base-95 со смещением
32
, так что все символы попадают в диапазон ASCII, и, к счастью, нет'
s, которые нужно экранировать.3 u:
получает коды символов строки,32x-~
делает каждое числоx
размеченным числом и вычитает32
из него;95#.
преобразует в число base-95 и2#.inv
преобразует его в массив двоичных цифр. Я добавил ведущий1
в двоичный файл, чтобы сделать его сплошным числом, поэтому я снимаю его с}.
. Я формирую массив в таблицу 16x16, а16 16$
затем транспонирую его, используя|:
. (Возможный гольф на потом: перенести буквально закодированную строку.)2#
Дублирует каждый символ по ширине. Мы остались с таблицей0
s и1
s.' #'{~
карты0
с' '
и1
к'#'
. Таким образом, мы остались с нашей бомбой.Прецедент
источник
BaCon ,
229227195 байтВклад в бейсик ради ностальгии. Переменная «а» определяет количество бомб.
Выход :
источник
Haskell,
191181 байтисточник
C (Atari TOS 2.06 US),
129 124 117113 байтовПри этом используется битовая карта бомбы из TOS ROM, которая немного отличается от той, о которой идет речь. Для других версий TOS вам придется изменить адрес, на который указывает
*a
. Обратите внимание, что некоторые эмуляторы не содержат битовую карту!Если вы не укажете аргумент командной строки, могут отображаться несколько битовых карт высокого разрешения :-)
источник
C ++ 11, 252 байта
источник
SmileBASIC, 127 байт
(Снимок экрана с версией без дублированных символов).
SB имеет квадратный шрифт, поэтому дублирование символов выглядит плохо (и не помещается на экране).
Символы, отличные от ASCII, были заменены на
x
's.Шестнадцатеричные значения:
0008,0002,0610,1F8A,3FC1,7FC1,7FF2,FFF4,FFF8,EFF0,73F0,7FC0,3FC0,1F80,0600
поскольку SB сохраняет файлы в формате UTF-8, некоторые из них считаются как 2 или 3 байта.
источник
FOR K=1TO N
сINPUT N
, я думаю, что он отображает количество бомб, заданных на входе. Тем не менее, я должен сказать, что, несмотря на квадратный шрифт, я считаю, что символы должны быть удвоены, чтобы соответствовать требованиям (чтобы избежать преимущества над другими ответами). Вы можете оставить текущее для более привлекательного решения, но я думаю, что вы все равно должны добавить правильное решение. Как только вы добавите это, я буду признателен за творческое использование символов UTF-8!Ruby 2.x (лямбда) - 157 байт
Вероятно, можно играть в гольф дальше, но мне нравится эта версия:
Идея, аналогичная версии (версиям) Python: разбить строку шестнадцатеричных кодированных бомб на секции по 4 символа, преобразовать в двоичную, преобразовать
1
в#
и0
в, удвоить каждый символ и распечатать полученный массив.
Обратите внимание, что put используется для печати массива. Это выведет массив из одной строки на элемент.
источник
Excel VBA, 204 байта
Anonymous VBE Immediate оконная функция, которая принимает входные данные из диапазона
[A1]
и выводит их в объект ActiveSheetВыход
источник