สลับคณะกรรมการเรือกวาดทุ่นระเบิด


32

Minesweeperเป็นเกมคอมพิวเตอร์ยอดนิยมที่คุณอาจเสียเวลาในการเล่นซึ่งคุณพยายามที่จะเปิดเผยเซลล์ที่ทำเหมืองในตารางสี่เหลี่ยมโดยคำแนะนำของจำนวนเหมืองที่อยู่ใกล้เคียงแต่ละเซลล์ที่ไม่ใช่ของเหมืองมี และในกรณีที่คุณไม่ได้เล่นมันทำที่นี่

ข้อเท็จจริงทางคณิตศาสตร์ที่ดีเกี่ยวกับ Minesweeper grid (aka board) คือ:

กระดานและส่วนประกอบของมันมีจำนวนเหมืองทั้งหมดเท่ากัน ( พิสูจน์ )

กล่าวคือถ้าคุณมีตาราง Minesweeper ที่เปิดเผยทั้งหมดผลรวมจำนวนทั้งหมดบนกริดนั้นคือผลรวมของเหมืองจะเท่ากับผลรวมทั้งหมดของส่วนเสริมของกริดซึ่งเป็นตารางที่ทุก ๆ เหมืองถูกแทนที่ กับไม่ใช่ของฉันและทุกไม่ใช่ของฉันถูกแทนที่ด้วยของฉัน

ตัวอย่างเช่นสำหรับตาราง Minesweeper

**1..
34321
*2**1

จำนวนเหมืองทั้งหมดคือ 1 + 3 + 4 + 3 + 2 + 1 + 2 + 1 = 17

ส่วนประกอบของกริดคือ

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

ซึ่งมีจำนวนของฉันทั้งหมด 2 + 4 + 3 + 4 + 4 = 17 อีกครั้ง

เขียนโปรแกรมที่ใช้ในตาราง Minesweeper ตามอำเภอใจในรูปแบบข้อความที่*แสดงถึงการขุดและ1ผ่าน8แสดงจำนวนเหมืองที่อยู่ติดกับเซลล์ที่ไม่ใช่ของฉัน คุณสามารถใช้.หรือ0หรือ (ช่องว่าง) เพื่อแสดงเซลล์ที่ไม่มีเพื่อนบ้านของฉันและตัวเลือกของคุณ คุณสามารถสันนิษฐานได้ว่ากริดอินพุตจะถูกทำเครื่องหมายอย่างถูกต้องนั่นคือเซลล์ที่ไม่ใช่ของฉันจะแสดงจำนวนทั้งหมดของเหมืองที่อยู่ติดกับ orthogonally หรือแนวทแยงมุมในทันที

โปรแกรมของคุณจะต้องพิมพ์สมบูรณ์ของตารางในรูปแบบเดียวกัน (โดยใช้แบบเดียวกัน., 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 และภาษาอื่น ๆ ที่มีข้อ จำกัด บรรทัดใหม่ที่แปลก
งานอดิเรกของ Calvin

คำตอบ:


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

ความคิด

เราเริ่มต้นด้วยการใส่เมทริกซ์อินพุตด้วยหนึ่งแถวและหนึ่งคอลัมน์ของดอกจัน

สำหรับการป้อนข้อมูล

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

Ungolfed ในโปรแกรมทดสอบ:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.