Проверить доску тральщика

33

Ваша цель - проверить, действительна ли заполненная доска Сапер . Это означает, что каждое число является правильным количеством мин в соседних с ним клетках, включая диагонали. Доска не оборачивается.

Как обычно , вы должны дать функцию или программу, и самый короткий код в байтах побеждает.

Смотрите также прошлые проблемы, чтобы создать , решить и полностью внедрить Сапер.

Входные данные:

Одна строка , как это: 02X2 13X2 X211.

  • Ряды доски тральщика разделены пробелами. Итак, вышесказанное представляет плату 3х4:

    02X2
    13X2
    X211

  • Каждая ячейка представляет собой символ: Xдля шахты, или номер 0через 8.

  • Все строки имеют одинаковую длину.

  • Есть как минимум 3 строки и 3 столбца.

  • Ввод не начинается и не заканчивается пробелом, но вы можете добавить новую строку в конце, если хотите.

Выход:

Последовательная Истина на правильных досках и постоянное значение Фалси на неправильных досках. Согласованный означает, что все выходы Truthy одинаковы и все выходы Falsey одинаковы.

Контрольные примеры

Каждая строка - это отдельный контрольный пример.

True:

02X2 13X2 X211
XXXX XXXX XXXX XXXX
XX4X2 5X6X4 XX6XX 4XX54 2X4XX

False:

02X2 13X2 X212
XXXX XXXX X7XX XXXX
XX5X2 5X6X4 XX6XX 4XX54 2X5XX
XNOR
источник
Вы, вероятно, должны указать, что непротиворечивый ложный вывод должен отличаться от непротиворечивого правдивого вывода ;-)
Джон Дворжак
@JanDvorak Это должно подразумеваться как Истина и Фолси соответственно.
xnor
На самом деле, нет. «истина» и «ложь» - это всего лишь два ярлыка, которые вы позволяете нам определить. Я не вижу никаких ограничений, они будут на самом деле правдивыми или ложными в языке, который мы используем. Единственное слово, которое может потребовать, чтобы они были различимы, - это «указывающий» глагол. Я не уверен, что это считается спецификацией (хотя это все еще запрещено как стандартная лазейка).
Джон Дворжак
4
@JanDvorak «истина» и «ложь» на самом деле являются довольно общими терминами, если я не ошибаюсь, в основном они используются для описания вещей (не обязательно bools), которые оцениваются как true или false при вводе в bools. Например, 0, как правило, ложно, а 1, как правило, верно.
KSab
1
@JanDvorak Нет, Truthy / Falsey должен соответствовать правильный / неправильный.
xnor

Ответы:

11

Python 2, 132 129 128

def f(s):w=s.find(' ');E=dict(enumerate(s));return all(E[i]in' X'+`sum(E.get(i+d/3*~w+d%3+w,5)>'O'for d in range(9))`for i in E)

Я использовал enumerateв гольфе ... и даже использовал в rangeдругом месте в той же программе. Очевидно, что-то здесь не так.

Редактировать: перебирать, dict(enumerate(s))а не enumerate(s), поэтому enumerateне нужно вызывать дважды.

feersum
источник
Какое умное использование ~! И из словарей для правильной индексации.
xnor
@xnor Ваш комментарий об ~операторе иронически заставил меня заметить, что я использовал его дважды безо всякой причины, хотя использование его только один раз, очевидно, могло бы выполнить то же самое. Я думал, что словарная часть была забавной, спасибо.
feersum
9

Пиф, 43

Jhxzd!f-@zT+" X"`sm/:+*JNztd+d2\Xm+T*kJU3Uz

Попробуй это здесь .

Объяснение:

  • Jhxzd: Это расположение первого пробела на входе + 1. ( zна входе dэто пробел.) Это разделение на входе между вертикально смежными ячейками на плате.
  • !f: Это логическое not ( !) для filter ( f), которое будет Trueтогда и только тогда, когда выражение ложно для каждого элемента последовательности.
  • -@zT: Возьмите символ в местоположении T(лямбда-переменную) из входных данных и удалите все появления: (Это будет правдой, если символ не удален, и ложным, если это так.
  • +" X": Удалить пробел, X и
  • `Репр
  • sm: сумма карты в
  • / \X: количество "X" в
  • :+*JNz: Часть ввода с префиксом Jфиктивных символов
  • td+d2: От д-1 до д + 2.
  • m+T*kJU3: Для d в [T, T + J, T + 2 * J].
  • UzДля Т в range(len(input)).
