Balikkan Papan Minesweeper

32

Minesweeper adalah gim komputer populer yang mungkin Anda buang-buang waktu untuk mencoba mengungkap sel-sel yang ditambang dalam kotak persegi panjang berdasarkan petunjuk tentang berapa banyak tambang tetangga yang dimiliki masing-masing sel non-tambang. Dan jika Anda belum memainkannya, lakukan di sini .

Fakta matematika yang bagus tentang kisi Minesweeper (alias papan) adalah:

Dewan dan pelengkapnya memiliki jumlah total tambang yang sama . ( Bukti )

Artinya, jika Anda memiliki kisi Minesweeper yang benar-benar terungkap, jumlah semua angka pada kisi itu, yaitu total tambang , akan sama dengan total tambang dari komplemen kisi, yang merupakan kisi tempat setiap tambang telah diganti dengan non-tambang dan setiap non-tambang diganti dengan tambang.

Misalnya, untuk kisi Minesweeper

**1..
34321
*2**1

total tambang adalah 1 + 3 + 4 + 3 + 2 + 1 + 2 + 1 = 17.

Komplemen grid adalah

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

yang memiliki total tambang 2 + 4 + 3 + 4 + 4 = 17 lagi.

Tulis program yang menggunakan kisi Minesweeper yang sewenang-wenang dalam bentuk teks yang *mewakili tambang dan 1melalui 8jumlah tambang yang berdekatan dengan sel non-tambang. Anda dapat menggunakan .atau 0atau (ruang) untuk mewakili sel dengan tetangga tidak tambang, pilihan Anda. Anda dapat mengasumsikan bahwa kisi-kisi input akan ditandai dengan benar, yaitu setiap sel non-ranjau akan secara akurat menunjukkan jumlah total tambang yang berbatasan langsung dengannya secara ortogonal atau diagonal.

Program Anda perlu untuk mencetak komplemen dari grid dalam format yang sama (menggunakan yang sama ., 0atau seperti yang Anda harapkan di input).

Kode terpendek dalam byte menang.

  • Alih-alih sebuah program Anda dapat menulis fungsi yang mengambil kisi input sebagai string dan mencetak atau mengembalikan kisi komplemen.
  • Baris tambahan di input atau output baik-baik saja, tetapi tidak boleh ada karakter lain selain yang membentuk kisi.
  • Anda dapat menganggap kisi 1 × 1 akan menjadi input terkecil.

Uji Kasus

Semua input dan output dapat ditukar karena komplemen dari komplemen adalah grid asli. Kisi-kisi dapat diputar juga untuk kasus uji lebih lanjut.

Memasukkan:

111
1*1
111

Keluaran:

***
*8*
***

Memasukkan:

.

Keluaran:

*

Memasukkan:

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

Keluaran:

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

Input: ( Potong contoh Simpul )

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

Keluaran:

24***4**
***7**64
*8**7***
******8*
4**7****
*33**5*3
Hobi Calvin
sumber
TI-BASIC tidak dapat menerima jalur input kosong. Apakah menggunakan pembatas akhir (misalnya ?) pada baris setelah baris akhir papan dapat diterima, atau bisakah saya mengambil jumlah baris input melalui baris perintah?
lirtosiast
@ThomasKwa Pembatas akhir terdengar bagus untuk TI-BASIC dan bahasa lain yang memiliki batasan baris baru yang aneh.
Calvin Hobbies

Jawaban:

12

Pyth, 39 38 byte

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

Cobalah online: Demonstrasi

Algoritma utama sangat mudah. Saya cukup mengulangi setiap sel, mengambil kotak 3x3 di sekitarnya (atau lebih kecil ketika sel di perbatasan) dan mencetak bintang atau jumlah non-bintang di kotak itu.

Penjelasan:

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
Jakube
sumber
Sangat rapi, +1
MKII
22

CJam, 58 57 byte

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

Input tidak boleh diakhiri dengan linefeed. Keluaran berisi 0sel tanpa tambang terdekat.

Cobalah online di juru bahasa CJam .

Ide

Kita mulai dengan mengisi matriks input dengan satu baris dan satu kolom tanda bintang.

Untuk input

*4*
**2

ini menghasilkan

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

Sekarang kami menghasilkan semua modifikasi yang mungkin terjadi akibat memutar baris dan kolom 0, -1 atau 1 unit ke atas / kiri:

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

Kami membuang "lokasi bantalan" dari setiap rotasi, yaitu,

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

dan membentuk matriks tunggal dengan menggabungkan karakter yang sesuai dari setiap rotasi:

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

Karakter pertama dari setiap posisi adalah karakter aslinya.

  • Jika itu bukan tanda bintang, itu harus diganti dengan tanda bintang.

  • Jika itu adalah tanda bintang, jumlah non-tanda bintang dalam string itu adalah jumlah tambang tetangga.

Bagaimana itu bekerja

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#
Dennis
sumber
7
Saya takut - ini luar biasa.
Deusovi
Anda Pak, baru saja merusak sistem. +1! Bolehkah saya bertanya di mana Anda menemukan teori ini?
GamrCorps
9
@IonLee Yang ini semua saya. Ide yang cukup sederhana, sebenarnya: Alih-alih memeriksa sel di sekitar sel yang diberikan, kami memindahkan seluruh kotak dan mengamati apa yang jatuh ke dalam sel.
Dennis
Bravo! Saya tidak akan pernah memikirkan itu.
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]<=>?*]}}

Tidak tergabung dalam program uji:

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*']
Level River St
sumber
2

Oktaf, 76

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

Penjelasan

  • Mengonversi string input ke matriks string menggunakan strsplitdan cell2mat.

  • Dapatkan matriks logis yang berisi di 1mana tidak ada *dalam matriks asli.

  • Ambil belokannya dengan matriks 3x3 dari 1.

  • Topeng dengan matriks logis terbalik dan tempatkan *topeng.

  • Catatan: Sel tanpa tetangga ranjau direpresentasikan sebagai 0.

Eksekusi

>> 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
gelas kimia
sumber