Skip to content

Instantly share code, notes, and snippets.

@ankitsinghaniyaz
Last active April 14, 2020 07:18
Show Gist options
  • Save ankitsinghaniyaz/fbaa15fbfe3669f0ee2dd80e2122c6ac to your computer and use it in GitHub Desktop.
Save ankitsinghaniyaz/fbaa15fbfe3669f0ee2dd80e2122c6ac to your computer and use it in GitHub Desktop.
=begin
expected output is a 2d array
irb(main):001:0> TicketGenerator.new.generate
=> [[nil, 10, 27, 31, 45, 54, 60, nil, nil], [nil, nil, 29, 32, nil, 58, 61, 77, nil], [5, 11, nil, nil, nil, nil, 64, nil, 88]]
irb(main):002:0> TicketGenerator.new.generate
=> [[2, nil, nil, nil, nil, 51, 68, 71, 82], [nil, 19, 23, 34, 45, 57, 69, 73, nil], [nil, nil, nil, 35, nil, nil, nil, 75, 83]]
irb(main):003:0>
=end
class TicketGenerator
def initialize
@shell = create_shell
end
def generate
generate_pattern
end
def flat
@shell.flatten.compact.sort
end
def to_s
@shell.each do |row|
row.each do |col|
print(("%02d" % col.to_i).ljust(3))
end
print "\n"
end
end
private
# this is the core logic of generating a tambola ticket
# it has 3 rows x 9 columns = 27 cells
# the ticket should have exactly 15 numbers values
# the number ranges from 1..90
# column 1 can have number from 1 - 9
# column 2 can have numbers from 10 - 19 and so on
# column 9 can have numbers from 80 - 90
# each column must have at least one number
# each column can have one, two or three numbers
# each row can have max 5 numbers
def generate_pattern
@cells_to_fill = 15
@ticket_capacity_left = Array.new(9) { 3 }
@exhaustive = Array(1..90)
# fill in a number for each column
fill_shell([1, 2, 3, 4, 5, 6, 7, 8, 9, 10].sample)
fill_shell([11, 12, 13, 14, 15, 16, 17, 18, 19, 20].sample)
fill_shell([21, 22, 23, 24, 25, 26, 27, 28, 29, 30].sample)
fill_shell([31, 32, 33, 34, 35, 36, 37, 38, 39, 40].sample)
fill_shell([41, 42, 43, 44, 45, 46, 47, 48, 49, 50].sample)
fill_shell([51, 52, 53, 54, 55, 56, 57, 58, 59, 60].sample)
fill_shell([61, 62, 63, 64, 65, 66, 67, 68, 69, 70].sample)
fill_shell([71, 72, 73, 74, 75, 76, 77, 78, 79, 80].sample)
fill_shell([81, 82, 83, 84, 85, 86, 87, 88, 89, 90].sample)
loop do
fill_shell(@exhaustive.sample)
break if @cells_to_fill == 0
end
# sort values in right order
@shell.each(&:sort!)
# fill up with right nil values
@shell = @shell.map do |col|
filled_probability = Array.new(col.size) { 1 }
empty_probability = Array.new(3 - col.size) { 0 }
order_by_probability = (filled_probability + empty_probability).shuffle
temp_col = []
order_by_probability.each do |p|
temp_col.push(nil) if p == 0
temp_col.push(col.delete_at(0)) if p == 1
end
temp_col
end
# remove unwanted instantce variables
clean_up
# transpose the values
@shell = @shell.transpose
end
# push the value in the right column
# removes the number from exhaustive list
# decrement the cells to fill counter
def fill_shell(value)
col = value.to_i / 10
# handle the special case of 90
col = 8 if value == 90
return if @ticket_capacity_left[col] == 0
@shell[col].push(value)
@exhaustive.delete(value);
@cells_to_fill -= 1
@ticket_capacity_left[col] -= 1
end
def create_shell
Array.new(9) { Array.new() }
end
def clean_up
remove_instance_variable(:@ticket_capacity_left)
remove_instance_variable(:@cells_to_fill)
remove_instance_variable(:@exhaustive)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment