给定一张输赢表,输出体育比赛中每场比赛的结果


11

这个问题的灵感来自正在进行的“先生们玩的流氓比赛” 橄榄球世界杯,该比赛刚刚结束了撞球阶段。锦标赛中有20支队伍,分成4组,每组5支。在小组赛阶段,每个团队与小组中的所有其他团队进行比赛(每个小组总共进行10场比赛),并且每个小组中排名前2的团队进入淘汰赛阶段。

在撞球阶段结束时,每个撞球都有一张表格,显示每个团队的胜利,失败和平局数量。这个问题的挑战是编写一个程序,输入一组中每个团队的获胜,失败和平局数,然后从该信息输出10场比赛中每场比赛的个人结果(谁赢,谁输,谁对谁)(如果可能),否则输出错误消息。

例如,这是今年锦标赛台球D的表:

            Win    Loss    Draw
Canada        0       4       0
France        3       1       0
Ireland       4       0       0
Italy         2       2       0
Romania       1       3       0

从这些信息中,我们可以推断出爱尔兰赢了加拿大,法国,意大利和罗马尼亚,因为他们赢得了所有比赛。法国一定赢了加拿大,意大利和罗马尼亚,但输给了爱尔兰,因为他们只输了一个,而且一定是不败的爱尔兰。我们刚刚得出的结论是意大利输给了爱尔兰和法国,因此他们一定赢了加拿大和罗马尼亚。加拿大输掉了所有比赛,因此罗马尼亚的胜利一定是对加拿大。

         Canada  France Ireland   Italy Romania
Canada        -       L       L       L       L
France        W       -       L       W       W
Ireland       W       W       -       W       W
Italy         W       L       L       -       W
Romania       W       L       L       L       -

这是一个更复杂的(虚构的)示例:

            Win    Loss    Draw
Canada        3       1       0
France        1       2       1
Ireland       0       3       1
Italy         0       2       2
Romania       4       0       0

在这种情况下,我们可以推断出罗马尼亚赢了加拿大,法国,意大利和爱尔兰,因为他们赢得了所有比赛。加拿大一定已经赢得了对爱尔兰,意大利和法国的胜利,但输给了罗马尼亚。我们刚刚得出的结论是意大利输给了罗马尼亚和加拿大,因此他们一定对法国和爱尔兰不利。这意味着爱尔兰与意大利并列而输给其他所有人,因此法国一定击败了爱尔兰,与意大利并列而输给加拿大和罗马尼亚。

         Canada  France Ireland   Italy Romania
Canada        -       W       W       W       L
France        L       -       W       D       L
Ireland       L       L       -       D       L
Italy         L       D       D       -       L
Romania       W       W       W       W       -

有些表无法解决,例如今年的B组,其中3个团队的W / L / D总数相同:

            Win    Loss    Draw
Japan         3       1       0
Samoa         1       3       0
Scotland      3       1       0
South Africa  3       1       0
United States 0       4       0

但是,某些具有重复行的表是可解决的,例如(虚构)这样的表:

            Win    Loss    Draw
Japan         4       0       0
Samoa         0       3       1
Scotland      2       2       0
South Africa  0       3       1
United States 3       1       0

输入值

您的程序或函数应接受15个数字,分别指定5支球队中每支球队的赢,输和平局。您可以使用所需的任何定界符,以行或列的主要顺序输入数字,并通过stdin或通过数组传递给函数来接受数字。

因为获胜+损失+平局= 4,所以您可以忽略其中一个值,并根据需要从其他值中计算出来,这意味着您只需输入10个数字。

您不需要输入任何团队名称。

输入样例:

3 1 0
1 2 1
0 3 1
0 2 2
4 0 0

输出量

程序或函数的输出应采用打印到stdout的5 x 5网格或函数返回的数组的形式。每个元素都应指定在行位置给定的团队是赢还是输,还是在列位置对战。输出的行顺序应与输入匹配。您可以定义表示赢,输或平局的内容,因此可以使用字母W,L,D或数字0 1 2或任何您想要的名称,只要它们定义明确并且可以彼此区分即可。对角元素是未定义的,您可以输出任何内容,但是每种情况下都应该相同。值可以用逗号,空格或您喜欢的任何字符(或字符)分隔。如果需要,输入和输出都可以在一行上格式化所有值。

如果表没有唯一的解决方案,那么您必须输出一个简单的错误消息。

样本输出:

- W W W L
L - W D L
L L - D L
L D D - L
W W W W -

不可解决表格的样本输出:

dunno mate

这是代码高尔夫,因此以字节为单位的最短程序获胜。

图片相关(日本与南非):

在此处输入图片说明

Answers:


4

CJam,57 49 47 45字节

{JZb:af{.*e_1+e!}:m*:e_5f/{_z2\ff-=},_,(0@?~}

这是一个匿名函数,该函数从堆栈中弹出一个二维数组,并返回一个二维数组。它包含2胜利,1平局和0损失。它还包含1对角线元素,您可以输出任何内容。如果问题无法解决,则函数返回-1

该代码可在线运行,但需要一段时间。在CJam解释器中尝试。

测试运行

$ cat input
3 1 0
1 2 1
0 3 1
0 2 2
4 0 0
$ time cjam results.cjam < input
[1 2 2 2 0]
[0 1 2 1 0]
[0 0 1 1 0]
[0 1 1 1 0]
[2 2 2 2 1]

real    0m1.584s
user    0m4.020s
sys     0m0.146s

这个怎么运作

JZb:a e# Push 19 in base 3; wrap each digit in an array. Pushes [[2] [0] [1]].
f{    e# For each row of the input, push it and [[2] [0] [1]]; then:
  .*  e# Repeat 2, 0 and 1 (win, loss, draw) the specified number of times.
  e_  e# Flatten the resulting array.
  1+  e# Append a 1 for the diagonal.
  e!  e# Push all possible permutations.
}     e#
:m*   e# Cartesian product; push all possible combinations of permutations.
:e_   e# Flatten the results.
5f/   e# Split into rows of length 5.
{     e# Filter:
  _z  e#   Push a transposed copy of the array.
  2\  e#   Swap the result with 2.
  ff- e#   Subtract all elements from 2.
  =   e#   Check for equality.
},    e# Keep the element if `=' pushed 1.
_,(   e# Get the length of the array of solutions and subtract 1.
0@?   e# Keep the array for length 1, push 0 otherwise.
~     e# Either dump the singleton array or turn 0 into -1.

4

Haskell中,180个 177字节

import Data.List
z=zipWith
m=map
a#b|(c,d)<-splitAt a b=c++[0]++d
f t=take 1[x|x<-m(z(#)[0..])$sequence$m(permutations.concat.z(flip replicate)[1,-1,0])t,transpose x==m(m(0-))x]

胜利显示为1,损失显示为,-1平局显示为0。对角元素也0。不可解决的表是空列表,即[]

用法示例:f [[3,1,0],[1,2,1],[0,3,1],[0,2,2],[4,0,0]]-> [[[0,1,1,1,-1],[-1,0,1,0,-1],[-1,-1,0,0,-1],[-1,0,0,0,-1],[1,1,1,1,0]]]

工作原理:蛮力!根据输入创建赢/输/平局列表,例如[3,1,0]-> [1,1,1,-1],置换,构建所有组合,插入对角线并保留所有等于其换位的表,而所有元素都取反。拿第一个。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.