Füllen Sie die Minesweeper-Hinweise aus

54

Minesweeper ist ein beliebtes Puzzlespiel, bei dem Sie herausfinden müssen, welche Kacheln "Minen" sind, ohne auf diese Kacheln zu klicken. Jedes Plättchen ist entweder eine Mine (dargestellt durch *) oder ein Hinweis, dh eine Zahl von 0 bis 8, die angibt, wie viele der 8 benachbarten Plättchen Minen sind. Ihre Aufgabe heute ist es, eine Tafel mit den Minen zu nehmen und alle Hinweise einzugeben. Schauen Sie sich zum Beispiel das folgende 5x4-Brett mit 5 Minen an:

 *  
*  * 
  *  
    *

Nachdem Sie die Hinweise eingegeben haben, sieht das Board folgendermaßen aus:

2*211
*33*1
12*32
0112*

Einzelheiten

Sie müssen entweder ein Vollprogramm oder eine Funktion schreiben, die ein Zeichenraster nur mit Leerzeichen und Sternchen aufnimmt und ein anderes Raster ausgibt, in dem jedes Leerzeichen durch die Anzahl der benachbarten Minen (Sternchen) ersetzt wird. Alle diese Formate sind für Ihre Raster akzeptabel:

  • Eine Zeichenfolge mit Zeilenumbrüchen

  • Eine 2D-Liste von Zeichen / Einzelzeichenfolgen

  • Eine Liste von Zeichenfolgen

Sie können davon ausgehen, dass das Gitter mindestens 1x1 beträgt, es können jedoch auch alle Minen oder alle Felder sein.

Das Eingaberaster wird immer mit der entsprechenden Anzahl von Leerzeichen aufgefüllt. Wie üblich ist dies , daher gelten Standardlücken und die kürzeste Antwort in Bytes gewinnt!

Beispiel IO

Damit Sie das Leerzeichen sehen können, zeige ich alle Beispiel-E / A mit eckigen Klammern.

Input:
[    * ]
[*     ]
[      ]
[      ]
[  **  ]
[ *  * ]

Output:
[1101*1]
[*10111]
[110000]
[012210]
[12**21]
[1*33*1]

Input:
[****]
[****]

Output:
[****]
[****]

Input:
[   ]
[   ]
[   ]
[   ]

Output:
[000]
[000]
[000]
[000]

Input:
[*   ]
[**  ]
[    ]
[   *]

Ouput:
[*310]
[**10]
[2221]
[001*]

Input:
[**    ]
[*    *]
[  *   ]
[      ]
[*     ]
[****  ]

Output:
[**1011]
[*4211*]
[12*111]
[121100]
[*43210]
[****10]

Input:
[     *    ]
[        * ]
[     *    ]
[**   ***  ]
[      *** ]
[          ]
[       ** ]
[  * *     ]
[*      ** ]
[       ** ]

Output:
[00001*1111]
[00002221*1]
[22102*4321]
[**102***31]
[221013***1]
[0000013542]
[0112111**1]
[12*2*12442]
[*212112**2]
[1100002**2]
DJMcMayhem
quelle
2
Zu Ihrer Information, ich habe alle Beispiel-E / A von Hand erstellt, daher ist es möglich, dass einige kleinere Fehler enthalten sind. Lassen Sie mich wissen, wenn etwas nicht stimmt, und ich werde versuchen, es so schnell wie möglich zu beheben.
DJMcMayhem
1
Kann das Gitter nicht quadratisch sein?
Ton Hospel
Können die Minen von einem anderen Charakter dargestellt werden?
Akangka
@ChristianIrwan Nein, die Minen werden immer ein Sternchen sein.
DJMcMayhem

Antworten:

21

MATL , 18 17 Bytes

Vielen Dank an @ mbomb007 für eine Korrektur in der Eingabe von Testfall 6

