Skip to content

Instantly share code, notes, and snippets.

@dluksza
Created February 29, 2012 09:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dluksza/1939503 to your computer and use it in GitHub Desktop.
Save dluksza/1939503 to your computer and use it in GitHub Desktop.
Simple minefield parser in Fantom
class Parser {
Str parse(Str input) {
lines := input.splitLines
validateInput(lines)
result := createMatrix(lines.size, lines[0].size)
lines.each |line, i| {
parseLine(line, result, i);
}
return convertToStr(result)
}
private Void validateInput(Str[] lines) {
firstLineSize := lines[0].size
if (!lines.all |line| {
line.size == firstLineSize && line.all |c| { c == '.' || c == '*' }
})
throw ArgErr("Line size mismatch or illegal character was used")
}
private Int[][] createMatrix(Int row, Int cols) {
Int[][] result := [,]
row.times {
result.add([,].fill(0, cols))
}
return result
}
private Void parseLine(Str input, Int[][] result, Int i) {
input.each |c, j| {
if (c == '*') {
prevCol := j - 1
nextCol := j + 1
result[i][j] = -10
if (j > 0)
result[i][prevCol]++
if (j < input.size - 1)
result[i][nextCol]++
range := prevCol.max(0)..nextCol.min(result[i].size - 1)
if (i > 0)
incrementInRange(result[i - 1], range)
if (i < result.size -1)
incrementInRange(result[i + 1], range)
}
}
}
private Void incrementInRange(Int[] row, Range range) {
row.eachRange(range) |value, p| {
row[p]++
}
}
private Str convertToStr(Int[][] result) {
buf := StrBuf(result.size * result[0].size)
result.each |row| {
row.each |i| {
if (i < 0)
buf.add("*")
else
buf.add(i)
}
buf.add("\n")
}
buf.remove(buf.size - 1)
return buf.toStr;
}
}
class SaperTest : Test {
Void testTrowErrWhenIllegalCharactedIsPresent() {
// given
input := ".a"
// when
verifyErr(ArgErr#) {
Parser().parse(input)
}
}
Void testEmptyInput() {
// given
input := ""
// when
result := Parser().parse(input)
// then
verifyEq(result, "")
}
Void testThrowErrWhenCollumnsSizeMissamtch() {
// given
input := ".\n.."
// when
verifyErr(ArgErr#) {
Parser().parse(input)
}
}
Void testSingleDot() {
// given
input := "."
// when
result := Parser().parse(input)
// then
verifyEq(result, "0")
}
Void testSingleMine() {
// given
input := "*"
// when
result := Parser().parse(input)
// then
verifyEq(result, "*")
}
Void testSingleLine() {
// given
input := ".*"
// when
result := Parser().parse(input)
// then
verifyEq(result, "1*")
}
Void testSingleLine2() {
// given
input := ".*."
// when
result := Parser().parse(input)
// then
verifyEq(result, "1*1")
}
Void testMultiline() {
// given
input := ".*\n.."
// when
result := Parser().parse(input)
// then
verifyEq(result, "1*\n11")
}
Void testMultiline2() {
// given
input := ".*.\n*..\n..*"
// when
result := Parser().parse(input)
// then
verifyEq(result, "2*1\n*32\n12*")
}
Void testMultiline3() {
// given
input := "..**.\n.....\n*****\n.*.*.\n*...*"
// when
result := Parser().parse(input)
// then
verifyEq(result, "01**1\n24553\n*****\n4*5*4\n*222*")
}
Void testColumnLine() {
// given
input := ".\n*\n."
// when
result := Parser().parse(input)
// then
verifyEq(result, "1\n*\n1")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment