Fill in the Minesweeper clues

54

2

Minesweeper is a popular puzzle game where you must discover which tiles are "mines" without clicking on those tiles. Each tile is either a mine (represented by *) or a clue, i.e. a number from 0 to 8 representing how many of the 8 neighboring tiles are mines. Your task today is to take a board containing the mines and fill in all of the clues. For example, look at the following 5x4 board, with 5 mines:

 *  
*  * 
  *  
    *

After filling in the clues, the board will look like this:

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

Details

You must write either a full-program or a function that takes in a grid of characters containing only spaces and asterisks and outputs another grid where each space is replaced with the number of adjacent mines (asterisks). Any of these are acceptable formats for your grids:

  • A string with newlines in it

  • A 2D list of characters/single character strings

  • A list of strings

You can assume the grid will be at least 1x1, although it is possible for it to be all mines or all spaces.

The input grid will always be padded with the appropriate number of spaces. As usual, this is , so standard loopholes apply and the shortest answer in bytes wins!

Sample IO

So that you can see the whitespace, I will show all sample IO with brackets around it.

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]

James

Posted 2016-10-23T04:44:36.600

Reputation: 54 537

2FYI, I made all of the sample IO by hand, so it's possible there are some minor errors in there. Let me know if something looks off and I'll try to fix it ASAP. – James – 2016-10-23T04:45:19.210

Related. – xnor – 2016-10-23T04:50:55.897

1Can the grid be non-square ? – Ton Hospel – 2016-10-23T08:56:39.927

Can the mines represented by another character? – Akangka – 2016-10-23T11:58:05.823

@ChristianIrwan No, the mines will always be an asterisk. – James – 2016-10-23T12:59:09.923

Can my output contain leading blank lines? – Lynn – 2016-10-23T13:19:42.260

Can we take I/O with brackets around it? – Destructible Lemon – 2016-10-23T22:21:01.280

@Lynn I guess that's fine. – James – 2016-10-24T15:19:16.343

@DestructibleWatermelon Re brackets around input: I don't see why that would make any difference, but I guess I don't have any problem with it. – James – 2016-10-24T15:19:50.210

Your first example says "look at the following 5x5 board", but in both the asterisk display and the numbers below it have 5 columns and 4 rows. – Cody – 2016-10-24T23:14:26.377

Answers

21

MATL, 18 17 bytes

Thanks to @mbomb007 for a correction in the input of test case 6

32>t3Y6Z+-6b(48+c

Input is a 2D char array, in the format

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

Try it online!

Test cases: 1, 2, 3, 4, 5, 6.

Explanation

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

Posted 2016-10-23T04:44:36.600

Reputation: 87 464

1Wow. That is impressive. – a25bedc5-3d09-41b8-82fb-ea6c353d75ae – 2016-10-24T15:01:05.170

2Getting test case 6 would piss me off playing the actual game. – Magic Octopus Urn – 2016-10-24T15:51:32.767

Why? Test case 6 seems the most realistic. – WBT – 2016-10-24T20:57:28.337

@carusocomputing Getting test case 2 would piss me off a lot more. :P – James – 2016-10-25T21:09:20.130

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

Edit: Saved 18 bytes thanks to an idea by @ETHproductions.

Neil

Posted 2016-10-23T04:44:36.600

Reputation: 95 035

I think you can save a bunch by defining a function to check if an index is non-space: 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 – 2016-10-23T18:38:53.617

@ETHproductions I took your idea to the extreme... I don't usually get to write function parameters! – Neil – 2016-10-23T18:56:28.347

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}

thanks to @gtwebb and @sebastian-c for improvements.

Notable points:

Matrices are vectors in R. You don't need 2-D indexing to get elements out.

seq(M) will return a sequence of the same "length" (rows x columns) as M.

You can't mix positive and negative extraction indices in R. M[-3] is legitimate R code, but not what is desired.

Input is in the form of an R matrix. Some examples:

> 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

Posted 2016-10-23T04:44:36.600

Reputation: 1 135

1You can cut a few characters off by using T instead of TRUE. I managed to slide some braces off one of the if functions too: 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 – 2016-10-24T16:27:58.797

1You define b=ncol(M) and then don't use it so you could get rid of that. – gtwebb – 2016-10-24T22:28:41.707

I can shave off four characters (and vectorise): 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)))} — however, this cheats slightly because it requires a redefined <- lambda, see klmr/functional/lambda

