英文:
Failing test cases on Set! on Kattis
问题
以下是您提供的代码的翻译部分:
我正在尝试解决一个名为Set!的Kattis问题。可以在[这里](https://open.kattis.com/problems/set)查看。
这是我的解决方案:
从sys导入stdin
ls = []
ls_output = []
ls_final = []
ls_answer = []
output = ''
对于i在stdin中:
ls += i.split()
ls1 = dict(list(enumerate(ls, 1)))
dc = {v: k for k, v in ls1.items()}
ls_values = list(ls1.values())
对于i在range(len(ls_values)):
对于j在range(i+1, len(ls_values)):
对于k在range(j+1, len(ls_values)):
ls_output.append([ls[i], ls[j], ls[k]])
对于m在ls_output中:
如果对于n在range(4),所有(len(set([m[0][n], m[1][n], m[2][n]]))在[1, 3]中)且m[0]!=m[1]!=m[2]!=m[0]:
ls_final.append(m)
如果ls_final存在:
对于x在ls_final中:
对于y在x中:
ls_answer.append(dc[y])
对于z在range(0, len(ls_answer), 3):
output += f'{ls_answer[z]} {ls_answer[z+1]} {ls_answer[z+2]}\n'
否则:
output += "no sets"
print(output)
由于代码较长,我只提供了主要的翻译部分。如果您需要更多的帮助或有其他问题,请随时提出。
英文:
I'm trying to solve a problem on Kattis called Set!. It can be viewed here.
This is my solution:
from sys import stdin
ls=[]
ls_output=[]
ls_final=[]
ls_answer=[]
output=''
for i in stdin:
ls+=i.split()
ls1=dict(list(enumerate(ls,1)))
dc={v:k for k,v in ls1.items()}
ls_values=list(ls1.values())
for i in range(len(ls_values)):
for j in range(i+1,len(ls_values)):
for k in range(j+1,len(ls_values)):
ls_output.append([ls[i],ls[j],ls[k]])
for m in ls_output:
if all(len(set([m[0][n], m[1][n], m[2][n]])) in [1, 3] for n in range(4))\
and m[0]!=m[1]!=m[2]!=m[0]:
ls_final.append(m)
if ls_final:
for x in ls_final:
for y in x:
ls_answer.append(dc[y])
for z in range(0,len(ls_answer),3):
output+=f'{ls_answer[z]} {ls_answer[z+1]} {ls_answer[z+2]}\n'
else:
output+="no sets"
print(output)
For some reason, it always fails the 8th test case (passing 7/31 cases). I cannot figure out what's wrong with the code as it looks correct to me, as a beginner. (I'm not asking for anyone to optimize my code. I know that it could be improved and be made more efficient, beautified. But that is not my main point. Also, please do not provide a solution from some GitHub repo. I'm interested in learning only from what I coded here. And yes, I've already tried consulting Chat-you-know-who)
#Updated the code according to a suggestion to do away with dictionaries and prevent the duplicates problem. Still had the same result (8th test case failed).
from sys import stdin
ls=[]
ls_output=[]
ls_final=[]
ls_answer=[]
output=''
for i in stdin:
ls+=i.split()
#enumerated ls1 and then unpacked the tuples to form ls2
ls2=[]
ls1=list(enumerate(ls,1))
list(ls2.extend(item) for item in ls1)
##ls1=dict(list(enumerate(ls,1)))
##ls_keys=list(ls1.keys())
##
####dc={v:k for k,v in ls1.items()}
##ls_values=list(ls1.values())
for i in range(len(ls)):
for j in range(i+1,len(ls)):
for k in range(j+1,len(ls)):
ls_output.append([ls[i],ls[j],ls[k]])
for m in ls_output:
if all(len(set([m[0][n], m[1][n], m[2][n]])) !=2 for n in range(4)):
ls_final.append(m)
if ls_final:
for x in ls_final:
for y in x:
ls_answer.append(ls2[ls2.index(y)-1]) ##ls2=[1,3SOP,2,2DOP,3,1STP..]
for z in range(0,len(ls_answer),3):
output+=f'{ls_answer[z]} {ls_answer[z+1]} {ls_answer[z+2]}\n'
else:
output+="no sets"
print(output)
Edit:
This is the correct solution (thanks to @ggorlen), keeping parts of my original code (dictionary) while eliminating other data structures/ possibility of duplicates being indexed wrongly. The code is more concise and solves all test cases now.
from sys import stdin
stdin=open('std.txt','r')
ls=[]
ls_final=[]
output=''
for i in stdin:
ls+=i.split()
ls1=dict(list(enumerate(ls,1)))
for i in range(len(ls)):
for j in range(i+1,len(ls)):
for k in range(j+1,len(ls)):
acc=[]
acc.append(ls1[i+1])
acc.append(ls1[j+1])
acc.append(ls1[k+1])
if all(len(set([acc[0][n], acc[1][n], acc[2][n]])) !=2 for n in range(4)):
ls_final.append([i+1,j+1,k+1])
ls_final=[j for i in ls_final for j in i]
if ls_final:
for z in range(0,len(ls_final),3):
output+=f'{ls_final[z]} {ls_final[z+1]} {ls_final[z+2]}\n'
else:
output+="no sets"
print(output)
答案1
得分: 2
你的基本逻辑看起来是正确的。虽然你忽略了简化和重构你的代码,但这正是我通过测试所做的。
这是我的解决方案,它以你的解决方案为基础,并剔除了不必要的中间步骤和数据结构:
from sys import stdin
found = False
cards = []
for line in stdin:
cards.extend(line.split())
for i in range(len(cards)):
for j in range(i + 1, len(cards)):
for k in range(j + 1, len(cards)):
x, y, z = cards[i], cards[j], cards[k]
if all(len(set([x[i], y[i], z[i]])) != 2 for i in range(4)):
found = True
print(i + 1, j + 1, k + 1)
if not found:
print("no sets")
我的直觉是直接使用卡片的索引信息会处理重复的情况。这个约束在描述中没有讨论,留下了这可能导致隐藏故障的可能性。
你的方法,使用字典将每张卡片映射到它的索引,将在存在重复卡片的情况下失败,因为两张卡片都将映射到相同的索引。在我的版本中,重复的卡片仍然保留它们各自的索引。
故事的教训:
- 尽量直接解决问题,步骤最少。每增加一个步骤和复杂性都会引入一个潜在的失败点。
- 不要太急于拒绝重构作为修复逻辑问题的工具。简化可以揭示隐藏的特征,这在复杂的设计中可能不明显。
- 重新审视问题的约束,考虑重复等边缘情况。正如Kelly所提到的,被建模成真实领域后的编程挑战通常会违反这些领域的规则,似乎在这里也是如此,因为Set不应该有重复的卡片。
- 使用Black格式化你的代码,并遵循PEP-8。杂乱的样式会降低逻辑的可理解性。
英文:
Your fundamental logic looks correct. Although you've discounted simplifying and refactoring your code, that's exactly what I did to pass the tests.
Here's my solution, which starts with your solution and strips out unnecessary intermediate steps and data structures:
from sys import stdin
found = False
cards = []
for line in stdin:
cards.extend(line.split())
for i in range(len(cards)):
for j in range(i + 1, len(cards)):
for k in range(j + 1, len(cards)):
x, y, z = cards[i], cards[j], cards[k]
if all(len(set([x[i], y[i], z[i]])) != 2 for i in range(4)):
found = True
print(i + 1, j + 1, k + 1)
if not found:
print("no sets")
My hunch was that using the card's index information directly would handle duplicates. This constraint isn't discussed in the description, leaving open the possibility that it could account for the hidden failures.
Your approach, using a dict to map each card to its index, will fail in the presence of duplicates as two cards will both map to the same index. In my version, duplicate cards still preserve their separate indices.
Morals of the story:
- Try to solve problems directly, with a minimum of steps. Every step and piece of complexity added introduces a potential failure point.
- Don't be too hasty to reject refactoring as a tool to fix logical problems. Simplification can reveal hidden characteristics that may not be obvious in a complex design.
- Revisit the problem constraints to consider edge cases like duplicates. As Kelly mentions, coding challenges that are ostensibly modeled after real-life domains often break rules in those domains, as appears to be the case here, since Set isn't supposed to have duplicate cards.
- Format your code with Black and adhere to PEP-8. Smushed-together style makes the logic less comprehensible.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论