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: 4549335"] My solution drops the numbers 1-90 into the tickets at random. If there are more than 3 numbers of the same column for a ticket, or it already has 15 numbers then it kicks out one of its other numbers at random. This number is put back to be distributed to some other ticket. After all the numbers are distributed, each Housie generates itself using the values it has been given. It will add one number at a time to the row with the least amount of numbers. If two rows have the same amount of numbers then their positions will be chosen randomly. I also included a method to generate a single ticket. The code got a bit messier than I'd like it, but it avoids brute force-generation and seem to generate tickets quickly. /Christoffer ##### class Housie def initialize @colset = Array.new(9) { [] } @numbers = 0 end # Push a number to this ticket. # # If this number can't fit with the numbers already in this housie, we return # one of the old numbers in the housie that we removed to make this number fit. # def push(number) raise "Tried to push to generated housie ticket" if @housie column = number == 90 ? 8 : number / 10 @colset[column] << number if @colset[column].size == 4 @colset[column].shift elsif @numbers == 15 value = @colset[rand(9)].shift while value.nil? value else @numbers += 1 nil end end # Generates a ticket from added data # Since we have 15 numbers, not more than 3 of each column type we know we # can create a ticket, but we want a randomized look to it. def generate raise "Not enough data to generate ticket" unless complete? @housie = Array.new(3) { Array.new(9) } (0..8).sort_by { rand }.each do |column| @colset[column].size.times do rows = @housie.sort_by { rand }.sort { |row1, row2| row1.compact.size <=> row2.compact.size } rows.shift until rows.first[column].nil? rows.first[column] = true end end 9.times do |column| @colset[column].sort! @housie.each { |row| row[column] = @colset[column].shift if row [column] } end self end # Ugly code to display a ticket. def to_s return "Not valid" unless @housie @housie.inject("") do |sum, row| sum + "+----" * 9 + "+\n" + row.inject("|") { | sum, entry | sum + " #{"%2s" % entry} |" } + "\n" end + "+----" * 9 + "+" end def complete? @numbers == 15 end def Housie.new_book housies = Array.new(6) { Housie.new } numbers = (1..90).to_a while numbers.size > 0 do pushed_out = housies[rand(6)].push(numbers.shift) numbers << pushed_out if pushed_out end housies.collect { |housie| housie.generate } end def Housie.new_ticket housie = Housie.new random_numbers = (1..90).sort_by { rand } until housie.complete? returned = housie.push random_numbers.shift random_numbers << returned if returned end housie.generate end end puts "A book of tickets:" Housie.new_book.each_with_index { |housie, index| puts "Ticket # {index + 1}"; puts housie.to_s } puts "A single ticket:" puts Housie.new_ticket.to_s [/QUOTE]
Verification
Post reply
Forums
Archive
Archive
Ruby
[QUIZ] Housie (#114)
Top