diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index af5a5b907..a341da91c 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -39,4 +39,5 @@ This file lists everyone, who contributed to this repo and wanted to show up her - nic-hartley - crafter312 - Christopher Milan -- Vexatos \ No newline at end of file +- Vexatos +- Björn Heinrichs diff --git a/contents/stable_marriage_problem/code/ruby/stable_marriage.rb b/contents/stable_marriage_problem/code/ruby/stable_marriage.rb new file mode 100644 index 000000000..9d449afd8 --- /dev/null +++ b/contents/stable_marriage_problem/code/ruby/stable_marriage.rb @@ -0,0 +1,84 @@ +class Person + def initialize(id, name, prefs) + @id = id + @name = name + @prefs = prefs + @partner = nil + @choices = 0 + end + + def lonely? + @partner.nil? + end + + def propose(partners) + unless self.lonely? + raise '%s is not lonely!' % self.name + end + choice = @prefs[@choices] + partners[choice].onPropose(self) + @choices += 1 + end + + def to_s + "#{@name.rjust(20)}: #{self.lonely? && "Lonely" || @partner.name}" + end + + def self.generate(size, prefix, r) + Array.new(size){|i| + Person.new( + i, + "#{prefix} #{i}", + (0 ... size).to_a.shuffle(random: r) + ) + } + end + + protected + attr_reader :id, :name + attr_writer :partner + + # Acts upon a given Proposal + def onPropose(partner) + unless self.lonely? + offer = score(partner) + current = score(@partner) + return unless offer > current + @partner.partner = nil + end + @partner = partner + partner.partner = self + end + + private + # Determines the preference of a given partner + def score(partner) + return 0 if partner.nil? + @prefs.size - @prefs.index(partner.id) + end +end + +# Deterministic Output, feel free to change seed +r = Random.new(42) + +# Determines Output Columns +men = Person.generate(4, "Man", r) +women = Person.generate(4, "Woman", r) + +# Assume no Name is longer than 20 characters +spacer = '-' * (20 * 2 + 2) + +# Solve the Problem +1.step do |round| + singles = men.select(&:lonely?) + singles.each do |m| + m.propose(women) + end + + break if singles.empty? + + puts "Round #{round}" + puts spacer + puts men, women + puts spacer +end diff --git a/contents/stable_marriage_problem/stable_marriage_problem.md b/contents/stable_marriage_problem/stable_marriage_problem.md index 10f9da2e4..716b263dc 100644 --- a/contents/stable_marriage_problem/stable_marriage_problem.md +++ b/contents/stable_marriage_problem/stable_marriage_problem.md @@ -21,6 +21,8 @@ I am incredibly interested to see what you guys do and how you implement the alg ## Example Code {% method %} +{% sample lang="ruby" %} +[import, lang:"ruby"](code/ruby/stable_marriage.rb) {% sample lang="jl" %} [import, lang:"julia"](code/julia/stable_marriage.jl) {% sample lang="py" %}