การสร้างกริดเรือกวาดทุ่นระเบิด


14

Minesweeperเป็นเกมลอจิกที่พบในระบบปฏิบัติการส่วนใหญ่ เป้าหมายของเกมคือการกำหนดตำแหน่งของระเบิดบนกริดให้ตัวเลขที่ระบุจำนวนเหมืองรอบ ๆ จุดนั้น

เมื่อกำหนดขนาดกริดและชุดของเหมืองให้สร้างกริด Minesweeper สำหรับชุดของเหมืองนั้น

อินพุต:จำนวนเต็มสองจำนวนที่ระบุขนาดของกริดและจำนวนเต็มที่ไม่ได้กำหนดซึ่งระบุตำแหน่งของทุ่น ตำแหน่งจะได้รับเป็น (ตำแหน่งคอลัมน์ตำแหน่งแถว) และดัชนีจะเริ่มที่แถว 1

เอาต์พุต:ตาราง Minesweeper xหากมีการทำเหมืองแร่รอบบล็อกไม่มีพิมพ์ สำหรับแต่ละแถวใหม่ให้พิมพ์บรรทัดใหม่ *เอาท์พุทโปรดเหมืองทั้งหมดเป็นเครื่องหมายดอกจัน อย่าเว้นช่องว่างระหว่างค่าในแถวเมื่อพิมพ์

กรณีทดสอบ:

อินพุต "5 5 1 3 3 5 2 4":

xxxxx
11xxx
*21xx
2*21x
12*1x

อินพุต "3 4 3 1 1 4 2 3 3 2":

x2*
13*
2*2
*21

รหัสที่สั้นที่สุดชนะ


เราปลอดภัยหรือไม่ที่จะสมมติว่าอินพุตทั้งหมดจะมีจำนวนแถวที่เท่ากัน? คือ5 5 1จะไม่ผ่าน?
Gaffi

@Gaffi: ใช่ อินพุตจะเป็นอินพุตที่ถูกต้องเสมอ
beary605

ข้อมูลจำเพาะในขณะนี้ปล่อยให้ผู้อ่านเพื่ออนุมานจากตัวอย่างที่ตำแหน่งใช้ดัชนีแบบ 1 และแถวที่ 1 อยู่ที่ด้านบนสุด (หรืออย่างน้อยก็ต่อรองได้อย่างแน่นอน)
Peter Taylor

@PeterTaylor: ใช่ ฉันเดาว่าฉันควรทำให้ชัดเจนยิ่งขึ้น
beary605

1
ไม่มีปัญหา. ฉันยังคงมุ่งมั่นที่จะหาวิธีที่จะโกนตัวละครสองตัวออกไปและนำกลับคืนมา :-)
Gareth

คำตอบ:


10

GolfScript 122 98 94 93 91 88 87 85 82 81 80 71

~]2/(\:m;~\:w*,{[.w%)\w/)]:^m\?)42{m{^*~-.*@@-.*+3<},,72or 48+}if}%w/n*

การสาธิตออนไลน์:

กรณีทดสอบ 1: ลิงค์

กรณีทดสอบ 2: ลิงค์


!!{a}{b}ifใช้อักขระหนึ่งตัวเกินความจำเป็น '*'สามารถถูกแทนที่ด้วย42เพราะคุณกำลังใส่มันลงในอาร์เรย์แล้ว stringifying อาร์เรย์ ในทำนองเดียวกันคุณสามารถใช้รหัส ASCII สำหรับอักขระเอาต์พุตอื่นและบันทึกอักขระด้วยorเพื่อจัดการเคสพิเศษ
Peter Taylor

@ PeterTaylor ว้าว!!{a}{b}ifโง่จริงๆจริงๆ :) มันเป็นเรื่องตลกที่ความผิดพลาดระดับสูงที่คุณสามารถทำได้ในขณะที่เน้นรายละเอียด orฉันไม่สามารถคิดออกสิ่งที่คุณหมายโดยใช้
Cristian Lupascu

