Проверка горизонтальной ASCII змеи


22

Недавно было несколько испытаний ASCII для домашних змей (например, здесь )

            0 0               
  0        0 0 000            
00 0     00       000 0      0
    000 0            0 0   00 
       0                000   

Эта задача состоит в том, чтобы взять случайно сгенерированную горизонтальную змею-питомца (высота 5 строк, длина 30) и убедиться, что

  • В каждом столбце есть только один 0
  • Каждый из 0них «связан» с 0до и после него (с вертикальным интервалом только в 0 или 1 строку)

Окончательный вывод может быть trueили 1если змея действительна, или falseили 0если змея недействительна

Edit-Разъяснение

Предположим, вход:

  • Это строка
  • Содержит только '', '0' и '\ n'
  • Точно 30 символов в каждой строке
  • Имеет ровно 5 строк

Т.е. проверить, подключена ли змея, и нет ли случайных символов. Не нужно проверять «холст», на котором напечатана змея.


4
Привет и добро пожаловать в PPCG :) Это хорошая задача для первого поста, но вы, вероятно, захотите добавить еще несколько тестов, которые ловят исключительных змей. Вы также, вероятно, захотите решить, должна ли змея быть представлена ​​нулями или быть любым персонажем. В будущем, пожалуйста, рассмотрите возможность использования песочницы . Удачи :)
FryAmTheEggman

5
Это воспринято как Стинг? Или это может быть введено как 2d массив?
JSchiff

6
Гарантируем ли мы, что входные данные состоят из 0 и пробелов? Что каждая строка имеет длину 30? Что там 5 строк?
xnor

9
Так как это решение проблемы, truthy/falseyа не true/false?
Джонатан Аллан

3
@JSchiff Я уверен, что змея Байт?
MarioDS

Ответы:


14

JavaScript (ES2018), 62 54 байта

s=>!/0(.{30}|.{60,62}(.{31})*)0|( .{30}){4} /s.test(s)

Ввод представляет собой одну строку:

  • без трейлинга новой строки
  • содержать только пробел, '0' и '\ n'
  • 30 символов в каждой строке, 5 строк, всего 154 символа

Флаг sозначает точку, совпадающую с чем угодно (включая '\ n'). Эта функция в настоящее время поддерживается Chrome 63+, Opera 50+, Safari 11.1+ на основе таблицы сравнения . Вы можете проверить эту функцию с помощью этих поддерживаемых браузеров. При загрузке страницы вы получите исключение, если ваш браузер не поддерживает эту функцию.

Как это работает:

  • Нет столбца без 0:
    • не совпадают /( .{30}){4} /
  • Нет двух 0s в одном столбце:
    • не совпадают /0.{30}(.{31})*0/
  • Нет 0не подключаться к соседям
    • не совпадают /0.{60}(.{31})*0/,/0.{62}(.{31})*0/

Объедините все эти регулярные выражения, и вы, наконец, получите это.

Благодаря Мартину Эндеру, отметим, что выполнение одного !оператора может сэкономить 8 байт.


8

SnakeEx , 51 байт

Это, очевидно, правильный язык для задачи. : ^ D

s:({c<L>}{c<R>}0[(<R> <L>)(<L> <R>)_?])%{30}
c:0 *$

Соответствует всему вводу, если это допустимая змея; не соответствует, если это не так. Попробуй это здесь!

объяснение

SnakeEx - это двумерный язык сопоставления с образцом . Программа состоит из списка определений «змей», которые ползут по вводимым совпадающим символам, меняют направления и порождают других змей. В нашей программе мы определяем двух змей, sи c.

Начнем с cтого, что проще. Это определение 0 *$, которое должно быть вполне читабельным, если вы знаете регулярное выражение: match 0, за которым следует ноль или более пробелов, за которыми следует край сетки. Основной улов здесь: это сопоставление может продолжаться в любом направлении. Мы будем использовать cкак змею вверх, так и вниз, чтобы убедиться, что 0в каждом столбце нет лишних s.

Теперь для главной змеи, s . Он принимает форму (...)%{30}, что означает «сопоставить содержимое скобок 30 раз» - один раз для каждого 0в змее. Все идет нормально. Что входит в круглые скобки?

{c<L>}

Это порождает новый c змею, повернутую влево на 90 градусов. Направление относительно направления sзмеи, поэтому новая змея движется к вершине сетки (главная змея движется вправо). В cзмее проверяет , что текущая ячейка сетки представляет собой 0и что каждая клетка над ним пространство. Если это не удается, весь матч не удается. Если это удастся, мы продолжим с