isaacg
источник
7
Downvoters: Почему downvotes?
Исаак
7

APL (NARS2000) (74)

{~0∊(G>9)∨G=(⍴G)↑{+/∊9<⍵∘⌷¨G∘.⊖(G←2-⍳3)∘.⌽⊂Z}¨⍳⍴Z←G↑⍨2+⍴G←¯1+⎕D⍳⊃⍵⊂⍨⍵≠' '}

Также работает в Dyalog APL, если ⎕ML установлено 3.

Объяснение:

  • ⊃⍵⊂⍨⍵≠' ': Трещина пробелы и использовать списки для формирования матрицы.
  • G←¯1+⎕D⍳: найдите индекс ⎕Dдля каждого значения, вычтите 1 и сохраните в G. ( ⎕Dсодержит цифры, любая не цифра превратится в10 ).
  • Z←G↑⍨2+⍴G: добавить две строки и столбцы нулей на краю матрицы, чтобы справиться с циклом
  • {... }¨⍳⍴Z: для каждой позиции вZ , найдите количество бомб в окрестности Мура этой позиции:
    • G∘.⊖(G←2-⍳3)∘.⌽⊂Z: поворот Zвлево, вправо, вверх, вниз, влево-вверх, вправо-вверх, влево-вниз и вправо-вниз.
    • ⍵∘⌷¨: для каждого из них найдите элемент в каждой из этих повернутых матриц
    • +/∊9<: посчитать, сколько элементов больше 9 (это количество бомб).
  • (⍴G)↑: снова удалить добавленные нули,
  • G=: проверить, Gравен ли каждый элемент количеству бомб, окружающих эту позицию (это должно быть верно для всех квадратов, не являющихся бомбами),
  • (G>9)∨: и проверьте, выше ли элементы в ( Gчем 9это бомбы).
  • ~0∊: вернуть, 1если полученная матрица не содержит нулей (= все квадраты либо бомбы, либо правильное число), и 0если это так.
Мэринус
источник
Вы считали байты или символы? Вы должны считать байты.
Тим С.
5
@TimS .: Есть множество 1-байтовых кодировок APL, вот одна .
Маринус
5

C #, 321 320 305

bool s(string B){var L=B.Split(' ').Select(s=>' '+s+' ').ToList();var b=new string(' ',L[0].Length);L.Insert(0,b);L.Add(b);Func<int,int,IEnumerable<int>>E=Enumerable.Range;return E(1,b.Length-2).All(x=>E(1,L.Count-2).All(y=>L[y][x]=='X'||L[y][x]-'0'==E(x-1,3).Sum(X=>E(y-1,3).Sum(Y=>L[Y][X]=='X'?1:0))));}

Первая попытка игры в гольф, и я знаю, что C # не идеальный язык.

Я надеюсь, что написание метода экземпляра разрешено, в противном случае добавьте еще 7 символов для static.

Разнесены:

bool s(string B) {
    var L = B.Split(' ').Select(s => ' ' + s + ' ').ToList();
    var b = new string(' ', L[0].Length);
    L.Insert(0, b);
    L.Add(b);
    Func<int, int, IEnumerable<int>> E = Enumerable.Range;
    return E(1, b.Length - 2).All(x =>
        E(1, L.Count - 2).All(y =>
            L[y][x] == 'X' ||
            L[y][x] - '0' == E(x - 1, 3).Sum(X =>
                E(y - 1, 3).Sum(Y =>
                  L[Y][X] == 'X' ? 1 : 0))));
}

Использование Linq экономит место по сравнению с циклами for, но его сложнее отлаживать.

Я выучил несколько вещей, таких как преобразование char => intпутем вычитания '0'.

Казалось, проще заполнить доску пробелами, поэтому итерации по ней будут проще.

Карл Уолш
источник
1
Вы не можете просто заменить -'0'на -48. Работает для меня и сохраняет несколько байтов для различных 'X' и ''
Роман Греф,
5

Python 2, 121

def f(B):n=B.find(' ')+1;R=range(len(B));print all(B[I]in' X'+`sum(2>I%n-i%n>-2<I/n-i/n<2<B[i]>'W'for i in R)`for I in R)

Это сильно вдохновлено ответом Feersum . Порядок дня излишний: вместо того, чтобы проверять наличие мин в 9 соседних ячейках, проверяйте каждую отдельную ячейку, чтобы узнать, является ли она соседней.

