Самоутверждающаяся треугольная программа шахматной доски

10

Программа шахматной доски - это программа, в которой порядковый номер каждого отдельного символа меняется от четного к нечетному, за исключением конца строки (который может быть любым стандартным окончанием строки).

Треугольная программа - это программа, в которой каждая строка имеет один дополнительный символ, чем предыдущая, причем первая строка имеет один символ. Вам не нужно обрабатывать пустой ввод.

Ваша задача состоит в том, чтобы создать программу, которая проверяет, что данный ввод соответствует этим критериям, и выводит / возвращает что-то правдивое, если программа соответствует критериям, или что-то неверное в противном случае.

Ваша программа также должна соответствовать этим критериям.

Примеры действительных программ

G
`e
@u^
5r{B

^
cB
+$C
VA01

правила

  • Ваша программа может начинаться с нечетного или четного байта, пока чередование символов чередуется.
  • Ваша программа должна проверять программы, которые начинаются с нечетного или четного символа.
  • Для символов Юникода базовые значения байтов должны иметь чередующуюся четность.
  • Вы можете предположить, что ввод содержит только печатные символы. Если ваша программа содержит непечатаемые, она все равно должна быть в состоянии проверить себя.
  • Ваша программа может включать в себя один завершающий символ новой строки, это не должно быть разрешено вашей проверкой, поскольку вы можете предположить, что она была удалена до проверки.
  • Стандартные лазейки запрещены.
  • Самый короткий код в байтах, на каждом языке, выигрывает.
Дом Гастингс
источник
@MartinEnder Спасибо за ваш вклад! Надеюсь, теперь это ясно. В связи с этим, я должен был оставить это в песочнице дольше?
Дом Гастингс
1
чётное / нечетное чередование горизонтального и вертикального? Я предполагаю, что да из «шахматной доски», но я не понимаю, где вы так говорите.
Тон Хоспел
@DomHastings Неделя кажется хорошей. Если через несколько дней вы не получите никакого отзыва, вы можете спросить в чате, есть ли у кого-нибудь еще комментарии.
Мартин Эндер
1
@TonHospel Мои оригинальные примеры сделали это, но это противоречило с моим описанием, так что для реализации этого, нет, он должен быть: E\nOE\nOEO. Надеюсь, это поможет!
Дом Гастингс
2
Мое мнение: пусть ответы предполагают, что ввод не начинается или заканчивается новой строкой.
Линн

Ответы:

3

Stax , 26 байт

L
Y$
i:-
 {2%
*OFyF
%vi =*

Запустите тестовые примеры онлайн

Я должен был представить 3 нежелательных персонажей. iне работает, когда находится вне всех конструкций цикла. это всегда неоперация. Oподнимает 1 под вершину стека, но значение не используется в программе.

LY      move input lines into a list and store in Y register
$       flatten
i       no-op
:-      get pairwise differences
{2%*OF  foreach delta, mod by 2, and multiply, then tuck a 1 under the top of stack
yF      foreach line in original input do...
  %v    subtract 1 from length of line
  i=    is equal to iteration index?
  *     multiply

Запустите этот

рекурсивный
источник
Эй, я надеюсь, что это не слишком мешает вашему коду, но вы можете отказаться от ведущей проверки новой строки.
Дом Гастингс
8

C (gcc), 189 байт

j
;l
;b;
d;f␉
(char
␉*␉t) 
{b=*␉t%
2;for␉(␉
j=d=0;j=j
+ 1,␉l=j+ 
1,␉*␉t; ) {
for␉(;l=l- 1
 ;t=t+ 1 )b= 
!b␉,␉d=d+ !(␉*
␉t␉*␉(␉*␉t- 10)
*␉(␉*␉t%2-b) ) ;
d␉|=*␉t- 10;t=t+ 
1 ; }b= !d; } ␉ ␉ 

Попробуйте онлайн!

представляет символ табуляции (извините). Обратите внимание, что есть несколько пробелов / табуляций (мне жаль). Оригинал с неповрежденными вкладками лучше всего просматривать в vim :set tabstop=1(слова не могут выразить, как мне жаль).

Это функция ( так называемый f, что не сразу видно из взглянув на него) , которая принимает строку в качестве аргумента и возвращает либо 0или 1.

Я мог бы уменьшить это, по крайней мере, на одну, а возможно, на две или более строчки, но учтите, что к концу это становится все более запутанным и не требующим больших усилий, в основном потому, что написание такого ужасного кода (даже по стандартам PPCG) заставляет меня чувствовать себя плохим человеком и я хотел остановиться как можно скорее.

Основная идея здесь заключается , чтобы избежать конструкции , которые обязательно ломают формат ( ++, +=, returnи т.д.). Чудесным образом, важные ключевые слова, такие как for, charи while(которые я не использовал в конечном итоге) оказались в соответствии с правилом чередующейся четности. Затем я использовал пробелы (четная четность) и табуляции (нечетная четность) в качестве отступов, чтобы остальные соответствовали правилам.

Дверная ручка
источник
1
Я не ожидал увидеть решение в C!
Дом Гастингс
Если вы изолируете часть решения программы в TIO, помещая другие элементы в разделы «Верхний колонтитул» и «Нижний колонтитул», людям будет проще проверить количество байтов.
Якоб
4

Haskell , 1080 1033 байта

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij
g ' ' =0
g '"' =0;
 g '$' =0;
 g '&' =0-0
g '(' =0-0-0
g '*' =0-0-0;
 g ',' =0-0-0;
 g '.' =0-0-0-0
g '0' =0-0-0-0-0
g '2' =0-0-0-0-0;
 g '4' =0-0-0-0-0;
 g '6' =0; g '8' =0
g ':' =0; g '<' =0-0
g '>' =0; g '@' =0-0;
 g 'B' =0; g 'D' =0-0;
 g 'F' =0; g 'H' =0-0-0
g 'J' =0; g 'L' =0-0-0-0
g 'N' =0; g 'P' =0-0-0-0;
 g 'R' =0; g 'T' =0-0-0-0;
 g 'V' =0; g 'X' =0-0-0-0-0
g 'Z' =0; g '^' =0; g '`' =0
g 'b' =0; g 'd' =0; g 'f' =0;
 g 'h' =0; g 'j' =0; g 'l' =0;
 g 'n' =0; g 'p' =0; g 'r' =0-0
