From 982490cfd52aef0740c8ac4cb4240fa7c0dee0af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20=C3=96zt=C3=BCrk?= Date: Thu, 5 Dec 2013 19:13:17 +0200 Subject: [PATCH 1/2] initial commit --- lib/sudoku_board.rb | 52 ++++++++++++++++++++++++++++++ lib/sudoku_validator.rb | 58 +++++++++++++++++++++++++++++++++ spec/sudoku_board_spec.rb | 60 +++++++++++++++++++++++++++++++++++ spec/sudoku_validator_spec.rb | 30 ++++++++++++++++++ 4 files changed, 200 insertions(+) create mode 100644 lib/sudoku_board.rb create mode 100644 lib/sudoku_validator.rb create mode 100644 spec/sudoku_board_spec.rb create mode 100644 spec/sudoku_validator_spec.rb diff --git a/lib/sudoku_board.rb b/lib/sudoku_board.rb new file mode 100644 index 0000000..eb6148d --- /dev/null +++ b/lib/sudoku_board.rb @@ -0,0 +1,52 @@ +require 'matrix' + +class SudokuBoard + attr_reader :board, :rows + def initialize(file) + @rows = [] + + File.readlines(file).each do |line| + row = get_row_from line + @rows << row unless row.empty? + end + @board = Matrix.rows(@rows) + end + + def point(row, col) + board.[](row - 1, col - 1) + end + + def row(n) + board.row(n-1).to_a + end + + def column(n) + board.column(n-1).to_a + end + + def subgrid(starting_row, starting_col) + board.minor(starting_row - 1, 3, starting_col - 1, 3).to_a.flatten! + end + + def columns + columns = (1..9).collect do |n| + column(n) + end + end + + def subgrids + subgrids = [] + [1,4,7].each do |n| + [1,4,7].each do |x| + subgrids << subgrid(n, x) + end + end + subgrids + end + + private + def get_row_from(line) + line.chomp!.delete!('-+| ').tr!('.', '0') + row = line.each_char.collect(&:to_i) + end +end diff --git a/lib/sudoku_validator.rb b/lib/sudoku_validator.rb new file mode 100644 index 0000000..70c8cb7 --- /dev/null +++ b/lib/sudoku_validator.rb @@ -0,0 +1,58 @@ +require_relative './sudoku_board' + +class SudokuValidator + attr_reader :board + + def initialize(board) + @board = board + end + + def validate + if valid_rows_columns_grids && contains_empty_points + 'valid but incomplete sudoku' + elsif valid_rows_columns_grids && !contains_empty_points + 'valid and complete sudoku' + elsif !valid_rows_columns_grids && contains_empty_points + 'incomplete and invalid sudoku' + elsif !valid_rows_columns_grids && !contains_empty_points + 'complete but invalid sudoku' + end + end + + private + def valid_rows_columns_grids + check_rows && check_columns && check_subgrids + end + + def check_rows + board.rows.none? do |row| + check_for_duplicates(row) + end + end + + def check_columns + board.columns.none? do |column| + check_for_duplicates(column) + end + end + + def check_subgrids + board.subgrids.none? do |subgrid| + check_for_duplicates(subgrid) + end + end + + def check_for_duplicates(elements) + elements.any? { |n| elements.count(n) > 1 unless n == 0 } + end + + def contains_empty_points + board.rows.any? do |row| + any_zeros?(row) + end + end + + def any_zeros?(element) + element.any? { element.count(0) >= 1 } + end +end diff --git a/spec/sudoku_board_spec.rb b/spec/sudoku_board_spec.rb new file mode 100644 index 0000000..2ad4999 --- /dev/null +++ b/spec/sudoku_board_spec.rb @@ -0,0 +1,60 @@ +require_relative '../lib/sudoku_board' + +describe 'SudokuBoard' do + before do + @incomplete_board = SudokuBoard.new('valid_incomplete.sudoku') + @complete_board = SudokuBoard.new('valid_complete.sudoku') + end + + describe '#row' do + it 'returns the row when passed an index' do + expect(@complete_board.row(2)).to eq [7,2,3,8,5,4,1,6,9] + end + + it 'reurns the row with zeros if the board is incomplete' do + expect(@incomplete_board.row(3)).to eq [0,0,4,0,0,0,0,0,0] + end + end + + describe '#column' do + it 'returns the expected column for the valid and complete file' do + expect(@complete_board.column(1)).to eq [8,7,1,9,3,2,4,6,5] + end + + it 'returns the expected column for the valid and incomplete file' do + expect(@incomplete_board.column(4)).to eq [0,0,0,1,0,0,0,0,0] + end + end + + describe '#subgrid' do + it 'returns a given subgrid' do + expect(@complete_board.subgrid(4, 4)).to eq [1,4,7,2,6,8,5,9,3] + end + + it 'returns a given subgrid for valid incomplete sudoku' do + expect(@incomplete_board.subgrid(7, 7)).to eq [0,7,0,0,0,0,0,4,0] + end + end + + describe '#point' do + it 'returns the value at a given point' do + expect(@complete_board.point(3,5)).to eq 7 + end + end + + describe '#columns' do + it 'returns all the columns from the board' do + expect(@complete_board.columns).to eq [[8,7,1,9,3,2,4,6,5],[5,2,6,8,7,4,3,1,9], + [9,3,4,6,5,1,2,7,8],[6,8,3,1,2,5,9,4,7],[1,5,7,4,6,9,8,2,3],[2,4,9,7,8,3,1,5,6], + [4,1,5,3,9,7,6,8,2], [3,6,2,5,1,8,7,9,4], [7,9,8,2,4,6,5,3,1]] + end + end + + describe '#subgrids' do + it 'returns all the subgrids frim the board' do + expect(@incomplete_board.subgrids).to eq [[8,5,0,7,2,0,0,0,4], + [0,0,2,0,0,0,0,0,0], [4,0,0,0,0,9,0,0,0], [0,0,0,3,0,5,0,4,0],[1,0,7,0,0,0,0,0,0], + [0,0,2,9,0,0,0,0,0], [0,0,0,0,1,7,0,0,0],[0,8,0,0,0,0,0,3,6], [0,7,0,0,0,0,0,4,0]] + end + end +end diff --git a/spec/sudoku_validator_spec.rb b/spec/sudoku_validator_spec.rb new file mode 100644 index 0000000..c867416 --- /dev/null +++ b/spec/sudoku_validator_spec.rb @@ -0,0 +1,30 @@ +require_relative '../lib/sudoku_validator' +require_relative '../lib/sudoku_board' + +describe 'SudokuValidator' do + + describe 'valid game' do + it 'points out valid sudoku when completed' do + board = SudokuBoard.new('valid_complete.sudoku') + expect(SudokuValidator.new(board).validate).to eq 'valid and complete sudoku' + end + + it 'points out valid sudoku when incomplete' do + board = SudokuBoard.new('valid_incomplete.sudoku') + expect(SudokuValidator.new(board).validate).to eq 'valid but incomplete sudoku' + end + end + + describe 'invalid game' do + it 'points out invalid but complete sudoku' do + board = SudokuBoard.new('invalid_complete.sudoku') + expect(SudokuValidator.new(board).validate).to eq 'complete but invalid sudoku' + end + + it 'points out invalid and incomplete sudoku' do + board = SudokuBoard.new('invalid_incomplete.sudoku') + expect(SudokuValidator.new(board).validate).to eq 'incomplete and invalid sudoku' + end + end + +end From 210711496448d1d0d2a2f8d98ddd11d230c0ddc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20=C3=96zt=C3=BCrk?= Date: Thu, 5 Dec 2013 19:52:03 +0200 Subject: [PATCH 2/2] remove unnecessary code --- lib/sudoku_validator.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sudoku_validator.rb b/lib/sudoku_validator.rb index 70c8cb7..815a7e9 100644 --- a/lib/sudoku_validator.rb +++ b/lib/sudoku_validator.rb @@ -53,6 +53,6 @@ def contains_empty_points end def any_zeros?(element) - element.any? { element.count(0) >= 1 } + element.count(0) >= 1 end end