Generowanie siatek Saperów


14

Saper to gra logiczna, którą można znaleźć w większości systemów operacyjnych. Celem gry jest ustalenie, gdzie znajdują się miny na siatce, z podanymi liczbami wskazującymi liczbę min wokół tego miejsca.

Biorąc pod uwagę rozmiar siatki i zestaw min, wygeneruj siatkę Saper dla tego zestawu min.

Dane wejściowe: dwie liczby całkowite wskazujące rozmiar siatki i nieokreślona liczba liczb całkowitych wskazujących pozycje kopalni. Pozycje zostaną podane jako (pozycja kolumny, pozycja wiersza), a indeksy zaczną się od wiersza 1.

Dane wyjściowe: siatka Saper. Jeśli wokół bloku nie ma min, wydrukuj x. Dla każdego nowego wiersza wydrukuj nowy wiersz. Proszę wypisać wszystkie kopalnie jako gwiazdkę *. Podczas drukowania nie należy pozostawiać spacji między wartościami w wierszu.

Przypadki testowe:

Wpisz „5 5 1 3 3 5 2 4”:

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

Wpisz „3 4 3 1 1 4 2 3 3 2”:

x2*
13*
2*2
*21

Najkrótszy kod wygrywa.


Czy możemy bezpiecznie założyć, że wszystkie dane wejściowe będą miały parzystą liczbę argumentów? tzn. 5 5 1nigdy nie zostanie przekazany?
Gaffi

@Gaffi: Tak. Dane wejściowe zawsze będą prawidłowe.
beary605

Specyfikacja obecnie pozostawia czytelnikowi wywnioskować z przykładów, że pozycje używają indeksów 1 i że wiersz 1 znajduje się na górze. (A może to ostatnie podlega negocjacji?)
Peter Taylor

@PeterTaylor: Tak. Chyba powinienem to uczynić bardziej oczywistym.
beary605

1
Nie ma problemu. Nadal jestem zdeterminowany, aby znaleźć sposób, aby zgolić kilka postaci i odzyskać prowadzenie. :-)
Gareth

Odpowiedzi:


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*

Dema online:

Przypadek testowy 1: link

Przypadek testowy 2: link


!!{a}{b}ifużywa jednej postaci więcej niż to konieczne. '*'można zastąpić, 42ponieważ umieszcza się go w tablicy, a następnie strituje tablicę. Podobnie możesz użyć kodów ASCII dla innych znaków wyjściowych i zapisać znak w orcelu obsługi specjalnego przypadku.
Peter Taylor

@PeterTaylor Wow, !!{a}{b}ifbył naprawdę głupi. :) To zabawne, jakie błędy na wysokim poziomie możesz popełnić, koncentrując się na szczegółach. Nie mogę zrozumieć, o co ci chodziło or.
Cristian Lupascu

W rzeczy samej! Pomaga też powrót do problemu po jakimś czasie. Kiedy napisałem kilka fragmentów kodu dla mojego bloga GolfScript, zauważyłem znaczną poprawę. W odniesieniu do mojej ostatniej sugestii, po tym, jak ,,masz numer. Chcesz przekonwertować go na odpowiedni ciąg (lub kod ASCII), chyba że ma wartość 0, w którym to przypadku chcesz x. Kody ASCII dla cyfr są sekwencyjne i biegną od 48. xto ASCII 120, czyli 72 + 48. Możesz więc zrobić 72or 48+i zapisać znak w oparciu o podejście łańcuchowe.
Peter Taylor

@PeterTaylor Świetnie! Zanim odpowiedziałeś, udało mi się zredukować tę część do .48 120if+, ale twoja orsztuczka jest o dwa znaki krótsza.
Cristian Lupascu

@ w0lf Gah! Właśnie kiedy myślę, że odzyskałem prowadzenie!
Gareth

8

J, 124 116 112 101 87 86 85 84 83 82 79 76 75 72 68 znaków

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

Znalazłem to, czego szukałem - sposób na pozbycie się spacji ( 1":) - i wreszcie jestem konkurencyjny. Teraz muszę tylko znaleźć problem z pustym zestawem min.

Pobiera dane z klawiatury.

Edytować

Nowa wersja wykorzystuje efekt uboczny 1":- liczby większe niż 9 są zastępowane przez *.


Zauważyłem dwie rzeczy: 1. Drukuje zamiast spacji 0, nie x; 2. Nie powiedzie się, jeśli zestaw min jest pusty (np .: 10 10- powinien wydrukować pustą tablicę 10x10, ale wraca |length error)
Cristian Lupascu

Ale w przeciwnym razie to działa, więc +1.
Cristian Lupascu

@ w0lf Ach, wciąż myślałem o pierwszej wersji pytania - w tej wersji xpo prostu reprezentowałem spację. Nie zauważyłem, że to się zmieniło. Hmm, nigdy nie myślałem, że zestaw min będzie pusty ... Muszę nad tym popracować.
Gareth

teraz widzę, że pytanie zostało zredagowane. Nie widziałem starej wersji. :)
Cristian Lupascu

@ w0lf Thanks. Znalazłem kilka dobrych przegrupowań, które pomogły pozbyć się niepotrzebnych wsporników. Widzę jedno miejsce, które mógłbym usunąć, ale podejrzewam, że jestem prawie na granicy. I wciąż jest problem z pustą listą kopalń ... :-)
Gareth

2

Mathematica - 247 znaków

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]

Przykłady:

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

Wynik:

wynik