– Konrad Rudolph – 2016-10-25T15:02:19.797

@Konrad interesting idea, but I'll keep it to base R thanks! – JDL – 2016-10-25T15:06:40.670

6

Java, 190 bytes

Edit:

  • -6 bytes off. Thanks to @Frozn
  • -1 byte off. Thanks to myself :)
  • -1 byte off. Also spotted some mistakes. Thanks to @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 it.

Roman Gräf

Posted 2016-10-23T04:44:36.600

Reputation: 2 915

You can compare the char values against the ASCII values which should be shorter in most cases. You can also combine the declarations of x,y,i,j – Frozn – 2016-10-23T14:00:03.533

I already did c[i][j]==32 and so on and just changed them in the Ungolfed part – Roman Gräf – 2016-10-23T14:09:36.243

And I'm shorter than Phyton. At least! – Roman Gräf – 2016-10-23T19:16:39.063

Are you sure your ungolfed code is correct? For the first test case it outputs: 0000*1\n*10011\n110000\n000000\n00**10\n0*22*1. Could you perhaps add an ideone.com test link? EDIT: Also, unless I'm doing something wrong myself, your golfed code output: ssss0s\n0sssss\nssssss\nssssss\nss00ss\ns0ss0s for the first test case (it has replaced all * with zeros..) :S – Kevin Cruijssen – 2016-10-24T08:03:39.430

Edited. I'll add a test link as soon as my pior internet allows that to me. – Roman Gräf – 2016-10-24T08:13:32.483

@RomanGräf Your ungolfed code works now, your golfed code not yet. If I'm not mistaken the >33 should be <33 instead. Also, you have a closing parenthesis too many right after the catch(Exception e){}) <- this last one should be removed. +1 though, after these two changes everything seems to work great. – Kevin Cruijssen – 2016-10-24T08:18:59.880

You could remove the whole return keyword and use a function with a void return type. You only have to say that your output is expressed in the original array. Nowhere is it written that the output must be the return value. Also, braces after the 2nd for and before the first if aren't necessary. – Olivier Grégoire – 2016-10-24T12:03:59.447

I don't think your second for-loop needs curly braces. Saves 2 bytes – Poke – 2017-02-27T20:56:00.680

5

JavaScript (ES6) 186 182 177 161 152 bytes

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}

Update

The above code for " *" returns "2*". This is fixed in the following script.

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}

Try it here.

sbisit

Posted 2016-10-23T04:44:36.600

Reputation: 291

1I think t+=(a[x+i%3-1]||[])[y+i/3-1|0]==k should work in a similar way and save you the try / catch part. – Arnauld – 2016-10-23T11:19:09.420

1@Arnauld. Actually, reading a property of literal number will not throw an error, so it can be also improved as (a[x+i%3-1]||1)[y+i/3-1|0]. – sbisit – 2016-10-24T16:33:40.930

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

Defines a function f that accepts an input string like

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

and prints a string to STDOUT:

23*
**2
*31

Lynn

Posted 2016-10-23T04:44:36.600

Reputation: 55 648

1Make enumerate start from 2 (enumerate(s,2)), and replace all occurrences of i + 2 with i and i - 1 with i - 3. That'll shave off a couple of bytes. – Roberto Bonvallet – 2016-10-25T00:54:05.390

5

JavaScript (ES6), 107

Input/output as an array of strings

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

note when the function s is called with an element of the list l out of the bounds, the parameter a is undefined and c+a will result in " undefined" thanks to the quirky conversion rules of javascript

More readable

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

Posted 2016-10-23T04:44:36.600

Reputation: 31 086

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]

Defines a function f on lists of strings

dianne

Posted 2016-10-23T04:44:36.600

Reputation: 1 049

3

Python 2, 192 bytes

-3 bytes thanks to Copper, -10 bytes if modifying the input grid is allowed, another -11 bytes by getting rid of continue and another -12 bytes for eliminating the counter variable

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

Uses a list of list of characters L and creates a padded version K, so no problem at boundaries. Indentation is

  1. Space
  2. Tab
  3. Tab+Space
  4. Tab+Tab

Usage:

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

Posted 2016-10-23T04:44:36.600

Reputation: 4 131

1A few minor golfs: you can put your first three variables assignments on the same line separated with semicolons and lose the indentation. Also, use if'*'==L[y][x]: to save a byte. – Copper – 2016-10-23T11:07:30.500