32>t3Y6Z+-6b(48+c

Die Eingabe ist ein 2D-Zeichen-Array im Format

[' *   '; '*  * '; '  *  '; '    *']

Probieren Sie es online!

Testfälle: 1 , 2 , 3 , 4 , 5 , 6 .

Erläuterung

32>      % Input 2D char array implicitly. Transform it into a 2D logical
         % array with asterisk replaced by true and space by false
t        % Duplicate
3Y6      % Push [1 1 1; 1 0 1; 1 1 1]. This defines the neighbourhood
Z+       % 2D convolution, keeping size. Gives the number of neighbouring
         % mines for each position
-6       % Push -6
b        % Bubble up in stack
(        % Assign -6 to the entries indicated by the logical array, i.e.
         % to the positions that originally contained asterisks 
48+      % Add 48. This transforms each number of neighbouring mines
         % into its ASCII code, and -6 into 42 (ASCII code of asterisk)
c        % Convert to char. Display implicitly
Luis Mendo
quelle
1
Beeindruckend. Das ist beeindruckend.
BladorthinTheGrey
2
Wenn ich Testfall 6 bekomme, würde es mich verärgern, das eigentliche Spiel zu spielen.
Magic Octopus Urn
Warum? Testfall 6 erscheint am realistischsten.
WBT
@carusocomputing Wenn ich Testfall 2 bekomme, würde mich das viel mehr verärgern. : P
DJMcMayhem
10

JavaScript (ES6), 114 96 Bytes

a=>a.map((s,i)=>s.replace(/ /g,(_,j)=>g(k=>(s=a[i+k])?g(k=>s[j+k]>' '):0)),g=f=>f(-1)+f(0)+f(1))

Bearbeiten: 18 Bytes dank einer Idee von @ETHproductions gespeichert.

Neil
quelle
Ich denke, Sie können eine Menge sparen, indem Sie eine Funktion definieren, die überprüft, ob ein Index kein Leerzeichen enthält:a=>a.map((s,i)=>s.replace(/ /g,(_,j)=>a.slice(i-!!i,i+2).reduce((t,s)=>t+(q=i=>s[i+j]>' ')(-1)+q(0)+q(1),0)))
ETHproductions
@ETHproductions Ich habe Ihre Idee auf die Spitze getrieben ... Normalerweise kann ich keine Funktionsparameter schreiben!
Neil
7

R 127 112 Bytes

function(M){a=nrow(M);for(i in seq(M))if(M[i]!="*")M[i]=sum(M[pmax(i+c(-1,1,-a+-1:1,a+-1:1),0)]=="*",na.rm=T);M}

danke an @gtwebb und @ sebastian-c für die verbesserungen.

Bemerkenswerte Punkte:

Matrizen sind Vektoren in R. Sie benötigen keine 2-D-Indizierung, um Elemente herauszuholen.

seq(M)gibt eine Sequenz mit der gleichen "Länge" (Zeilen x Spalten) zurück wie M.

Sie können in R keine positiven und negativen Extraktionsindizes mischen. Dies M[-3]ist ein legitimer R-Code, aber nicht das, was gewünscht wird.

Die Eingabe erfolgt in Form einer R-Matrix. Einige Beispiele:

> M <- matrix("",5,5)
> M[3,3] <- "*"
> f(M)
     [,1] [,2] [,3] [,4] [,5]
[1,] "0"  "0"  "0"  "0"  "0" 
[2,] "0"  "1"  "1"  "1"  "0" 
[3,] "0"  "1"  "*"  "1"  "0" 
[4,] "0"  "1"  "1"  "1"  "0" 
[5,] "0"  "0"  "0"  "0"  "0" 
> M[2,2] <- "*"
> f(M)
     [,1] [,2] [,3] [,4] [,5]
[1,] "1"  "1"  "1"  "0"  "0" 
[2,] "1"  "*"  "2"  "1"  "0" 
[3,] "1"  "2"  "*"  "1"  "0" 
[4,] "0"  "1"  "1"  "1"  "0" 
[5,] "0"  "0"  "0"  "0"  "0" 
> M[3,2] <- "*"
> f(M)
     [,1] [,2] [,3] [,4] [,5]
[1,] "1"  "1"  "1"  "0"  "0" 
[2,] "2"  "*"  "3"  "1"  "0" 
[3,] "2"  "*"  "*"  "1"  "0" 
[4,] "1"  "2"  "2"  "1"  "0" 
[5,] "0"  "0"  "0"  "0"  "0" 
> 
JDL
quelle
1
Sie können einige Zeichen abschneiden, indem Sie Tanstelle von verwenden TRUE. Ich habe es geschafft, einige Klammern von einer der if-Funktionen zu schieben:f=function(M){a=nrow(M);b=ncol(M);for(i in seq(M))if(M[i]!="*")M[i]=sum(M[pmax(i+c(-1,1,-a+-1:1,a+-1:1),0)]=="*",na.rm=T);M}
sebastian-c
1
Sie definieren es b=ncol(M)und verwenden es dann nicht, damit Sie es loswerden können.
gtwebb
Ich kann vier Zeichen abschneiden (und vektorisieren): M->{a=nrow(M);p=M=='*';M[]=ifelse(p,'*',sapply(seq(M),i->sum(p[pmax(i+c(-1,1,-a+-1:1,a+-1:1),0)],na.rm=T)))}- dies betrügt jedoch leicht, weil es ein neu definiertes <-Lambda erfordert , siehe klmr / functional / lambda
Konrad Rudolph
@Konrad interessante Idee, aber ich werde es behalten, um R danke zu stützen!
JDL
6

Java, 190 Bytes

Bearbeiten:

  • -6 Bytes aus. Vielen Dank an @Frozn
  • -1 Byte aus. Danke an mich :)
  • -1 Byte aus. Auch einige Fehler entdeckt. Vielen Dank an Kevin Cruijssen

Snipet

c->{for(int x,y,j,i=-1;++i<c.length;)for(j=-1;++j<c[0].length;){if(c[i][j]<33){c[i][j]=48;for(x=i-2;++x<i+2;)for(y=j-2;++y<j+2;)try{if(c[x][y]==43)c[i][j]++;}catch(Exception e){}}}return c;}

Ungolfed:

public class Main{
  public static char[][] minesweeper(char[][] woclues){
    for(int i = 0; i < woclues.length ; i++){
      for(int j = 0; j < woclues[0].length ; j++){
        if( woclues[i][j] == ' '){
          woclues[i][j] = '0';
          for(int x = i - 1; x < i + 2 ; x++){
            for(int y = j - 1; y < j + 2 ; y++){
              try{
                if(woclues[x][y] == '*'){
                  woclues[i][j]++;
                }
              }catch( ArrayIndexOutOfBoundsException e){}
            }
          }
        }
      }
    }
    return woclues;
  }
  public static void main(String[]args){
    char[][] in = new char[args.length][args[0].length()];
    for(int i = 0; i < args.length;i++){
      in[i]=args[i].toCharArray();
    }
    for(char[] c:minesweeper(in)){
      System.out.println(new String(c));
    }
  }
}

Ideone es.

Roman Gräf
quelle
Sie können die Zeichenwerte mit den ASCII-Werten vergleichen, die in den meisten Fällen kürzer sein sollten. Sie können auch die Erklärungen vonx,y,i,j
Frozn
Ich habe es bereits getan c[i][j]==32und so weiter und habe sie im Ungolfed-Teil geändert
Roman Gräf,
Und ich bin kleiner als Phyton. Mindestens!
Roman Gräf
Sind Sie sicher, dass Ihr ungolfed Code korrekt ist? Für den ersten Testfall gibt sie : 0000*1\n*10011\n110000\n000000\n00**10\n0*22*1. Könnten Sie vielleicht einen ideone.com-Testlink hinzufügen? EDIT: Ausserdem, wenn ich nicht selbst etwas falsch mache, wird Ihr Golfcode ausgegeben: ssss0s\n0sssss\nssssss\nssssss\nss00ss\ns0ss0sfür den ersten Testfall (der alle *durch Nullen ersetzt hat ..): S
Kevin Cruijssen
Bearbeitet Ich werde einen Testlink hinzufügen, sobald mein Vorgänger-Internet dies mir erlaubt.
Roman Gräf
5

JavaScript (ES6), 107

Eingabe / Ausgabe als Array von Zeichenfolgen

f=l=>l.map((r,i)=>r.replace(/ /g,(c,j)=>(s=r=>(c+r).substr(j,3).split`*`.length,s(l[i-1])+s(l[i+1])+s(r)-3)))

beachten Sie, wenn die Funktion s mit einem Element der Liste l außerhalb der Grenzen genannt wird, der Parameter aist undefinedund c+awird in Folge " undefined"dank der schrulligen Konvertierungsregeln von JavaScript

Mehr lesbar

l=>
  l.map(
    (r,i) =>
      r.replace(/ /g, (c,j) =>
        (
          s = a => (c+a).substr(j,3).split`*`.length,
          s(l[i-1])+s(l[i+1])+s(r)-3
        )
      )
  )
edc65
quelle
5

Python 2, 138 Bytes

def f(s):w=s.find('\n')+1;print''.join([c,`(s[i-(i>0):i+2]+(w*' '+s)[i-1:i+2]+s[i-1+w:i+2+w]).count('*')`][c==' ']for i,c in enumerate(s))

Definiert eine Funktion f, die eine Eingabezeichenfolge wie annimmt

"  *\n** \n*  \n"

und druckt einen String nach STDOUT:

23*
**2
*31
Lynn
quelle
1
Beginnen Sie mit 2 ( enumerate(s,2)) und ersetzen Sie alle Vorkommen von i + 2mit iund i - 1mit i - 3. Das spart ein paar Bytes.
Roberto Bonvallet
5

JavaScript (ES6) 186 182 177 161 152 Byte

f=a=>{for(s='',y=a[0].length;y--;)for(s=`
`+s,x=a.length;x--;)(k=>{for(t=0,i=9;i--;)t+=(a[x+i%3-1]||[])[y+i/3-1|0]==k;s=(a[x][y]<k?t:k)+s})`*`;return s}

Aktualisieren

Der obige Code für " *"Rücksendungen "2*". Dies wird im folgenden Skript behoben.

168 167 Bytes

f=a=>{for(s='',y=a[0].length;y--;)for(s=`
`+s,x=a.length;x--;)a[x][y]=='*'?s='*'+s:(k=>{for(t=0,j=3;j--;)for(i=3;i--;)t+=(a[x+i-1]||1)[y+j-1]=='*';s=t+s})`*`;return s}

Probieren Sie es hier aus.

sbisit
quelle
1
Ich denke, t+=(a[x+i%3-1]||[])[y+i/3-1|0]==ksollte auf ähnliche Weise funktionieren und dir den try/ catchTeil ersparen .
Arnauld
1
@Arnauld. Tatsächlich löst das Lesen einer Eigenschaft mit der Literalnummer keinen Fehler aus, sodass es auch verbessert werden kann (a[x+i%3-1]||1)[y+i/3-1|0].
Bis zum
4

Haskell, 115 Bytes

z=zip[1..]
x%i=[a|(j,a)<-z x,abs(i-j)<2]
f x=[[head$[c|c>' ']++show(sum[1|'*'<-(%j)=<<x%i])|(j,c)<-z r]|(i,r)<-z x]

Definiert eine Funktion ffür Listen von Zeichenfolgen

Dianne
quelle
3

Python 2, 192 Bytes

-3 Bytes dank Copper, -10 Bytes, wenn das Eingaberaster geändert werden darf, weitere -11 Bytes durch Entfernen continueund weitere -12 Bytes zum Entfernen der Zählervariable

def f(L):
 n,S,s=len(L[0]),[0,1,2],[' '];P=[s*(n+2)];K=P+[s+x+s for x in L]+P
 for y in range(len(L)):
    for x in range(n):
     if'*'!=L[y][x]:L[y][x]=`sum(K[y+d][x+e]=='*'for d in S for e in S)`

Verwendet eine Liste mit Zeichen Lund erstellt eine gepolsterte Version K, also kein Problem an den Grenzen. Einrückung ist

  1. Platz
  2. Tab
  3. Tab + Leertaste
  4. Tab + Tab

Verwendungszweck:

s=""" *   
*  * 
  *  
    *"""
print s
s=[[c for c in x] for x in s.split('\n')]
f(s)
s='\n'.join([ ''.join(x) for x in s])
print s
Karl Napf
quelle
1
Ein paar Minor Golfs: Sie können Ihre ersten drei Variablenzuweisungen in derselben Zeile mit Semikolons trennen und den Einzug verlieren. Verwenden Sie auch if'*'==L[y][x]:, um ein Byte zu speichern.
Kupfer
Wenn Sie zuweisen r=range;auf der gleichen Linie wie n,S,skönnen Sie fünf Zeichen speichern , indem die Anrufe zu ersetzen range(...)mit r(...).
Alexwlchan
@alexwlchan dies zu tun spart 2 * angealso 8 Bytes, aber ich muss hinzufügen ,rund ,rangewas ist auch 8 Bytes so nichts verdient.
Karl Napf
@KarlNapf Gah, du hast recht - ich hatte das vergessen range.
Alexwlchan
3

Ruby, 112

Nimmt und gibt einen String zurück. Die Zeichenfolge muss durch Zeilenumbrüche getrennt und durch Zeilenumbrüche abgeschlossen sein.

->s{w=1+s=~/\n/
s.size.times{|i|s[i]==' '&&(n=0;9.times{|j|(s+$/*w)[i+j%3-1+j/3*w-w]==?*&&n+=1};s[i])=n.to_s}
s}

im Testprogramm

f=->s{
  w=(s=~/\n/)+1                              #Calculate width.
  s.size.times{|i|                           #For each char in s
    s[i]==' '&&(                             #If it is a space
      n=0                                    #set counter n to 0 and visit
      9.times{|j|                            #a 3x3 square of chars.
        (s+$/*w)[i+j%3-1+j/3*w-w]==?*&&n+=1  #If *, increment n.
      }                                      #(Pad s with w newlines to avoid *'s detected by wraparound.)
      s[i]=n.to_s                            #Write n back to s in string format
    )
  }
s}                                           #Return s.

puts f[
" *   
*  * 
  *  
    *
"]
Level River St
quelle
3

TSQL 292 291 Bytes

Golf gespielt:

DECLARE @ varchar(max)=
' *   
*  * 
  *  
    *';
WITH C as(SELECT x+1i,substring(@,x+1,1)v,x/z r,x%z c FROM master..spt_values CROSS APPLY(SELECT number x,charindex(char(10),@)z)z WHERE type='P'and x<len(@))SELECT @=stuff(@,i,1,z)FROM(SELECT i,(SELECT count(*)FROM C WHERE abs(D.c-c)<2and abs(D.r-r)<2and'*'=v)z FROM C D WHERE''=v)h PRINT @

Ungolfed:

DECLARE @ varchar(max)=
' *   
*  * 
  *  
    *';
WITH C as
(
  SELECT x+1i,substring(@,x+1,1)v,x/z r,x%z c
  FROM master..spt_values
  CROSS APPLY(SELECT number x,charindex(char(10),@)z)z
  WHERE type='P'and x<len(@)
)
SELECT @=stuff(@,i,1,z)
FROM
(
  SELECT
    i,
    (
      SELECT count(*)
      FROM C
      WHERE 
       abs(D.c-c)<2and abs(D.r-r)<2and'*'=v
    )z
  FROM C D
  WHERE''=v
)h
PRINT @

Geige

t-clausen.dk
quelle
Zählt das ;am Anfang Ihres Codes? Es scheint, dass Sie es gezählt haben.
Erik der Outgolfer
@EriktheGolfer Ja, wo gibt es ein Skript vor WITH. Der Compiler gibt einen Fehler aus, wenn er entfernt wird. Es ist möglich, Ideen in der Geige zu testen
t-clausen.dk
Ich meine, sollte es in der Byteanzahl der allgemeinen Quelle sein? Weil es den Anschein hat, als sollte es stattdessen Teil der "Initial STDIN" -Anweisung sein.
Erik der Outgolfer
@EriktheGolfer Ich weiß es nicht wirklich, ich nehme an, es kann Teil der Erklärung sein. Kann auch master .. ausschließen, wenn sich am Anfang des Skripts ein USE-Master befindet. Aber es gibt eine nervige Botschaft in der Geige.
t-clausen.dk
Ich habe versucht, das Semikolon in die vorherige Zeile zu setzen, und es hat funktioniert. Ich gehe davon aus, dass die letzte Zeile zählt.
Erik der Outgolfer
2

Schläger 415 Bytes

(let*((l(string->list s))(g (λ(r c)(if(or(>= r n)(>= c n)(< r 0)(< c 0))#f(list-ref l(+ c(* n r))))))(ng (λ(r c)(let*((h'(-1 0 1))(k(filter(λ(x)x)
(for*/list((i h)(j h)#:unless(= 0 i j))(g(+ r i)(+ c j))))))(count(λ(x)(equal? x #\*))k))))(k(for*/list((i n)(j n))(ng i j)))
(ol(map(λ(x y)(if(equal? x #\*)"*"(number->string y)))l k)))(for((i(* n n))(j ol))(display j)(when(= 0(modulo(add1 i)n))(displayln ""))))

Ungolfed:

(define (f s n)
  (let* ((l (string->list s))
         (get                            ; fn to get value at a (row, col)
          (lambda(r c)                   ; #f if invalid row or col
            (if (or (>= r n)
                    (>= c n)
                    (< r 0)
                    (< c 0))
                #f (list-ref l (+ c (* n r))))))

         (neighbors                      ; fn to count neighboring "*"
          (lambda(r c)
            (let* ((h '(-1 0 1))
                   (u (filter
                       (lambda(x) x)
                       (for*/list ((i h)(j h)
                                   #:unless (= 0 i j))
                         (get (+ r i) (+ c j))))))
              (count (lambda(x)(equal? x #\*)) u))))

         (k (for*/list ((i n) (j n))    ; for each row,col count neighboring "*"
              (neighbors i j)))
         (ol(map (lambda(x y)           ; get outlist- replace blanks with neighboring star count
                   (if(equal? x #\*) 
                      "*"
                      (number->string y)))
                 l k)))

    (for ((i (* n n))(j ol))            ; display outlist
      (display j)
      (when (= 0 (modulo (add1 i) n))
        (displayln "")))))

Testen (Listen als einzelne Zeichenfolge mit angegebener Spaltennummer; funktionieren auch mit Leerzeichen):

(f "----*-*-------------------**---*--*-" 6) 

Ausgabe:

1101*1
*10111
110000
012210
12**21
1*33*1
rnso
quelle
2

PHP, 145 133 132 127 Bytes

for($s=$argv[1];$s[$p];print$c)if(" "==$c=$s[$p++])for($y=-2;$y++<1;)for($x=$p-3;$x++<$p;)$c+="!"<$s[$x+$y*strpos($s,"\n")+$y];

Nimmt Eingaben als einzelne Zeichenfolge mit Zeilenumbruch als Trennzeichen an. Laufen Sie mit -r.

Nervenzusammenbruch

for($s=$argv[1];$s[$p]; // loop through all characters (including newlines)
    print$c                     // 3. print result
)
    if(" "==$c=$s[$p++])        // 1. if character is space
        for($y=-2;$y++<1;)      // 2. count surrounding asterisk characters
            for($x=$p-3;$x++<$p;)
                $c+="!"<$s[$x+$y*strpos($s,"\n")+$y];
Titus
quelle
"!">$n=$s[$p]statt " "==$n=$s[$p]spart ein Byte
Jörg Hülsermann
@ JörgHülsermann Das würde die Zeilenumbrüche zerstören.
Titus
@ JörgHülsermann ... aber der Trick funktioniert für den Asterisk-Vergleich (in der neuen Version)
Titus
2

Turtlèd , 99 Bytes

(Hoppla, ich vergesse immer wieder den Link: |)

Übernimmt Eingaben mit Klammern um jede Zeile

Turtlèd kann keine mehrzeiligen Eingaben vornehmen. Schreiben Sie daher nach der letzten Zeile, um |das Ende der Eingabe zu signalisieren

Beachten Sie, dass die nicht übereinstimmenden Klammern darauf zurückzuführen sind, dass offene Klammern das nächste Zeichen als Teil des Klammerbefehls analysieren

[|!.([[]r+.][[l]d)][ u]d[|[]r( #012345678#l(*+)u(*+)r(*+)r(*+)d(*+)d(*+)l(*+)l(*+)ur.)]' [[l]' d]' 

Probieren Sie es online!

Wie es funktioniert (allgemeine Beschreibung):

Bis |zur Eingabe wird die Eingabe in jede Zeile mit eckigen Klammern geschrieben, um das Ende jeder Zeile zu erkennen. Nachdem dies geschehen ist, kehrt es zum oberen Rand der Eingabe zurück. Es durchläuft jedes eingegebene Zeichen. Wenn es sich um ein Feld handelt, sieht es sich im Feld um und fügt für jede gefundene Bombe ein Feld hinzu. Nach jeder Zeile werden die Klammern gelöscht. Wenn die letzte Zeile erreicht ist, wird mit | Darin stoppt es und löscht das |. Das Raster wird implizit gedruckt.

Zerstörbare Zitrone
quelle
0

C, 152 150 147 145 Bytes

i,j,r,c;f(B,R,C)char**B;{for(i=R*C;i--;)for(j=9;j--;){char*b=B[i/C]+i%C;r=i/C+j/3-1;c=i%C+j%3-1;r<0|c<0|r/R|c/C|*b&8||(*b=16|*b+(B[r][c]==42));}}

Die Eingabe erfolgt in Form einer zweidimensionalen Zeichenfolge, gefolgt von der Anzahl der Zeilen und Spalten. Das Ergebnis wird an Ort und Stelle zurückgegeben.

(Meistens) Ungolfed:

i, j, r, c;
f(B, R, C) char **B; {
    for (i = R*C; i--;)
        for (j = 9; j--;) {
            char *b = B[i/C] + i%C;
            r = i/C + j/3 - 1;
            c = i%C + j%3 - 1;
            r < 0 | c < 0 | r / R | c / C | *b & 8 ||
                (*b = 16 | *b + (B[r][c] == 42));
        }
}

Der Ansatz ist unkompliziert: Schleife über jede Position, Schleife über die Nachbarn und addiere alle Sternchen. Es gibt zwei Tricks auf Bitebene:

  • Wenn wir entscheiden, ob eine Zelle ein Sternchen ist oder nicht, können wir einfach prüfen, ob das Bit mit der achten Stelle gesetzt ist, da die Zahl in der Zelle kleiner als 8 sein muss (der maximale Zellenwert).

  • Wir können ein Leerzeichen durch ODER-Verknüpfung von 16 in ein Nullzeichen umwandeln.

Edit: Golfed aus zwei Bytes mit /anstelle von >=.

Bearbeiten: Weitere fünf Bytes durch Umkehren der Schleifenrichtung.

Chris Bouchard
quelle
0

C #, 341 Bytes

Eine naive Implementierung, die definitiv verkürzt werden kann.

s=>s=="*"?1:0;s=>{for(int i=0,j,n,l=s.Length,c=s[i].Length;i<l;++i)for(j=0;j<c;++j)if(s[i][j]!="*"){n=0;if(i>0){n+=a(s[i-1][j]);n+=j>0?a(s[i-1][j-1]):0;n+=j+1<c?a(s[i-1][j+1]):0;}n+=a(s[i][j]);n+=j>0?a(s[i][j-1]):0;n+=j+1<c?a(s[i][j+1]):0;if(i+1<l){n+=a(s[i+1][j]);n+=j>0?a(s[i+1][j-1]):0;n+=j+1<c?a(s[i+1][j+1]):0;}s[i][j]=n+"";}return s;};
TheLethalCoder
quelle
0

Python 2, 183 Bytes

def s(m):
 j=m.find('\n')+1;q='q'*j*2;m=list(q+m+q)
 for i in range(len(m)):
  if m[i]==' ':m[i]=`sum([m[k+i]=='*'for k in [-j-1,-j,-j+1,-1,1,j-1,j,j+1]])`
 return''.join(m)[j*2:-j*2]
Skyler
quelle