{c<R>}

который делает то же самое, только повернул направо (к нижней части сетки).

Обратите внимание, что эти порождения не влияют на положение указателя совпадения в главной змее. Они немного похожи на взглядов в регулярных выражениях. (Может быть, здесь мы могли бы назвать их «lookb Кроме»?) Итак, после проверки, что мы указываем на0 а остальная часть столбца содержит только пробелы, нам нужно на самом деле соответствовать 0:

0

Теперь указатель совпадения находится на символе справа от 0 . Нам нужно проверить три разных варианта: змея наклонена вниз, змея наклонена вверх, или змея идет прямо. Для этого мы можем использовать выражение OR:

[...]

Внутри нашего OR у нас есть три возможности:

(<R> <L>)

Поверните направо, найдите пробел и снова поверните налево (углы змеи вниз).

(<L> <R>)

Поверните налево, найдите пробел и снова поверните направо (змея наклонена вверх).

_?

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

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


2

CJam , 35 34 байта

{z_{'0e=1=}%:*\'0f#2ew::-[W0X]-!*}

Попробуйте онлайн! Ввод представляет собой прямоугольный массив массивов символов. Предполагается, что вход содержит только и 0.

Объяснение:

{z_{'0e=1=}%:*\'0f#2ew::-[W0X]-!*}   Function taking a character matrix:
 z                                      Transpose.
   {      }%                            Consider whether each row
      e=                                  contains
        1=                                exactly one
    '0                                    of the character '0'.
            :*                            This must be true for every row.
                  #                     Next, find the position
               '0                         of the character '0'
                 f                        at every row
  _           \                           in the original input.
                       :-               Find the differences between
                      :                   each
                   2                      pair
                    ew                    of adjacent elements (in other words, compute
                                            the increments).
                                        For the snake to be valid, this array of increments
                                            must only contain {0, 1, -1}, so
                              -         Remove from this list
                         [   ]            the elements
                          W                 -1,
                           0                0,
                            X               and 1,
                               !          and then check whether the array is empty.
                                *       The previous code tested two different properties
                                          of the matrix; they both must be true for a
                                          valid snake.

2

05AB1E , 18 байт

ζDε0k}¥Ä2‹sεþg}ìPΘ

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

объяснение

ζ                    # transpose
 D                   # duplicate
  ε  }               # for each row in the first copy (column of input)
   0k                # get the index of the first 0
      ¥Ä             # calculate absolute delta's
        2‹           # check that each is less than 2
          sε  }      # for each row in the second copy (column of input)
            þg       # calculate the length of the string with non-digits removed
               ì     # concatenate the lists
                P    # calculate product
                 Θ   # truthify (turn false values to 0)

2

Шелуха , 12 байт

В зависимости от разъяснений правил, может быть 11 байтов или 13 байтов .

±Λ=;1Ẋ×≈mηfT

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

Ввод - это список строк, содержащий только пробелы и 0; если требуется одна строка, разделите программу на строки. Ссылка TIO уже делает это для ясности. Выход 0 или 1; если любые ложные и правдивые значения в порядке, их ±можно удалить.

объяснение

±Λ=;1Ẋ×≈mηfT  Implicit input: a list of lines.
           T  Transpose into list of columns.
        m     For each column,
         ηf   get list of indices of truthy elements.
              In Husk, whitespace characters are falsy and other are truthy,
              so this gets us the indices of 0s on each column.
     Ẋ        For each adjacent pair of these index lists,
      ×       for all pairs drawn from the two lists,
       ≈      give 1 if they differ by at most 1, otherwise 0.
              For each adjacent pair, this produces a list of 1s and 0s.
 Λ            Do all of these lists
  =;1         equal [1]? Return either 0 or 30 (length of the outer list + 1).
±             Signum; convert to 0 or 1.

Идея состоит в том, ×≈чтобы гарантировать, что (а) все столбцы содержат ровно один 0, и (б) их позиции отличаются не более чем на один. В качестве примера рассмотрим 8-колоночный ввод

0  0  0 
 000 0  
  00   0

Сначала mηfTпреобразует его в список списков индексов.

[[1],[2],[2,3],[1,2,3],[],[2],[1],[3]]

Потом Ẋ×≈дает

[[1],[1,1],[1,1,0,1,1,1],[],[],[1],[0]]

Каждый 1соответствует паре индексов, которые отличаются не более чем на 1, и каждый 0соответствует паре, которая не имеет. Каждый результат равен [1]точно, когда оба списка имеют один индекс, и индексы отличаются не более чем на 1.