ChessboardDistanceoblicza, jak daleko każda komórka jest od kopalni, gdzie 1 odpowiada „obok kopalni”. Z Count1 daje numer komórki. Następnie miny (*) są wstawiane do tablicy.


David, miło widzieć tutaj innego użytkownika Mathematica . Zobaczę, czy uda mi się to pokonać! :-)
Mr.Wizard

@ Mr.Wizard Będę zainteresowany zobaczeniem twojego rozwiązania. Jeśli chcesz, możesz ulepszyć moje.
DavidC

2

Mathematica , 140 139 137

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

Pisząc to w bardziej czytelnej formie:

"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

Elegancki! Przyznaję, że nie rozumiem, jak ListCorrelate[BoxMatrix@1, %, 2, 0]działa jego magia.
DavidC

@David Cieszę się, że (domyślnie) zapytałeś, bo to moja ulubiona część. ListCorrelateskutecznie nakłada jądro ( BoxMatrix@1) na każdą pozycję w siatce, mnoży i daje sumę. (pinguj mnie na czacie mma, jeśli chcesz ilustrację) - Twój komentarz przypomina mi, że ListConvolvetutaj też powinien działać, ponieważ jest to rodzaj lustrzanego odbicia, ListCorrelatea moje jądro jest symetryczne. To uratuje mi postać. :-)
Mr.Wizard

Twój kod niepoprawnie generuje minę (5,5). „5 5” podaje wymiary siatki.
DavidC

@David Thanks. Masz rację, ale tylko w wersji białej przestrzeni; I jakoś stracił 2in ##2. Naprawię to teraz. ps: Jak to zauważyłeś po tak długim czasie?
Mr.Wizard

Niedawno pojawiło się kolejne pytanie trałowca, codegolf.stackexchange.com/questions/10635/… , i postanowiłem ponownie przeanalizować twoje rozwiązanie.
DavidC

1

VBA - 298 znaków

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

Pomijanie błędów w On Error Resume Nextzapisaniu mi niektórych postaci, ale wciąż nie jest tak dobre, jak niektóre inne odpowiedzi. : - /


1

Python, 192 182 180 znaków

Mógłbym zapisać trochę, gdyby dane wejściowe były oddzielone przecinkami. Wtedy byłaby pierwsza linia d=input()i długość 171 znaków.
Pomogłoby także współrzędne kopalni oparte na 0 zamiast na 1. Pokonanie mnie kosztowało mnie 8 znaków.

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]))

Wersja bez golfa:

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

Scala, 280 znaków

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 znaków

To gorsze niż moja odpowiedź VBA, co prawdopodobnie oznacza, że ​​nie wiem, co robię w C ++. Jednak staram się bazować na tym, co wiem o C ++, więc oto jest. Jeśli ktoś ma jakieś sugestie dotyczące ulepszeń, byłbym wdzięczny za ich wysłuchanie!

#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;}

nie musisz return 0. I można #include<cstdio>, #include<cstdlib>. Możesz nawet usunąć te dwa elementy! Co więcej, using name.....jest za długi, można go użyć std::cin, std::cout, std::stringzamiast tego.
Ray

@Ray Aye, masz rację co do przestrzeni nazw ... Minęło trochę czasu, odkąd to połączyłem, ale myślę, że miałem więcej std::połączeń, które sprawiłyby, że było to bardziej opłacalne (myślę, że jeszcze jeden stringzrobiłby to ). Dziękuję również za informacje o #includeliniach. Nie jestem ekspertem od C ++. ;-)
Gaffi

0

C # (691 znaków)

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});}}}

Wersja bez gry w golfa:

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 (Modern Javascript) - 116 bajtów

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))

wersja bez golfa

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
  )
)

to rozwiązanie nie ściśle przestrzega formatu wejścia / wyjścia, ale pokazuje zwięzły algorytm.

przykład: https://gist.github.com/missinglink/ee02084cfb523665e8c9d34c24f01537


0

brainfuck , 1001 896 bajtów

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

Wypróbuj online! lub wypróbuj starą wersję z liczbą całkowitą

Jeden dzień programowania i trzy dni naprawy błędów ^^

Wykorzystuje to kilka części mojego kodu Game of Life. Zamiast zliczać żywe komórki, liczy się bomby. Ponieważ ogólne zasady dopuszczają wprowadzanie jako punkty kodowe, wykorzystuje je zamiast liczb całkowitych „czytelnych”.

[
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

To początek rozwiązania Brainfuck. Powinien być dość czytelny z wcięciami i komentarzami stosu ( @wskazuje wskaźnik stosu):

>>,>,  |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|

Jest jednak daleki od ukończenia i zaczynam wątpić, czy moje podejście jest optymalne. Jak dotąd bierze pod uwagę tylko dwa pierwsze znaki wejściowe i drukuje tabelę Xs. Na przykład „43” daje:

XXXX
XXXX
XXXX

Chciałbym zobaczyć, czy ktoś inny ma to, czego potrzeba i jest w stanie rozwiązać ten problem w Brainfuck.


Optymalność nie ma dla mnie żadnego znaczenia w przypadku BrainFuck. Na jakie specyfikacje tłumacza jesteś kierowany? Jak 8-bitowe komórki czy co? Chciałbym zobaczyć, jak to się skończy.
captncraig

Myślę, że jest to dość niezależne od konkretnego tłumacza? O ile liczby nie są nieuzasadnione duże.
paldepind

Praca nad soulution, ale oczywiście zawsze okazuje się trudniejsza niż się wydaje w Brainfuck.
captncraig

Ostatnie kilka dni spędziłem na zbudowaniu działającego kodu do pieprzenia mózgów.
Dorian
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.