If you assign r=range; on the same line as n,S,s, you can save five characters by replacing the calls to range(...) with r(...). – alexwlchan – 2016-10-23T22:36:25.083

@alexwlchan doing this saves 2*ange so 8 bytes, but i have to add ,r and ,range which is also 8 bytes so nothing earned. – Karl Napf – 2016-10-24T08:34:52.607

@KarlNapf Gah, you're right -- I'd forgotten about the range. – alexwlchan – 2016-10-24T10:12:44.360

3

Ruby, 112

Takes and returns a string. String must be newline separated and newline terminated.

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

in test program

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

Posted 2016-10-23T04:44:36.600

Reputation: 22 049

3

TSQL 292 291 bytes

Golfed:

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 @

Fiddle

t-clausen.dk

Posted 2016-10-23T04:44:36.600

Reputation: 2 874

Does the ; at the front of your code count? It seems that you have counted it. – Erik the Outgolfer – 2016-10-24T13:28:19.447

@EriktheGolfer Yes, where there is script prior to WITH. Compiler will give an error if it is removed. It is possible to test ideas in the fiddle – t-clausen.dk – 2016-10-24T13:33:09.637

I mean, should it be in the byte count of the general source? Because it seems like it should be part of the "Initial STDIN" statement instead. – Erik the Outgolfer – 2016-10-24T13:34:42.410

@EriktheGolfer I don't really know, I suppose it can be part of the declaration. Can also exclude master.. if there is a USE master in the beginning of the script. But it gives an annoying message in the fiddle. – t-clausen.dk – 2016-10-24T13:38:15.493

I tried putting the semicolon on the previous line, and it worked. I assume the last line is what counts. – Erik the Outgolfer – 2016-10-24T13:42:55.380

Adjusted the count and code, thanks – t-clausen.dk – 2016-10-24T13:45:33.750

2

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

Testing (lists as a single string with column number specified; will also work with spaces):

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

Output:

1101*1
*10111
110000
012210
12**21
1*33*1

rnso

Posted 2016-10-23T04:44:36.600

Reputation: 1 635

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

takes input as single string, newline separated. Run with -r.

breakdown

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

Posted 2016-10-23T04:44:36.600

Reputation: 13 814

"!">$n=$s[$p] instead of " "==$n=$s[$p] saves one Byte – Jörg Hülsermann – 2016-10-24T16:24:05.507

@JörgHülsermann That would destroy the linebreaks. – Titus – 2016-10-24T16:27:21.803

@JörgHülsermann ... but the trick works for the asterisk comparison (in the new version) – Titus – 2016-10-24T16:35:40.773

2

Turtlèd, 99 bytes

(whoops I keep forgetting the link :| )

Takes inputs with brackets around each line

Turtlèd cannot take multi-line input, so after the last line, write | to signal end of input

Note the mismatched brackets are because open brackets parse the next char as part of the bracket command

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

Try it online!

How it works (general description):

Until | is entered, it writes out the input on each line, with brackets to help it recognise the end of each line. After that has happened, it goes back up to the top of input. It goes through each character in input. If it is a space, it looks around the space, adding one to the counter for each bomb it finds. after each line, it deletes the brackets. When it gets to the last line, with the | in it, it stops, and deletes the |. the grid is implicitly printed.

Destructible Lemon

Posted 2016-10-23T04:44:36.600

Reputation: 5 908

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

Input is in the form of a two-dimensional array of characters, followed by the numbers of rows and columns. The result will be returned in-place.

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

The approach is straight-forward — loop over each position, loop over its neighbors, and add up all the asterisks. There are two bit-level tricks:

  • When we're deciding if a cell is an asterisk or not, we can just check if the eights-place bit is set, because the number in the cell must be less than 8 (the maximum cell value).

  • We can turn a space character into a zero character by OR-ing 16.

Edit: Golfed off two bytes by using / in place of >=.

Edit: Another five bytes by reversing the direction of the loops.

Chris Bouchard

Posted 2016-10-23T04:44:36.600

Reputation: 111

0

C#, 341 Bytes

A naïve implementation that can definitely be shortened.

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

Posted 2016-10-23T04:44:36.600

Reputation: 6 930

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

Posted 2016-10-23T04:44:36.600

Reputation: 897