Skip to content

Instantly share code, notes, and snippets.

@jawspeak
Created August 20, 2009 21:04
Show Gist options
  • Select an option

  • Save jawspeak/171375 to your computer and use it in GitHub Desktop.

Select an option

Save jawspeak/171375 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
require 'pp'
require 'set'
require 'test/unit'
$heights = %w(T S)
$colors = %w(D F)
$looks = %w(H U)
$people = %w(Adam Bond Cruz Dumbo)
class DatingSolver
def initialize
@one_persons_attribute_combos = combinations_for_a_persons_attributes
end
def solve
possibilities = all_possible_date_arrangements
puts "Combinations: #{possibilities.length}"
possibilities.reject!{|row| Set.new([score_person(row['Adam']), score_person(row['Bond']), score_person(row['Cruz']), score_person(row['Dumbo']) ]).length != 4} #rule1
puts "Combinations, after filtering rule 1: #{possibilities.length}"
possibilities.reject!{|row| row['Bond'].match(/TF/) || row['Cruz'].match(/TF/)} #rule2, demorgan's
puts "Combinations, after filtering rule 2: #{possibilities.length}"
possibilities.reject!{|row| row['Dumbo'].match(/S.H/) || row['Adam'].match(/S.H/)} #rule3, demorgan's
puts "Combinations, after filtering rule 3: #{possibilities.length}"
possibilities.reject!{|row| (row['Adam'].match(/T/) && row['Cruz'].match(/S/)) || (row['Adam'].match(/S/) && row['Cruz'].match(/T/))} # rule4
puts "Combinations, after filtering rule 4: #{possibilities.length}"
possibilities.reject!{|row| (row['Dumbo'].match(/D/) && row['Bond'].match(/F/)) || (row['Dumbo'].match(/F/) && row['Bond'].match(/D/))} #rule5
puts "Combinations, after filtering rule 5: #{possibilities.length}"
i = 0
dates = {}
possibilities.each do |row|
row.each do |name, attributes|
if attributes.match(/TDH/)
dates[name] = 1 unless dates[name]
dates[name] = dates[name]+1 if dates[name]
end
end
end
# every one of the remaining possibilities must have a TDH person in there, because they have 1, 2, 3, adn 4 matching attributes in rule1
pp possibilities
# but these are the number of times each person came up as a TDH person.
puts "Frequencies per dater: "
pp dates
end
def score_person(person_attributes)
score = 0
score += 1 if person_attributes.match(/T/)
score += 1 if person_attributes.match(/D/)
score += 1 if person_attributes.match(/H/)
score
end
def combinations_for_a_persons_attributes()
attribute_combos = []
$heights.each do |height|
$colors.each do |color|
$looks.each do |look|
attribute_combos << height + color + look
end
end
end
attribute_combos
end
def combinations_for_all_peoples
peoples_attributes = {}
$people.each do |person|
peoples_attributes[person] = combinations_for_a_persons_attributes()
end
peoples_attributes
end
# all possible arrangements, including invalid ones that don't meet rules
def all_possible_date_arrangements
combos = []
$people.each do |person1|
@one_persons_attribute_combos.each do |person1_attribute_option|
$people.reject{|p| Set.new([person1]).member?(p)}.each do |person2|
@one_persons_attribute_combos.each do |person2_attribute_option|
$people.reject{|p| Set.new([person1, person2]).member?(p)}.each do |person3|
@one_persons_attribute_combos.each do |person3_attribute_option|
$people.reject{|p| Set.new([person1, person2, person3]).member?(p)}.each do |person4|
@one_persons_attribute_combos.each do |person4_attribute_option|
row = {}
row[person1] = person1_attribute_option
row[person2] = person2_attribute_option
row[person3] = person3_attribute_option
row[person4] = person4_attribute_option
# # reject these, could do it this way too
# next if row['Bond'].match(/TF/) || row['Cruz'].match(/TF/) #rule2, demorgan's
# next if row['Dumbo'].match(/S.H/) || row['Adam'].match(/S.H/) #rule3, demorgan's
# next if (row['Adam'].match(/T/) && row['Cruz'].match(/S/)) || (row['Adam'].match(/S/) && row['Cruz'].match(/T/)) # rule4
# next if (row['Dumbo'].match(/D/) && row['Bond'].match(/F/)) || (row['Dumbo'].match(/F/) && row['Bond'].match(/D/)) #rule5
combos << row
puts "Calculating combinations #{combos.length} ..." if combos.length % 10000 == 0
end
end
end
end
end
end
end
end
combos
end
end
class DatingSolverTest < Test::Unit::TestCase
def test_2_exp_8_attribute_combos
attribute_combos = DatingSolver.new.combinations_for_a_persons_attributes
assert attribute_combos.length == 2**3
end
def test_score_for_row
solver = DatingSolver.new
assert_equal 0, solver.score_person("SFU")
assert_equal 1, solver.score_person("TFU")
assert_equal 2, solver.score_person("TDU")
assert_equal 3, solver.score_person("TDH")
assert_equal 1, solver.score_person("SDU")
assert_equal 2, solver.score_person("SDH")
assert_equal 1, solver.score_person("SFH")
end
end
# THIS RUNS THE SOLVER
DatingSolver.new.solve
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment