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.