2

Python 2 , 71 байт

f=lambda s:s[1]<' 'or'0'in s[::31]in' %s '%s[1::31]in'%6s'%0*2*f(s[1:])

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

Принимает ввод в виде многострочной строки. Тестовый кейс от Bubbler .

Первый столбец извлекается как s[::31]и второй как s[1::31], и они проверяются на достоверность. Мы находимся наs первый символ, что приведет к проверке последовательных пар столбцов.

Проверка для двух столбцов использует цепочку сравнения Python для inобъединения нескольких проверок:

  • '0'in s[::31] проверяет, что в первом столбце есть хотя бы один 0
  • s[::31]in' %s '%s[1::31]проверяет, что первый столбец является подстрокой сэндвичей второго столбца между двумя пробелами, что обеспечивает 0смещение позиции не более чем на один пробел
  • ' %s '%s[1::31]in'%6s'%0*2проверяет, что второй столбец содержит не более одного 0.

Окончание *f(s[1:])также заставляет рекурсивный случай быть верным.


Теперь, когда я думаю об этом, Python является отличным языком для этих "змеиных" задач. : P
УсыMoses

2

C (gcc) ,246 245 232 215 212 байт

#define F)exit(1);
#define L for(i=l=0;i<30;i++)
#define X b[7][i]
char b[8][31];k,j,l;main(i){for(;j++<5;){gets(b);L{if(i[*b]>47){if(X++F memset(b[j+1]+i-1,l=1,3);}else if(!X&b[j][i]F}k+=!!l;}if(k<5 F L if(!X F}

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

Подумал, что я возьму свой любимый язык к этому (хотя, как я вижу по многим другим, более мелким записям, это, вероятно, далеко не идеально для такого рода задач) и C, что я мог бы сделать. Программный подход к проблеме относительно прост, только с большим количеством байтов-зажима; он принимает змею в stdin и дает свой результат в возвращаемом значении main (таким образом, код выхода;в соответствии с запросом в задаче 0 указывает недопустимую змею, а 1 действителен, хотя для кода выхода это страннокак правило, для кодов выхода 0 - допустимая змея, а 1 - недопустимая змея). С расширенными макросами и небольшим пробелом это выглядит примерно так:

char b[8][31];l,j,k;                           //Declares a buffer to work in, initialized all to 0; l j and k default to int and as globals are init to 0
main(i) {                                      //This is run no-args, so argc is 1 and the undeclared type defaults to int.
  for (; j++ < 5;) {                           //Iterating over each row, 1-indexed for convenience accessing the buffer
    gets(b);                                   //Reads into b[0] because of stack array decl layout
    for (i = l = 0; i < 30; i++) {             //j and l both init each time we begin this overall loop
      if (i[*b] > 47) {                        //Did we read a zero?
        if(b[7][i]++) exit(1);                 //If the snake already had a zero in this column, fail out
        memset(b[j+1] + i-1, l = 1, 3);        //Expect them on the next row in the columns left and right of this one (also set l)
      } else if (!b[7][i] & b[j][i]) exit(1);  //If we didn't read a zero, and we had reason to expect one this row, and there wasn't already a zero in this column, fail out
    }
    k+=!!l;                                    //Adds 1 to k iff l is nonzero 
  } if (k < 5) exit(1);                        //If less than 5 rows had zeroes in them, fail out
  for(i = l = 0 ; i < 30; i++) {               //l isn't relevant in this loop but saves some bytes when sharing a macro with the other horizontal loop
    if(!b[7][i]) exit(1);                      //If any columns didn't have zeroes, fail out
  }                                            //Else, snake is valid. main default returns 0.
}

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

Это совсем не надёжно (gets() это только начало), и входные данные должны содержать все соответствующие пробелы (например, без остаточного пробела), и gcc выдает предупреждения и заметки о неявно объявленной функциональности stdlib и так далее, но, C жизнь.

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

Спасибо пользователю 202729 за ок. 26 байтов сохранено.



Вы можете пропустить пространство между #define Fи )для -1 байта.
user202729

Кроме того, поскольку вход имеет только \n(10), <space>(32) и 0(48), вы можете проверить ==48с помощью >47(-1 байт). / Вы можете удалить ={0}инициализацию, bесли переменная является глобальной. Аналогичным образом создайте kглобальный и i(нетипизированный -> int) параметр main(вместо argcкоторого есть 1).
user202729

Спасибо! Отредактировано, прежде чем я увидел последние предложения; Я пройду через них (это iкак argcгений). Первые проекты этого были более 400 байтов; Мне потребовалось достаточно много времени, чтобы перетащить его к моим личным целям - 300, а затем - 256, так что, может быть, есть и другие способы уменьшить это, что я пропустил.
SevenStarConstellation

Решил сделать k, jи lвсе глобальные перемены сэкономить на наличии отдельных intобъявлений, потом понял, что настройки по умолчанию позволят мне сойти с рук, полностью исключив тип. Еще раз спасибо!
SevenStarConstellation

1

MATL , 18 17 байт

32>&fun30=wd|2<vA

Ввод представляет собой двумерный массив символов. Любой непробельный символ может быть использован для змеи.

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

объяснение

32>      % Implicit input. Transform non-space into 1, space into 0
&f       % Push vector of row indices and vector of column indices of nonzeros
u        % Unique: vector of deduplicated entries
n        % Length
30=      % Does it equal 30? (*)
w        % Swap. Moves vector of row indices to top
d|       % Absolute consecutive differences
2<       % Is each value less than 2? (**)
v        % Concatenate results (*) and (**) vertically
A        % All: true if all entries are nonzero. Implicit display

1
Спецификация подразумевает, что длина линии составляет 30, поэтому я думаю, что вы можете сэкономить несколько.
Джонатан Аллан

@JonathanAllan Спасибо! Я использую, un30=чтобы проверить, что все индексы столбцов разные, и ни один из 30 столбцов не пуст. Может быть, я могу проверить это более напрямую, но я не понимаю, как
Луис Мендо


1

Желе , 19 байт

Zn⁶T€L€=1$$;FIỊ$$$Ạ

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

-2 байта благодаря мистеру Xcoder

объяснение

Zn⁶T€L€=1$$;FIỊ$$$Ạ  Main Link
Z                    Transpose the matrix of characters
                         (string -> list of chars in Jelly)
 n⁶                  != " " (vectorizing)
   T€                For each column, get (row) indices of snake parts
     L€=1$$          For each index list, is its length 1? (that is, exactly one snake part per column)
           ;     $   Append (helper part)
            FIỊ$$    helper part:
            F        flatten index list
             I       get increments/forward differences
              Ị      are the values insignificant? (|z| <= 1)
                  Ạ  Are these all true?

Ввод в виде списка строк


@ Mr.Xcoder Да, не получается, проблемы с представлением строк Jelly. исправлено путем разгона 1 байта
HyperNeutrino

1

Желе , (14? *) 13 байт

Zn⁶T€z-IỊ0-¦Ȧ

Монадическая ссылка, содержащая список из пяти строк *, каждая длиной 30, состоящая из пробелов и любых других символов (например, 0 s), и возвращающая целое число (1, если змея определена, 0 в противном случае)

* Если входные данные должны быть единственной строкой (список символов), тогда добавьте a, чтобы разделить строку в переводе строки.

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

Как?

Zn⁶T€z-IỊ0-¦Ȧ - Link: list of lists of characters, Lines
Z             - transpose the lines -> columns
  ⁶           - literal space character
 n            - not equal? -> 0 where there were spaces and 1 where there were "0"s
   T€         - truthy indices for each -> e.g. [0,0,1,0,0] -> [3] or [0,1,1,0,0] -> [2,3]
              -                           note: [0,0,0,0,0] -> []
      -       - literal minus one
     z        - transpose with filler (-1) -> {valid: a single list of heights {top:1,...,bottom:5}
              -                              invalid: list of >1 lists, some of which contain -1
              -                                       ...OR an empty list (no 0s in the input at all)}
       I      - differences -> {up:-1; down:1; flat:0; invalid:-6,-5,...,-2,2,...4}
        Ị     - insignificant (abs(z)<=1) -? {up/down/flat:1; invalid:0}
           ¦  - sparse application///
         0    - ...action: literal zero
          -   - ...to indices: [-1] -> make penultimate list into a zero (when one exists)
            Ȧ - any & all -> when flattened:{empty or contains a 0:0; otherwise:1}

Ах, думал, что я перепробовал все крайние случаи, спасибо за хедз-ап; придется обратиться позже.
Джонатан Аллан

@ LuisMendo хе и исправляя это я спас три, так что спасибо еще раз!
Джонатан Аллан

... но я представила другую. Исправлено еще на 3 :(
Джонатан Аллан

Неплохой счетчик байтов :-)
Луис Мендо

1

Stax , 20 байтов CP437

Å┴m▐◘5)ît╢V¼≥+╝╜►º½ê

24 байта в распакованном виде,

LM{'0|Ic%vChm:-{Jh!f%29=

Запускать и отлаживать онлайн!

Возможно, не самый лучший в гольфе, но я думаю, что метод новый и интересный.

объяснение

LM                          Load the input string as a 2d array of characters, and transpose it

  {         m               Map array with block
   '0|I                     Get all indices of substring "0"
       c%vC                 Map to nothing if the indices are not unique
           h                Otherwise map to the unique index

             :-             Take pairwise difference

               {   f        Filter array with block
                Jh!         Only keep 0, 1 and -1

                    %29=    Check whether the final array has exactly 29 elements

1

J , 38, 37 30 байт

-8 байт благодаря FrownyFrog

[:($e.~[:(-:*)2-/\])@:I.'0'=|:

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


1
Как насчет [:(-:*)2-/\, проверьте, все ли различия -1, 0 или 1.
FrownyFrog

@FrownyFrog Да, это намного лучше! Спасибо!
Гален Иванов

@ FrownyFrog Хм, я этого не понимал. Я постараюсь это исправить. Спасибо за указание на это.
Гален Иванов

1
[:(#@{.=[:(-:*)2-/\])@:I.'0'=|:
FrownyFrog

1
О, это тоже работает[:($e.~[:(-:*)2-/\])@:I.'0'=|:
FrownyFrog

1

Желе , 16 байт

Zµi€”0IỊ;ċ€⁶=4ƊẠ

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

Предполагается, что входная строка всегда будет содержать только пробелы и нули. Принимает input как список строк (каждая представляет строку) и выводит 1, если truey, 0 противном случае.

объяснение

Zµi€”0IỊ;ċ€⁶=4ƊẠ | Monadic full program.
Z                | Transpose.
 µ               | Start a new monadic chain.
  i€”0           | Retrieve the first index of 0 in each column.
      IỊ         | Check whether their increments are insignificant (element-wise).
        ;     Ɗ  | Append the result of the following:
         ċ€⁶     | In each list of characters, count the occurrences of a space.
            =4   | Check whether they equal 4 (returns a boolean array).
               Ạ | All. Check whether all the elements are truthy.


0

Python 2 и Python 3 , 122 120 119 байтов

lambda s:s.count('0')<31and all(s[i-31*(i>30):31*(i<124)-~i:31].strip(' ')for i,x in enumerate(s,1)if' '<x)and' '<s[62]

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

Формат ввода - одна строка длиной 154 (5 х 30 символов, 4 перевода строки):

'''
            0 0               
  0        0 0 000            
00 0     00       000 0      0
    000 0            0 0   00 
       0                000   '''[1:] # to exclude starting newline

Если голова не должна быть в центре ряда

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

Python 2 и Python 3 , 124 123 байта

lambda s:s.count('0')<31and all(s[i-31*(i>30):31*(i<124)-~i:31].strip(' ')for i,x in enumerate(s,1)if' '<x)and'0'in s[::31]

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


Редактировать:

  • Уменьшено 2 байта путем замены equals ( ==) на неравенства для каждого кода.
  • Нашли ошибки в менее ограничивающей версии и исправили ее. (К счастью, это не так уж и страшно, поэтому я мог бы сохранить все версии одинаковыми по длине.) Вы можете увидеть дополнительные тестовые примеры в последних двух ссылках TIO.
  • Нашел висящий байт в решениях Py2, сделав all()трюк бессмысленным в Py3, поэтому объединил обе версии.

0

Excel (VBA), 68 байт

Использование Immediate Window в Cell[A6]качестве вывода.

[A1:AD5]="=CHOOSE(ROUND(RAND()+1,),0,"""")":[A6]="=COUNT(A1:AD5)=30"





0

Питон 3 , 197 185 байт

В командной строке do verify.py<snake.txtили в bash do cat snake.txt | python verify.py. гдеsnake.txt находится файл, содержащий змею для проверки.

Если змея верна, ничего не будет выведено. Если это не правильно, Python выдаст ошибку индекса.

import sys
s=sys.stdin.read().split("\n")
x=0
exec('t,y="",0\nwhile y<5:t+=s[y][x];y+=1\ns+=[t];x+=1;'*30)
s=list(map(lambda l:len(l.rstrip()),s))
while y<35:"ee"[abs(s[y]-s[y+1])];y+=2

О, не заметил, что мой вывод должен быть либо истинным, либо ложным. Возвращается ли код ошибки?
УсыMoses

Гольф 12 байтов.
УсыMoses
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.