マインスイーパボードの反転


32

マインスイーパは人気のあるコンピューターゲームで、おそらくプレイに時間を浪費しているので、各非地雷セルがいくつの隣接地雷を持っているかのヒントに基づいて、長方形のグリッド内の地雷であるセルを明らかにしようとします。また、まだプレイしていない場合は、ここで行います

マインスイーパグリッド(ボード)についての気の利いた数学的な事実は、次のとおりです。

ボードとその補数の鉱山総数は同じです。(証明

つまり、マインスイーパグリッドが完全に表示されている場合、そのグリッド上のすべての数値の合計、つまり鉱山の合計は、グリッドの補数の鉱山の合計、つまりすべての鉱山が置き換えられたグリッドに等しくなります非地雷とすべての非地雷が地雷に置き換えられました。

たとえば、マインスイーパグリッドの場合

**1..
34321
*2**1

鉱山の合計は1 + 3 + 4 + 3 + 2 + 1 + 2 + 1 = 17です。

グリッドの補数は

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

合計で2 + 4 + 3 + 4 + 4 = 17になります。

任意のマインスイーパグリッドをテキスト形式で取り込むプログラムを作成します。ここで*は、地雷を表し、地雷は非地雷セルに隣接する地雷の数18表します。.または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は、空の入力行を受け入れることができません。?ボードの最終行の後の行で終了区切り文字(たとえば)を使用できますか、またはコマンドラインで入力行の数を取得できますか?
リルトシアスト

@ThomasKwa TI-BASICや、奇妙な改行の制限がある他の言語の場合、終了区切り記号は適切に聞こえます。
カルバンの趣味

回答:


12

Pyth、39 38バイト

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

オンラインで試してください: デモンストレーション

メインのアルゴリズムは本当に簡単です。各セルを繰り返し処理し、周囲の3x3ボックス(またはセルが境界にある場合はそれより小さい)を取り、そのボックスに星または星以外の数を印刷します。

説明:

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インタープリターでオンラインで試す

アイディア

入力行列に1行1列のアスタリスクでパディングすることから始めます。

入力用

*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ない部分を含む論理行列を取得し*ます。

  • 1の3x3行列で畳み込みを行います。

  • 逆論理行列で*マスクし、マスクの代わりに配置します。

  • 注:地雷が隣接していないセルはとして表され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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.