diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..094498c --- /dev/null +++ b/.rspec @@ -0,0 +1,3 @@ +--color +--drb +--format documentation diff --git a/.swp b/.swp new file mode 100644 index 0000000..1e37e18 Binary files /dev/null and b/.swp differ diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..87f5932 --- /dev/null +++ b/Gemfile @@ -0,0 +1,6 @@ +source 'https://rubygems.org' +ruby '2.0.0' + +gem "rspec", "~> 2.14.1" +gem 'guard-spork' +gem 'terminal-notifier-guard' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..5429edb --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,55 @@ +GEM + remote: https://rubygems.org/ + specs: + celluloid (0.15.2) + timers (~> 1.1.0) + childprocess (0.3.9) + ffi (~> 1.0, >= 1.0.11) + coderay (1.1.0) + diff-lcs (1.2.5) + ffi (1.9.3) + formatador (0.2.4) + guard (2.2.5) + formatador (>= 0.2.4) + listen (~> 2.1) + lumberjack (~> 1.0) + pry (>= 0.9.12) + thor (>= 0.18.1) + guard-spork (1.5.0) + childprocess (>= 0.2.3) + guard (>= 1.1) + spork (>= 0.8.4) + listen (2.4.0) + celluloid (>= 0.15.2) + rb-fsevent (>= 0.9.3) + rb-inotify (>= 0.9) + lumberjack (1.0.4) + method_source (0.8.2) + pry (0.9.12.4) + coderay (~> 1.0) + method_source (~> 0.8) + slop (~> 3.4) + rb-fsevent (0.9.3) + rb-inotify (0.9.3) + ffi (>= 0.5.0) + rspec (2.14.1) + rspec-core (~> 2.14.0) + rspec-expectations (~> 2.14.0) + rspec-mocks (~> 2.14.0) + rspec-core (2.14.7) + rspec-expectations (2.14.4) + diff-lcs (>= 1.1.3, < 2.0) + rspec-mocks (2.14.4) + slop (3.4.7) + spork (1.0.0rc4) + terminal-notifier-guard (1.5.3) + thor (0.18.1) + timers (1.1.0) + +PLATFORMS + ruby + +DEPENDENCIES + guard-spork + rspec (~> 2.14.1) + terminal-notifier-guard diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..f3ab131 --- /dev/null +++ b/Guardfile @@ -0,0 +1,14 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +guard 'spork', :cucumber_env => { 'RAILS_ENV' => 'test' }, :rspec_env => { 'RAILS_ENV' => 'test' } do + watch('Gemfile') + watch('lib/sudoku_validator.rb') + watch('spec/sudoku_validator_spec.rb') + watch('spec/spec_helper.rb') { :rspec } + +end + +guard 'rspec', all_after_pass: false do +end + diff --git a/examples/one_row.sudoku b/examples/one_row.sudoku new file mode 100644 index 0000000..b512a45 --- /dev/null +++ b/examples/one_row.sudoku @@ -0,0 +1 @@ +8 5 9 |6 1 2 |4 3 7 diff --git a/examples/one_row_invalid.sudoku b/examples/one_row_invalid.sudoku new file mode 100644 index 0000000..d38254d --- /dev/null +++ b/examples/one_row_invalid.sudoku @@ -0,0 +1 @@ +8 5 9 |6 1 2 |4 3 3 diff --git a/examples/three_row.sudoku b/examples/three_row.sudoku new file mode 100644 index 0000000..d6b5207 --- /dev/null +++ b/examples/three_row.sudoku @@ -0,0 +1,4 @@ +8 5 9 |6 1 2 |4 3 7 +7 2 3 |8 5 4 |1 6 9 +1 6 4 |3 7 9 |5 2 8 +------+------+------ \ No newline at end of file diff --git a/examples/three_row_incomplete.sudoku b/examples/three_row_incomplete.sudoku new file mode 100644 index 0000000..b650a03 --- /dev/null +++ b/examples/three_row_incomplete.sudoku @@ -0,0 +1,4 @@ +8 5 . |. . 2 |4 . . +7 2 3 |8 5 4 |1 6 9 +1 6 4 |3 7 9 |5 2 8 +------+------+------ \ No newline at end of file diff --git a/examples/three_row_invalid.sudoku b/examples/three_row_invalid.sudoku new file mode 100644 index 0000000..000b836 --- /dev/null +++ b/examples/three_row_invalid.sudoku @@ -0,0 +1,4 @@ +8 5 9 |6 1 2 |4 3 7 +7 2 3 |8 5 4 |1 6 9 +1 6 4 |3 7 9 |5 2 2 +------+------+------ \ No newline at end of file diff --git a/examples/two_row.sudoku b/examples/two_row.sudoku new file mode 100644 index 0000000..879a438 --- /dev/null +++ b/examples/two_row.sudoku @@ -0,0 +1,2 @@ +8 5 9 |6 1 2 |4 3 7 +7 2 3 |8 5 4 |1 6 9 \ No newline at end of file diff --git a/lib/sudoku_parser.rb b/lib/sudoku_parser.rb new file mode 100644 index 0000000..248be95 --- /dev/null +++ b/lib/sudoku_parser.rb @@ -0,0 +1,24 @@ +class SudokuParser + def initialize(file) + @file = File.new(file, "r") + end + + def parse + sudoku_array = [] + counter = 1 + while (line = @file.gets) + next if line.index('-') + line = remove_bars(line) + sudoku_array << convert_string_to_array(line).collect{|i| i.to_i} + end + @file.close + sudoku_array + end + + def remove_bars(line) + line.gsub('|', '') + end + def convert_string_to_array(string) + string.split(' ') + end +end \ No newline at end of file diff --git a/lib/sudoku_validator.rb b/lib/sudoku_validator.rb new file mode 100644 index 0000000..f3687ac --- /dev/null +++ b/lib/sudoku_validator.rb @@ -0,0 +1,154 @@ +class SudokuValidator + def initialize(sudoku = []) + @sudoku = sudoku + @rows = get_rows + @columns = get_columns + @grids = get_grids + end + + def get_rows + @sudoku + end + + def get_columns + @sudoku.transpose + end + + def get_grids + a = @sudoku + grids = [] + sub_grid = [] + + (0..2).each do |j| + (0..2).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] +(0..2).each do |j| + (3..5).each do |i| + sub_grid << a[j][i] + end + + end + + grids << sub_grid + sub_grid = [] + (0..2).each do |j| + (6..8).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] + + (3..5).each do |j| + (0..2).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] +(3..5).each do |j| + (3..5).each do |i| + sub_grid << a[j][i] + end + + end + + grids << sub_grid + sub_grid = [] + (3..5).each do |j| + (6..8).each do |i| + sub_grid << a[j][i] + end + end + + + sub_grid = [] + + (6..8).each do |j| + (0..2).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] +(6..8).each do |j| + (3..5).each do |i| + sub_grid << a[j][i] + end + + end + + grids << sub_grid + sub_grid = [] + (6..8).each do |j| + (6..8).each do |i| + sub_grid << a[j][i] + end + end + +grids << sub_grid + grids + end + + def validate_row(row) + row.collect{|i| i.to_i}.sort.join == "123456789" + end + + def validate_column(column) + column.collect{|i| i.to_i}.sort.join == "123456789" + end + + def validate_grid(grid) + grid.collect{|i| i.to_i}.sort.join == "123456789" + end + + + def validate_rows + @rows.each do |row| + if validate_row(row) + next + else + return false + end + return true + end + end + + def validate_columns + @columns.each do |column| + if validate_column(column) + next + else + return false + end + return true + end + end + + def validate_grids + @grids.each do |grid| + if validate_grid(grid) + next + else + return false + end + return true + end + end + + def validate + if validate_rows && validate_columns && validate_grids + "This sudoku is valid." + else + "This sudoku is invalid." + end + end +end \ No newline at end of file diff --git a/one_row.sudoku b/one_row.sudoku new file mode 100644 index 0000000..b512a45 --- /dev/null +++ b/one_row.sudoku @@ -0,0 +1 @@ +8 5 9 |6 1 2 |4 3 7 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 0000000..2eb5722 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,15 @@ +require 'rubygems' +require 'spork' + +Spork.prefork do + ENV["RAILS_ENV"] ||= 'test' + require 'rspec/autorun' + + RSpec.configure do |config| + end +end + +Spork.each_run do + # This code will be run each time you run your specs. + +end diff --git a/spec/sudoku_parser_spec.rb b/spec/sudoku_parser_spec.rb new file mode 100644 index 0000000..57d9045 --- /dev/null +++ b/spec/sudoku_parser_spec.rb @@ -0,0 +1,57 @@ +require 'spec_helper' +require_relative '../lib/sudoku_parser' +describe SudokuParser do + context "#parse" do + it "returns the one row sudoku in an array" do + parser = SudokuParser.new('examples/one_row.sudoku') + result = parser.parse + result.should eq([[8, 5, 9, 6, 1, 2, 4, 3, 7 ]]) + end + + it "returns the two sudoku in an array" do + parser = SudokuParser.new('examples/two_row.sudoku') + result = parser.parse + result.should eq([[8, 5, 9, 6, 1, 2, 4, 3, 7 ],[7 ,2, 3 ,8, 5, 4, 1, 6, 9]]) + end + + it "returns the three sudoku in an array" do + parser = SudokuParser.new('examples/three_row.sudoku') + result = parser.parse + result.should eq([[8,5, 9, 6, 1, 2, 4, 3, 7 ],[7 ,2, 3 ,8, 5, 4, 1, 6, 9],[1, 6, 4, 3, 7, 9, 5, 2, 8 ]]) + end + + it "returns the three incomplete row sudoku in an array by replacing empty values with zero" do + parser = SudokuParser.new('examples/three_row_incomplete.sudoku') + result = parser.parse + result.should eq([[8, 5, 0, 0, 0, 2, 4, 0, 0], [7, 2, 3, 8, 5, 4, 1, 6, 9], [1, 6, 4, 3, 7, 9, 5, 2, 8]]) + end + + it "returns the full sudoku in an array" do + parser = SudokuParser.new('valid_complete.sudoku') + result = parser.parse + result.should eq([[8, 5, 9, 6, 1, 2, 4, 3, 7], + [7, 2, 3, 8, 5, 4, 1, 6, 9], + [1, 6, 4, 3, 7, 9, 5, 2, 8], + [9, 8, 6, 1, 4, 7, 3, 5, 2], + [3, 7, 5, 2, 6, 8, 9, 1, 4], + [2, 4, 1, 5, 9, 3, 7, 8, 6], + [4, 3, 2, 9, 8, 1, 6, 7, 5], + [6, 1, 7, 4, 2, 5, 8, 9, 3], + [5, 9, 8, 7, 3, 6, 2, 4, 1]]) + end + + it "returns the full incomplete sudoku in an array" do + parser = SudokuParser.new('valid_incomplete.sudoku') + result = parser.parse + result.should eq([[8, 5, 0, 0, 0, 2, 4, 0, 0], + [7, 2, 0, 0, 0, 0, 0, 0, 9], + [0, 0, 4, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 1, 0, 7, 0, 0, 2], + [3, 0, 5, 0, 0, 0, 9, 0, 0], + [0, 4, 0, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 8, 0, 0, 7, 0], + [0, 1, 7, 0, 0, 0, 0, 0, 0], + [0, 0, 0, 0, 3, 6, 0, 4, 0]]) + end + end +end \ No newline at end of file diff --git a/spec/sudoku_validator_spec.rb b/spec/sudoku_validator_spec.rb new file mode 100644 index 0000000..35903a3 --- /dev/null +++ b/spec/sudoku_validator_spec.rb @@ -0,0 +1,39 @@ +require 'spec_helper' +require_relative '../lib/sudoku_validator' +require_relative '../lib/sudoku_parser' +describe SudokuValidator do + context "#validate" do + it "validates complete valid sudoku" do + parser = SudokuParser.new('valid_complete.sudoku') + sudoku_in_multidimensional_array = parser.parse + validator = SudokuValidator.new(sudoku_in_multidimensional_array) + result = validator.validate + result.should eq("This sudoku is valid.") + end + + it "validates incomplete valid sudoku" do + parser = SudokuParser.new('valid_incomplete.sudoku') + sudoku_in_multidimensional_array = parser.parse + validator = SudokuValidator.new(sudoku_in_multidimensional_array) + result = validator.validate + result.should eq("This sudoku is invalid.") + end + + it "validates complete invalid sudoku" do + parser = SudokuParser.new('invalid_complete.sudoku') + sudoku_in_multidimensional_array = parser.parse + validator = SudokuValidator.new(sudoku_in_multidimensional_array) + result = validator.validate + result.should eq("This sudoku is invalid.") + end + + it "validates incomplete invalid sudoku" do + parser = SudokuParser.new('invalid_incomplete.sudoku') + sudoku_in_multidimensional_array = parser.parse + validator = SudokuValidator.new(sudoku_in_multidimensional_array) + result = validator.validate + result.should eq("This sudoku is invalid.") + end + + end +end \ No newline at end of file diff --git a/sudoku-validator.rb b/sudoku-validator.rb new file mode 100644 index 0000000..62a468c --- /dev/null +++ b/sudoku-validator.rb @@ -0,0 +1,7 @@ +require_relative 'lib/sudoku_validator' +require_relative 'lib/sudoku_parser' +parser = SudokuParser.new(ARGV[0]) +sudoku_in_multidimensional_array = parser.parse +validator = SudokuValidator.new(sudoku_in_multidimensional_array) +result = validator.validate +puts result \ No newline at end of file diff --git a/test.rb b/test.rb new file mode 100644 index 0000000..403de3b --- /dev/null +++ b/test.rb @@ -0,0 +1,94 @@ +a = [[8, 5, 9, 6, 1, 2, 4, 3, 7], + [7, 2, 3, 8, 5, 4, 1, 6, 9], + [1, 6, 4, 3, 7, 9, 5, 2, 8], + [9, 8, 6, 1, 4, 7, 3, 5, 2], + [3, 7, 5, 2, 6, 8, 9, 1, 4], + [2, 4, 1, 5, 9, 3, 7, 8, 6], + [4, 3, 2, 9, 8, 1, 6, 7, 5], + [6, 1, 7, 4, 2, 5, 8, 9, 3], + [5, 9, 8, 7, 3, 6, 2, 4, 1]] +grids = [] + sub_grid = [] + + (0..2).each do |j| + (0..2).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] +(0..2).each do |j| + (3..5).each do |i| + sub_grid << a[j][i] + end + + end + + grids << sub_grid + sub_grid = [] + (0..2).each do |j| + (6..8).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] + + (3..5).each do |j| + (0..2).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] +(3..5).each do |j| + (3..5).each do |i| + sub_grid << a[j][i] + end + + end + + grids << sub_grid + sub_grid = [] + (3..5).each do |j| + (6..8).each do |i| + sub_grid << a[j][i] + end + end + + + sub_grid = [] + + (6..8).each do |j| + (0..2).each do |i| + sub_grid << a[j][i] + end + end + + grids << sub_grid + sub_grid = [] +(6..8).each do |j| + (3..5).each do |i| + sub_grid << a[j][i] + end + + end + + grids << sub_grid + sub_grid = [] + (6..8).each do |j| + (6..8).each do |i| + sub_grid << a[j][i] + end + end + + + + + + + grids << sub_grid +p grids \ No newline at end of file diff --git a/three_row.sudoku b/three_row.sudoku new file mode 100644 index 0000000..d6b5207 --- /dev/null +++ b/three_row.sudoku @@ -0,0 +1,4 @@ +8 5 9 |6 1 2 |4 3 7 +7 2 3 |8 5 4 |1 6 9 +1 6 4 |3 7 9 |5 2 8 +------+------+------ \ No newline at end of file diff --git a/two_row.sudoku b/two_row.sudoku new file mode 100644 index 0000000..879a438 --- /dev/null +++ b/two_row.sudoku @@ -0,0 +1,2 @@ +8 5 9 |6 1 2 |4 3 7 +7 2 3 |8 5 4 |1 6 9 \ No newline at end of file