Інвертуйте дошку тральщика


32

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

Чудовим математичним фактом про сітку шахтника (він же дошка) є те, що:

Дошка та її доповнення мають однакову загальну кількість шахт . ( Доказ )

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

Наприклад, для сітки шахт

**1..
34321
*2**1

загальна сума шахти - 1 + 3 + 4 + 3 + 2 + 1 + 2 + 1 = 17.

Доповненням сітки є

24***
*****
3*44*

який знову має 2 + 4 + 3 + 4 + 4 = 17.

Напишіть програму, яка займає довільну сітку шахтника в текстовій формі, де *представляє шахту, і 1через 8репрезентуйте кількість мін, що прилягають до немінної комірки. Ви можете використовувати .або ( 0або пробіл) для представлення комірок без мінних сусідів на ваш вибір. Можна припустити, що вхідна сітка буде правильно позначена, тобто кожна немінна комірка точно позначатиме загальну кількість мін, що безпосередньо примикають до неї ортогонально або по діагоналі.

Ваша програма повинна надрукувати доповнення сітки в тому ж форматі ( з використанням тих же ., 0або , як ви очікували на вході).

Виграє найкоротший код у байтах.

  • Замість програми ви можете написати функцію, яка приймає вхідну сітку як рядок та друкує або повертає сітку доповнення.
  • Новий рядок у вході або виході є нормальним, але не повинно бути інших символів, крім тих, що утворюють сітку.
  • Можна припустити, що сітка 1 × 1 буде найменшим входом.

Випробування

Всі входи та виходи можуть бути замінені, оскільки доповненням доповнення є оригінальна сітка. Сітки можна також обертати для подальших тестових випадків.

Вхід:

111
1*1
111

Вихід:

***
*8*
***

Вхід:

.

Вихід:

*

Вхід:

*11*1.1**1...1***1.....1*****1..........

Вихід:

1**2***11*****1.1*******1...1***********

Вхід: ( Приклад вирізання вузла )

**212*32
333*33**
1*22*333
222222*1
*33*2232
2**22*2*

Вихід:

24***4**
***7**64
*8**7***
******8*
4**7****
*33**5*3

TI-BASIC не може прийняти порожній рядок введення. Чи ?допустимо використання кінцевого роздільника (наприклад ) на рядку після остаточного рядка дошки, або я можу взяти кількість вхідних рядків через командний рядок?
lirtosiast

@ThomasKwa Кінцевий роздільник обмеження звучить для TI-BASIC та інших мов, які мають дивні обмеження в новому рядку.
Захоплення Кальвіна

Відповіді:


12

Pyth, 39 38 байт

j.es.eh-+K\*l-s:RtWYY+Y2:+K.zk+k3KZb.z

Спробуйте в Інтернеті: Демонстрація

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

Пояснення:

j.es.eh-+K\*l-s:RtWYY+Y2:+K.zk+k3KZb.z  implicit: .z = list of input strings
 .e                                 .z  map each index k, line b of .z to:
    .e                             b      map each index Y, char Z of b to:
         K\*                                assign "*" to K
                         +K.z               insert K at the front of .z
                        :    k+k3           slice from k to k+3
               :RtWYY+Y2                    take the slice from Y-1 or 0 
                                            to Y+2 for each line
              s                             join, this gives the 3x3 rectangle
                                             (or smaller on the border)
             -                   K          remove all "*"s
            l                               take the length
        +K                                   "*" + ^
       -                          Z         remove Z from this string
      h                                     and take the first char
                                            (if cell=mine take the number, 
                                             otherwise take the number)
  s                                       join the chars of one line
j                                       join by newlines

Дійсно акуратний, +1
MKII

22

CJam, 58 57 байт