Мы проверяем, являются ли две ячейки соседями 2>r>-2<c<2, где rи где cразличия в строках и столбцах ячеек эквивалентны {r,c}<{-1,0,1}. Эти координаты вычисляются из индексов ячеек Iи iкак c=I%n-i%nи r=I/n-i/n. Более эффективно индексировать непосредственно в строку и извлекать строки и столбцы, чем преобразовывать его в 2D-объект, такой как список списков. Проверка шахты B[i]>'W'здесь эквивалентна B[i]=='X'.

Использование enumerateспасло бы два символа над уродливым, range(len(B))за исключением того, что оно возвращает объект итератора, который не поддерживает два вложенных цикла через него.

XNOR
источник
Я думаю, что отрицательный модуль должен работать для п; тогда вы могли бы использовать ~B.find.
feersum
@feersum К сожалению, это портит /и негативы, потому что они округляют и негативы.
xnor
4

Python 2, 140

s=input();w=s.index(' ')+1
print all(c in'X 'or(int(c)==sum(s[max(0,a-1):max(0,a+2)].count('X')for a in[i-w,i,i+w]))for i,c in enumerate(s))
KSab
источник
4

JavaScript (ES6), 135 133 125 122

f=s=>s.split(" ")[e="every"]((l,i,a)=>[...l][e]((c,j)=>!(-[-1,0,k=1][e]((y,m,q)=>q[e](x=>k+=(a[i+y]||0)[j+x]=="X"))-c+k)))

Обеспечить ввод функции в виде строки:

f("XX4X2 5X6X4 XX6XX 4XX54 2X4XX");

Для объяснения см. Старую версию ниже. Новая версия заменяет forциклы everyвызовами и использует переменную e="every"для выполненияsomeArray[e](...) вместо someArray.every(...).

Кроме того, счетчик kтеперь индексируется 1так, чтобы k+=...выражение всегда было верным, чтобы everyцикл продолжался. Мы убираем это лишнее 1, вычитая trueрезультат (который численно приводится 1), возвращаемый everyоперацией [-1,0,k=1][e](...).


Старая версия:

f=s=>s.split(" ").every((l,i,a)=>[...l].every((c,j)=>{q=[-1,k=0,1];for(y of q)for(x of q)k+=(a[i+y]||0)[j+x]=="X";return c=="X"||k==c}))

Код с пробелами и комментариями:

f=s=>s.split(" ")                 // split on spaces
      .every((l,i,a)=>             // for every line
                                   //     l: line string, i: line number, a: whole array
          [...l].every((c,j)=>{    // for every character
                                   //     c: character, j: index in string
              q=[-1,k=0,1];        // define counter k=0 and q=[-1,0,1]
              for(y of q)          // use q to loop adjacent spaces
                  for(x of q)

                      k+=              // add the following boolean to k:

                          (a[i+y]      //   from line number i+y...
                                 ||0)  //   (or a dummy zero, to prevent lookups on undefined)
                          [j+x]        //   ...get index j+x from the above value...
                                =="X"; //   ...and compare it to "X"

              return !(k-c)     // after the loop, this character passed if
                                // the char equals the number of counted X's (so k-c is 0)
                                // or it is an X itself (so `k-c` is NaN)
          })
      )

Метод everyмассива JavaScript принимает обратный вызов и применяет обратный вызов ко всем элементам массива. Если какой-либо обратный вызов возвращает ложное значение, everyвызов возвращается false.

Логические значения в JS приводятся к 1 или 0, когда являются частью дополнения. Для каждого окружающего пространства мы «добавляем» логический результат сравнения его значения Xи затем добавляем это значение к счетчику kв выражении k += (... == "X"). Следовательно, kсодержит счетчик числа окружающих Xs, потому что trueсчитается как 1и falseсчитается как 0.

