Ruby 组合学
我想生成一个包含俱乐部列表的足球比赛。每场比赛都在周日进行,时间随机包含在 match_starts_at 数组中。每个俱乐部每周日只打一场比赛。
示例:
拥有这些俱乐部:
Club Atlético All Boys
Asociación Atlética Argentinos Juniors
Arsenal Fútbol Club
Club Atlético Banfield
Club Atlético Belgrano
Club Atlético Boca Juniors
Club Atlético Colón
Club Estudiantes de La Plata
Club Deportivo Godoy Cruz Antonio Tomba
Asociación Mutual Social y Deportiva Atlético de Rafaela
Club Atlético Independiente
Club Atlético Lanús
Club Atlético Newell's Old Boys
Club Olimpo
Racing Club
Club Atlético San Martín
Club Atlético San Lorenzo de Almagro
Club Atlético Tigre
Club Atlético Unión
Club Atlético Vélez Sarsfield
俱乐部结构示例:
=> # Club @id=1 @name="Example Name"
=> # Club @id=2 @name="Example2 Name"
Fixture 结构示例:
=> # Fixture @id=1 @datetime='2011-11-19 19:12:49' @home_id=1 @away_id=2
Fixture 对象需要将以下内容保存到数据库中:
a home club (:home)
an away club (:away)
and the time of the match (:datetime)
每个俱乐部只能与其他俱乐部比赛一场,并且所有俱乐部都应该参加一场比赛主场,另一场客场,另一场主场,等等。一个日期应该有 10 场比赛。如何创建匹配列表?
这就是我到目前为止所做的。
competition = Competition.get(1)
clubs = Club.all #20 clubs
@time = Time.now
@count = 0
until @time.sunday? do
@time += (24*60*60) # add 1 day until it's sunday
end
@first_time = @time
@fixture = {1 => []}
clubs.combination(2).each_with_index do |(club1, club2), idx|
Fixture.create(
:home => idx.even? ? club1 : club2,
:away => idx.even? ? club2 : club1,
:datetime => available_fixture_date(club1,club2)
).save
end
def getFecha(club1, club2)
@fixture.keys.each do |fecha|
if (!@fixture[fecha].include?(club1.name) && !@fixture[fecha].include?(club2.name))
@fixture[fecha] << club1.name
@fixture[fecha] << club2.name
@fixture[@fixture.keys.last + 1] = []
return fecha
end
end
end
def available_fixture_date(club1, club2)
fecha = getFecha(club1, club2)
match_starts_at = ['16:00', '17:30', '18:10', '22:00']
match_time = match_starts_at.shuffle.first
@time = @first_time + (24*60*60) * fecha * 7
Time.new(@time.year, @time.month, @time.day, match_time[0,2], match_time[3,2])
end
使用我的代码,我可以获得超过 19 个日期,并且我应该获得 19 个日期,每个日期有 10 个匹配项。
I want to generate a soccer football fixture with a list of clubs. Each game is played on Sundays in a random time included in the match_starts_at array. Each club plays only one game each Sunday.
Example:
Having these clubs:
Club Atlético All Boys
Asociación Atlética Argentinos Juniors
Arsenal Fútbol Club
Club Atlético Banfield
Club Atlético Belgrano
Club Atlético Boca Juniors
Club Atlético Colón
Club Estudiantes de La Plata
Club Deportivo Godoy Cruz Antonio Tomba
Asociación Mutual Social y Deportiva Atlético de Rafaela
Club Atlético Independiente
Club Atlético Lanús
Club Atlético Newell's Old Boys
Club Olimpo
Racing Club
Club Atlético San Martín
Club Atlético San Lorenzo de Almagro
Club Atlético Tigre
Club Atlético Unión
Club Atlético Vélez Sarsfield
Result should be similar to what is seen here: http://www.afa.org.ar/index.php?option=com_content&view=article&id=16780%3Afixture-del-torneo-de-primera-division&Itemid=100
Club structure example:
=> # Club @id=1 @name="Example Name"
=> # Club @id=2 @name="Example2 Name"
Fixture structure example:
=> # Fixture @id=1 @datetime='2011-11-19 19:12:49' @home_id=1 @away_id=2
A Fixture object needs the following to be saved to the database:
a home club (:home)
an away club (:away)
and the time of the match (:datetime)
Each club should play only one time with the other clubs and all clubs should play one match at home, the other away , the other at home, etc. There should be 10 matches in a date. How can I create the list of matches?
This is what I've done so far.
competition = Competition.get(1)
clubs = Club.all #20 clubs
@time = Time.now
@count = 0
until @time.sunday? do
@time += (24*60*60) # add 1 day until it's sunday
end
@first_time = @time
@fixture = {1 => []}
clubs.combination(2).each_with_index do |(club1, club2), idx|
Fixture.create(
:home => idx.even? ? club1 : club2,
:away => idx.even? ? club2 : club1,
:datetime => available_fixture_date(club1,club2)
).save
end
def getFecha(club1, club2)
@fixture.keys.each do |fecha|
if (!@fixture[fecha].include?(club1.name) && !@fixture[fecha].include?(club2.name))
@fixture[fecha] << club1.name
@fixture[fecha] << club2.name
@fixture[@fixture.keys.last + 1] = []
return fecha
end
end
end
def available_fixture_date(club1, club2)
fecha = getFecha(club1, club2)
match_starts_at = ['16:00', '17:30', '18:10', '22:00']
match_time = match_starts_at.shuffle.first
@time = @first_time + (24*60*60) * fecha * 7
Time.new(@time.year, @time.month, @time.day, match_time[0,2], match_time[3,2])
end
With my code I get more than 19 dates and I should get 19 dates with 10 matches per date.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不会得到一个很好的俏皮话,就像你为团队配对所做的那样,因为它需要查阅现有数据来找出已经采取的日期。但这应该可以正常工作。请注意,我使用了 ActiveSupport 的时间助手,但如果您没有可用的 ActiveSupport 并且不想包含它,则可以使用 Chronic 之类的东西。
You won't get a nice one-liner for that, like you did for the pairing of teams, since it requires consulting the existing data to find out what dates are already taken. But this should work fine. Note that I've used ActiveSupport's time helpers, but you could use something like Chronic if you don't have ActiveSupport available and don't want to include it.
我相信您在这里寻找的通用算法是循环。以下代码为我正确获取了日期,最终总共 19 个日期,每个日期 10 个匹配项:
I believe the general algorithm you're looking for here is the Round-Robin. The following gets the dates correctly for me, ending up with 19 dates total, 10 matches per date:
不确定您到底想要什么,但您似乎想要一种更简单的方法来进行时间计算?
如果是这样,Chronic 就非常酷了。
Not sure exactly what you are after here, but you seem to want an easier way to do time calculations?
If so, Chronic is pretty cool.