sudoku_builder 0.1.3 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -39
- data/Gemfile +1 -1
- data/README.md +8 -35
- data/lib/sudoku_builder.rb +28 -9
- data/lib/sudoku_builder/builder.rb +32 -76
- data/lib/sudoku_builder/errors.rb +9 -0
- data/lib/sudoku_builder/presenter.rb +19 -0
- data/lib/sudoku_builder/solver.rb +25 -93
- data/lib/sudoku_builder/tools.rb +91 -0
- data/lib/sudoku_builder/values.rb +45 -0
- data/lib/sudoku_builder/version.rb +2 -2
- metadata +6 -14
- data/.idea/.name +0 -1
- data/.idea/.rakeTasks +0 -7
- data/.idea/encodings.xml +0 -4
- data/.idea/misc.xml +0 -4
- data/.idea/modules.xml +0 -8
- data/.idea/scopes/scope_settings.xml +0 -5
- data/.idea/sudoku.iml +0 -18
- data/.idea/vcs.xml +0 -6
- data/.idea/workspace.xml +0 -558
- data/Gemfile.lock +0 -17
- data/LICENSE +0 -22
- data/lib/sudoku_builder/sudoku.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e2f78e53297fdec3ed32da905e2f8fc984436e7c
|
4
|
+
data.tar.gz: 7f308155099b5b3a3337bcffbdabf9fac49b243d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 068da8c8bb8943e81ed6e45ebcb959c8c07c0d7c39fe78396e4d994247f5b218c2afb145a10c483a01a96e3f4934fefa99b574c6456aa6b6b6591bafadbbc0a5
|
7
|
+
data.tar.gz: 9efc78638e5afd319a73c1baca0f699e58ae2e95443748e14cf44c7e52fd17af9820027754981677234150a306e7418ace9fde78005b7664d027754b3f97e616
|
data/.gitignore
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
<<<<<<< HEAD
|
2
1
|
/.bundle/
|
3
2
|
/.yardoc
|
4
3
|
/Gemfile.lock
|
@@ -8,41 +7,3 @@
|
|
8
7
|
/pkg/
|
9
8
|
/spec/reports/
|
10
9
|
/tmp/
|
11
|
-
=======
|
12
|
-
*.gem
|
13
|
-
*.rbc
|
14
|
-
/.config
|
15
|
-
/coverage/
|
16
|
-
/InstalledFiles
|
17
|
-
/pkg/
|
18
|
-
/spec/reports/
|
19
|
-
/test/tmp/
|
20
|
-
/test/version_tmp/
|
21
|
-
/tmp/
|
22
|
-
|
23
|
-
## Specific to RubyMotion:
|
24
|
-
.dat*
|
25
|
-
.repl_history
|
26
|
-
build/
|
27
|
-
|
28
|
-
## Documentation cache and generated files:
|
29
|
-
/.yardoc/
|
30
|
-
/_yardoc/
|
31
|
-
/doc/
|
32
|
-
/rdoc/
|
33
|
-
|
34
|
-
## Environment normalisation:
|
35
|
-
/.bundle/
|
36
|
-
/vendor/bundle
|
37
|
-
/lib/bundler/man/
|
38
|
-
|
39
|
-
# for a library or gem, you might want to ignore these files since the code is
|
40
|
-
# intended to run in multiple environments; otherwise, check them in:
|
41
|
-
# Gemfile.lock
|
42
|
-
# .ruby-version
|
43
|
-
# .ruby-gemset
|
44
|
-
|
45
|
-
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
46
|
-
.rvmrc
|
47
|
-
>>>>>>> 672b09b6331859edf9d3a2a39930340418f78e37
|
48
|
-
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,14 +1,8 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
Welcome to `SudokuBuilder`. Build and fill out sudoku's with the same tool!
|
4
|
-
|
5
|
-
### Quick Start
|
6
|
-
`> require 'sudoku_builder'`
|
7
|
-
|
8
|
-
Run the following in the console:
|
9
|
-
`> SudokuBuilder.new.pretty_print`
|
1
|
+
# SudokuBuilder
|
10
2
|
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/sudoku_builder`. To experiment with that code, run `bin/console` for an interactive prompt.
|
11
4
|
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
12
6
|
|
13
7
|
## Installation
|
14
8
|
|
@@ -28,38 +22,17 @@ Or install it yourself as:
|
|
28
22
|
|
29
23
|
## Usage
|
30
24
|
|
31
|
-
|
32
|
-
|
33
|
-
`SudokuBuilder.new`
|
34
|
-
|
35
|
-
This will return a `SudokuBuilder::Builder` object that looks like this:
|
36
|
-
|
37
|
-
```ruby
|
38
|
-
#<SudokuBuilder::Builder:0x007fdc729373e8 @sud={0=>[6], 1=>[8], 2=>[9], 3=>[5], 4=>[7], 5=>[2], 6=>[3], ...
|
39
|
-
```
|
40
|
-
|
41
|
-
On the builder object you can call a handful of different methods:
|
42
|
-
|
43
|
-
- `valid?` checks if the sudoku is valid.
|
44
|
-
- `to_hash` turns it into a regular hash.
|
45
|
-
- `poke(number, poke_with)` pokes holes in the puzzle. (to create a solvable sudoku)
|
46
|
-
- `medium`, `easy` and `hard` poke a set number of holes in the puzzle.
|
47
|
-
- `pretty_print` makes it print out nice on the command line.
|
48
|
-
|
49
|
-
To solve an existing puzzle, call:
|
25
|
+
TODO: Write usage instructions here
|
50
26
|
|
51
|
-
|
27
|
+
## Development
|
52
28
|
|
53
|
-
|
54
|
-
|
55
|
-
```
|
56
|
-
{0=>6, 1=>8, 2=>[], 3=>[], 4=>[], 5=>[], 6=>[3] ...
|
57
|
-
```
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
58
30
|
|
31
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
59
32
|
|
60
33
|
## Contributing
|
61
34
|
|
62
|
-
1. Fork it ( https://github.com/
|
35
|
+
1. Fork it ( https://github.com/[my-github-username]/sudoku_builder/fork )
|
63
36
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
64
37
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
65
38
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/lib/sudoku_builder.rb
CHANGED
@@ -1,11 +1,30 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
1
|
+
require "sudoku_builder/version"
|
2
|
+
require "sudoku_builder/builder"
|
3
|
+
require "sudoku_builder/presenter"
|
4
|
+
require "sudoku_builder/tools"
|
5
|
+
require "sudoku_builder/values"
|
6
|
+
require "sudoku_builder/errors"
|
7
|
+
require "sudoku_builder/solver"
|
8
|
+
|
9
|
+
class SudokuBuilder
|
10
|
+
attr_reader :tot, :res
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@sud = blank
|
14
|
+
@used = blank
|
15
|
+
@loc = [0,0,0] ; @tot = 0 ; @res = 0
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.create
|
19
|
+
sudoku = SudokuBuilder.new
|
20
|
+
sudoku.build
|
21
|
+
sudoku
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.solve(puzzle)
|
25
|
+
sudoku = SudokuBuilder.new
|
26
|
+
sudoku.parse_for_solve(puzzle)
|
27
|
+
sudoku.solve
|
28
|
+
sudoku
|
10
29
|
end
|
11
30
|
end
|
@@ -1,90 +1,46 @@
|
|
1
|
-
|
1
|
+
class SudokuBuilder
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
@sud
|
7
|
-
end
|
3
|
+
def build
|
4
|
+
@loc = [0,0,0] ; @tot = 0 ; @res = 0
|
5
|
+
loop do
|
6
|
+
return @sud if @loc == [9,0,0]
|
8
7
|
|
9
|
-
|
10
|
-
|
11
|
-
if
|
12
|
-
|
13
|
-
elsif v.class == Array && v[0] != nil
|
14
|
-
@sud[k] = v[0]
|
15
|
-
else
|
16
|
-
@sud[k] = v
|
8
|
+
poss = []
|
9
|
+
(1..9).each do |i|
|
10
|
+
if check?(i)
|
11
|
+
poss << i
|
17
12
|
end
|
18
13
|
end
|
19
|
-
@sud
|
20
|
-
end
|
21
|
-
|
22
|
-
def to_hash
|
23
|
-
@sud.each do |k,v|
|
24
|
-
@sud[k] = v[0] if v.class == Array
|
25
|
-
end
|
26
|
-
@sud
|
27
|
-
end
|
28
|
-
|
29
|
-
# pokes holes in a built sudoku to make it solvable.
|
30
|
-
# arranged by level of difficulty.
|
31
|
-
def poke(number, poke_with = [])
|
32
|
-
@sud.to_hash
|
33
|
-
poke = []
|
34
|
-
until poke.count == number # number is related to difficulty.
|
35
|
-
poke << rand(0..80) # 0 - 80 refers to the index of the sudoku cells.
|
36
|
-
poke = poke.uniq
|
37
|
-
end
|
38
|
-
poke.each do |p| # pokes random holes.
|
39
|
-
@sud[p] = poke_with
|
40
|
-
end
|
41
|
-
Builder.new(@sud)
|
42
|
-
end
|
43
14
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
build_crg(k,c,r,g,@sud)
|
50
|
-
v.class == Array ? val = v[0] : val = v
|
51
|
-
if check?(val, c,r,g) # runs the check method used before on every value.
|
52
|
-
valid << false
|
53
|
-
else
|
54
|
-
valid << true
|
55
|
-
end
|
15
|
+
if !poss.empty?
|
16
|
+
write(poss.sample)
|
17
|
+
increment
|
18
|
+
else
|
19
|
+
de_increment
|
56
20
|
end
|
57
|
-
!valid.include?(false)
|
58
|
-
end
|
59
21
|
|
60
|
-
|
61
|
-
self.poke(45, poke_with)
|
22
|
+
@tot += 1
|
62
23
|
end
|
24
|
+
end
|
63
25
|
|
64
|
-
|
65
|
-
|
26
|
+
def poke(num)
|
27
|
+
sud = to_flat_a
|
28
|
+
num.times do
|
29
|
+
sud[rand(0..80)] = nil
|
66
30
|
end
|
31
|
+
sud
|
32
|
+
end
|
67
33
|
|
68
|
-
|
69
|
-
|
70
|
-
|
34
|
+
def hard
|
35
|
+
poke(65)
|
36
|
+
end
|
71
37
|
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
puts "| #{b[0]} #{b[1]} #{b[2]} | #{b[3]} #{b[4]} #{b[5]} | #{b[6]} #{b[7]} #{b[8]} |"
|
76
|
-
puts "| #{b[9]} #{b[10]} #{b[11]} | #{b[12]} #{b[13]} #{b[14]} | #{b[15]} #{b[16]} #{b[17]} |"
|
77
|
-
puts "| #{b[18]} #{b[19]} #{b[20]} | #{b[21]} #{b[22]} #{b[23]} | #{b[24]} #{b[25]} #{b[26]} |"
|
78
|
-
puts "+-----------------------------+"
|
79
|
-
puts "| #{b[27]} #{b[28]} #{b[29]} | #{b[30]} #{b[31]} #{b[32]} | #{b[33]} #{b[34]} #{b[35]} |"
|
80
|
-
puts "| #{b[36]} #{b[37]} #{b[38]} | #{b[39]} #{b[40]} #{b[41]} | #{b[42]} #{b[43]} #{b[44]} |"
|
81
|
-
puts "| #{b[45]} #{b[46]} #{b[47]} | #{b[48]} #{b[49]} #{b[50]} | #{b[51]} #{b[52]} #{b[53]} |"
|
82
|
-
puts "+-----------------------------+"
|
83
|
-
puts "| #{b[54]} #{b[55]} #{b[56]} | #{b[57]} #{b[58]} #{b[59]} | #{b[60]} #{b[61]} #{b[62]} |"
|
84
|
-
puts "| #{b[63]} #{b[64]} #{b[65]} | #{b[66]} #{b[67]} #{b[68]} | #{b[69]} #{b[70]} #{b[71]} |"
|
85
|
-
puts "| #{b[72]} #{b[73]} #{b[74]} | #{b[75]} #{b[76]} #{b[77]} | #{b[78]} #{b[79]} #{b[80]} |"
|
86
|
-
puts "+-----------------------------+"
|
87
|
-
end
|
38
|
+
def medium
|
39
|
+
poke(50)
|
40
|
+
end
|
88
41
|
|
42
|
+
def easy
|
43
|
+
poke(35)
|
89
44
|
end
|
90
|
-
|
45
|
+
|
46
|
+
end
|
@@ -1,108 +1,40 @@
|
|
1
|
-
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'builder'))
|
1
|
+
class SudokuBuilder
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+
def solve
|
4
|
+
@loc = [0,0,0] ; @tot = 0 ; @res = 0 ; up = true
|
6
5
|
|
7
|
-
|
8
|
-
@sud
|
9
|
-
@used = {
|
10
|
-
0=> [], 1=> [], 2=> [], 3=> [], 4=> [], 5=> [], 6=> [], 7=> [], 8=> [],
|
11
|
-
9=> [], 10=>[], 11=>[], 12=>[], 13=>[], 14=>[], 15=>[], 16=>[], 17=>[],
|
12
|
-
18=>[], 19=>[], 20=>[], 21=>[], 22=>[], 23=>[], 24=>[], 25=>[], 26=>[],
|
13
|
-
27=>[], 28=>[], 29=>[], 30=>[], 31=>[], 32=>[], 33=>[], 34=>[], 35=>[],
|
14
|
-
36=>[], 37=>[], 38=>[], 39=>[], 40=>[], 41=>[], 42=>[], 43=>[], 44=>[],
|
15
|
-
45=>[], 46=>[], 47=>[], 48=>[], 49=>[], 50=>[], 51=>[], 52=>[], 53=>[],
|
16
|
-
54=>[], 55=>[], 56=>[], 57=>[], 58=>[], 59=>[], 60=>[], 61=>[], 62=>[],
|
17
|
-
63=>[], 64=>[], 65=>[], 66=>[], 67=>[], 68=>[], 69=>[], 70=>[], 71=>[],
|
18
|
-
72=>[], 73=>[], 74=>[], 75=>[], 76=>[], 77=>[], 78=>[], 79=>[], 80=>[]
|
19
|
-
}
|
20
|
-
end
|
6
|
+
loop do
|
7
|
+
return @sud if @loc == [9,0,0]
|
21
8
|
|
22
|
-
|
23
|
-
@sud
|
24
|
-
end
|
9
|
+
if value.class == Fixnum
|
25
10
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
used = pristine
|
31
|
-
if sud.nil?
|
32
|
-
'Sudoku entered is not valid/
|
33
|
-
does not exist.'
|
34
|
-
else
|
35
|
-
loop do
|
36
|
-
if sud[key].class == Array # skips pre-filled numbers.
|
37
|
-
c = [] ; r = [] ; g = [] # build values for current grid, row, column.
|
38
|
-
build_crg(key,c,r,g,sud) # updates the relevant variables for check.
|
39
|
-
sud[key] = [] # makes a fresh possibilities array.
|
40
|
-
for i in 1..9
|
41
|
-
if check?(i, c,r,g) &&
|
42
|
-
!used[key].include?(i)
|
43
|
-
sud[key] << i
|
44
|
-
end
|
45
|
-
end
|
46
|
-
if sud[key].count == 0 # backtrack if no possibilities.
|
47
|
-
key -= 1
|
48
|
-
direction = false # setting backtrack to false sends the key down if the
|
49
|
-
else # next number down is a fixnum.
|
50
|
-
use = sud[key].sample # pick a random possibility.
|
51
|
-
sud[key] = [use] # uses the possibility.
|
52
|
-
used[key] << use # also puts it into the used array.
|
53
|
-
key += 1
|
54
|
-
direction = true
|
55
|
-
end
|
56
|
-
elsif sud[key].class == Fixnum
|
57
|
-
direction ? key += 1 : key -= 1 # backt or forward track based on current direction.
|
58
|
-
end
|
59
|
-
if key == 0 || t > 104 ||
|
60
|
-
key == 1 && t > 3 # resets everything if we've reached a high amount
|
61
|
-
sud = solver_pristine
|
62
|
-
used = pristine
|
63
|
-
key = 0 ; t = 0
|
64
|
-
direction = true
|
65
|
-
end
|
66
|
-
break if key == 81 # break if we've reached the last value.
|
67
|
-
t += 1 ; o += 1 # add the reporting variables.
|
68
|
-
break if o > 10000000 # there is the possibility to be given an unsolvable.
|
11
|
+
if up == true
|
12
|
+
increment
|
13
|
+
elsif up == false
|
14
|
+
de_increment
|
69
15
|
end
|
70
|
-
Builder.new(@sud)
|
71
|
-
end
|
72
|
-
end
|
73
16
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
build_crg(key,c,r,g,sud) # updates the relevant variables for check.
|
81
|
-
sud[key] = [] # makes a fresh possibilities array.
|
82
|
-
for i in 1..9
|
83
|
-
if check?(i,c,r,g) &&
|
84
|
-
!used[key].include?(i)
|
85
|
-
sud[key] << i
|
17
|
+
else
|
18
|
+
|
19
|
+
poss = []
|
20
|
+
(1..9).each do |i|
|
21
|
+
if check?(i)
|
22
|
+
poss << i
|
86
23
|
end
|
87
24
|
end
|
88
|
-
|
89
|
-
|
25
|
+
|
26
|
+
if !poss.empty?
|
27
|
+
write(poss.sample)
|
28
|
+
increment ; up = true
|
90
29
|
else
|
91
|
-
|
92
|
-
sud[key] = [use] # uses the possibility.
|
93
|
-
used[key] << use # also puts it into the used array.
|
94
|
-
key += 1
|
95
|
-
end
|
96
|
-
if key == 0 || t > 104 # resets everything if we've reached a high count.
|
97
|
-
sud = pristine
|
98
|
-
used = pristine
|
99
|
-
key = 0 ; t = 0
|
30
|
+
de_increment ; up = false
|
100
31
|
end
|
101
|
-
|
102
|
-
t += 1 ; o += 1 # add the reporting variables
|
32
|
+
|
103
33
|
end
|
104
|
-
|
34
|
+
|
35
|
+
@tot += 1
|
105
36
|
end
|
106
37
|
|
107
38
|
end
|
39
|
+
|
108
40
|
end
|