g 't' =0; g 'v' =0; g 'x' =0-0-0
g 'z' =0; g '\92' =0-0; g '|' =0;
 g '~' =0; g y = 1 ;z=0; i(-0)z=z;
 i m('\10':y ) ="y"; ; ; ; ; ; ; ; 
i m(mnmnmnmnm:y ) = i(m - 1 ) y ; ; 
i k m ="y"; ; k i [ ] =01<1010101010;
 k m('\10':y ) = k(m + 1 )(i m y ) ; ;
 k m y =01>10; m o = k 1$'\10':o ; ; ; 
o i('\10':y ) = o i y ; ; ; ; ; ; ; ; ; 
o i(k:y )|g k<i = o(1 - i ) y ; ; ; ; ; ;
 o i(k:y )|g k>i = o(1 - i ) y ; ; ; ; ; ;
 o i [ ] =01<10; o i y =01>10;v=01>10101010
s y|o 1 y = m y|o(-0) y = m y ; s y =v; ; ; 

Попробуйте онлайн!

объяснение

Это было довольно интересное задание для Haskell.

паритет

Для начала нам нужен способ определить, имеет ли символ четную или нечетную кодовую точку. Обычный способ сделать это - получить кодовую точку и изменить ее на 2. Однако, как известно, получение кодовой точки символа требует импорта, что из-за ограничения исходного кода означает, что это невозможно используемый. Более опытный Хаскеллер подумал бы использовать рекурсию. CharЭто часть класса Enumтипов, поэтому мы можем получить их предшественников и преемников. Однако predи succони также непригодны для использования, потому что они не чередуют четность байтов.

Так что это оставляет нас в тупике, мы почти не можем манипулировать символами. Решение этой проблемы - жестко закодировать все. Мы можем представить (большинство) четных символов как литералы, с которыми мы сталкиваемся с проблемами, потому что они 'странные, поэтому он не может быть рядом с самим символом, что делает литерал невозможным для выражения большинства нечетных символов. Таким образом, мы жестко кодируем все четные байты, а затем добавляем перехват всех нечетных байтов в конце.

Проблема в байтах

Вы можете заметить, что есть некоторые четные байты, для которых литералы нельзя создать, заключив их в одинарные кавычки. Это непечатные, новые строки и \. Нам не нужно беспокоиться о непечатаемых печатях, поскольку, пока мы не используем ни один из них, нам не нужно проверять. На самом деле мы все еще можем использовать странные непечатаемые шрифты, такие как tab, мне просто не нужно. Новая строка может быть проигнорирована, потому что она все равно будет удалена из программы. (Мы могли бы включить символ новой строки, потому что его код довольно удобен, но нам это не нужно). Это оставляет \, теперь \имеет кодовую точку 92, которая удобно является нечетным числом, за которым следует четное число, так что \92чередуется между четными и нечетными числами, таким образом, литералом'\92'совершенно верно. Позже, когда нам нужно будет представить символ новой строки, мы заметим, что он, к счастью, обладает тем же свойством '\10'.