แน่นอน! กลับมาที่ปัญหาหลังจากเวลาช่วยด้วย เมื่อฉันเขียนการแยกโค้ดสำหรับบล็อก GolfScript ของฉันฉันพบการปรับปรุงจำนวนมาก ด้วยความเคารพต่อคำแนะนำสุดท้ายของฉันหลังจากที่,,คุณมีจำนวน คุณต้องการแปลงเป็นสตริงที่เกี่ยวข้อง (หรือรหัส ASCII) เว้นแต่ว่าจะเป็น 0 ซึ่งในกรณีนี้คุณต้องการ x รหัส ASCII สำหรับตัวเลขนั้นเรียงตามลำดับและเรียกใช้จาก 48 xคือ ASCII 120 ซึ่งคือ 72 + 48 ดังนั้นคุณสามารถทำได้72or 48+และบันทึกอักขระผ่านวิธีการแบบสตริง
Peter Taylor

@PeterTaylor เยี่ยมมาก! ก่อนที่คุณจะตอบฉันจัดการเพื่อลดส่วน.48 120if+นั้น แต่orเคล็ดลับของคุณสั้นกว่าสองตัวอักษร
Cristian Lupascu

@ w0lf Gah! เมื่อฉันคิดว่าฉันได้รับการตอบกลับ!
Gareth

8

J, 124 116 112 101 87 86 85 84 83 82 79 76 75 72 68 อักขระ

'0x'charsub|:1":3 3(+/@,+9*4&{@,);._3[1(}.x)}0$~2+>{.x=._2<\".1!:1[1

พบสิ่งที่ฉันกำลังมองหา - วิธีกำจัดช่องว่าง ( 1":) - และสุดท้ายฉันก็แข่งขันได้ ตอนนี้ฉันแค่ต้องคิดหาชุดปัญหาเหมืองที่ว่างเปล่า

ใช้อินพุตจากคีย์บอร์ด

แก้ไข

เวอร์ชั่นใหม่ทำให้การใช้ผลข้างเคียงของ1":- ตัวเลขขนาดใหญ่กว่า 9 *จะถูกแทนที่ด้วย


ฉันสังเกตเห็นสองสิ่ง: 1.มันพิมพ์ช่องว่างแทน0ไม่ใช่x; 2.ล้มเหลวหากชุดของเหมืองว่างเปล่า (เช่น: 10 10- ควรพิมพ์บอร์ดว่าง 10x10 แต่ส่งคืน|length error)
Cristian Lupascu

แต่มันใช้งานได้ดีดังนั้น +1
Cristian Lupascu

@ w0lf อาฉันยังคงคิดถึงร่างคำถามแรกอยู่ - ในฉบับนั้นxแสดงถึงช่องว่าง ฉันไม่ได้สังเกตว่ามันเปลี่ยนไป อืมไม่เคยคิดเลยว่าเหมืองจะว่างเปล่า ... ข้าจะต้องจัดการกับมันให้ได้
Gareth

ตอนนี้ฉันเห็นว่าคำถามได้ถูกแก้ไขแล้ว ฉันไม่เห็นการแก้ไขแบบเก่า :)
Cristian Lupascu

@ w0lf ขอบคุณ ฉันพบการจัดเรียงใหม่ที่ดีสองสามอย่างที่ช่วยกำจัดวงเล็บเหลี่ยมที่ไม่จำเป็นออกไป ฉันสามารถเห็นที่ว่างหนึ่งอันที่ฉันสามารถถอดออกได้ แต่ฉันคิดว่าฉันค่อนข้าง จำกัด และยังคงมีปัญหารายการเหมืองเปล่า ... :-)
Gareth

2

Mathematica - 247 ตัวอักษร

