Основы:
Рассмотрим следующие тетромино и пустое игровое поле:
0123456789 IOZTLSJ [] [] # ## ## ### # ## # [] # ## ## # # ## # [] # ## ## [] # [] [==========]
Размеры игрового поля фиксированы. Цифры вверху предназначены только для обозначения номера столбца (см. Также ввод).
Вход:
1 . Вам предоставляется определенное игровое поле (основанное на вышеизложенном), которое уже может быть частично заполнено тетромино (это может быть в отдельном файле или предоставлено через стандартный ввод).
Пример ввода:
[] [] [] [] [# # #] [## ######] [==========]
2 . Вам дается строка, которая описывает (разделенные пробелами), какой тетромино вставить (и раскрыть) в какой столбец. Тетромино не нужно вращать. Ввод можно прочитать со стандартного ввода.
Пример ввода:
T2 Z6 I0 T7
Вы можете предположить, что ввод «правильно сформирован» (или произвести неопределенное поведение, когда это не так).
Вывод
Визуализируйте результирующее поле («полные» строки должны исчезнуть) и распечатайте счет очков (каждая выпавшая строка составляет 10 очков).
Пример вывода на основе примера ввода выше:
[] [] [] [# ###] [# ###] [##### ####] [==========] 10
Победитель:
Кратчайшее решение (по количеству символов кода). Примеры использования хороши. Удачи в игре в гольф!
Изменить : добавил щедрость +500
репутации, чтобы привлечь больше внимания к хорошим усилиям, которые уже сделали ответчики (и, возможно, некоторым новым решениям этого вопроса) ...
источник
Ответы:
GolfScript - 181 символ
Новые строки не нужны. Вывод находится в стандартном выводе, хотя некоторые ошибки присутствуют в stderr.
\10
должен быть заменен соответствующим символом ASCII, чтобы программа состояла из 181 символа.Пример ввода / вывода:
Сжатие тетромино:
фрагменты хранятся в виде трех цифр по основанию 8. Это простое двоичное представление, например
T=[7,2,0], S=[6,3,0], J=[2,2,3]
.[1]
используется дляI
фрагмента при сжатии, но это явно установлено[1,1,1,1]
позже (т.е.4*
в коде). Все эти массивы объединяются в один массив, который преобразуется в целое число, а затем в строку (база 126 для минимизации непечатаемых символов, длины и исключения UTF8). Эта строка является очень коротким:"R@1(XBc_"
.Декомпрессия тогда проста. Сначала мы выполняем преобразование по основанию 126, за которым следует преобразование по основанию 8 (
"~\10"{base}/
т. Е. Выполняем итерацию"~\10"
и выполняем базовое преобразование для каждого элемента). Результирующий массив разбивается на группы по 3, массив дляI
fixed (3/~4*
). Затем мы преобразуем каждый элемент в основание 2 и (после удаления нулей) заменяем каждую двоичную цифру символом этого индекса в строке" #"
(2base{" #"=}%...-1%
- обратите внимание, что нам нужно перевернуть массив, иначе2
он стал бы"# "
вместо" #"
).Формат «доска / кусок», сбрасывание частей
Доска - это просто массив строк, по одной на каждую строку. Изначально над этим не ведется никакой работы, поэтому мы можем сгенерировать его
n/(
на входе. Куски также представляют собой массивы строк, заполненные пробелами слева для их позиции X, но без завершающих пробелов. Части отбрасываются путем добавления к массиву и непрерывного тестирования, есть ли столкновение.Тестирование столкновений выполняется путем повторения всех символов в фигуре и сравнения с персонажем той же позиции на доске. Мы хотим рассматривать
#
+=
и#
+#
как столкновения, поэтому мы проверяем, не равно ли ((piecechar & 3) & boardchar) нулю. Выполняя эту итерацию, мы также обновляем (копию) доски с помощью ((piecechar & 3) | boardchar), который правильно устанавливает значение для пар#
+,
+
#
,+
[
. Мы используем эту обновленную доску, если происходит столкновение после перемещения фигуры вниз на другой ряд.Убрать заполненные ряды довольно просто. Удаляем все строки, для которых
"= "&
возвращается false. В заполненной строке не будет ни=
или, поэтому соединение будет пустой строкой, что приравнивается к false. Затем мы подсчитываем количество строк, которые были удалены, добавляем счетчик к результату и добавляем это количество
"[ ... ]"
s. Мы генерируем это компактно, беря первую строку сетки и заменяя ее#
на.
Бонус
Так как мы вычисляем, как доска будет выглядеть в каждой позиции фигуры при падении, мы можем оставить их в стеке, а не удалять! Всего на три символа мы можем вывести все эти позиции (или два символа, если у нас есть состояния доски с одинарным интервалом).
источник
Perl,
586 523 483472427 407 404 386 387 356353 символа(Требуется Perl 5.10 для
//
оператора defined-or ).Принимает весь ввод со стандартного ввода.
По-прежнему нужен серьезный гольф.Обратите внимание, что ^ Q представляет ASCII 17 (DC1 / XON), ^ C представляет ASCII 3, а ^ @ представляет ASCII 0 (NUL).
Прокомментированная версия:
Редактировать 1: серьезная игра в гольф, исправить ошибку вывода.
Редактировать 2: некоторое встраивание, объединение двух петель в одну для чистой экономии (барабанная дробь ...) 3 символа, разное игра в гольф.
Изменить 3: какое-то общее устранение подвыражения, небольшое постоянное слияние и настроенное регулярное выражение.
Редактировать 4: изменено представление тетромино в упакованный битовый вектор, разное гольф.
Редактировать 5: более прямой перевод из письма тетромино в индекс массива, использовать непечатаемые символы, разное гольф.
Правка 6: исправлена ошибка очистки верхней строки, представленная в r3 (редактирование 2), обнаруженная Накилоном. Используйте больше непечатаемых символов.
Изменить 7: использовать
vec
для получения данных тетромино. Воспользуйтесь тем, что игровое поле имеет фиксированные размеры.if
заявление =>if
модификатор, слияние циклов редактирования 2 начинает приносить плоды. Используйте//
для случая с 0 баллами.Редактировать 8: исправлена еще одна ошибка, появившаяся в r6 (редактирование 5), обнаруженная Накилоном.
Изменить 9: не создавайте новые ссылки при очистке строк, просто перемещайте ссылки с помощью нарезки массива. Объедините два
map
в одно. Более умное регулярное выражение. «Умнее»for
. Разные игры в гольф.Изменить 10: встроенный массив тетромино, добавлена закомментированная версия.
источник
Рубин -
427 408 398 369359источник
Сценарий оболочки Bash (
301304 символа)ОБНОВЛЕНИЕ: исправлена ошибка, связанная с частями, доходящими до верхнего ряда. Кроме того, выходные данные теперь отправляются в стандартный режим, и в качестве бонуса можно снова запустить сценарий, чтобы продолжить игру (в этом случае вы должны сами сложить общий счет).
Сюда входят непечатаемые символы, поэтому я предоставил шестнадцатеричный дамп. Сохраните как
tetris.txt
:Затем в командной строке bash, желательно с установкой,
elvis
а неvim
какvi
:Как это устроено
Код самораспаковывается аналогично тому, как это
gzexe
делают исполняемые программы, сжатые с помощью сценария. Фрагменты тетромино представлены в виде последовательностей команд редактора vi. Подсчет символов используется для обнаружения коллизий, а подсчет строк используется для подсчета очков.Распакованный код:
Исходный код перед игрой в гольф:
источник
Python:
504519 символов(Решение Python 3)
В настоящее время требуется установить ввод в формате, показанном вверху (код ввода не учитывается). Я разверну, чтобы читать из файла или стандартного ввода позже.Теперь работает с подсказкой, просто вставьте ввод (всего 8 строк).Не уверен, что смогу сэкономить там намного больше. Из-за преобразования в битовые поля теряется довольно много символов, но это позволяет сэкономить гораздо больше символов, чем при работе со строками. Также я не уверен, смогу ли я удалить там больше пробелов, но попробую позже.Больше не удастся уменьшить; Получив решение на основе битового поля, я вернулся к строкам, так как нашел способ еще больше сжать их (сохранил 8 символов над битовым полем!). Но учитывая , что я забыл включать
L
и была ошибка с точками внутри, мой счетчик символов только идет вверх Вздох ... Может быть , я что - то найти позже , чтобы сжать его немного больше, но я думаю , что я ближе к концу. Исходный и прокомментированный код см. Ниже:Оригинальная версия:
источник
Рубин 1.9,
357355353339330310309 символовОбратите внимание, что
\000
escape-символы (включая нулевые байты в третьей строке) должны быть заменены их фактическим непечатаемым эквивалентом.Пример ввода:
Применение:
или же
источник
?\s
.C,
727 [...] 596 581 556 517 496 471 461457 символовЭто мой первый кодовый гольф, я думаю, что количество персонажей может стать
намногоменьше, было бы неплохо, если бы опытные игроки в гольф могли дать мне несколько подсказок.Текущая версия также поддерживает игровые поля разных размеров.Входные данные могут иметь разрывы строк как в формате DOS / Windows, так и в формате Unix.Код был довольно простым до оптимизации, тетромино хранятся в 4 целых числах, которые интерпретируются как (7 * 3) x4-битный массив, игровое поле сохраняется как есть, плитки удаляются, а полные строки удаляются в начале и после каждого падение плитки.
Я не знал, как считать символы, поэтому использовал размер файла кода, удалив все ненужные разрывы строк.
РЕДАКТИРОВАТЬ 596 => 581: Благодаря KitsuneYMG все, кроме
%ls
предложения, работало отлично, кроме того, я заметил, чтоputch
вместо этогоputchar
можно использовать (getch
как-то не работает) и удалил все круглые скобки в#define G
.РЕДАКТИРОВАТЬ 581 => 556: не был удовлетворен оставшимися
for
и вложеннымиF
циклами, поэтому было некоторое слияние, изменение и удаление циклов, что довольно запутанно, но определенно того стоило.РЕДАКТИРОВАТЬ 556 => 517: Наконец-то нашел способ создать
a
массив int. НекоторыеN;
слилисьc
, большеbreak
нет.РЕДАКТИРОВАТЬ 496 => 471: ширина и высота игрового поля теперь исправлены.
РЕДАКТИРОВАТЬ 471 => 461: Незначительные изменения,
putchar
снова используются какputch
нестандартная функция.РЕДАКТИРОВАТЬ: Исправление: полные строки удалялись до падения плитки, а не после , поэтому полные строки можно было оставить в конце. Исправление не меняет количество символов.
источник
for
как#define F(x,m) for(x=0;x++<m;)
? Он работает на C # ...: PF(x,3){printf("%i",x}
печатает12
вместо012
этого изменения. Можно было поменять наfor(x=-1;x++<m;)
, но это ничего не спасает :)(c=getchar())
и удалить все строки c = N, сохранив 6 символов. Если я не ошибаюсь насчет этого, вам следует снизить до 585Python 2.6+ -
334322316 символов397368366 символов без сжатия#coding:l1 exec'xÚEPMO!½ï¯ i,P*Ýlš%ì‰=‰Ö–*†þz©‰:‡—Lò¾fÜ”bžAù,MVi™.ÐlǃwÁ„eQL&•uÏÔ‹¿1O6ǘ.€LSLÓ’¼›î”3òšL¸tŠv[ѵl»h;ÁºŽñÝ0Àë»Ç‡ÛûH.ª€¼âBNjr}¹„V5¾3Dë@¼¡•gO. ¾ô6 çÊsÃЮürÃ1&›ßVˆùZ`Ü€ÿžcx±ˆ‹sCàŽ êüRô{U¯ZÕDüE+³ŽFA÷{CjùYö„÷¦¯Î[0þøõ…(Îd®_›â»E#–Y%’›”ëýÒ·X‹d¼.ß9‡kD'.decode('zip')
Требуется одна новая строка, и я посчитал ее как один символ.
Мумбо-джамбо кодовой страницы браузера может помешать успешному копированию и вставке этого кода, поэтому вы можете при желании сгенерировать файл из этого кода:
s = """ 23 63 6F 64 69 6E 67 3A 6C 31 0A 65 78 65 63 27 78 DA 45 50 4D 4F 03 21 10 BD EF AF 20 69 2C 50 2A 02 DD 6C 9A 25 EC AD 07 8D 89 07 3D 89 1C D6 96 2A 86 05 02 1B AD FE 7A A9 89 3A 87 97 4C F2 BE 66 DC 94 62 9E 41 F9 2C 4D 56 15 69 99 0F 2E D0 6C C7 83 77 C1 16 84 65 51 4C 26 95 75 CF 8D 1C 15 D4 8B BF 31 4F 01 36 C7 98 81 07 2E 80 4C 53 4C 08 D3 92 BC 9B 11 EE 1B 10 94 0B 33 F2 9A 1B 4C B8 74 8A 9D 76 5B D1 B5 6C BB 13 9D 68 3B C1 BA 8E F1 DD 30 C0 EB BB C7 87 DB FB 1B 48 8F 2E 1C AA 80 19 BC E2 42 4E 6A 72 01 7D B9 84 56 35 BE 33 44 8F 06 EB 40 BC A1 95 67 4F 08 2E 20 BE F4 36 A0 E7 CA 73 C3 D0 AE FC 72 C3 31 26 9B DF 56 88 AD F9 5A 60 DC 80 FF 9E 63 78 B1 88 8B 73 43 E0 8E A0 EA FC 52 F4 7B 55 8D AF 5A 19 D5 44 FC 45 2B B3 8E 46 9D 41 F7 7B 43 6A 12 F9 59 F6 84 F7 A6 01 1F AF CE 5B 30 FE F8 F5 85 28 CE 64 AE 5F 9B E2 BB 45 23 96 59 25 92 9B 94 EB FD 10 D2 B7 58 8B 64 BC 2E DF 39 87 6B 44 27 2E 64 65 63 6F 64 65 28 27 7A 69 70 27 29 """ with open('golftris.py', 'wb') as f: f.write(''.join(chr(int(i, 16)) for i in s.split()))
Тестирование
Интетрис
Новые строки должны быть в стиле Unix (только перевод строки). Завершающий символ новой строки в последней строке не является обязательным.
Тестировать:
Этот код распаковывает исходный код и выполняет его с расширением
exec
. Этот распакованный код весит 366 символов и выглядит так:import sys r=sys.stdin.readlines();s=0;p=r[:1];a='[##########]\n' for l in r.pop().split(): n=int(l[1])+1;i=0xE826408E26246206601E>>'IOZTLSJ'.find(l[0])*12;m=min(zip(*r[:6]+[a])[n+l].index('#')-len(bin(i>>4*l&31))+3for l in(0,1,2)) for l in range(12): if i>>l&2:c=n+l/4;o=m+l%4;r[o]=r[o][:c]+'#'+r[o][c+1:] while a in r:s+=10;r.remove(a);r=p+r print''.join(r),s
Новые строки обязательны и состоят из одного символа каждая.
Не пытайтесь читать этот код. Имена переменных выбираются буквально случайным образом в поисках максимального сжатия (с разными именами переменных после сжатия я видел целых 342 символа). Далее следует более понятная версия:
import sys board = sys.stdin.readlines() score = 0 blank = board[:1] # notice that I rely on the first line being blank full = '[##########]\n' for piece in board.pop().split(): column = int(piece[1]) + 1 # "+ 1" to skip the '[' at the start of the line # explanation of these three lines after the code bits = 0xE826408E26246206601E >> 'IOZTLSJ'.find(piece[0]) * 12 drop = min(zip(*board[:6]+[full])[column + x].index('#') - len(bin(bits >> 4 * x & 31)) + 3 for x in (0, 1, 2)) for i in range(12): if bits >> i & 2: # if the current cell should be a '#' x = column + i / 4 y = drop + i % 4 board[y] = board[y][:x] + '#' + board[y][x + 1:] while full in board: # if there is a full line, score += 10 # score it, board.remove(full) # remove it, board = blank + board # and replace it with a blank line at top print ''.join(board), score
Суть в трех загадочных строках, которые я сказал, что объясню.
Форма тетромино здесь закодирована в шестнадцатеричном числе. Считается, что каждый тетронимо занимает сетку ячеек 3x4, где каждая ячейка либо пуста (пробел), либо заполнена (знак числа). Затем каждый фрагмент кодируется 3 шестнадцатеричными цифрами, каждая цифра описывает один столбец с 4 ячейками. Наименее значащие цифры описывают крайние левые столбцы, а младший значащий бит в каждой цифре описывает самую верхнюю ячейку в каждом столбце. Если бит равен 0, то эта ячейка пуста, в противном случае это '#'. Например, I tetronimo кодируется как
00F
, с четырьмя битами наименее значимой цифры, установленными для кодирования четырех числовых знаков в крайнем левом столбце, а T - это131
, с верхним битом, установленным слева и справа, и двумя верхними битами, установленными в середине.Затем все шестнадцатеричное число сдвигается на один бит влево (умножается на два). Это позволит нам игнорировать самый нижний бит. Я объясню почему через минуту.
Таким образом, учитывая текущий фрагмент из входных данных, мы находим индекс в этом шестнадцатеричном числе, где начинаются 12 бит, описывающих его форму, затем сдвигаем его вниз так, чтобы биты 1–12 (пропускающий бит 0)
bits
переменной описывали текущий фрагмент.Присваивание
drop
определяет, на сколько рядов от вершины сетки упадет фигура, прежде чем она приземлится на другие фрагменты. Первая строка определяет, сколько пустых ячеек находится в верхней части каждого столбца игрового поля, а вторая находит самую низкую занятую ячейку в каждом столбце фигуры.zip
Функция возвращает список кортежей, где каждый кортеж состоит из п - й клетки от каждого элемента в списке ввода. Итак, используя образец платы ввода,zip(board[:6] + [full])
вернемся:[ ('[', '[', '[', '[', '[', '[', '['), (' ', ' ', ' ', ' ', ' ', ' ', '#'), (' ', ' ', ' ', ' ', '#', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', ' ', ' ', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', '#', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', ' ', '#', '#'), (' ', ' ', ' ', ' ', '#', '#', '#'), (']', ']', ']', ']', ']', ']', ']') ]
Мы выбираем кортеж из этого списка, соответствующий соответствующему столбцу, и находим индекс первого
'#'
в столбце. Вот почему мы добавили «полную» строку перед вызовомzip
, чтобыindex
получить разумный возврат (вместо выдачи исключения), когда столбец в противном случае пуст.Затем, чтобы найти наименьшее значение
'#'
в каждом столбце фрагмента, мы сдвигаем и маскируем четыре бита, которые описывают этот столбец, а затем с помощьюbin
функции превращаем его в строку из единиц и нулей.bin
Функция возвращает только значащие биты, так что нам нужно только вычислить длину этой строки , чтобы найти самую низкую занятую ячейку (наиболее значимого набор бит).bin
Функция также присоединяет'0b'
, поэтому мы должны вычесть это. Мы также игнорируем младший бит. Вот почему шестнадцатеричное число сдвигается на один бит влево. Это необходимо для учета пустых столбцов, строковые представления которых будут иметь ту же длину, что и столбец с заполненной только верхней ячейкой (например, T- фрагмент).Например, столбцы I Tetromino, как упоминалось ранее, являются
F
,0
и0
.bin(0xF)
есть'0b1111'
. После игнорирования'0b'
мы получаем длину 4, что правильно. Ноbin(0x0)
есть0b0
. После игнорирования'0b'
мы все еще имеем длину 1, что неверно. Чтобы учесть это, мы добавили в конец дополнительный бит, чтобы мы могли игнорировать этот незначительный бит. Следовательно,+3
в коде нужно учесть дополнительную длину, занимаемую'0b'
в начале, и незначительный бит в конце.Все это происходит в выражении генератора для трех столбцов (
(0,1,2)
), и мы беремmin
результат, чтобы найти максимальное количество строк, которое кусок может отбросить, прежде чем он коснется любого из трех столбцов.Остальное должно быть довольно легко понять, прочитав код, но
for
цикл, следующий за этими назначениями, добавляет фрагмент на доску. После этогоwhile
цикл удаляет полные строки, заменяя их пустыми наверху, и подсчитывает счет. В конце концов, доска и счет распечатываются на выходе.источник
Python, 298 символов
Превосходит все неэзотерические языковые решения на данный момент (Perl, Ruby, C, bash ...)
... и даже не использует ухищрения, связанные с архивированием кода.
На тестовом примере
он выводит
PS. исправлена ошибка, указанная Накилоном, стоимостью +5
источник
Golfscript 260 символов
Я уверен, что это можно улучшить, я новичок в Golfscript.
Конец строк актуален (в конце не должно быть ни одной). В любом случае, вот некоторые из тестовых примеров, которые я использовал:
Обратите внимание, что во входном файле нет конца строки, конец строки сломает скрипт как есть.
источник
O'Caml
809782 символаисточник
Common Lisp
667 657645 символовМоя первая попытка кодового гольфа, так что, вероятно, есть много трюков, которых я еще не знаю. Я оставил там несколько новых строк, чтобы сохранить некоторую остаточную «читаемость» (я посчитал новые строки как 2 байта, поэтому удаление 6 ненужных новых строк дает еще 12 символов).
На входе сначала поместите фигуры, затем поле.
Тестирование
источник
Рубин
505 479 474 442 439426 символовПервая попытка. Сделали это с помощью IronRuby. Я уверен, что его можно улучшить, но мне действительно нужно поработать сегодня!
Тестирование
Редактировать сейчас, используя обычный рубин. Получил вывод стен ..
источник
Еще один на Ruby,
: **573546 символовТестирование:
источник
a.each{|x|s=a.max_by(&:size).size;x[s-=1]||=' 'while s>0}