This repository was archived by the owner on Jun 8, 2019. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 36
initial commit #7
Open
brozturk
wants to merge
2
commits into
thoughtbot:master
Choose a base branch
from
brozturk:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like that you've made this method generic since the logic is the same for rows, columns, and subgrids. I think you could push a bit further in removing the duplication though, since the def valid_rows_columns_grids
[board.rows, board.columns, board.subgrids].none? { |set|
set.none? { |elements| check_for_duplicates(elements) }
}
endThe inner |
||
| 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.count(0) >= 1 | ||
| end | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can avoid the nested loops by using
repeated_permutation, which will give you exactly the same combinations ofnandxas nestingeach.If you combine that with
mapyou can also remove both the first and the last lines of the method.