s[q_] :=
  Module[{d, r},
    d = ToExpression@Partition[Cases[Characters@q, Except@" "], 2];
    r = Rest@d;
    StringJoin @@@ 
    ReplacePart[
    Table[ToString@
       Count[ChessboardDistance[{i, j}, #] & /@ Reverse /@ r, 1], {i,d[[1, 2]]}, 
       {j, d[[1, 1]]}] /. {"0" -> "x"}, # -> "*" & /@ Reverse /@ r] // TableForm]

ตัวอย่าง:

s@"5 5 1 3 3 5 2 4"
s@"3 4 3 1 1 4 2 3 3 2"

เอาท์พุท:

เอาท์พุต

ChessboardDistanceคำนวณว่าแต่ละเซลล์อยู่ห่างจากเหมืองมากน้อยเพียงใดโดยที่ 1 สอดคล้องกับ "ถัดจากเหมือง" ค่าCountของ 1 ให้ผลเป็นจำนวนเซลล์ จากนั้นจะแทรกทุ่นระเบิด (*) ลงในอาร์เรย์


เดวิดยินดีที่ได้พบผู้ใช้Mathematicaคนอื่นที่นี่ ฉันจะดูว่าฉันสามารถเอาชนะสิ่งนี้! :-)
Mr.Wizard

@ Mr.Wizard ฉันจะสนใจดูวิธีแก้ปัญหาของคุณ รู้สึกฟรีเพื่อปรับปรุงในเหมืองถ้าคุณต้องการ
DavidC

2

Mathematica , 140 139 137

Grid[(ListConvolve[BoxMatrix@1,#,2,0]/. 0->x)(1-#)/. 0->"*"]&@Transpose@SparseArray[{##2}->1,#]&@@#~Partition~2&@@#~ImportString~"Table"&

การเขียนในรูปแบบที่อ่านได้ง่ายขึ้น:

"5 5 1 3 3 5 2 4"

ImportString[%, "Table"][[1]] ~Partition~ 2

Transpose @ SparseArray[{##2} -> 1, #]& @@ %

ListConvolve[BoxMatrix@1, %, 2, 0]

(% /. 0 -> x) (1 - %%) /. 0 -> "*" // Grid

สง่างาม! ฉันสารภาพฉันไม่สามารถเข้าใจได้ว่าListCorrelate[BoxMatrix@1, %, 2, 0]มันวิเศษอย่างไร
DavidC

@ David ฉันดีใจที่คุณ (โดยปริยาย) ถามว่าเป็นส่วนที่ฉันชอบ ListCorrelateซ้อนทับเคอร์เนล ( BoxMatrix@1) อย่างมีประสิทธิภาพที่แต่ละตำแหน่งในกริดคูณและให้ผลรวม (ping ฉันในการแชท mma หากคุณต้องการภาพประกอบ) - ความคิดเห็นของคุณเตือนฉันว่าListConvolveควรทำงานที่นี่เช่นกันเพราะมันเป็นภาพสะท้อนในกระจกListCorrelateและเคอร์เนลของฉันมีความสมมาตร ที่จะช่วยฉันตัวละคร :-)
Mr.Wizard

รหัสของคุณสร้างเหมืองอย่างไม่ถูกต้องที่ (5,5) "5 5" ให้ขนาดของกริด
DavidC

@ David ขอบคุณ คุณพูดถูก แต่อยู่ในพื้นที่สีขาวเท่านั้น ฉันอย่างใดหายไปใน2 ##2ฉันจะแก้ไขทันที ปล.: คุณมาสังเกตเรื่องนี้ได้อีกนานแค่ไหน?
Mr.Wizard

อีกคำถามของเรือกวาดทุ่นระเบิดcodegolf.stackexchange.com/questions/10635/ ......ปรากฏขึ้นเมื่อเร็ว ๆ นี้และฉันตัดสินใจที่จะให้โซลูชันของคุณดูอีกครั้ง
DavidC

1

VBA - 298 ตัวอักษร

Sub m(x,y,ParamArray a())
On Error Resume Next:ReDim b(x,y):For i=0 To (UBound(a)-1) Step 2:c=a(i):d=a(i+1):b(c,d)="*":For e=c-1 To c+1:For f=d-1 To d+1:v=b(e,f):If v<>"*" Then b(e,f)=v+1
Next:Next:Next:For f=1 To y:For e=1 To x:v=b(e,f):s=s & IIf(v<>"",v,"x")
Next:s=s & vbCr:Next:MsgBox s
End Sub

การข้ามข้อผิดพลาดด้วยการOn Error Resume Nextบันทึกอักขระบางตัวให้ฉัน แต่ก็ยังไม่ดีเท่าคำตอบอื่น ๆ : - /


1

Python 192 182 180 ตัวอักษร

ฉันสามารถบันทึกบางอย่างถ้าการป้อนข้อมูลถูกคั่นด้วยเครื่องหมายจุลภาค จากนั้นบรรทัดแรกจะเป็นd=input()และความยาว 171 ตัวอักษร
การมีค่าพิกัดของเหมืองเป็น 0 มากกว่า 1 จะช่วยได้เช่นกัน มันมีค่าฉัน 8 ตัวอักษรที่จะเอาชนะ

d=map(int,raw_input().split())
m=zip(d[2::2],d[3::2])
for y in range(d[1]):print"".join((str(sum(abs(a-x-1)|abs(b-y-1)<2for a,b in m)or'x')+'*')[(x+1,y+1)in m]for x in range(d[0]))

เวอร์ชันที่ไม่ถูกปรับแต่ง:

d=map(int,raw_input().split())          # Read whitespace terminated numbers into a list of numbers
xsize,ysize = d[:2]                     # The first two numbers are the board size
mines=zip(d[2::2],d[3::2])              # Convert items 3,4,5,6... to pairs (3,4),(5,6) representine mine coordinates

def dist(point,mine):                   # Distance between point (0-based coordinates) and mine (1-based coordinates)
    dx = abs(mine[0]-(point[0]+1))
    dy = abs(mine[1]-(point[1]+1))
    return dx | dy                      # Should be max(dx,dy), but this is close enough. Wrong for d>=2, but returns >=2 in this case.

for y in range(ysize):                  # Print lines one by one
    line_chars = [
        (str(
            sum(dist((x,y),(a,b))<2 for a,b in mines)   # Number of neighboring mines
            or 'x'                                  # 'x' instead of 0
        )
        +'*')                                       # For a single neighbor, we get "1*"
        [(x+1,y+1)in mines]                         # If a mine, get the '*', else the neighbor number
        for x in range(xsize)
    ]
    print "".join(line_chars)

1

สกาลา 280 ตัวอักษร

val n=readLine split" "map{_.toInt}
val b=Array.fill(n(1),n(0))(0)
n drop 2 sliding(2,2)foreach{case Array(x,y)=>b(y-1)(x-1)=9
for{i<-(x-2 max 0)to(x min n(0)-1);j<-(y-2 max 0)to(y min n(1)-1)}b(j)(i)+=1}
b.map{r=>println(r.map{case 0=>"x"case x if x>8=>"*"case x=>""+x}mkString)}

0

C ++ - 454 ตัวอักษร

นี่แย่กว่าคำตอบ VBA ของฉันซึ่งอาจหมายความว่าฉันไม่รู้ว่าฉันกำลังทำอะไรใน C ++ อย่างไรก็ตามฉันพยายามที่จะสร้างสิ่งที่ฉันรู้ของ C ++ ดังนั้นนี่คือ หากใครมีข้อเสนอแนะสำหรับการปรับปรุงฉันจะขอบคุณที่ได้ยินพวกเขา!

#define Z for(int i=
#define Y for(int j=
#define X d[i][j]
#define W Z 0;i<x;i++){
#define V Y 0;j<y;j++){
#define U cout<<
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
int main(){using namespace std;int x,y,a,b;cin>>y>>x;string c[x][y];int d[x][y];W V X=0;}}while(cin>>b>>a){c[--a][--b]="*";Z a-1;i<=a+1;i++){Y b-1;j<=b+1;j++){if(x>i&&i>=0&&y>j&&j>=0){X=X+1;}}}}W V if(c[i][j]!="*"){if(X>0){U X;}else{U"x";}}else{U"*";}}U endl;}return 0;}

return 0คุณไม่จำเป็นต้อง และคุณสามารถ#include<cstdio>, #include<cstdlib>. คุณสามารถลบสองรายการนี้ได้ด้วย! ยิ่งไปกว่าusing name.....นั้นยาวเกินไปคุณสามารถใช้std::cin, std::cout, std::stringแทนได้
เรย์

@ Ray Aye คุณถูกต้องเกี่ยวกับเนมสเปซ ... มันเป็นเวลานานแล้วที่ข้ารวมมันเข้าด้วยกัน แต่ฉันคิดว่าฉันมีstd::โทรศัพท์มากกว่าที่จะทำให้มันคุ้มค่ามากขึ้น (ฉันคิดว่าอีกอย่างหนึ่งstringจะทำได้ ) ขอบคุณสำหรับข้อมูลเกี่ยวกับ#includeสายเช่นกัน ฉันไม่ใช่ผู้เชี่ยวชาญ C ++ ;-)
Gaffi

0

C # (691 ตัวอักษร)

using System;namespace M{class P{static char C(char[][] g,int r,int c){int n=0;for(int i=r-1;i<=r+1;i++){if(i<0||i>=g.Length)continue;for(int j=c-1;j<=c+1;j++){if((j<0||j>=g[0].Length)||(i==r&&j==c))continue;if(g[i][j]=='*')n++;}}return n==0?'x':(char)(n+48);}static char[][] G(int[] p){char[][] r=new char[p[1]][];for(int i=0;i<r.Length;i++)r[i]=new char[p[0]];for(int i=2;i<p.Length;){r[p[i+1]-1][p[i]-1]='*';i+=2;}for(int i=0;i<r.Length;i++)for(int j=0; j<r[0].Length;j++)if(r[i][j]!='*')r[i][j]=C(r,i,j);for(int i=0;i<r.Length;i++){for(int j=0;j<r[0].Length;j++)Console.Write(r[i][j]);Console.WriteLine();}return r;}static void Main(string[] args){G(new int[]{3,4,3,1,1,4,2,3,3,2});}}}

เวอร์ชันที่ไม่ใช่กอล์ฟ:

using System;
namespace M
{
    class P
    {
        static char C(char[][] g, int r, int c)
        {
            int n = 0;
            for (int i = r - 1; i <= r + 1; i++)
            {
                if (i < 0 || i >= g.Length) continue;
                for (int j = c - 1; j <= c + 1; j++)
                {
                    if ((j < 0 || j >= g[0].Length) || (i == r && j == c)) continue;
                    if (g[i][j] == '*') n++;
                }
            }
            return n == 0 ? 'x' : (char)(n + 48);
        }

        static char[][] G(int[] p)
        {
            char[][] r = new char[p[1]][];
            for (int i = 0; i < r.Length; i++)
                r[i] = new char[p[0]];
            for (int i = 2; i < p.Length; )
            {
                r[p[i + 1] - 1][p[i] - 1] = '*';
                i += 2;
            }
            for (int i = 0; i < r.Length; i++)
                for (int j = 0; j < r[0].Length; j++)
                    if (r[i][j] != '*') r[i][j] = C(r, i, j);
            for (int i = 0; i < r.Length; i++)
            {
                for (int j = 0; j < r[0].Length; j++)
                    Console.Write(r[i][j]);
                Console.WriteLine();
            } return r;
        } 
        static void Main(string[] args) 
        { 
            G(new int[] { 3, 4, 3, 1, 1, 4, 2, 3, 3, 2 }); 
        }
    }
}

0

K, 175

f:{g::(y;x)#(x*y)#"x";{.[`g;x;:;"*"]}@'-1+|:'(_(#z)%2;2)#z;{if[~"0"~z;$["x"=g .(x;y);.[`g;(x;y);:;z];]]}.'i,'$s:+/'{"*"=g . x}''{,/((x-1)+!3),\:/:(y-1)+!3}.'i:,/(!x),\:/:!y;g}

.

k)f[5;5;1 3 3 5 2 4]
"xxxxx"
"11xxx"
"*21xx"
"2*21x"
"12*1x"
k)f[3;4;3 1 1 4 2 3 3 2]
"x2*"
"13*"
"2*2"
"*21"

0

ECMAScript 2019 (Javascript สมัยใหม่) - 116 ไบต์

m.map((r,i)=>r.map((c,j)=>c=='X'?c:[,...m].splice(i,3).map(r=>[,...r].splice(j,3)).flat().filter(v=>v=='X').length))

รุ่นที่ไม่ได้ถูกดัดแปลง

m.map(
  (r,i) => r.map(
    (c,j) => c=='X' ? c :
      [,...m].splice(i,3).map(r=>[,...r].splice(j,3)).flat().filter(v=>v=='X').length
  )
)

โซลูชันนี้ไม่ยึดติดกับรูปแบบอินพุต / เอาต์พุตอย่างเคร่งครัด แต่แสดงให้เห็นถึงอัลกอริธึมที่กระชับ

ตัวอย่าง: https://gist.github.com/missinglink/ee02084cfb523665e8c9d34c24f01537


0

brainfuck , 1001 896 ไบต์

,[>,]-[<]>>++[<[<+<+>>-]<[>+<-]>[>]>[>>[>>>>]>]++[-<+]-[<]<++[>>[>]>[>>[>>>>]>]+<++[-<+]-[<]<-]>>>-]>[>]>[>>[>>>>]<<<->>>>]+[-<+]-[<]>>[[>]>--<<[<]>>[[>]+[->+]+>>[>>>>]>--<+[-<+]-[<]>>-]>[>]+[->+]+>>--<+[-<+]-[<]<[>>[>]+[->+]+>>>>--<+[-<+]-[<]<-]>>[>]+[->+]+>++[-<+]-[<]>>]>[+>>[>>>>]>]<<<<<[<<<<]>>-<+[-<+]>>>>[>>>>]>[-[--<<<<<[<<<<]>>>>--[>>>>]>>>[>>>>]>>>--<+[-<+]++>>>>>>[>[<--<<<[-[>>>>>>+<<<<<+<-]>+<]>[<+>-]>>>>+++[<<<+[-<+]->[-[+[->+]->>>+<<<<+[-<+]->>+<-]>+<]>[<+>-]+[->+]->>-[<<<+[-<+]+>>>>-->+[->+]->>[<<<+>>>-]]<<<[>>>+<<<-]>>>]<<<+[-<+]+<<<<-->+[->+]->>>>>[-[<<+>>>+<-]>+<]>[<+>-]<<<<+++[+[->+]->[-[<<+[-<+]->>>++[->+]->>+<-]>+<]>[<+>-]<<<+[-<+]->>-[+[->+]+>>>>--<+[-<+]->>[<<<+>>>-]]<<<[>>>+<<<-]>>>]+[->+]+<<<<--<+[-<+]->-[>>[-]<<++++++[>++++++<-]>.[-]+<<<]<[>>>[<++++++[>++++++++<-]>.[-]<]<<<[<++++++++[<+++++++++++>-]<.[-]>]<]>>>>+<<++>]>[<+>-]>>]->+[->+]++[-<+]++++++++++.[-]]>]

