Invertire una scheda per dragamine


32

Minesweeper è un popolare gioco per computer che probabilmente hai perso tempo giocando in cui provi a rivelare le celle che sono miniere in una griglia rettangolare sulla base di suggerimenti su quante miniere vicine ha ogni cella non-mia. E se non l'hai ancora giocato, fallo qui .

Un bel fatto matematico su una griglia di Minesweeper (aka board) è che:

Una tavola e il suo complemento hanno lo stesso numero totale di mine . ( Prova )

Vale a dire che se si dispone di una griglia Minesweeper completamente rivelata, la somma di tutti i numeri su quella griglia, ovvero il totale della miniera , sarà uguale al totale della miniera del complemento della griglia, che è la griglia in cui ogni miniera è stata sostituita con una non mia e ogni non mia sostituita con una miniera.

Ad esempio, per la griglia di Minesweeper

**1..
34321
*2**1

il totale delle miniere è 1 + 3 + 4 + 3 + 2 + 1 + 2 + 1 = 17.

Il complemento della griglia è

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

che ha di nuovo il mio totale 2 + 4 + 3 + 4 + 4 = 17.

Scrivi un programma che includa una griglia di dragamine arbitraria in forma di testo dove *rappresenta una miniera e 1attraverso 8rappresenta il numero di mine adiacenti a una cella non miniera. Puoi usare .o 0o (spazio) per rappresentare celle senza vicini di miniera, la tua scelta. Si può presumere che la griglia di input sarà contrassegnata correttamente, cioè ogni cella non mia indicherà accuratamente il numero totale di mine immediatamente adiacenti ad essa ortogonalmente o diagonalmente.

Il vostro programma deve stampare il complemento della griglia nello stesso formato (utilizzando lo stesso ., 0o come vi aspettavate in ingresso).

Vince il codice più breve in byte.

  • Invece di un programma è possibile scrivere una funzione che accetta la griglia di input come stringa e stampa o restituisce la griglia del complemento.
  • Una nuova riga finale nell'input o output va bene, ma non dovrebbero esserci altri caratteri oltre a quelli che formano la griglia.
  • Puoi supporre che una griglia 1 × 1 sia l'input più piccolo.

Casi test

Tutti gli input e gli output potrebbero essere scambiati poiché il complemento del complemento è la griglia originale. Le griglie possono essere ruotate anche per ulteriori casi di test.

Ingresso:

111
1*1
111

Produzione:

***
*8*
***

Ingresso:

.

Produzione:

*

Ingresso:

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

Produzione:

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

Input: ( esempio Cut The Knot )

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

Produzione:

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

TI-BASIC non può accettare una riga vuota di input. È ?accettabile utilizzare un delimitatore di fine (ad esempio ) sulla riga dopo l'ultima riga della scheda oppure è possibile rilevare il numero di righe di input tramite la riga di comando?
lirtosiast,

@ThomasKwa Un delimitatore di fine suona bene per TI-BASIC e altre lingue che hanno strane limitazioni newline.
Calvin's Hobbies,

Risposte:


12

Pyth, 39 38 byte

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

Provalo online: dimostrazione

L'algoritmo principale è davvero semplice. Ho semplicemente iterato su ogni cella, prendo la casella 3x3 circostante (o più piccola quando la cella si trova sul bordo) e stampo una stella o il numero di non stelle in quella casella.

Spiegazione:

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

Davvero pulito, +1
MKII

22

CJam, 58 57 byte

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

L'input non deve terminare con un avanzamento riga. L'output contiene 0celle senza miniere vicine.

Provalo online nell'interprete CJam .

Idea

Iniziamo riempiendo la matrice di input con una riga e una colonna di asterischi.

Per input

*4*
**2

questo risulta in

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

Ora generiamo tutte le possibili modifiche che risultano dalla rotazione delle righe e delle colonne di 0, -1 o 1 unità in alto / a sinistra:

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

Eliminiamo le "posizioni di riempimento" da ogni rotazione, ovvero

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

e formare una singola matrice concatenando i caratteri corrispondenti di ciascuna rotazione:

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

Il primo personaggio di ogni posizione è il suo personaggio originale.

  • Se è un non-asterisco, deve essere sostituito con un asterisco.

  • Se si tratta di un asterisco, il numero di non asterischi in quella stringa è il numero di mine vicine.

Come funziona

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
Ho paura - è fantastico.
Deusovi,

Signore, ho appena rotto il sistema. +1! Posso chiederti dove hai trovato questa teoria?
GamrCorps,

9
@IonLee Questo è tutto per me. È un'idea piuttosto semplice, davvero: invece di controllare le celle attorno a una data cella, spostiamo l'intera griglia intorno e osserviamo ciò che cade nella cella.
Dennis,

Bravo! Non ci avrei mai pensato.
GamrCorps,

7

Ruby, 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]<=>?*]}}

Non registrato nel programma di test:

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

Ottava, 76

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

Spiegazione

  • Converti stringa di input in matrice di stringhe utilizzando strsplite cell2mat.

  • Ottieni la matrice logica contenente 1dove non c'è *nella matrice originale.

  • Prendi la sua convoluzione con una matrice 3x3 di 1.

  • Mascheralo con la matrice logica inversa e mettilo *al posto della maschera.

  • Nota: le celle senza vicini di miniera sono rappresentate come 0.

Esecuzione

>> 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.