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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5cd22cf34be740677d7e4c7ba5f7997a2e41dc36
4
- data.tar.gz: bf6f3b10480eabb2e75faf004bb7f87b830745db
3
+ metadata.gz: e2f78e53297fdec3ed32da905e2f8fc984436e7c
4
+ data.tar.gz: 7f308155099b5b3a3337bcffbdabf9fac49b243d
5
5
  SHA512:
6
- metadata.gz: 806f32b0950b8e93781c3645bc674904deeb3974dfad7eb5be944f10d8eea92a2bfbf96ce55cf6d08a9ad3d856147f3acdd350382b02c9241446468f1ed990b9
7
- data.tar.gz: 9bc41c7f3727ac016540af440d11dbba71eff35ee0621ecab6f2da877db5391ad77e48faacdffffef657b9c63ff76c32389f36ad11b9415e3f0d665e885f8f2d
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
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in sudoku.gemspec
3
+ # Specify your gem's dependencies in sudoku_builder.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -1,14 +1,8 @@
1
- # Sudoku
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
- To create a new puzzle:
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
- `SudokuBuilder::Solver.new(my_puzzle).solve`
27
+ ## Development
52
28
 
53
- my_puzzle must be equal to a hash with keys from 0 to 80 and values equal to an integer for already given squares, and an array for empty squares. ie:
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/ColDog/sudoku/fork )
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`)
@@ -1,11 +1,30 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'sudoku_builder/sudoku'))
2
- require File.expand_path(File.join(File.dirname(__FILE__), 'sudoku_builder/builder'))
3
- require File.expand_path(File.join(File.dirname(__FILE__), 'sudoku_builder/solver' ))
4
- require File.expand_path(File.join(File.dirname(__FILE__), 'sudoku_builder/version'))
5
-
6
- module SudokuBuilder
7
- extend self
8
- def new
9
- Solver.new.create
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
- require File.expand_path(File.join(File.dirname(__FILE__), 'sudoku'))
1
+ class SudokuBuilder
2
2
 
3
- module SudokuBuilder
4
- class Builder < Sudoku
5
- def initialize(sudoku)
6
- @sud = sudoku
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
- def parse
10
- @sud.each do |k,v|
11
- if v.class == Array && v[0] == nil
12
- @sud[k] = []
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
- # checks if a sudoku is valid.
45
- def valid?
46
- valid = []
47
- @sud.each do |k,v|
48
- c = [] ; r = [] ; g = []
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
- def medium(poke_with = [])
61
- self.poke(45, poke_with)
22
+ @tot += 1
62
23
  end
24
+ end
63
25
 
64
- def easy(poke_with = [])
65
- self.poke(55, poke_with)
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
- def hard(poke_with = [])
69
- self.poke(65, poke_with)
70
- end
34
+ def hard
35
+ poke(65)
36
+ end
71
37
 
72
- def pretty_print
73
- b = self.to_hash
74
- puts "+-----------------------------+"
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
- end
45
+
46
+ end
@@ -0,0 +1,9 @@
1
+ class SudokuBuilder
2
+
3
+ class PuzzleFormatError < StandardError
4
+ end
5
+
6
+ class SolverError < StandardError
7
+ end
8
+
9
+ end
@@ -0,0 +1,19 @@
1
+ class SudokuBuilder
2
+
3
+ def pretty
4
+ @sud.each_with_index do |row|
5
+ print row.join(' ')
6
+ puts ' '
7
+ end
8
+ puts ' '
9
+ end
10
+
11
+ def to_a
12
+ @sud
13
+ end
14
+
15
+ def to_flat_a
16
+ @sud.flatten
17
+ end
18
+
19
+ end
@@ -1,108 +1,40 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), 'sudoku'))
2
- require File.expand_path(File.join(File.dirname(__FILE__), 'builder'))
1
+ class SudokuBuilder
3
2
 
4
- module SudokuBuilder
5
- class Solver < Sudoku
3
+ def solve
4
+ @loc = [0,0,0] ; @tot = 0 ; @res = 0 ; up = true
6
5
 
7
- def initialize(sudoku = nil)
8
- @sud = sudoku
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
- def solver_pristine
23
- @sud
24
- end
9
+ if value.class == Fixnum
25
10
 
26
- def solve
27
- t = 0 ; o = 0 ; key = 0 # main key and metric vars.
28
- direction = true # indicates the direction in case of a backtrack on number.
29
- sud = solver_pristine
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
- def create
75
- sud = pristine
76
- used = pristine
77
- t = 0 ; o = 0 ; key = 0 # main key and metric variables
78
- loop do
79
- c = [] ; r = [] ; g = [] # build values for current grid, row, column.
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
- if sud[key].count == 0 # backtrack if no possibilities.
89
- key -= 1
25
+
26
+ if !poss.empty?
27
+ write(poss.sample)
28
+ increment ; up = true
90
29
  else
91
- use = sud[key].sample # pick a random possibility.
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
- break if key == 81 # break if we've reached the last value.
102
- t += 1 ; o += 1 # add the reporting variables
32
+
103
33
  end
104
- Builder.new(sud)
34
+
35
+ @tot += 1
105
36
  end
106
37
 
107
38
  end
39
+
108
40
  end