ลองออนไลน์! หรือลองใช้เวอร์ชั่นเก่าที่มีอินพุตจำนวนเต็ม

วันหนึ่งของการเขียนโปรแกรมและการแก้ไขข้อผิดพลาดสามวัน ^^

สิ่งนี้ใช้โค้ดบางส่วนของ Game Of Life ของฉัน แทนที่จะนับเซลล์ที่มีชีวิตสิ่งนี้นับเป็นระเบิด เนื่องจากอินพุตเป็น codepoints ได้รับอนุญาตโดยกฎทั่วไปจึงใช้แทนการเป็นจำนวนเต็ม "สามารถอ่านได้"

[
Data: colCount, rowCount, {BombCoordinates}, -1 (start of arrays/"soa"), 0, {RowData}
BombCoordinates: bombCol, bombRow
RowData: rowFlag, 0, {CellData}, 0
CellData: cellFlag, cellState, temp, bombCount

rowFlag: 0=EOF, 1=inactive (all cells inactive), 2=active
cellFlag: -1=marker for finding cell (cell to be counted or current cell), 0=EOF, 1=normal
cellState: 0=inactive, 1=normal, 2=bomb
temp: helper to exit if-statements
bombCount: count of neighbor cells that contain bombs
inactive cells or rows will not be printed. They are only used for an easier counting algorithm.
]

#### input values as codepoints ####
,[>,]

#### setup two dimensional array ####
-                   set soa
[<]>>               go to rowCount
++                  add two inactive rows
[                   for each row
  <[<+<+>>-]          copy colCount two times to the next left cells
  <[>+<-]             move one of the copies back to the original cell
  >[>]>[>>[>>>>]>]    go to new row position
  +                   set rowFlag (only 1 while initialization)
  +[-<+]-[<]<         go to copy of colCount
  ++                  add two inactive cells per row
  [                   for each col
    >>[>]>[>>[>>>>]>]   go to new cell position
    +<+                 set cellFlag and cellState = normal
    +[-<+]-[<]<         return to copy of colCount
    -                   decrement
  ]
  >>>-                decrement rowCount
]

#### setup active/inactive flags of cells ####
>[>]>[              for each row
  >>[>>>>]<<<-        set last cell inactive
  >>>>                go to next row
]

#### mark the bombs ####
+[-<+]-[<]>>        go to bombRow
[                   while there are bombRow values left
  [>]>--              set rowFlag of first row = neg 1 (as a marker)
  <<[<]>>             return to bombRow
  [                   for each bombRow
    [>]+[->+]           find first marker after soa
    +                   set rowFlag = 1
    >>[>>>>]>           go to next rowFlag
    --                  make a marker of it
    <+[-<+]-[<]>>       return to bombRow
    -                   decrement
  ]
  >[>]+[->+]          go to selected rowFlag
  +                   set rowFlag = 1
  >>--                set cellFlag of first cell = marker
  <+[-<+]-[<]<        go to bombCol
  [                   for each bombCol
    >>[>]+[->+]         find first marker after soa
    +                   set cellState = 1
    >>>>                go to next cellState
    --                  set it neg 1 (as a marker)
    <+[-<+]-[<]<        return to bombCol
    -                   decrement
  ]
  >>[>]+[->+]         find first marker after soa
  +                   set cellFlag = normal
  >+                  set cellState = bomb
  +[-<+]-[<]>>        go to next bombRow
]

#### setup active/inactive flags of rows ####
>[                  for each row
  +                   set rowFlag = 2 (active)
  >>[>>>>]>           go to next rowFlag
]
<<<<<[<<<<]>>-      set rowFlag of last row = 1 (inactive)

#### count bombs in neighborhood ####
<+[-<+]>>>>[>>>>]>  go to second row
[                   for each row
  -[                  if active
    --                  set it neg 1 (marker)
    <<<<<[<<<<]>>>>     go to cellFlag of first cell in previous row
    --                  set it neg 1 (marker)
    [>>>>]>>>[>>>>]>>>  go to cellFlag of first cell in next row
    --                  set it neg 1 (marker)
    <+[-<+]             return to rowFlag
    ++                  set rowFlag = 2 (active)

    >> >>>>[            for each cell (starting with second)
      >[                  if active
        <--                 set cellFlag = neg 1 (marker)

        # check if cell to the left is a bomb
        < <<                go to cellState of previous cell
        [                   if active
          -[                  if bomb
            >> >>>>+            increment bombCount
            <<<< <              go back to checked cell
            +                   set temp = 1
            <-                  set cellState = 0 to exit if
          ]
          >+<                 increment temp
        ]
        >[<+>-]             restore cellState

        # check if cells on top are bombs
        > >>>               go to temp of current cell
        +++[                do three times
          <<<+[-<+]-          go to next marker to the left
          >[                  if active
            -[                  if bomb
              +[->+]-             return to current cell
              >>>+                increment bombCount
              <<<<+[-<+]->        return to counted cell
              >+                  set temp = 1
              <-                  set cellState = 0 to exit if
            ]
            >+<                 increment temp
          ]
          >[<+>-]             restore cellState
          +[->+]-             go to current cell
          >>-                 decrement temp
          [                   if temp != 0
            <<<+[-<+]           go to marked cell
            +                   set cellFlag = normal
            >>>>--              set cellFlag of next cell = marker
            >+[->+]->>          return to currentCell temp
            [<<<+>>>-]          store value of temp in previous cell bombCount (to exit if)
          ]
          <<<[>>>+<<<-]>>>    restore temp value
        ]
        <<<+[-<+]           go to marked cell
        +                   set cellFlag = normal
        <<<<--              set previous cellFlag = marker
        >+[->+]-            return to current cell

        # check if cell to the right is a bomb
        >>> >>              go to cellState of next cell
        [                   if active
          -[                  if bomb
            <<+                 increment bombCount
            >>>                 go back to checked cell
            +                   set temp = 1
            <-                  set cellState = 0 to exit if
          ]
          >+<                 increment temp
        ]
        >[<+>-]             restore cellState

        # check if cells below are bombs
        <<< <               go to currentCell temp
        +++[                do three times
          +[->+]-         go to next marker to the right
          >[              if active
            -[              if bomb
              <<+[-<+]-       return to current cell
              >>>+            increment bombCount
              +[->+]->        return to counted cell
              >+              set temp = 1
              <-              set cellState = 0 to exit if
            ]
            >+<             increment temp
          ]
          >[<+>-]         restore cellState
          <<<+[-<+]-      go to current cell
          >>-             decrement temp
          [               if temp != 0
            +[->+]          go to marked cell
            +               set cellFlag = normal
            >>>>--          set cellFlag of next cell = marker
            <+[-<+]->>      return to currentCell temp
            [<<<+>>>-]      store value of temp in previous cell bombCount (to exit if)
          ]
          <<<[>>>+<<<-]>>>restore temp value
        ]
        +[->+]          go to marked cell
        +               set cellFlag = normal
        <<<<--          set previous cellFlag = marker
        <+[-<+]-        return to current cell

        # print
        >-[             if bomb
          >>[-]<<         delete bombCount
          ++++++[>++++++<-]>.print "*"
          [-]+            set temp = 1
          <<<             use previous cell bombCount as exitIf
        ]
        <[              else
          >>>[            if bombCount != 0
            <++++++[>++++++++<-]add 48 to get ascii number
            >.              print
            [-]             set number = 0 (for use as exitIf from next cell)
            <               go to temp for exit if
          ]
          <<<[            else
            <++++++++[<+++++++++++>-]<.print "X"
            [-]             delete value (for use as exitIf from next cell)
            >               go to exitIf
          ]
          <               go to exitElse
        ]
        > >>>+          increment temp
        <<++>           set cellFlag = normal
      ]
      >[<+>-]         restore cellState
      >>              go to cellFlag of next cell
    ]
    -               set marker
    >+[->+]         go to next marker
    +               set cellFlag = normal
    +[-<+]          return to marker
    +++++ +++++.[-] print newline
  ]
  >               go to next row
]

