Parse sudoku boards from strings
This commit is contained in:
parent
3136a94793
commit
d573aad4f2
3 changed files with 104 additions and 3 deletions
62
spec/parse_spec.cr
Normal file
62
spec/parse_spec.cr
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
require "./spec_helper"
|
||||||
|
|
||||||
|
describe Sudoku::Parser do
|
||||||
|
|
||||||
|
it "should parse an empty board" do
|
||||||
|
board_string = "....\n....\n....\n...."
|
||||||
|
board = Sudoku::Parser.parse(board_string, block_size: 2)
|
||||||
|
board.size.should eq 4
|
||||||
|
board.block_size.should eq 2
|
||||||
|
|
||||||
|
(0..3).each { |x|
|
||||||
|
(0..3).each { |y|
|
||||||
|
board.get(x, y).should eq nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an exception if number of rows and colums is different" do
|
||||||
|
expect_raises(Sudoku::ParseException) do
|
||||||
|
Sudoku::Parser.parse("....\n....", block_size: 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should put numbers correctly on the board" do
|
||||||
|
board_string = "1...\n.2..\n..3.\n...4"
|
||||||
|
board = Sudoku::Parser.parse(board_string, block_size: 2)
|
||||||
|
|
||||||
|
board.get(0,0).should eq 1
|
||||||
|
board.get(1,1).should eq 2
|
||||||
|
board.get(2,2).should eq 3
|
||||||
|
board.get(3,3).should eq 4
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should raise an exception if a cell contains a character that is not a number or a dot" do
|
||||||
|
expect_raises(Sudoku::ParseException) do
|
||||||
|
Sudoku::Parser.parse(".A..\n....\n....\n....", block_size: 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should parse 9x9 boards correctly" do
|
||||||
|
board_string =
|
||||||
|
"8........\n" \
|
||||||
|
"..36.....\n" \
|
||||||
|
".7..9.2..\n" \
|
||||||
|
".5...7...\n" \
|
||||||
|
"....457..\n" \
|
||||||
|
"...1...3.\n" \
|
||||||
|
"..1....68\n" \
|
||||||
|
"..85...1.\n" \
|
||||||
|
".9....4.."
|
||||||
|
|
||||||
|
board = Sudoku::Parser.parse(board_string, block_size: 3)
|
||||||
|
|
||||||
|
board.get(0,0).should eq 8
|
||||||
|
board.get(2,1).should eq 3
|
||||||
|
board.get(3,1).should eq 6
|
||||||
|
board.get(1,2).should eq 7
|
||||||
|
board.get(4,2).should eq 9
|
||||||
|
board.get(8,8).should eq nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -10,9 +10,14 @@ module Sudoku
|
||||||
|
|
||||||
@grid : Array(Array(Value))
|
@grid : Array(Array(Value))
|
||||||
getter grid
|
getter grid
|
||||||
|
|
||||||
|
getter size
|
||||||
|
getter block_size
|
||||||
|
|
||||||
def initialize(@size : Int32, @block_size : Int32)
|
def initialize(@size : Int32, @block_size : Int32)
|
||||||
raise BoardException.new() unless @size.divisible_by?(@block_size)
|
if !@size.divisible_by?(@block_size)
|
||||||
|
raise BoardException.new("Invalid block size: #{@block_size} for board size: #{@size}")
|
||||||
|
end
|
||||||
@grid = Array(Array(Value)).new(@size) { Array(Value).new(@size, nil) }
|
@grid = Array(Array(Value)).new(@size) { Array(Value).new(@size, nil) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,41 @@
|
||||||
module Sudoku
|
module Sudoku
|
||||||
# Parse a sudoku board from a string. Return a board.
|
|
||||||
|
class ParseException < Exception
|
||||||
|
end
|
||||||
|
|
||||||
class Parser
|
class Parser
|
||||||
def self.parse(board_str)
|
|
||||||
|
# Parse a sudoku board from a string. Return a board.
|
||||||
|
# The string must contain valid board rows. Each row must be separated by a newline.
|
||||||
|
# Blanks are represented by dots.
|
||||||
|
# E.g.:
|
||||||
|
# .1.2
|
||||||
|
# 2..4
|
||||||
|
# .3..
|
||||||
|
# ....
|
||||||
|
def self.parse(board_str, block_size)
|
||||||
|
rows = board_str.split('\n')
|
||||||
|
board_size = rows.size
|
||||||
|
board = Sudoku::Board.new(board_size, block_size)
|
||||||
|
|
||||||
|
rows.each_with_index { |row, y|
|
||||||
|
if row.size != board_size
|
||||||
|
raise ParseException.new("Invalid row size: #{row.size} for row: #{row}")
|
||||||
|
end
|
||||||
|
|
||||||
|
row.each_char_with_index { |c, x|
|
||||||
|
case c
|
||||||
|
when '.'
|
||||||
|
board.put(nil, x, y)
|
||||||
|
when .number?
|
||||||
|
board.put(c.to_s.to_i, x, y)
|
||||||
|
else
|
||||||
|
raise ParseException.new("Invalid character: #{c}")
|
||||||
|
end
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
board
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Add table
Add a link
Reference in a new issue