每周挑战:最大冲突
Source: Dev.to
每周,Mohammad S. Anwar 会发布 The Weekly Challenge,这是我们所有人为两个每周任务想出解决方案的机会。
我的解决方案首先用 Python 编写,然后转换为 Perl。除非另有说明,否则 Copilot(以及其他 AI 工具)未被用于生成该解决方案。这是我们所有人练习编码的好方式。
- Challenge: https://theweeklychallenge.org/blog/perl-weekly-challenge-367/
- My solutions: https://github.com/manwar/perlweeklychallenge-club/tree/master/challenge-367/sgreen
任务 1 – 最大奇数二进制
任务
给定一个至少包含一个 1 的二进制字符串。
编写脚本重新排列位,使得到的二进制数成为 最大奇数二进制数,并返回得到的二进制字符串。结果字符串可以有前导零。
我的解决方案(Python)
思路很简单:
- 数必须是奇数 → 最后 一位必须是
1。 - 为了使数值最大,所有其余的
1应尽可能放在左侧(最高位)。
import re
def max_odd_binary(input_string: str) -> str:
"""Return the maximum odd binary string that can be built from the bits
of *input_string*.
The input must contain at least one '1' and consist only of '0' and '1'.
"""
if not re.search(r'^[01]*1[01]*$', input_string):
raise ValueError("Input not in expected format")
zeros = input_string.count('0')
ones = input_string.count('1')
# (ones‑1) leading 1s, all zeros, final 1 to make it odd
return '1' * (ones - 1) + '0' * zeros + '1'Perl 对应实现
Perl 版本遵循相同的逻辑,使用 tr/// 统计位数并利用 x 操作符进行重复。
示例
$ ./ch-1.py 1011
1101
$ ./ch-1.py 100
001
$ ./ch-1.py 111000
110001
$ ./ch-1.py 0101
1001
$ ./ch-1.py 1111
1111任务 2 – 冲突事件
任务
给定两个(或更多)事件,每个事件由 HH:MM 格式的开始时间和结束时间定义。
编写脚本判断是否有任意两个事件 冲突,即它们的时间区间存在非空交集。
我的解决方案(Python)
- 将
HH:MM转换为午夜后的分钟数(hm2m)。 - 为每个事件构建分钟范围列表,处理跨午夜的情况。
- 遍历这些分钟,使用集合检测重叠。
import re
def hm2m(t: str) -> int:
"""Convert HH:MM to minutes after midnight."""
if not re.search(r'^([01][0-9]|2[0-3]):[0-5][0-9]$', t):
raise ValueError("Input is not in the expected format (HH:MM)")
return int(t[:2]) * 60 + int(t[3:])
def conflict_events(events) -> bool:
"""Return True if any two (or more) events overlap.
*events* is a list of (start, end) tuples, each in HH:MM format.
"""
event_minutes = []
for start, end in events:
start_min = hm2m(start)
end_min = hm2m(end)
# Zero‑length events are ignored
if start_min == end_min:
continue
# Event crosses midnight → split into two ranges
if end_min < start_min:
event_minutes.extend([
range(start_min, 1440), # up to midnight
range(0, end_min) # after midnight
])
else:
event_minutes.append(range(start_min, end_min))
minutes_seen = set()
for r in event_minutes:
for minute in r:
if minute in minutes_seen:
return True
minutes_seen.add(minute)
return FalsePerl 对应实现
Perl 版本采用相同的算法;由于 Perl 没有内置的 range 对象,它将开始/结束分钟存入数组中。
示例
$ ./ch-2.py 10:00 12:00 11:00 13:00
True
$ ./ch-2.py 09:30 10:30 10:30 12:00
False
$ ./ch-2.py 14:00 15:30 14:30 16:00
True
$ ./ch-2.py 08:00 09:00 09:01 10:00
False
$ ./ch-2.py 23:00 00:30 00:00 01:00
True祝编码愉快!
