jSudoku : a Sudoku solver with difficulty rating

Download jsudoku.zip

Synopsis:

jSudoku.rb


jSudoku.rb

Synopsis
#!ruby
#require 'profile'
require 'set'

$complexity = 1

#----------------------------------------
class Possibles
  #---------------
  def initialize()
    @Possible = Array.new(9)
    @Possible.each_index { |i| @Possible[i] = true }
  end

  #---------------
  def ClearAll()
    @Possible.each_index { |i| @Possible[i] = false }
  end

  #---------------
  def Clear(val)
    @Possible[val-1] = false
  end

  #---------------
  def IsPossible(val)
    return @Possible[val-1]
  end

  #---------------
  def GetOnePossible()
    v = nil
    count = 0
    @Possible.each_index { |i| 
#      print "y: #{i} #{@Possible[i]} #{count} #{v}\n"
      if @Possible[i] 
        count = count + 1
        v = i + 1
      end
    }
#    print "y: #{count} #{v}\n"
    return nil if count > 1
    return v
  end

  #---------------
  def Print(val)
    if @Possible[val-1]
      print "#{val}"
    else
      print " "
    end
  end
end

#----------------------------------------
class Cell
  #---------------
  def initialize(r, c)
    @Row = r
    @Col = c
    @Val = '?'
    @Possibles = Possibles.new
  end

  #---------------
  def Set(val)
    @Val = val
    @Possibles.ClearAll
  end

  #---------------
  def Get()
    return @Val
  end

  #---------------
  def IsSet()
    return @Val != '?'
  end

  #---------------
  def GetOnePossible
    return @Possibles.GetOnePossible
  end

  #---------------
  def IsPossible(val)
    return @Possibles.IsPossible(val)
  end

  #---------------
  def ClearPossible(val)
    @Possibles.Clear(val)
  end

  #---------------
  def PrintPossibles(i)
    @Possibles.Print(i)
  end

  #---------------
  def PrintVal()
    print "#@Val"
  end

  #---------------
  def Print()
    print "#@Row #@Col: #@Val\n"
  end

end 

#----------------------------------------
class Matrix < Array
  #---------------
  def initialize (rows, columns)
    super(rows)
    self.each_index { |i| 
          self[i] = Array.new(columns) 
          self[i].each_index { |j| self[i][j] = Cell.new(i+1, j+1) }
        }
  end
end

#----------------------------------------
class Board

  RowIndex0 = [[0,0], [0,1], [0,2], [0,3], [0,4], [0,5], [0,6], [0,7], [0,8]]
  RowIndex1 = [[1,0], [1,1], [1,2], [1,3], [1,4], [1,5], [1,6], [1,7], [1,8]]
  RowIndex2 = [[2,0], [2,1], [2,2], [2,3], [2,4], [2,5], [2,6], [2,7], [2,8]]
  RowIndex3 = [[3,0], [3,1], [3,2], [3,3], [3,4], [3,5], [3,6], [3,7], [3,8]]
  RowIndex4 = [[4,0], [4,1], [4,2], [4,3], [4,4], [4,5], [4,6], [4,7], [4,8]]
  RowIndex5 = [[5,0], [5,1], [5,2], [5,3], [5,4], [5,5], [5,6], [5,7], [5,8]]
  RowIndex6 = [[6,0], [6,1], [6,2], [6,3], [6,4], [6,5], [6,6], [6,7], [6,8]]
  RowIndex7 = [[7,0], [7,1], [7,2], [7,3], [7,4], [7,5], [7,6], [7,7], [7,8]]
  RowIndex8 = [[8,0], [8,1], [8,2], [8,3], [8,4], [8,5], [8,6], [8,7], [8,8]]
  Rows = [RowIndex0, RowIndex1, RowIndex2, RowIndex3, RowIndex4, RowIndex5, RowIndex6, RowIndex7, RowIndex8]
  
  ColIndex0 = [[0,0], [1,0], [2,0], [3,0], [4,0], [5,0], [6,0], [7,0], [8,0]]
  ColIndex1 = [[0,1], [1,1], [2,1], [3,1], [4,1], [5,1], [6,1], [7,1], [8,1]]
  ColIndex2 = [[0,2], [1,2], [2,2], [3,2], [4,2], [5,2], [6,2], [7,2], [8,2]]
  ColIndex3 = [[0,3], [1,3], [2,3], [3,3], [4,3], [5,3], [6,3], [7,3], [8,3]]
  ColIndex4 = [[0,4], [1,4], [2,4], [3,4], [4,4], [5,4], [6,4], [7,4], [8,4]]
  ColIndex5 = [[0,5], [1,5], [2,5], [3,5], [4,5], [5,5], [6,5], [7,5], [8,5]]
  ColIndex6 = [[0,6], [1,6], [2,6], [3,6], [4,6], [5,6], [6,6], [7,6], [8,6]]
  ColIndex7 = [[0,7], [1,7], [2,7], [3,7], [4,7], [5,7], [6,7], [7,7], [8,7]]
  ColIndex8 = [[0,8], [1,8], [2,8], [3,8], [4,8], [5,8], [6,8], [7,8], [8,8]]
  Cols = [ColIndex0, ColIndex1, ColIndex2, ColIndex3, ColIndex4, ColIndex5, ColIndex6, ColIndex7, ColIndex8]

  BlockIndex0 = [[0,0], [0,1], [0,2], [1,0], [1,1], [1,2], [2,0], [2,1], [2,2]]
  BlockIndex1 = [[0,3], [0,4], [0,5], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5]]
  BlockIndex2 = [[0,6], [0,7], [0,8], [1,6], [1,7], [1,8], [2,6], [2,7], [2,8]]
  BlockIndex3 = [[3,0], [3,1], [3,2], [4,0], [4,1], [4,2], [5,0], [5,1], [5,2]]
  BlockIndex4 = [[3,3], [3,4], [3,5], [4,3], [4,4], [4,5], [5,3], [5,4], [5,5]]
  BlockIndex5 = [[3,6], [3,7], [3,8], [4,6], [4,7], [4,8], [5,6], [5,7], [5,8]]
  BlockIndex6 = [[6,0], [6,1], [6,2], [7,0], [7,1], [7,2], [8,0], [8,1], [8,2]]
  BlockIndex7 = [[6,3], [6,4], [6,5], [7,3], [7,4], [7,5], [8,3], [8,4], [8,5]]
  BlockIndex8 = [[6,6], [6,7], [6,8], [7,6], [7,7], [7,8], [8,6], [8,7], [8,8]]
  Blocks = [BlockIndex0, BlockIndex1, BlockIndex2, BlockIndex3, BlockIndex4, BlockIndex5, BlockIndex6, BlockIndex7, BlockIndex8]

  #---------------
  def initialize()
    @Cells = Matrix.new(9, 9)
    @NumSet = 0
  end

  #---------------
  def InitRow(row, vals)
    (0..(vals.length-1)).each { |col|
      v = vals[col].chr
      next if v == ' '
      self.SetCell([row, col], v.to_i)
    }  
  end

  #---------------
  def IsComplete()
    return @NumSet == 81
  end
  
  #---------------
  def SetCell(pair, val)
    CellAt(pair).Set(val)
    ClearPossibles()
    @NumSet += @NumSet
  end

  #---------------
  def CellAt(pair)
    return @Cells[pair[0]][pair[1]]
  end

  #---------------
  def ClearPossiblesFor(indices)
    indices.each { |index|
      index.each { |pair| 
        cell = CellAt(pair)
        next unless cell.IsSet
        val = cell.Get()
        index.each { |pair2| CellAt(pair2).ClearPossible(val) }
      }
    }
  end

  #---------------
  def ClearPossibles()
    ClearPossiblesFor(Rows)
    ClearPossiblesFor(Cols)
    ClearPossiblesFor(Blocks)
  end

  #---------------
  def FindSingletonPossibleFor(indices)
    madechange = false
    indices.each { |index|
      index.each { |pair| 
        cell = CellAt(pair)
        next if cell.IsSet
        v = cell.GetOnePossible
        next if v == nil
        SetCell(pair, v)
        madechange = true
      }
    }
    return madechange
  end


  #---------------
  def ClearRowRange(val, row, cols)
    changed = false
    cols.each { |col|
    	cell = CellAt([row, col])
    	next unless cell.IsPossible(val)
  	  cell.ClearPossible(val)
  	  changed = true
    }
    return changed
  end

  #---------------
  def ClearColRange(val, col, rows)
    changed = false
    rows.each { |row|
    	cell = CellAt([row, col])
    	next unless cell.IsPossible(val)
  	  cell.ClearPossible(val)
  	  changed = true
    }
    return changed
  end
  
  #---------------
  def ClearRowIfInBlock(val, alist)
    rows2 = SortedSet.new()
    restofcols2 = SortedSet.new(0..8)
    alist.each { |pair|
       rows2.add(pair[0])
       restofcols2.delete(pair[1])	
    }
    rows = rows2.to_a
    restofcols = restofcols2.to_a
    
    count0 = 0
    count1 = 0
    count2 = 0
    count0 += CellAt(alist[0]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[1]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[2]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[3]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[4]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[5]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[6]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[7]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[8]).IsPossible(val) ? 1 : 0

    madechange = false
    #print "val:", val, " count0:", count0, " count1:", count1, " count2:", count2, "\n"
    if (count0 > 0 and (count1 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearRowRange(val, rows[0], restofcols)
    end
    if (count1 > 0 and (count0 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearRowRange(val, rows[1], restofcols)
    end
    if (count2 > 0 and (count0 + count1) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearRowRange(val, rows[2], restofcols)
    end
    return madechange
  end

  #---------------
  def FindSubRowInBlocks()
    madechange = false
    Blocks.each { |b|
	    (1..9).each { |val| 
	    	madechange |= ClearRowIfInBlock(val, b) 
	    }
	  }

    #print "=== return ", madechange, "\n"
    return madechange
  end

  #---------------
  def ClearColIfInBlock(val, alist)
    cols2 = SortedSet.new()
    restofrows2 = SortedSet.new(0..8)
    alist.each { |pair|
       cols2.add(pair[1])
       restofrows2.delete(pair[0])	
    }
    cols = cols2.to_a
    restofrows = restofrows2.to_a
    
    count0 = 0
    count1 = 0
    count2 = 0
    count0 += CellAt(alist[0]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[1]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[2]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[3]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[4]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[5]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[6]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[7]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[8]).IsPossible(val) ? 1 : 0

    madechange = false
    #print "val:", val, " count0:", count0, " count1:", count1, " count2:", count2, "\n"
    if (count0 > 0 and (count1 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearColRange(val, cols[0], restofrows)
    end
    if (count1 > 0 and (count0 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearColRange(val, cols[1], restofrows)
    end
    if (count2 > 0 and (count0 + count1) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearColRange(val, cols[2], restofrows)
    end
    return madechange
  end

  #---------------
  def FindSubColInBlocks()
    madechange = false
    Blocks.each { |b|
	    (1..9).each { |val| 
	    	madechange |= ClearColIfInBlock(val, b) 
	    }
	  }

    #print "=== return ", madechange, "\n"
    return madechange
  end

  #---------------
  def ClearBlockRange(val, rows, cols)
    #print "x=val:#{val} rows:#{rows} cols:#{cols} \n"  

	  changed = false
	  rows.each { |row|
	  	cols.each { |col|
	    	cell = CellAt([row, col])
	   	  next unless cell.IsPossible(val)
	      cell.ClearPossible(val)
	      changed = true
	  	}
	  }
	  return changed     	
  end

  #---------------
  def ClearBlockIfInCol(val, alist)
    c = alist[0][1]
    cols2 = SortedSet.new()
    if (c == 0 or c == 1 or c == 2)
      cols2.merge([0, 1, 2]).delete(c)  
    elsif (c == 3 or c == 4 or c == 5)
      cols2.merge([3, 4, 5]).delete(c)
    elsif (c == 6 or c == 7 or c == 8)
      cols2.merge([6, 7, 8]).delete(c)
    end
    cols = cols2.to_a

    count0 = 0
    count1 = 0
    count2 = 0
    count0 += CellAt(alist[0]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[1]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[2]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[3]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[4]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[5]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[6]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[7]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[8]).IsPossible(val) ? 1 : 0

    madechange = false
    #print "val:", val, " count0:", count0, " count1:", count1, " count2:", count2, "\n"
    if (count0 > 0 and (count1 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearBlockRange(val, [alist[0][0], alist[1][0], alist[2][0]], cols)
    end
    if (count1 > 0 and (count0 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearBlockRange(val, [alist[3][0], alist[4][0], alist[5][0]], cols)
    end
    if (count2 > 0 and (count0 + count1) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearBlockRange(val, [alist[6][0], alist[7][0], alist[8][0]], cols)
    end
    return madechange
  end

  #---------------
  def FindSubBlockInCol()
    madechange = false
    Cols.each { |c|
	    (1..9).each { |val| 
	    	madechange |= ClearBlockIfInCol(val, c) 
	    }
	  }

    #print "=== return ", madechange, "\n"
    return madechange
  end

  #---------------
  def ClearBlockIfInRow(val, alist)
    r = alist[0][0]
    rows2 = SortedSet.new()
    if (r == 0 or r == 1 or r == 2)
      rows2.merge([0, 1, 2]).delete(r)  
    elsif (r == 3 or r == 4 or r == 5)
      rows2.merge([3, 4, 5]).delete(r)
    elsif (r == 6 or r == 7 or r == 8)
      rows2.merge([6, 7, 8]).delete(r)
    end
    rows = rows2.to_a

    count0 = 0
    count1 = 0
    count2 = 0
    count0 += CellAt(alist[0]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[1]).IsPossible(val) ? 1 : 0
    count0 += CellAt(alist[2]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[3]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[4]).IsPossible(val) ? 1 : 0
    count1 += CellAt(alist[5]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[6]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[7]).IsPossible(val) ? 1 : 0
    count2 += CellAt(alist[8]).IsPossible(val) ? 1 : 0

    madechange = false
    #print "val:", val, " count0:", count0, " count1:", count1, " count2:", count2, "\n"
    if (count0 > 0 and (count1 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearBlockRange(val, rows, [alist[0][1], alist[1][1], alist[2][1]])
    end
    if (count1 > 0 and (count0 + count2) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearBlockRange(val, rows, [alist[3][1], alist[4][1], alist[5][1]])
    end
    if (count2 > 0 and (count0 + count1) == 0)
      #print "-- clearing val ", val, "\n";
      madechange |= ClearBlockRange(val, rows, [alist[6][1], alist[7][1], alist[8][1]])
    end
    return madechange
  end

  #---------------
  def FindSubBlockInRow()
    madechange = false
    Rows.each { |r|
	    (1..9).each { |val| 
	    	madechange |= ClearBlockIfInRow(val, r) 
	    }
	  }

    #print "=== return ", madechange, "\n"
    return madechange
  end

  #---------------
  def FindUniquePossibleFor(indices)
    madechange = false
    indices.each { |index|
      (1..9).each { |val|
        count = 0
        thecell = nil
        index.each { |pair| 
          cell = CellAt(pair)
          next if cell.IsSet
          next unless cell.IsPossible(val)
          thecell = pair
          count = count + 1
        }
        #print "x= num:#{val} = #{count}\n"
        if (count == 1)
          SetCell(thecell, val) 
          madechange = true
        end  
      }
    }
    return madechange
  end

  #---------------
  def HiddenPair(region)
    madechange = false
    (1..9).each { |val|
      u = SortedSet.new()
      region.each { |pair|
        u.add(pair) if CellAt(pair).IsPossible(val)
      }  
      next unless (u.size() == 2)
      #print "x=u.size=2 val=#{val} ", u.to_a, "\n"
      ((val+1)..9).each { |val2|
      	v = SortedSet.new() 
        region.each { |pair|
          v.add(pair) if CellAt(pair).IsPossible(val2)
        }
        #print "x= val=#{val} val2=#{val2}\n"
        next unless (v.size() == 2)
        next unless (u == v)
        #print "x=matched #{val} #{val2}  ", u.to_a, " ", v.to_a,"\n"
        u.each { |pair|
           #print "x=pair: #{pair}\n";
           (1..9).each { |v|
           	  next unless CellAt(pair).IsPossible(v)
           	  next if v == val or v == val2
           	  CellAt(pair).ClearPossible(v) 
           	  madechange = true
           } 	
        }
    #    if (u.row == v.row)   
    #      row = u.row
    #      remove row.possible if p == val or p == val2
    #    if (u.col == v.col)   
    #      col = u.col
    #      remove col.possible if p == val or p == val2
      }
    }
    return madechange
  end

  #---------------
  def HiddenPairInRegions(regions)
    madechange = false
    regions.each { |region|
    	madechange |= HiddenPair(region)
    }
    return madechange
  end
  
  #---------------
  def EvalOnce
    localcomplexity = 0
    while true
      break if IsComplete()
      
      #more times thru means more complexity
      localcomplexity = localcomplexity + 1
      
      if FindSingletonPossibleFor(Rows) 
        $complexity = $complexity + 1 + localcomplexity
        print "Singleton - row :  1  #{$complexity}\n"
        next
      end
      
      if FindSingletonPossibleFor(Cols) 
        $complexity = $complexity + 1 + localcomplexity
        print "Singleton - col :  1  #{$complexity}\n"
        next
      end

      if FindSingletonPossibleFor(Blocks) 
        $complexity = $complexity + 1 + localcomplexity
        print "Singleton - blk :  1  #{$complexity}\n"
        next
      end

      if FindUniquePossibleFor(Rows)
        $complexity = $complexity + 5 + localcomplexity
        print "Unique    - row :  5  #{$complexity}\n"
        next
      end

      if FindUniquePossibleFor(Cols) 
        $complexity = $complexity + 5 + localcomplexity
        print "Unique    - col :  5  #{$complexity}\n"
        next
      end

      if FindUniquePossibleFor(Blocks) 
        $complexity = $complexity + 5 + localcomplexity
        print "Unique    - blk :  5  #{$complexity}\n"
        next
      end
      
      if (FindSubRowInBlocks())     
        $complexity = $complexity + 20 + localcomplexity
        print "Subrow    - row : 20  #{$complexity}\n"
        next
      end

      if (FindSubColInBlocks())     
        $complexity = $complexity + 20 + localcomplexity
        print "Subcol    - col : 20  #{$complexity}\n"
        next
      end

      if (FindSubBlockInRow())
        $complexity = $complexity + 30 + localcomplexity
        print "Subblk    - row : 30  #{$complexity}\n"
        next
      end

      if (FindSubBlockInCol())
        $complexity = $complexity + 30 + localcomplexity
        print "Subblk    - col : 30  #{$complexity}\n"
        next
      end

      if (HiddenPairInRegions(Blocks))
        $complexity = $complexity + 40 + localcomplexity
        print "HiddenPair- blk : 40  #{$complexity}\n"
        next	
      end

      if (HiddenPairInRegions(Rows))
        $complexity = $complexity + 40 + localcomplexity
        print "HiddenPair- row : 40  #{$complexity}\n"
        next	
      end

      if (HiddenPairInRegions(Cols))
        $complexity = $complexity + 40 + localcomplexity
        print "HiddenPair- col : 40  #{$complexity}\n"
        next	
      end
          
      #if we made it to here, there's been no changes, so exit loop
      break
    end
  end


  #---------------
  def VerifyEntity(type, indices)
     vals = []
     indices.each { |pair|
     	 cell = CellAt(pair)
     	 if (!cell.IsSet)
          print type, " value isn't set at ", pair, "\n"
          return true 
       end
       vals.push(cell.Get())
     }
     if (vals.sort != (1..9).to_a)
       print type, " values aren't 1 to 9: ", vals.sort, "\n"
       return true
     end
     return false
  end

  #---------------
  def Verify
     isbad = false
     Rows.each { |index| isbad |= VerifyEntity("Row", index)  }
     Cols.each { |index| isbad |= VerifyEntity("Column", index)  }
     Blocks.each { |index| isbad |= VerifyEntity("Block", index)  }
     print (isbad ? "Unverified" : "Verified"), "\n"
  end

  #---------------
  def Print
    #print
    @Cells.each_index { |row|
      if (row == 0 or row == 3 or row == 6)
        print "#########################################################################\n"
      else
        print "#-------+-------+-------#-------+-------+-------#-------+-------+-------#\n"
               #   8   |   5   |   7   #   6   |   3   |   4   #   9   |   1   |   2   #
      end  
      
      (0..8).each { |col|
        if (col == 0 or col == 3 or col == 6)
          print  "# " 
        else
          print  "| "
        end
        @Cells[row][col].PrintPossibles(1)
        @Cells[row][col].PrintPossibles(2)
        @Cells[row][col].PrintPossibles(3)
        @Cells[row][col].PrintPossibles(4)
        @Cells[row][col].PrintPossibles(5)
        print " "
        }
      print "#\n"  
      (0..8).each { |col|
        if (col == 0 or col == 3 or col == 6)
          print  "#  " 
        else
          print  "|  "
        end
        @Cells[row][col].PrintPossibles(6)
        @Cells[row][col].PrintPossibles(7)
        @Cells[row][col].PrintPossibles(8)
        @Cells[row][col].PrintPossibles(9)
        print " "
        }
      print "#\n"  
      
      @Cells[row].each_index { |col|
        if (col == 0 or col == 3 or col == 6)
          print "#   "  
        else
          print "|   "  
        end
        @Cells[row][col].PrintVal
        print "   "
      }
      print "#\n"
      }
    print "#########################################################################\n"
  end

end

#----------------------------------------
#-- MAIN
b = Board.new 
#7,9 are unsolved

BoardSelect = ARGV[0]
if BoardSelect == nil
  BoardSelect = 1 
else
  BoardSelect = BoardSelect.to_i
end
if (BoardSelect == 1)
  b.InitRow(0, "4376     ")
  b.InitRow(1, "62    4  ")
  b.InitRow(2, "  5 32  8")
  b.InitRow(3, " 8  97   ")
  b.InitRow(4, "3 21 48 9")
  b.InitRow(5, "   85  2 ")
  b.InitRow(6, "8  71 5  ")
  b.InitRow(7, "  3    84")
  b.InitRow(8, "     8176")
elsif BoardSelect == 2
  b.InitRow(0, " 3  1   7")
  b.InitRow(1, "   74   1")
  b.InitRow(2, "8  5 2   ")
  b.InitRow(3, "7     9 6")
  b.InitRow(4, " 8 951 4 ")
  b.InitRow(5, "3 9     2")
  b.InitRow(6, "   1 8  4")
  b.InitRow(7, "1   64   ")
  b.InitRow(8, "2   7  1 ")
elsif BoardSelect == 3
  b.InitRow(0, "1   8 69 ")
  b.InitRow(1, "   1 9   ")
  b.InitRow(2, " 8 5 6 2 ")
  b.InitRow(3, "7  6     ")
  b.InitRow(4, "62     51")
  b.InitRow(5, "     3  9")
  b.InitRow(6, " 1 8 5 3 ")
  b.InitRow(7, "   4 2   ")
  b.InitRow(8, " 95 6   7")
elsif BoardSelect == 4
  b.InitRow(0, "9   521  ")
  b.InitRow(1, "7        ")
  b.InitRow(2, "  5 8   6")
  b.InitRow(3, "8    49  ")
  b.InitRow(4, " 3  9  7 ")
  b.InitRow(5, "  41    8")
  b.InitRow(6, "2   6 4  ")
  b.InitRow(7, "        3")
  b.InitRow(8, "  624   1")
elsif BoardSelect == 5
  b.InitRow(0, " 31      ")
  b.InitRow(1, " 7  9    ")
  b.InitRow(2, "5   72   ")
  b.InitRow(3, "46 1   5 ")
  b.InitRow(4, "  3 5 4 8")
  b.InitRow(5, "9       2")
  b.InitRow(6, "   9   3 ")
  b.InitRow(7, "3     8 1")
  b.InitRow(8, "21   49  ")
elsif BoardSelect == 6
  b.InitRow(0, "   2 9  7")
  b.InitRow(1, "61 35   4")
  b.InitRow(2, "      2  ")
  b.InitRow(3, "   4   9 ")
  b.InitRow(4, "357      ")
  b.InitRow(5, "2        ")
  b.InitRow(6, " 4   27  ")
  b.InitRow(7, "  8      ")
  b.InitRow(8, "  5  413 ")
elsif BoardSelect == 7
  b.InitRow(0, "  9    5 ")
  b.InitRow(1, "6       9")
  b.InitRow(2, " 3 76    ")
  b.InitRow(3, " 1       ")
  b.InitRow(4, "5    2 4 ")
  b.InitRow(5, "3 78  2  ")
  b.InitRow(6, "8        ")
  b.InitRow(7, "4  2   3 ")
  b.InitRow(8, "    3 675")
elsif BoardSelect == 8
  b.InitRow(0, "  2     7")
  b.InitRow(1, " 8 1 4  6")
  b.InitRow(2, "      95 ")
  b.InitRow(3, "  5 46   ")
  b.InitRow(4, "3      7 ")
  b.InitRow(5, "  72    9")
  b.InitRow(6, "7  8    3")
  b.InitRow(7, "  6  5   ")
  b.InitRow(8, "   6  42 ")
elsif BoardSelect == 9
  b.InitRow(0, "743 6  5 ")
  b.InitRow(1, " 9 8     ")
  b.InitRow(2, "5    1   ")
  b.InitRow(3, "   5   4 ")
  b.InitRow(4, "87     91")
  b.InitRow(5, " 1   8   ")
  b.InitRow(6, "   6    9")
  b.InitRow(7, "     2 7 ")
  b.InitRow(8, " 6  7 412")
elsif BoardSelect == 10
  b.InitRow(0, "  7   28 ")
  b.InitRow(1, "  4 25   ")
  b.InitRow(2, "28   46  ")
  b.InitRow(3, " 9   6   ")
  b.InitRow(4, "3       2")
  b.InitRow(5, "   1   9 ")
  b.InitRow(6, "  62   75")
  b.InitRow(7, "   57 4  ")
  b.InitRow(8, " 78   3  ")
elsif BoardSelect == 11
  b.InitRow(0, "         ")
  b.InitRow(1, "   1 7  8")
  b.InitRow(2, " 7 392541")
  b.InitRow(3, "  4    92")
  b.InitRow(4, "  5   6  ")
  b.InitRow(5, "93    4  ")
  b.InitRow(6, "192785 6 ")
  b.InitRow(7, "5  4 3   ")
  b.InitRow(8, "         ")
elsif BoardSelect == 12 
  b.InitRow(0, "    5  3 ")
  b.InitRow(1, "1 928   5")
  b.InitRow(2, "5 43  2 7")
  b.InitRow(3, " 68   9 2")
  b.InitRow(4, "4   7   1")
  b.InitRow(5, "2 1   85 ")
  b.InitRow(6, "9 6  47 3")
  b.InitRow(7, "7   385 9")
  b.InitRow(8, " 5  9    ")
elsif BoardSelect == 13
  b.InitRow(0, "     79 5")
  b.InitRow(1, "4      81")
  b.InitRow(2, "9 82 6  3")
  b.InitRow(3, " 3    5 8")
  b.InitRow(4, "   693   ")
  b.InitRow(5, "2 6    9 ")
  b.InitRow(6, "1  4 82 6")
  b.InitRow(7, "57      9")
  b.InitRow(8, "6 29     ")
elsif BoardSelect == 14
  b.InitRow(0, "   5  7 6")
  b.InitRow(1, " 671    8")
  b.InitRow(2, "  1  8   ")
  b.InitRow(3, "13    64 ")
  b.InitRow(4, " 8     2 ")
  b.InitRow(5, " 96    37")
  b.InitRow(6, "   8  5  ")
  b.InitRow(7, "6    297 ")
  b.InitRow(8, "4 3  5   ")
elsif BoardSelect == 15
  b.InitRow(0, " 2 5     ")
  b.InitRow(1, " 4   7  3")
  b.InitRow(2, "87      1")
  b.InitRow(3, "7  3   58")
  b.InitRow(4, "   8 6   ")
  b.InitRow(5, "26   1  7")
  b.InitRow(6, "1      36")
  b.InitRow(7, "3  7   8 ")
  b.InitRow(8, "     9 2 ")
else
  print "Unknown Board: #{BoardSelect}\n"
  exit(1)
end

b.Print
b.EvalOnce
b.Print
print "Complexity: #$complexity\n"
b.Verify






Contact me about content on this page using john_web-at-arrizza-dot-com
For Web Master or site problems contact: webadmin-at-arrizza-dot-com
Copyright John Arrizza (c) 2001-2010