Forums
New posts
Search forums
Members
Current visitors
Log in
Register
What's new
Search
Search
Search titles only
By:
New posts
Search forums
Menu
Log in
Register
Install the app
Install
Forums
Archive
Archive
Ruby
[QUIZ] Housie (#114)
JavaScript is disabled. For a better experience, please enable JavaScript in your browser before proceeding.
You are using an out of date browser. It may not display this or other websites correctly.
You should upgrade or use an
alternative browser
.
Reply to thread
Message
[QUOTE="Christoffer Lernö, post: 4549390"] Here is a different solution. This first populates each ticket with at least 1 entry. After that it treats the tickets as 18 rows and populates it with the "max 5 in a row"-constraint. To avoid getting stuck, it will swap out a random number if there already are 5 numbers in the row. This could cause a ticket to lose its minimum of 1 entry per column, so the initial entries in every ticket column are prevented from being swapped out. Finally the actual numbers are added instead of the placeholders used up to this point. #### class Housie def initialize(housie_array) @housie_array = housie_array raise "Illegal size" unless @housie_array.size == 3 @housie_array.each { |row| raise "Illegal row in housie # {row.inspect}" unless row.compact.size == 5 } 9.times do |col| raise "Illegal column #{col}" unless @housie_array.collect { | row| row[col] }.compact.size > 0 end end # Ugly code to display a ticket. def to_s @housie_array.inject("") do |sum, row| sum + "+----" * 9 + "+\n" + row.inject("|") { | sum, entry | sum + " #{"%2s" % entry} |" } + "\n" end + "+----" * 9 + "+" end def Housie.new_book housies = Array.new(6) { Array.new(3) { Array.new(9) } } columns = Array.new(9) { |col| Array.new(10, col) } columns[0].shift columns[8] << 8 # First make sure every book has at least one entry. # These entires are fixed and can't be swapped out. columns.each do |col| housies.each do |housie| housie.select { |row| row.compact.size < 5 }.sort_by { rand }.first[col.shift] = :fixed end end # Merge all rows all_rows = [] housies.each { |housie| housie.each { |row| all_rows << row } } # Fill all rows, start with the one with fewest entries, resolve ties randomly while (columns.flatten.compact.size > 0) do columns.select { |col| col.size > 0 }.each do |col| all_rows.reject { |row| row[col.first] }.sort_by { rand }.each do |row| break unless col.first # A full row needs to have a value swapped out if row.compact.size == 5 # Only try to swap if we have swappable entries if row.member? :selected removed_col = rand(9) while removed_col.nil? || row [removed_col] != :selected; row[removed_col] = nil columns[removed_col] << removed_col row[col.shift] = :selected end else row[col.shift] = :selected end end end end # Populate actual numbers values = Array.new(9) { |col| Array.new(10) { |i| i + col * 10 } } values[0].shift # remove 0 values[8] << 90 # add 90 values.each_with_index do |col, index| col = col.sort_by { rand } housies.each do |housie| entries = housie.inject(0) { |sum, row| sum + (row[index] ? 1 : 0) } values = col.slice!(0...entries).sort housie.each { |row| row[index] = values.shift if row[index] } end end housies.collect { |housie| Housie.new(housie) } end end [/QUOTE]
Verification
Post reply
Forums
Archive
Archive
Ruby
[QUIZ] Housie (#114)
Top