在 Python 中,以下代码如何工作?
In Python, How does the following code work?
说明
越狱
监狱可以表示为牢房列表。每个牢房只包含一名囚犯。 1 代表未锁定的单元格,0 代表锁定的单元格。
[1, 1, 0, 0, 0, 1, 0]
从最左边的牢房开始,您的任务是查看可以释放多少囚犯,但要有条件。你是第一个牢房里的囚犯。如果第一个牢房被锁定,您将无法释放任何人。每次释放一名囚犯,锁定的牢房就会解锁,解锁的牢房会再次锁定。
所以,如果我们使用上面的例子:
[1, 1, 0, 0, 0, 1, 0]
# You free the prisoner in the 1st cell.
[0, 0, 1, 1, 1, 0, 1]
# You free the prisoner in the 3rd cell (2nd one locked).
[1, 1, 0, 0, 0, 1, 0]
# You free the prisoner in the 6th cell (3rd, 4th and 5th locked).
[0, 0, 1, 1, 1, 0, 1]
# You free the prisoner in the 7th cell - and you are done!
Here, we have set free 4 prisoners in total.
创建一个函数,根据这种独特的监狱安排,returns 释放囚犯的人数。
例子
freed_prisoners([1, 1, 0, 0, 0, 1, 0]) ➞ 4
freed_prisoners([1, 1, 1]) ➞ 1
freed_prisoners([0, 0, 0]) ➞ 0
freed_prisoners([0, 1, 1, 1]) ➞ 0
备注
你是一号牢房的犯人。您必须获得自由才能释放其他任何人。
您必须释放一名囚犯才能打开锁。因此,在第二个示例中,在您释放第一个囚犯后,输入为 [1, 1, 1],锁变为 [0, 0, 0]。由于所有牢房都已锁定,您不能再释放囚犯。
您总是从列表中最左边的元素开始(第一个牢房)。如果你右边的所有牢房都是零,你就不能释放更多的囚犯。
致谢:Edabit
我在解决方案中找到了以下代码:
def freed_prisoners(prison):
freed = [k for k, _ in groupby(prison)]
return len(freed) if freed[0] == 1 else 0
我知道 groupby
函数会给我密钥:[1, 0, 1, 0]
.
我的问题是这段代码是如何恰好符合逻辑的?是否恰好给出了相同的答案?
从囚犯的角度来看,越狱是这样的:
- 如果我的牢房被锁定,则没有人可以获释 (
freed[0] == 1
)。结束。除此以外,
继续第 2 步。
- 在我离开我的牢房后,锁会切换,我组中的任何人都留在他们的牢房里,因为它刚刚从解锁状态变为锁定状态。跳过我组中的每个人 (
k, _ in groupby(prison)
)。
- 对单元格块的其余部分重复步骤 1 和 2。
从第2步,我们可以推断出每个锁状态相同的组中只有一名囚犯被释放。而且我们还可以推断,从以下每一组中,我们可以释放一名囚犯。因此,确定获释囚犯的数量可以简化为计算不同群体的数量(如果我的牢房被锁定,则为零)。这将是 len(freed)
.
从下面的代码中可以更容易地看出这一点。另请注意第二个示例,它解决了“每组仅释放一个”部分;与第一个例子比较:
import itertools
def freed_prisoners(prison):
groups = [(k,list(v)) for k,v in itertools.groupby(prison)]
print(f"Groups: {groups}")
freed = [k for k, _ in groups]
persons = len(freed) if freed[0] == 1 else 0
print(f"Freed list: {freed}; freed {persons} persons")
return persons
freed_prisoners([1, 1, 0, 0, 0, 1, 0]) # ➞ 4
freed_prisoners([1, 0, 1, 0]) # ➞ 4
freed_prisoners([1, 1, 1]) # ➞ 1
freed_prisoners([0, 0, 0]) # ➞ 0
freed_prisoners([0, 1, 1, 1]) # ➞ 0
输出
Groups: [(1, [1, 1]), (0, [0, 0, 0]), (1, [1]), (0, [0])]
Freed list: [1, 0, 1, 0]; freed 4 persons
Groups: [(1, [1]), (0, [0]), (1, [1]), (0, [0])]
Freed list: [1, 0, 1, 0]; freed 4 persons
Groups: [(1, [1, 1, 1])]
Freed list: [1]; freed 1 persons
Groups: [(0, [0, 0, 0])]
Freed list: [0]; freed 0 persons
Groups: [(0, [0]), (1, [1, 1, 1])]
Freed list: [0, 1]; freed 0 persons
说明
越狱
监狱可以表示为牢房列表。每个牢房只包含一名囚犯。 1 代表未锁定的单元格,0 代表锁定的单元格。
[1, 1, 0, 0, 0, 1, 0]
从最左边的牢房开始,您的任务是查看可以释放多少囚犯,但要有条件。你是第一个牢房里的囚犯。如果第一个牢房被锁定,您将无法释放任何人。每次释放一名囚犯,锁定的牢房就会解锁,解锁的牢房会再次锁定。
所以,如果我们使用上面的例子:
[1, 1, 0, 0, 0, 1, 0]
# You free the prisoner in the 1st cell.
[0, 0, 1, 1, 1, 0, 1]
# You free the prisoner in the 3rd cell (2nd one locked).
[1, 1, 0, 0, 0, 1, 0]
# You free the prisoner in the 6th cell (3rd, 4th and 5th locked).
[0, 0, 1, 1, 1, 0, 1]
# You free the prisoner in the 7th cell - and you are done!
Here, we have set free 4 prisoners in total.
创建一个函数,根据这种独特的监狱安排,returns 释放囚犯的人数。
例子
freed_prisoners([1, 1, 0, 0, 0, 1, 0]) ➞ 4
freed_prisoners([1, 1, 1]) ➞ 1
freed_prisoners([0, 0, 0]) ➞ 0
freed_prisoners([0, 1, 1, 1]) ➞ 0
备注
你是一号牢房的犯人。您必须获得自由才能释放其他任何人。
您必须释放一名囚犯才能打开锁。因此,在第二个示例中,在您释放第一个囚犯后,输入为 [1, 1, 1],锁变为 [0, 0, 0]。由于所有牢房都已锁定,您不能再释放囚犯。
您总是从列表中最左边的元素开始(第一个牢房)。如果你右边的所有牢房都是零,你就不能释放更多的囚犯。
致谢:Edabit
我在解决方案中找到了以下代码:
def freed_prisoners(prison):
freed = [k for k, _ in groupby(prison)]
return len(freed) if freed[0] == 1 else 0
我知道 groupby
函数会给我密钥:[1, 0, 1, 0]
.
我的问题是这段代码是如何恰好符合逻辑的?是否恰好给出了相同的答案?
从囚犯的角度来看,越狱是这样的:
- 如果我的牢房被锁定,则没有人可以获释 (
freed[0] == 1
)。结束。除此以外, 继续第 2 步。 - 在我离开我的牢房后,锁会切换,我组中的任何人都留在他们的牢房里,因为它刚刚从解锁状态变为锁定状态。跳过我组中的每个人 (
k, _ in groupby(prison)
)。 - 对单元格块的其余部分重复步骤 1 和 2。
从第2步,我们可以推断出每个锁状态相同的组中只有一名囚犯被释放。而且我们还可以推断,从以下每一组中,我们可以释放一名囚犯。因此,确定获释囚犯的数量可以简化为计算不同群体的数量(如果我的牢房被锁定,则为零)。这将是 len(freed)
.
从下面的代码中可以更容易地看出这一点。另请注意第二个示例,它解决了“每组仅释放一个”部分;与第一个例子比较:
import itertools
def freed_prisoners(prison):
groups = [(k,list(v)) for k,v in itertools.groupby(prison)]
print(f"Groups: {groups}")
freed = [k for k, _ in groups]
persons = len(freed) if freed[0] == 1 else 0
print(f"Freed list: {freed}; freed {persons} persons")
return persons
freed_prisoners([1, 1, 0, 0, 0, 1, 0]) # ➞ 4
freed_prisoners([1, 0, 1, 0]) # ➞ 4
freed_prisoners([1, 1, 1]) # ➞ 1
freed_prisoners([0, 0, 0]) # ➞ 0
freed_prisoners([0, 1, 1, 1]) # ➞ 0
输出
Groups: [(1, [1, 1]), (0, [0, 0, 0]), (1, [1]), (0, [0])]
Freed list: [1, 0, 1, 0]; freed 4 persons
Groups: [(1, [1]), (0, [0]), (1, [1]), (0, [0])]
Freed list: [1, 0, 1, 0]; freed 4 persons
Groups: [(1, [1, 1, 1])]
Freed list: [1]; freed 1 persons
Groups: [(0, [0, 0, 0])]
Freed list: [0]; freed 0 persons
Groups: [(0, [0]), (1, [1, 1, 1])]
Freed list: [0, 1]; freed 0 persons