apsillers
источник
Вместо того, чтобы c=="X"попытаться !c/1, это сэкономит вам огромное количество байт! Если не получится, попробуйте !!c/1. Аргументация в том 'X'/1 => NaN, что и NaNфальсификация. Вы проверяете, если c=='X', почему бы не попробовать проверить, если это не так false?
Исмаэль Мигель
@IsmaelMiguel Это оценивает так же, как (!c)/1, к сожалению, не помогает; Мне нужно иметь круглые скобки для !(c/1), что стоит 2. Кроме того, 0/1это ложь, поэтому неверный ввод " 0X" будет иметь неправильный результат true. Лучшее, что я могу сделать, все еще уважая нули, - это объединить два условия в отрицательную фразу, например !(+c+1&&k-c), но это такой же длины, как у меня уже есть.
Апсиллеры
@IsmaelMiguel Спасибо, что заставили меня задуматься об этом - я понял, что !(k-1-c)проверяет оба условия, потому что, если kсовпадения c(минус 1 смещение), то отрицание делает 0истинным, а если cне число, мы получаем NaNи отрицание также true.
Апсиллеры
Вы действительно были голодны! Вы съели 10 байт с исходного кода! Мне действительно нравится решение, которое вы придумали. +1 за ваше решение!
Исмаэль Мигель
3

CJam, 70 65 63 байта

1l_S#):L)S*+:Q{Ii33/2%[0~1LL)L(L~)L~_))]W):Wf+Qf='X/,(scI==&}fI

Это может быть много в гольфе.

Дает 1действительную доску и 0недействительную доску.

Контрольные примеры

{-1:W;
1l_S#):L)S*+:Q{Ii33/2%[0~1LL)L(L~)L~_))]W):Wf+Qf='X/,(scI==&}fI
}6*]N*

вход

02X2 13X2 X211
XXXX XXXX XXXX XXXX
XX4X2 5X6X4 XX6XX 4XX54 2X4XX
02X2 13X2 X212
XXXX XXXX X7XX XXXX
XX5X2 5X6X4 XX6XX 4XX54 2X5XX

Выход

1
1
1
0
0
0

Попробуйте онлайн здесь

оптимизатор
источник
3

JavaScript (ES6) 98

Использование некоторых для применения функции к каждому символу строки.
Функция возвращает

  • false если пусто
  • NaN, если 'X' (многократное вычитание значений из нечислового символа, такого как 'X', дает NaN)
  • Числовое значение 0, если есть правильное число знака «X», иначе не 0.
    Внутренняя проверка выполняется с использованием карты только потому, что она короче, чем forEach

некоторые возвращают true при первом значении truey (в данном случае, ненулевом), что означает неудачную проверку. Результат сводится на нет, чтобы дать более узнаваемую истину / ложь.

F=v=>![...v].some(
  (x,p)=>x!=' '&&[1,-1,l=v.search(' '),-l,++l,-l,++l,-l].map(q=>x-=v[p+q]=='X')|x
)

Тест в консоли FireFox / FireBug

;["02X2 13X2 X212","XXXX XXXX X7XX XXXX","XX5X2 5X6X4 XX6XX 4XX54 2X5XX"
,"02X2 13X2 X211","XXXX XXXX XXXX XXXX","XX4X2 5X6X4 XX6XX 4XX54 2X4XX","111 1X1 111"]
.forEach(t => console.log(t, F(t)))

Выход

02X2 13X2 X212 false
XXXX XXXX X7XX XXXX false
XX5X2 5X6X4 XX6XX 4XX54 2X5XX false
02X2 13X2 X211 true
XXXX XXXX XXXX XXXX true
XX4X2 5X6X4 XX6XX 4XX54 2X4XX true
111 1X1 111 true
edc65
источник
1

R 156 символов

a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])

С отступами, пробелами и переносами строк для удобочитаемости:

a = b = do.call(rbind,strsplit(scan(,""),"")) #Reads stdin and turn into a matrix
for(i in 1:nrow(a)) #Ugly, ugly loop
    for(j in 1:ncol(a))
        b[i,j] = sum(a[abs(i-row(a))<2 & abs(j-col(a))<2]=="X")
v = a!="X"
all(b[v]==a[v])

Примеры:

> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XX4X2 5X6X4 XX6XX 4XX54 2X4XX
6: 
Read 5 items
[1] TRUE
> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XXXX XXXX XXXX XXXX
5: 
Read 4 items
[1] TRUE
> a=b=do.call(rbind,strsplit(scan(,""),""));for(i in 1:nrow(a))for(j in 1:ncol(a))b[i,j]=sum(a[abs(i-row(a))<2&abs(j-col(a))<2]=="X");v=a!="X";all(b[v]==a[v])
1: XX5X2 5X6X4 XX6XX 4XX54 2X5XX
6: 
Read 5 items
[1] FALSE
plannapus
источник