Codeeval Challenge 230:足球,只回答部分正确

时间:2016-06-04 17:54:54

标签: python-2.7

我正在CodeEval中开展一项名为“足球”的相对较新的挑战。描述列在以下链接中: https://www.codeeval.com/open_challenges/230/

输入是由Python读取的文件的行,并且在每行中有以“|”分隔的列表,每个列表代表一个国家:第一个是国家“1”,第二个是国家“2”,所以上。

  

1 2 3 4 | 3 1 | 4 1

     

19 11 | 19 21 23 | 31 39 29

输出也是响应从文件读取的每一行的行。

  

1:1,2,3; 2:1; 3:1,2; 4:1,3;

     

11:1; 19:1,2; 21:2; 23:2; 29:3; 31:3; 39:3;

所以国家1支持第1,第2和第3组,如第一行输出所示:1:1,2,3

下面是我的解决方案,因为我不知道为什么该解决方案仅适用于描述链接中的两个示例案例,我想请任何人提供有关如何更正我的代码的注释和提示。非常感谢你提前的时间和帮助。

import sys

def football(string):
    countries = map(str.split, string.split('|'))
    teams = sorted(list(set([i[j] for i in countries for j in range(len(i))])))
    results = []
    for i in range(len(teams)):
        results.append([teams[i]+':'])
        for j in range(len(countries)):
            if teams[i] in countries[j]:
                results[i].append(str(j+1))
    for i in range(len(results)):
        results[i] = results[i][0]+','.join(results[i][1:])
    return '; '.join(results) + '; '

if __name__ == '__main__':
    lines = [line.rstrip() for line in open(sys.argv[1])]
    for line in lines:
        print football(line) 

2 个答案:

答案 0 :(得分:1)

故意尝试检查完整的测试输入和输出后,我发现了问题。这一行:

teams = sorted(list(set([i[j] for i in countries for j in range(len(i))])))

会使输出在排序方面出现问题。例如,这是一个示例输入:

10 20 | 43 23 | 27 | 25 | 11 1 12 43 | 33 18 3 43 41 | 31 3 45 4 36 | 25 29 | 1 19 39 | 39 12 16 28 30 37 | 32 | 11 10 7

并产生输出:

1:5,9; 10:1,12; 11:5,12; 12:5,10; 16:10; 18:6; 19:9; 20:1; 23:2; 25:4,8; 27:3; 28:10; 29:8; 3:6,7; 30:10; 31:7; 32:11; 33:6; 36:7; 37:10; 39:9,10; 4:7; 41:6; 43:2,5,6; 45:7; 7:12;

但挑战期望输出团队按数字按升序排序,这是由上述代码无法实现的,因为数字是字符串格式,而不是整数格式。因此,解决方案只是添加一个键,按整数的升序排序团队列表:

teams = sorted(list(set([i[j] for i in countries for j in range(len(i))])), key=lambda x:int(x))

这一行的变化很小,代码会通过测试。示例输出如下所示:

1:5,9; 3:6,7; 4:7; 7:12; 10:1,12; 11:5,12; 12:5,10; 16:10; 18:6; 19:9; 20:1; 23:2; 25:4,8; 27:3; 28:10; 29:8; 30:10; 31:7; 32:11; 33:6; 36:7; 37:10; 39:9,10; 41:6; 43:2,5,6; 45:7; 

如果您有更好,更有效的解决方案,请与我们联系。我希望阅读更好的代码或提高编程技巧的好建议。

答案 1 :(得分:0)

以下是我如何解决它:

import sys

with open(sys.argv[1]) as test_cases:
    for test in test_cases:
        if test:
            team_supporters = {}
            for nation, nation_teams in enumerate(test.strip().split("|"), start=1):
                for team in map(int, nation_teams.split()):
                    team_supporters.setdefault(team, []).append(nation)
            print(*("{}:{};".format(team, ",".join(map(str, sorted(nations))))
                    for team, nations in sorted(team_supporters.items())))

问题并不复杂。我们给出了来自国家(通过输入中的顺序隐式编号)到团队列表的映射。我们需要反过来创建一个从团队映射到国家列表的输出。

使用以与所需输出相同的方式映射的字典似乎很自然。当我们迭代它们时,我们可以使用enumerate为国家提供数字。 dict的setdefault方法在需要时将空列表添加到字典中(使用collections.defaultdict而不是常规字典将是另一种处理此问题的方法)。我们不需要关心输入的顺序,也不需要将命令存储在字典的内部列表中。

我们使用str.format调用构建的输出和print函数的默认空格分隔符。如果不需要最后一个分号,我会使用print("; ".join("{}:{}.format(...)))代替。由于输出需要按照顶层的团队和内部列表中的国家进行排序,因此我们会在必要时进行一些sorted次调用。

对内部列表进行排序可能甚至不是必需的,因为各国按顺序处理,其数字来自它们在输入行中的顺序。幸运的是,Python的Timsort算法在已经排序的输入上非常快,所以即使进行了一些不必要的排序,我们的代码仍然足够快。