Пространственные проблемы

Теперь, чтобы начать писать настоящий код, мы должны иметь возможность поместить значительное количество символов в одну строку. Для этого я написал шапку:

;
f=
 g 
ij=f
a =hi
hi = g
hij= ij

Кепка не делает ничего, кроме как быть действительным Haskell. Сначала я надеялся дать определения, которые позже помогут нам в коде, но это не помогло. Есть также более простые способы сделать ограничение, например, пробел и точку с запятой, но они не сохраняют байты таким образом, поэтому я не потрудился изменить его.

Hardcoder

Теперь, когда у меня достаточно места в строке, я начинаю жестко кодировать значения. Это в основном довольно скучно, но есть несколько интересных вещей. Один раз, когда строки становятся еще длиннее, мы можем использовать ;для размещения нескольких объявлений в строке, что экономит нам тонну байтов.

Во-вторых, так как мы не всегда можем начинать строку с gсимвола так часто, нам приходится немного отступать от строки. Теперь Haskell действительно заботится об отступах, поэтому он будет жаловаться на это. Однако, если последняя строка перед отступом заканчивается точкой с запятой, это разрешит это. Почему? У меня нет слабых, но это работает. Таким образом, мы просто должны помнить, чтобы поставить точку с запятой в конце строки.

Функциональные блоки

Как только хардкодер готов, он плавно подходит к концу программы. Нам нужно построить несколько простых функций. Сначала я создаю версию drop, называемую i. iотличается от того, dropчто если мы пытаемся пропустить конец строки, он просто возвращается "y". iотличается от drop также тем, что, если он попытается удалить новую строку, он вернется. "y"Это будет полезно, потому что позже, когда мы проверяем, что программа является треугольником, это позволит нам вернуться, Falseкогда последняя строка не завершена или когда линия заканчивается рано.

kkNssTrueNkN+1False

Затем сделать псевдоним k, m. mпросто kс 1первым аргументом, и символом новой строки добавляется второй аргумент.

Далее у нас есть o. oзанимает число и строку. Он определяет, чередуются ли строковые байты (игнорируя символы новой строки) по четности (используя нашу g), начиная с входного числа.

Наконец, у нас есть, sкоторый работает oс обоими 1и 0, если любой из них удастся, это откладывает m. Если это терпит неудачу оба, это только возвращается False. Это функция, которую мы хотим. Он определяет, что вход является треугольным и чередующимся.

Специальный охотник за гарфами
источник
1
Треугольная строка начинается с 1-символьной строки, а не пустой строки.
Якоб
@ Якоб Я думаю, что это глупо, но это было довольно легко исправить.
Специальный охотник за
3

05AB1E , 34 26 байт

