Красивый шаблон ящик
Доброе утро, PPCG!
На днях, когда я пытался помочь кому-то в переполнении стека, часть его проблемы дала мне идею для этой задачи.
Прежде всего, проверьте следующую форму:
Где все черные цифры - это индекс точек в форме, а все синие цифры - это индекс связей между точками.
Теперь, учитывая шестнадцатеричное число от 0x00000 до 0xFFFFF, вам нужно нарисовать фигуру в консоли, используя только символьное пространство и «■» (с помощью символа «o» тоже хорошо).
Вот несколько примеров, где вводится шестнадцатеричное число и выводится форма:
0xE0C25 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
0xC1043 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■
■
■
■
■
■
■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xE4F27 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xF1957 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xD0C67 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0x95E30 :
■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■
0x95622 :
■ ■ ■ ■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■
■
■
■ ■ ■ ■ ■
0xC5463 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
0xE5975 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xB5E75 :
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xF4C75 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■
■ ■ ■ ■ ■ ■
0xF5D75 :
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■
■ ■ ■ ■ ■ ■
Вот некоторые объяснения о том, как это работает:
0xFFFFF(16) = 1111 1111 1111 1111 1111(2)
У вас здесь есть 20 бит, каждый бит говорит, существует ли ссылка или нет.
Индекс старшего значащего бита (MSB) равен 0 (ссылка на изображение) или Младший бит (LSB) равен 19 (ссылка на изображение снова).
Вот как это работает для первой фигуры, приведенной в качестве примера:
0xE0C25(16) = 1110 0000 1100 0010 0101(2)
Это означает, что вы будете иметь следующие существующие ссылки: 0,1,2,8,9,14,17,19.
Если вы выделите строки на контрольном изображении этими цифрами, это даст вам следующую форму:
■ ■ ■ ■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■ ■
■ ■
■ ■
■ ■
■ ■ ■ ■ ■
Вот простая и незаметная реализация Python, если вам нужна дополнительная помощь:
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)
Конечно, он не идеален, и это довольно долго для того, что он должен делать, и именно поэтому вы здесь!
Делать эту программу смехотворно короткой :)
Это код-гольф, поэтому выигрывает самый короткий ответ!
Ответы:
JavaScript (ES6),
202188187 байтКак это устроено
Мы работаем над сеткой
g
из 9 рядов по 10 символов. Сетка изначально заполнена пробелами, с LineFeed каждый 10-й символ.Каждый сегмент определяется начальной позицией и направлением.
Направления закодированы следующим образом:
Каждый сегмент закодирован как целое число:
Например, сегмент № 3 начинается с позиции 55 и использует 3-е направление. Поэтому он закодирован как
(55 << 2) | 3 == 223
.Ниже приведен список целых чисел от сегмента № 19 до сегмента № 0:
После дельта-кодирования, начиная с 356, он становится:
Который в конечном итоге кодируется как:
источник
Python 3, 289 байт
Ничего умного, только жесткое.
источник
"trq|t...a|eca".split("|")
стать"tqr t...a eca".split()
?.split()
разрушает||
.Рубин, 116 байт
Это зависит от нескольких моделей, которые я наблюдал. Во-первых, шаблон повторяется каждые 9 строк. Во-вторых, если начальные точки горизонтальных линий выбраны надлежащим образом, направления х непрерывно чередуются вправо, влево, прямо.
Неуправляемый в тестовой программе
Я считаю, что есть 112-байтовое решение с использованием 20-символьной строки и некоторого декодирования для определения параметров 20 строк. Я попробую это позже, если у меня будет время.
источник
PHP,
142150149 байтпечатает форму по мере необходимости; т.е. если нижняя часть пуста, она будет обрезана.
Беги с
php -nr '<code>' <input>
. Не вводите префиксПротестируйте это онлайн
Добавьте 11 байтов для вырезания: вставьте
,$r[80]=" "
после$r=""
.объяснение кодировки
Каждая строка может быть описана с начальной точкой и одним из четырех направлений.
Рисуя на сетке 9x9, начальная позиция варьируется от
0,0
до8,4
; или, в сочетании, от0
до8*9+4=76
. К счастью, все начальные точки[0,4,8,36,40,44,72,76]
делятся на 4; поэтому код направления[0..3]
можно сжать в биты 0 и 1 -> сдвиг не требуется вообще.Для простоты расчета перемещения курсора
0
берется для востока (только направление без вертикального перемещения) и[1,2,3]
для юго-запада, юга, юго-востока, где смещение9
(для вертикального перемещения) плюс[-1,0,1]
->[8,9,10]
->delta=code?code+7:1
.Направление для первой и последней строк является восточным, что приводит к кодам в диапазоне от 0 до 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]
; и битовое значение xor 96 для каждого значения приводит к печатным и беспроблемным кодам ascii[96,100,98,99,101,102,103,105,106,68, 72,70,71,73,74,75,77,78,40,44]
->`dbcefgijDHFGIJKMN(,
. Код использует LSB для бита 0, а строка 0 соответствует MSB, поэтому строка должна быть обращена. Finito.сломать
некоторые игры в гольф объяснили
^96
не влияет на младшие два бита, при извлечении направления его можно игнорировать; поэтому нет необходимости хранить значение в переменной, которая экономит 5 байт на курсоре init.~3
вместо124
сохранения одного байта и позволяет следующий гольф:$k=3
внутри$p
присваивания сохраняет два байта,и это не повредит предварительному условию (поскольку верхнее значение все еще имеет одну цифру).
chunk_split
это самый короткий способ вставить разрывы строк.Я даже не хочу знать, сколько еще что-нибудь потребуется.
7+($c&3?:-6)
на один байт короче$c&3?$c%4+7:1
.hexdec()
(8 байт) для удовлетворения ограничения ввода.источник
JavaScript,
184183178168167 байтПервоначально было 206 байт, но ответ @ Arnauld вдохновил меня на исследование решения одномерного массива. Редактировать: 1 байт сохранен благодаря @ edc65. Сохранено
515 байт благодаря @Arnauld. Сохраненный еще байт путем настройки выбора символов.источник
[0,1,2,3,4]
короче[67,65,52,36,51,50,34,49,48,35,33,20,4,19,18,2,17,16,3,1]
и[0,2,4,6,8].map(i=>a[(e&102)*4+(e&17||15)*i]='o')
[..."ecVFUTDSREC6&54$32%#"]
и[0,2,4,6,8].map(i=>a[(e&102)*4+(e&17||15)*i]='o',e=e.charCodeAt()-34)
сохранить еще 10 байтов.~
вместо этого-34
(к сожалению, я не справляюсь с `\`, поэтому я не сохраняю 2 байта).Пакетный, 491 байт
Примечание: последняя строка заканчивается пробелом. Помещение
if
условия с переменной внутриfor
цикла выходит за рамки пакета, поэтому для него требуется собственная подпрограмма. Поскольку ничего не видно, я проваливаюсь в него, чтобы выйти.~
Unquotes струны во внешнем контуре , позволяя внутреннюю петлю к петле над числами. Числа - это просто битовые маски для всех мест, гдеo
нужно рисовать s.источник
C
267262260256 символовПодсчет побегов как 1 символа
k - это поиск, в котором указаны поля, в которые нужно добавить 'o'.
Попробуйте онлайн!
источник
Befunge, 468 байт
Попробуйте онлайн!
Первая строка читает строку из stdin, оценивая ее как шестнадцатеричное число. Остальная часть кода по сути представляет собой просто двойной цикл по координатам x / y сетки, с массивным логическим вычислением, определяющим,
o
следует ли выводить для каждого местоположения.В принципе, для каждой из 20 точек сетки существует отдельное условие (первые четыре):
И затем, как только мы вычислили все 20 из них, мы ИЛИ партию вместе, и если этот результат верен, мы выведем a
o
, в противном случае мы выведем пробел.У Befunge нет ничего в плане операций с битами, поэтому, чтобы извлечь биты из ввода, мы просто многократно оцениваем,
n%2
а затем проходимn/=2
20 вычислений условий.источник