Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@dan-manges
Last active August 29, 2015 14:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dan-manges/11072330 to your computer and use it in GitHub Desktop.
Save dan-manges/11072330 to your computer and use it in GitHub Desktop.
require_relative "helper"
available = {}
0.upto(15).each do |i|
available[i] = {}
i.upto(15).each do |j|
available[i][j] = true
if i / 4 == j / 4
available[i][j] = false
end
end
end
results = []
4.times do |dinner_number|
dinner = []
taken = {}
0.upto(3) do |starting_member|
party = [starting_member]
1.upto(3) do |group|
0.upto(15) do |potential|
next unless potential / 4 == group
next unless party.all? { |m| available[m][potential] }
next if taken[potential]
party.each { |m| available[m][potential] = false }
party << potential
taken[potential] = true
end
end
dinner_number.times { party.unshift(party.pop) }
dinner << party
end
results << dinner
end
Helper.print_results(results)
__END__
Dinner Evening #1
+-------------+
| H A S D |
+-------------+
| 0 4 8 12 |
| 1 5 9 13 |
| 2 6 10 14 |
| 3 7 11 15 |
+-------------+
Dinner Evening #2
+-------------+
| H A S D |
+-------------+
| 15 0 5 10 |
| 14 1 4 11 |
| 13 2 7 8 |
| 12 3 6 9 |
+-------------+
Dinner Evening #3
+-------------+
| H A S D |
+-------------+
| 11 13 0 6 |
| 10 12 1 7 |
| 9 15 2 4 |
| 8 14 3 5 |
+-------------+
Dinner Evening #4
+-------------+
| H A S D |
+-------------+
| 7 9 14 0 |
| 6 8 15 1 |
| 5 11 12 2 |
| 4 10 13 3 |
+-------------+
require_relative "helper"
def fill(roles_filled, met, dinners, taken, dinner_to_fill, party_to_fill, role_to_fill)
return dinners if dinner_to_fill == 4
if party_to_fill == 4
return fill(roles_filled, met, dinners, 0, dinner_to_fill + 1, 0, 0)
elsif role_to_fill == 4
return fill(roles_filled, met, dinners, taken, dinner_to_fill, party_to_fill + 1, 0)
end
party = dinners[dinner_to_fill][party_to_fill]
0.upto(15) do |couple|
next if taken & (1 << couple) > 0
next if roles_filled & (1 << (role_to_fill + couple * 4)) > 0
next if party.any? { |c| met[c] & (1 << couple) > 0 }
new_met = met.dup
new_dinners = dinners.map { |x| x.map { |y| y.dup } }
new_dinners[dinner_to_fill][party_to_fill] << couple
party.each { |c| new_met[c] |= (1 << couple); new_met[couple] |= (1 << c) }
if result = fill(
roles_filled | (1 << (role_to_fill + couple * 4)),
new_met,
new_dinners,
taken | (1 << couple),
dinner_to_fill,
party_to_fill,
role_to_fill + 1
)
return result
end
end
return false
end
solution = fill(
0,
[0] * 16,
[
[[], [], [], []],
[[], [], [], []],
[[], [], [], []],
[[], [], [], []]
],
0,
0,
0,
0
)
Helper.print_results solution
__END__
Dinner Evening #1
+-------------+
| H A S D |
+-------------+
| 0 1 2 3 |
| 4 5 6 7 |
| 8 9 10 11 |
| 12 13 14 15 |
+-------------+
Dinner Evening #2
+-------------+
| H A S D |
+-------------+
| 1 4 8 12 |
| 2 6 9 13 |
| 3 7 11 14 |
| 10 0 15 5 |
+-------------+
Dinner Evening #3
+-------------+
| H A S D |
+-------------+
| 5 3 12 9 |
| 6 14 1 10 |
| 7 8 13 0 |
| 15 11 4 2 |
+-------------+
Dinner Evening #4
+-------------+
| H A S D |
+-------------+
| 9 15 7 1 |
| 11 12 0 6 |
| 13 10 3 4 |
| 14 2 5 8 |
+-------------+
module Helper
def self.print_results(results)
results.each.with_index do |dinner, dinner_index|
puts "Dinner Evening ##{dinner_index+1}"
puts "+-------------+"
puts "| H A S D |"
puts "+-------------+"
dinner.each do |party|
puts "| %2d %2d %2d %2d |" % party
end
puts "+-------------+"
puts ""
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment