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


33

Ваша мета - перевірити, чи дійсна заповнена дошка тральщика . Це означає, що кожне число - це правильний підрахунок мін у сусідніх з ним осередках, включаючи діагоналі. Дошка не загортається.

Як завжди , ви повинні дати функцію або програму, і найкоротший код у байтах виграє.

Дивіться також минулі виклики, щоб створити , вирішити та повністю впровадити тральщик.

Вхід:

Один рядок , як це: 02X2 13X2 X211.

  • Ряди дошки тральщиків задані розділеними пробілами. Отже, вище представлено дошку 3x4:

    02X2
    13X2
    X211

  • Кожна комірка - це символ: Xдля шахти чи числа 0наскрізь 8.

  • Всі ряди мають однакову довжину.

  • Є щонайменше 3 ряди та 3 стовпчики.

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

Вихід:

Послідовна Truthy на правильних дошках та послідовне значення Falsey на неправильних дошках. Послідовне означає, що всі результати 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

Вам, мабуть, слід вказати, що послідовний фальшивий вихід повинен відрізнятися від послідовного результату ;-)
Джон Дворак

@JanDvorak Це має мати на увазі під собою Труті та Фалсі відповідно.
xnor

Не зовсім. "truthy" і "falesy" - це лише дві мітки, які ви дозволяєте нам визначити. Я не бачу жодних обмежень, вони є фактично неправдивими або хибними відповідно до мови, якою ми користуємось. Єдине слово, яке може вимагати від них розрізнення, - дієслово "вказівка". Я не впевнений, що це враховується як специфікація (все ж це заборонено як стандартна лазівка).
Джон Дворак

4
@JanDvorak 'truthy' та 'falesy' насправді є дещо поширеними термінами, якщо я не помиляюсь, в основному використовуються для опису речей (не обов'язково булів), які оцінюються як істинні чи помилкові, коли набираються в bools. Наприклад, 0 зазвичай є хибним, а 1 - як правило, неправдоподібним.
KSab

1
@JanDvorak Nope, Truthy / Falsey має відповідати правильним / неправильним.
xnor

Відповіді:


11

Пітон 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не потрібно дзвонити двічі.


Яке розумне використання ~! І словники, щоб зробити індексацію поза межами роботи правильно.
xnor

@xnor Ваш коментар щодо ~оператора іронічно змусив мене помітити, що я два рази його використовував без будь-якої причини, коли, використовуючи його лише один раз, явно вдалося б виконати те саме. Я думав, що словникова частина була смішною, дякую.
feersum

9

Піта, 43

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

Спробуйте тут .

Пояснення:

  • Jhxzd: Це розташування першого простору на вході + 1. ( zна вході d- пробіл.) Це розділення у вході між вертикально сусідніми комітками на дошці.
  • !f: Це логічний not ( !) фільтра ( f), який буде Trueтоді і лише тоді, коли вираз буде хибним для кожного елемента послідовності.
  • -@zT: Візьміть у Tвхідного символу (лямбда-змінну) і видаліть будь-які види: (Це буде правдою, якщо символ не буде видалено, і хибним, якщо він є.
  • +" X": Видаліть пробіл, X та
  • `: Репр
  • sm: сума карти до
  • / \X: кількість "X" в
  • :+*JNz: Епізод введення з префіксом Jфіктивних символів
  • td+d2: Від d-1 до d + 2.
  • m+T*kJU3: Для d в [T, T + J, T + 2 * J].
  • UzДля Т в range(len(input)).

7
Похідні: Чому нивоти?
isaacg

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∊: return, 1якщо отримана матриця не містить нулів (= всі квадрати є або бомбами, або правильним числом), і 0якщо вона є.

Ви рахували байти чи символи? Вам слід порахувати байти.
Тім С.

5
@TimS. Існує безліч однобайтових кодувань APL, ось одне .
marinus

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 економить деякий простір порівняно з циклами, але це важче налагоджувати.

Я навчився кількох речей, як перетворення char => int, віднімаючи '0'.

Здавалося, простіше застелити дошку пробілами, щоб ітерація над нею була простішою.


1
Ви не можете просто замінити -'0'з -48. Працює для мене і економить кілька байт для різних "X" і ""
Роман Греф

5

Пітон 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))за винятком того, що він повертає ітератор-об'єкт, який не підтримує дві вкладені петлі через нього.


Я думаю, що негативний модуль повинен працювати для n; тоді ви могли б використовувати ~B.find.
feersum

@feersum На жаль, це псує те, /що воно також спрямовує негативи вниз.
xnor

4

Пітон 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))

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+=...вираз завжди є truthy, щоб підтримувати 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.


Замість того, щоб 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.
    Внутрішня перевірка проводиться за допомогою карти лише тому, що вона коротша, ніж дляEach

деякі повертають істину на перше значення truthy (в даному випадку ненульове), що означає невдалу перевірку. Результат заперечується для отримання більш впізнаваного істинного / хибного.

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

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.