0

นี่คือจุดเริ่มต้นของการแก้ปัญหา Brainfuck มันควรจะอ่านง่ายด้วยความคิดเห็นการเยื้องและสแต็ค ( @บ่งชี้ตัวชี้สแต็ค):

>>,>,  |0|x|@y| Pop the first two characters
[>>+<<-]>>  |0|x|0|0|@y|
[<<+>+>-]<  |0|x|@y|y|0|
[  |0|x|y|@y|
  [>>+<<-]< |0|x|@y|0|0|y|
  [>>+<<-]< |0|@x|0|0|y|y|
  [>>+<<-]>> |0|0|0|@x|y|y|
  [<<+>+>-]<<  |0|@x|x|0|y|y|
  [>>+<<-]> |0|0|@x|x|y|y|
  [<< |@0|0|x|x|y|y|
    ++++++++[>+++++++++++<-]>>>>> |0|88|x|x|@y|y|
    [>+<-]< [>+<-]< [>+<-]< [>+<-]< |0|@88|0|x|x|y|y|
    [<+>-]>>-  |88|0|0|@x_1|x|y|y|
  ]<< |x x's|@0|0|0|x|y|y|
  ++++++++++>>> x's|\n|0|0|@x|y|y|
  [<+>-]>  x's|\n|0|x|0|@y|y|
  [<+>-]>  x's|\n|0|x|y|0|@y|
  [<+>-]<- |x 88s|0|x|@y_1|y|
] |@x 88s|0|x|y|

อย่างไรก็ตามมันยังไม่เสร็จสมบูรณ์และฉันเริ่มสงสัยว่าวิธีการของฉันเหมาะสมหรือไม่ จนถึงตอนนี้พิจารณาเพียงอักขระอินพุตสองตัวแรกและพิมพ์ตาราง Xs เช่น "43" จะให้คุณ:

XXXX
XXXX
XXXX

ฉันชอบที่จะดูว่าคนอื่นมีสิ่งที่ต้องใช้และสามารถแก้ไขปัญหานี้ได้ใน Brainfuck หรือไม่


สิ่งที่ดีที่สุดในใจของฉันก็คือการจัดการกับ BrainFuck คุณกำลังกำหนดเป้าหมายรายละเอียดของล่าม? เช่นเดียวกับเซลล์ 8 บิตหรืออะไร ฉันชอบที่จะเห็นสิ่งนี้เสร็จสิ้น
captncraig

ฉันคิดว่ามันค่อนข้างอิสระจากผู้บุกรุกที่เฉพาะเจาะจง? ตราบใดที่ตัวเลขไม่ใหญ่เกินไป
paldepind

การทำงานเพื่อวิญญาณ แต่แน่นอนว่ามันจะยากกว่าที่เคยเป็นในตอนแรกใน Brainfuck
captncraig

ฉันใช้เวลาไม่กี่วันที่ผ่านมาเพื่อสร้างรหัส brainfuck สำหรับสิ่งนี้
Dorian
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.