¶
¡D
©€g
´ā´Q
´sJÇÈ
¥Ä{´нP

Попробуйте онлайн!

Принимает ввод в виде многострочной строки (ввод между "" " ). Пояснения будут позже.

Kaldo
источник
1
Если я неправильно понял правила, программа должна иметь возможность проверять ввод, начиная с новой строки.
Эминья
@Emigna Я думаю, что ваша программа должна быть в состоянии проверить ведущий символ новой строки, только если она сама начинается с ведущего символа новой строки.
Тон Хоспел
Я понятия не имею, если это правильно (я ужасно читаю спецификации): попробуйте онлайн!
Волшебная Осьминог Урна
@MagicOctopusUrn Ваш ответ выглядит хорошо для меня, но я задаюсь вопросом о входе: мы можем принять это как массив? В вашей ссылке ваш первый ввод - пустое место, а не символ новой строки.
Кальдо
1
Эй, я надеюсь, что это не слишком мешает вашему коду, но вы можете отказаться от ведущей проверки новой строки.
Дом Гастингс
1

Java 10, 209 байт

Пустая лямбда, принимающая итерацию или массив byte. Указывает true, возвращая обычно, false, вызывая исключение времени выполнения. Программа ожидает, что последняя строка будет правильно завершена, т.е. завершится символом новой строки. Финальная строка программы заканчивается аналогичным образом.

Все сделано в соответствии с UTF-8, с интерпретацией, что «символ» относится к кодовым точкам Unicode.

В этом представлении вкладки заменяются пробелами.

d
->
{  
long
f= 1,
 h=0 ,
c = - 1
,e ;for 
( byte a:
 d) {var b
=(e = a^10)
<1&e>- 1 ;f=
b?( h ^ f)> 0
?0/0 : f+ 1: f
;h=b?0 :a>-65 ?
h+ 1: h; c =b? c
:c>=0 & ( (c^a )&
1 )<1 ?0/0 :a ; } 
/*1010101010101*/ }

Попробуйте онлайн

Шестнадцатеричный дамп

Возврат с помощью xxd -p -rUnix.

640a2d3e0a7b20090a6c6f6e670a663d20312c0a09683d30092c0a63203d
202d20310a2c65203b666f72090a28096279746520613a0a096429207b76
617209620a3d2865203d20615e3130290a3c3126653e2d2031203b663d0a
623f280968095e0966293e09300a3f302f30093a09662b20313a09660a3b
683d623f30093a613e2d3635203f0a682b20313a09683b2063203d623f20
630a3a633e3d30092609280928635e612029260a3120293c31203f302f30
093a61203b207d200a2f2a313031303130313031303130312a2f207d0a

Ungolfed

d -> {
    long f = 1, h = 0, c = ~h, e;
    for (byte a : d) {
        var b = (e = a^10) < 1 & e > -1;
        f = b ?
            (h^f) > 0 ? 0/0 : f + 1
            : f
        ;
        h = b ? 0 :
            a > -65 ? h + 1 : h
        ;
        c = b ? c :
            c >= 0 & ((c^a) & 1) < 1 ? 0/0 : a
        ;
    }
}

fявляется ожидаемым количеством символов в текущей строке, hявляется количеством символов, видимых до сих пор в текущей строке, cявляется последним увиденным байтом и bявляется ли символ aновой строки.

Условие a > -65проверяет, aявляется ли первый байт в символе. Это работает, потому что однобайтовые (ASCII) символы неотрицательны в дополнении к 8-битовым двум, первый байт более длинных символов имеет двоичную форму 11xxxxxx(по крайней мере -64 в дополнении к двум), а не ведущие байты в этих символах имеют форма 10xxxxxx, самое большее -65 в двух дополнениях. ( Источник )

Когда символ нарушает шаблон треугольника или шахматной доски (т. Е. Новая строка появляется рано или поздно или появляется байт неправильной четности), активируется левая ветвь соответствующей троицы (в присваивании fили c), и метод генерирует арифметическое исключение.

Jakob
источник
0

Python 3 (3,4?), 350 байт

Сложная задача для языка, в частности, о пробелах, таких как Python 3. Представление выводится на печать 0или 1выводится из строя и вылетает для некоторых входных данных. Программа ожидает, что последняя строка будет правильно завершена, т.е. завершится символом новой строки. Финальная строка программы заканчивается аналогичным образом. UTF-8 используется для проверки четности байтов.

В этом представлении вкладки заменяются пробелами.

0
i\
= 1
t=(#
 '0'*
 0) ;(
g,) =(#
 open (1
, "w"),) 
k = eval (
'p' + 'rin'
 + 't' ) #01
for  a in (#0
open ( 0) ):#0
#01010101010101
 a = a [:- 1 ] #
 if ( len (a )<i\
or len (a )>i ):[\
k('0' ),1 /0] #0101
 i, t= -~i, t+ a #01
(k( 2-len ({(c^i )&1\
 for  i,c in  eval (#0
 "enu"+"m"+"erate")(#01
 eval ( " byte"+"s")( t#
,' u8' ) ) } ) ) ) #01010

У меня работает с Python 3.4.2; не работает ни на каком Python 3 на TIO. Мне кажется, это ошибка в интерпретаторах TIO.

Шестнадцатеричный дамп

Возврат с помощью xxd -p -rUnix.

300a695c0a3d20310a743d28230a202730272a0a093029203b280a672c29
203d28230a206f70656e0928310a2c09227722292c29200a6b203d206576
616c09280a277027202b202772696e270a202b202774272029202330310a
666f7209206120696e092823300a6f70656e092809302920293a23300a23
30313031303130313031303130310a2061203d2061205b3a2d2031205d20
230a2069660928096c656e09286120293c695c0a6f72096c656e09286120
293e6920293a5b5c0a6b2827302720292c31202f305d2023303130310a20
692c09743d202d7e692c09742b2061202330310a286b2809322d6c656e09
287b28635e69202926315c0a09666f720920692c6320696e09206576616c
092823300a0922656e75222b226d222b2265726174652229282330310a20
6576616c092809220962797465222b22732229280974230a2c2720753827
20292029207d202920292029202330313031300a
Jakob
источник