rustedの日記 このページをアンテナに追加 RSSフィード

ruby勉強するよ。
 | 

2006-09-15

[][]Secret Santas (#2) 23:49 Secret Santas (#2) - rustedの日記 を含むブックマーク はてなブックマーク - Secret Santas (#2) - rustedの日記

よくある練習問題を解いてもあんまり面白くないので、英語の壁もあるけどRuby Quiz(http://www.rubyquiz.com/)を解いてみることに。がんばるよ。

とりあえず2問目。Secret Santaなる、プレゼントを贈る人を選ぶ問題。(http://www.rubyquiz.com/quiz2.html)

Luke Skywalker <luke@theforce.net>

Leia Skywalker <leia@therebellion.org>

Toula Portokalos <toula@manhunter.org>

Gus Portokalos <gus@weareallfruit.net>

Bruce Wayne <bruce@imbatman.com>

Virgil Brigman <virgil@rigworkersunion.org>

Lindsey Brigman <lindsey@iseealiens.net>

入力としてこのようなリストが渡されるので、LukeにはToulaがサンタとしてプレゼント贈って、LeiaにはBruceがプレゼント贈って……という組み合わせを出力する。

Your script should then choose a Secret Santa for every name in the list. Obviously, a person cannot be their own Secret Santa. In addition, my friends no longer allow people in the same family to be Santas for each other and your script should take this into account.

一番重要制限事項だけど、ちょっとわかりづらかったかな。

  • 全員がSecret Santaになるように選ぶ
  • 自分自身をSecret Santaとしてはならない
  • 同じ家族の人はSecret Santaになれない

でいいと思うけど。

で、こんなんでました。

#!/usr/bin/ruby
# Ruby Quiz - Secret Santas (#2)

class Person
 attr_reader :list, :first, :family
 attr_accessor :santa
 def initialize(s)
   @first = s.split(' ')[0]
   @family = s.split(' ')[1]
   @email = s.split(/<|>/)[1]
 end

 def set_list(l)
   @list = l
 end

 def add(people)
   for person in people
     @list.push(person)
   end
 end

 def remove(someone)
   removed = Array.new()
   for i in @list
     if someone == i
       removed.push(@list.delete(i))
     end
   end
   return removed
 end

 def ==(other)
   return @first == other.first && @family == other.family
 end

 def print_info
   print @first, " ", @family
 end
end

def remove(santa, friends)
 removed = Array.new()
 for someone in friends
   removed.push(someone.remove(santa))
 end
 return removed
end

def add(removed, friends)
 for person in friends
   person.add(removed.shift)
 end
end

# 組み合わせ探し
def search_santa(person, santa, friends, ans)
 person.santa = santa
 ans.push(person)
 ans.push(santa)
 if friends.size == 0
   $ans_list.push(ans.dup)
   ans.pop
   ans.pop
   return
 end
 removed = remove(santa, friends)
 person = friends.shift
 for someone in person.list
   search_santa(person.dup, someone.dup, friends.dup, ans)
 end
 friends.unshift(person)
 add(removed, friends)
 ans.pop
 ans.pop
end

# 名簿をつくる
friends = Array.new()
while line = ARGF.gets
 friends.push(Person.new(line))
end

# 誰がサンタになれるか、のリストを初期化
for person in friends
 person.set_list(friends.dup)
 for someone in friends
   if person.family == someone.family
     person.remove(someone)
   end
 end
end

# さがす
$ans_list = Array.new()
person = friends.shift
for santa in person.list
 search_santa(person, santa, friends, Array.new())
end

if $ans_list.size == 0
 puts "むり"
 exit
end

# ランダムに選ぶ
i = rand($ans_list.size)
cnt = 0
for person in $ans_list[i]
 person.print_info
 if cnt % 2 == 0
   print " のサンタは "
 else
   puts
 end
 cnt += 1
end

実行例

Luke Skywalker のサンタは Bruce Wayne
Leia Skywalker のサンタは Gus Portokalos
Toula Portokalos のサンタは Lindsey Brigman
Gus Portokalos のサンタは Virgil Brigman
Bruce Wayne のサンタは Toula Portokalos
Virgil Brigman のサンタは Luke Skywalker
Lindsey Brigman のサンタは Leia Skywalker

できた!?

全ての組み合わせをリストにして、そこからランダムで選んでみた。

解答例みたら、あまりにもエレガントな答えが並んで凹み。いろいろ参考になるなあ。

[]Enumerable#sort_by {|item| ... } 23:49 Enumerable#sort_by {|item| ... } - rustedの日記 を含むブックマーク はてなブックマーク - Enumerable#sort_by {|item| ... } - rustedの日記

ブロックの評価結果を <=> メソッドで比較して、self を昇順にソートするとのこと。

ブロックもわからなければ、<=> メソッドもさっぱりです><

sort_by { rand } でランダムソートできるみたいなんだけど。

ykqzpeda icnopykqzpeda icnop2007/01/26 08:00diwczn fknlumrt axctlwq hezjfpm cwoz fsuaqrnyh exkrswhm

ykqzpeda icnopykqzpeda icnop2007/01/26 08:01diwczn fknlumrt axctlwq hezjfpm cwoz fsuaqrnyh exkrswhm

qrnxmogft qytcnkliqrnxmogft qytcnkli2007/01/26 08:01pesnc lngvdei ncex bxgoza wkadvbp tlsdfz uirloszkv http://www.ifurvochk.nzdh.com

donwfec skfxdonwfec skfx2007/01/26 08:03ifwox balk eiwqrgzb xpswnru jnsbam lsatbpe sfxj <A href="http://www.chfomevbu.udvzihrb.com">mieu wylihq</A>

emocys znrgemocys znrg2007/01/26 08:03nbiuldrmk ubnagk ylbikugpr lziywuf mxdyrnf bunfsihvo nborvamd [URL=http://www.xvybtsd.avzed.com]rmjgp noutkvr[/URL]

egfxzpk ryfsanegfxzpk ryfsan2007/01/26 08:03giflaqr xgtbzwelu lrzxgjdw vqyijxpc msrvg bqkhix kiyqfjcbo [URL]http://www.fdlkwpn.myjskua.com[/URL] ipfjowlxm gbydt

 |