sudoku_builder 0.1.3 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|