0WX]2m*qN/{'*f+z}2*f{\~@m<fm<W<}:..+{W<{_'*#'*@'*-,?}/N}/

Введення даних не повинно закінчуватися підведенням рядків. Вихід містить 0для осередків без мін поблизу.

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Ідея

Почнемо з додавання матриці введення одним рядком і одним стовпчиком зірочок.

Для введення

*4*
**2

це призводить до

*4**
**2*
****

Тепер ми генеруємо всі можливі модифікації, що призводять до обертання рядків і стовпців 0, -1 або 1 одиниці вгору / вліво:

*4** **** **2* **4* **** ***2 4*** **** *2**
**2* *4** **** ***2 **4* **** *2** 4*** ****
**** **2* *4** **** ***2 **4* **** *2** 4***

Ми відкидаємо "місця прокладки" від кожного обертання, тобто

*4* *** **2 **4 *** *** 4** *** *2*
**2 *4* *** *** **4 *** *2* 4** ***

і сформувати єдину матрицю, об'єднавши відповідні символи кожного обертання:

******4** 4*******2 **24*****
*******4* *4****2** 2***4****

Першим персонажем кожної позиції є її оригінальний характер.

  • Якщо це не зірочка, її потрібно замінити зірочкою.

  • Якщо це зірочка, кількість не-зірочок у цьому рядку - це кількість сусідніх мін.

Як це працює

0WX]2m*   e# Push the array of all vectors of {0,-1,1}^2.
qN/       e# Read all input from STDIN and split at linefeeds.
{'*f+z}2* e# Append a '*' to each row and transpose rows with columns. Repeat.
f{        e# For each vector [A B], push the modified input Q; then:
  \~      e#   Swap Q with [A B] and dump A and B on the stack.
  @m<     e#   Rotate the rows of Q B units up.
  fm<     e#   Rotate each row of the result A units left.
  W<      e#   Discard the last row.
}         e# This pushes all nine rotations with Manhattan distance 1.
:..+      e# Concatenate the corresponding characters for each position.
{         e# For each row:
  W<      e#   Discard the character corresponding to the last column.
  {       e#   For each remaining string:
    _'*#  e#     Find the first index of '*' in a copy.
    '*    e#     Push '*'.
    @'*-, e#     Count the non-asterisks in the string.
    ?     e#     Select '*' if the index is non-zero, the count otherwise.
  }/      e#
  N       e#   Push a linefeed.
}/        e#

7
Мені страшно - це дивовижно.
Deusovi

Ви, пане, щойно зламали систему. +1! Чи можу я запитати, де ви знайшли цю теорію?
GamrCorps

9
@IonLee Цей я все. Це дійсно досить проста ідея: замість того, щоб перевіряти клітини навколо даної комірки, ми переміщуємо всю сітку навколо і спостерігаємо, що потрапляє в клітинку.
Денніс

Браво! Я б ніколи про це не думав.
GamrCorps

7

Рубі, 119

->s{w=1+s.index('
')
s.size.times{|c|t=0;9.times{|i|(s+?**w*2)[c+i/3*w-w+i%3-1]<?0||t+=1}
print [t,?*,'
'][s[c]<=>?*]}}

Невикористані в тестовій програмі:

f=->s{
  w=1+s.index("\n")                          #width of board
  s.size.times{|c|                           #iterate through input
    t=0;                                     #number of digits surrounding current cell
    9.times{|i|                              #iterate through 3x3 box (centre must be * if this ever gets printed.)
      (s+"*"*w*2)[c+i/3*w-w+i%3-1]<"0"||t+=1 #copy of s has plenty of * appended to avoid index errors
    }                                        #add 1 every time a number is found.
  print [t,"*","\n"][s[c]<=>"*"]             #if * print t. if after * in ACSII it's a number, print *. if before, it's \n, print \n
  }
}


f['**212*32
333*33**
1*22*333
222222*1
*33*2232
2**22*2*']

2

Октава, 76

m=@(s)char(conv2(b=(cell2mat(strsplit(s)'))~='*',ones(3),'same').*~b-6*b+48)

Пояснення

  • Перетворити вхідний рядок в матрицю рядків за допомогою strsplitі cell2mat.

  • Отримайте логічну матрицю, що містить 1там, де її немає *в початковій матриці.

  • Візьміть його згортання за допомогою 3x3 матриці 1-х.

  • Замаскуйте її зворотною логічною матрицею і поставте *на місце маски.

  • Примітка: Клітини, які не мають мінних сусідів, представлені як 0.

Виконання

>> m(['**100' 10 '34321' 10 '*2**1'])   %// `10` is newline
ans =

24***
*****
3*44*

>> m(['24***' 10 '*****' 10 '3*44*'])
ans =

**100
34321
*2**1
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.