Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ### NOTES:
- # some examples of how i use the term 'index', 'column', 'row', 'square' below
- # index(0)=row(0) col(0) square(0)
- # index(8)=row(0) col(1) square(3)
- # index(9)=row(1) col(0) square(0)
- # index(27)=row(3) col(0) square(4)
- # index(80)=row(8) col(8) square(8)
- #
- # index is between 0 and 80 inclusive
- # row column and square are between 0 and 8 inclusive
- #
- # i use the term 'box' to indicate a something which has one number in it. (each row has 9 boxes...)
- ############################################################# THE BAREBONES
- class Sudo
- def self.index_to_row_col_sq(index) #### converts the index of a 'box' (0-81) to its row, column and square
- row,col=index.divmod(9)
- sq=((row/3)*3)+((col/3)) #Row 0 includes squares 0,1,2. Col 0 includes squares 0,3,6.
- [row,col,sq]
- end
- attr_accessor :rows,:cols,:squares
- def initialize (arr) ### input is an array of 81 things in the set [1,2,3,4,5,6,7,8,9,nil]
- if arr.length != 81 then raise "BAD INPUT - length not 81" end
- if arr.uniq - [1,2,3,4,5,6,7,8,9,nil] != [] then raise "BAD INPUT - includes things that arent 1-9 or nil" end
- @rows=Array.new;@cols=Array.new; @squares=Array.new
- 9.times{ @rows << Array.new; @cols << Array.new; @squares << Array.new}
- arr.each_with_index{|anel,i|
- row,col,sq=Sudo.index_to_row_col_sq(i)
- @rows[row] << anel; @cols[col] << anel; @squares[sq] << anel
- }
- end
- def potential_numbers_at_index(index) #checks the row,square and column of
- row,col,sq=Sudo.index_to_row_col_sq(index)
- [1,2,3,4,5,6,7,8,9]-@rows[row]-@cols[col]-@squares[sq]
- end
- def simple_children
- tochange=@rows.flatten.index(nil) #fill in the first blank
- totry=potential_numbers_at_index(tochange)
- totry.collect{|onetotry|
- newarr=@rows.flatten; newarr[tochange]=onetotry
- Sudo.new(newarr)
- }
- end
- def solutions
- poss=[self]
- @rows.flatten.count(nil).times{|i| ### for every unsolved number
- nextset=[]
- poss.each{|aposs| nextset+=aposs.simple_children}
- poss=nextset
- }
- poss
- end
- end
- # asquare=Sudo.new [nil, nil, 3, nil, 2, nil, 6, nil, nil,
- # 9 , nil, nil, 3, nil, 5, nil, nil, 1,
- # nil, nil, 1, 8, nil, 6, 4, nil, nil,
- # nil, nil, 8, 1, nil, 2, 9, nil, nil,
- # 7 , nil, nil, nil, nil, nil, nil, nil, 8,
- # nil, nil, 6, 7, nil, 8, 2, nil, nil,
- # nil, nil, 2, 6, nil, 9, 5, nil, nil,
- # 8 , nil, nil, 2, nil, 3, nil, nil, 9,
- # nil, nil, 5, nil ,1, nil, 3, nil, nil,
- # ]
- # z=Time.now
- # asquare.solutions
- # p Time.now-z #0.0625 seconds
- # asquare.solutions[0].rows.each{|arow| p arow}
- # [4, 8, 3, 9, 2, 1, 6, 5, 7]
- # [9, 6, 7, 3, 4, 5, 8, 2, 1]
- # [2, 5, 1, 8, 7, 6, 4, 9, 3]
- # [5, 4, 8, 1, 3, 2, 9, 7, 6]
- # [7, 2, 9, 5, 6, 4, 1, 3, 8]
- # [1, 3, 6, 7, 9, 8, 2, 4, 5]
- # [3, 7, 2, 6, 8, 9, 5, 1, 4]
- # [8, 1, 4, 2, 5, 3, 7, 6, 9]
- # [6, 9, 5, 4, 1, 7, 3, 8, 2]
- # exit
- ############################################################# SOME 'NICE TO HAVE's
- class Sudo
- def self.fromtext(string)
- newstring=string.gsub(/\s/,"")
- newarr=[]
- newstring.each_char{|a| if a=="0" then newarr << nil else newarr << a.to_i end}
- self.new(newarr)
- end
- def showsolutions
- timeatstart=Time.now
- allsol=self.solutions
- timeatend=Time.now
- if allsol.empty? then puts "NO SOLUTIONS" end
- self.solutions.each_with_index{|asol,i|
- puts
- puts "SOLUTION: "+(i+1).inspect+" of "+allsol.length.inspect
- asol.showit
- }
- p "TIME TO SOLVE: "+(timeatend-timeatstart).inspect+" seconds"
- end
- def showit
- self.rows.each_with_index{|arow,index|
- arow.each_with_index{|abox,i| print abox; if i==2 or i==5 then print "|" end };puts
- # puts arow[0..2].inspect+"|"+arow[3..5].inspect+"|"+arow[6..8].inspect
- if index==2 or index==5 then
- puts "---+---+---"
- end
- }
- end
- end
- #### EXAMPLES FROM http://projecteuler.net/project/sudoku.txt
- ### Grid 01
- # Sudo.fromtext("003020600
- # 900305001
- # 001806400
- # 008102900
- # 700000008
- # 006708200
- # 002609500
- # 800203009
- # 005010300").showsolutions #0.078125 seconds
- ### Grid 25
- # Sudo.fromtext("360020089
- # 000361000
- # 000000000
- # 803000602
- # 400603007
- # 607000108
- # 000000000
- # 000418000
- # 970030014").showsolutions #0.578125 seconds
- ### Grid 50
- # Sudo.fromtext("300200000
- # 000107000
- # 706030500
- # 070009080
- # 900020004
- # 010800050
- # 009040301
- # 000702000
- # 000008006").showsolutions #8.078125 seconds
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement