Last active
April 14, 2020 07:18
-
-
Save ankitsinghaniyaz/fbaa15fbfe3669f0ee2dd80e2122c6ac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=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