import re
TASKS_TEXT = """
task001, task002, task003, task004, task005, task006, task007, task008, task009, task010, task011, task012, task013, task014, task015, task016, task017, task019, task020, task022, task023, task024, task025, task026, task027, task028, task029, task030, task031, task032, task033, task034, task035, task036, task037, task038, task039, task040, task041, task042, task043, task044, task045, task046, task047, task048, task049, task050, task051, task052, task053, task054, task056, task057, task058, task059, task060, task061, task062, task063, task064, task065, task067, task068, task069, task070, task071, task072, task073, task074, task075, task077, task078, task079, task081, task082, task083, task084, task085, task086, task087, task088, task089, task090, task091, task092, task093, task094, task095, task097, task098, task099, task100, task101, task102, task103, task104, task105, task106, task107, task108, task109, task110, task111, task112, task113, task114, task115, task116, task117, task118, task119, task120, task121, task122, task123, task124, task125, task126, task127, task128, task129, task130, task131, task132, task134, task135, task136, task137, task138, task139, task140, task141, task142, task143, task144, task145, task146, task147, task148, task149, task150, task151, task152, task153, task154, task155, task156, task157, task159, task160, task161, task162, task163, task164, task165, task166, task167, task168, task169, task170, task171, task172, task174, task175, task176, task177, task178, task179, task180, task181, task183, task185, task186, task187, task188, task189, task190, task191, task192, task193, task194, task195, task196, task197, task198, task199, task200, task201, task203, task204, task205, task206, task207, task208, task209, task210, task211, task212, task214, task215, task216, task217, task218, task220, task221, task222, task223, task224, task225, task226, task227, task228, task229, task230, task231, task232, task234, task235, task236, task237, task238, task239, task240, task241, task242, task243, task244, task245, task246, task247, task248, task249, task250, task251, task252, task253, task254, task256, task257, task258, task259, task260, task261, task262, task263, task266, task267, task268, task269, task270, task271, task272, task273, task274, task276, task277, task278, task279, task280, task281, task282, task283, task287, task288, task289, task290, task291, task292, task293, task294, task295, task296, task297, task298, task299, task300, task301, task302, task303, task304, task305, task306, task307, task308, task309, task310, task311, task312, task313, task314, task315, task316, task317, task318, task320, task321, task322, task323, task325, task326, task327, task329, task330, task331, task332, task333, task334, task335, task336, task337, task338, task339, task340, task341, task342, task343, task344, task345, task346, task347, task348, task350, task352, task353, task354, task355, task356, task357, task359, task360, task361, task362, task365, task368, task369, task371, task372, task373, task374, task375, task376, task378, task380, task381, task384, task385, task386, task388, task389, task390, task391, task393, task394, task395, task398, task399, task400"""
def compress_ranges(nums):
if not nums:
return []
nums = sorted(nums)
ranges = []
start = nums[0]
prev = nums[0]
for n in nums[1:]:
if n == prev + 1:
prev = n
else:
ranges.append((start, prev))
start = prev = n
ranges.append((start, prev))
return ranges
def format_task(n):
return f"task{n:03d}"
present = {int(x) for x in re.findall(r"task(\d{3})", TASKS_TEXT)}
all_tasks = set(range(1, 401))
missing = sorted(all_tasks - present)
print(f"Present: {len(present)}")
print(f"Missing: {len(missing)}")
compressed = compress_ranges(missing)
print("\nMissing tasks:")
for a, b in compressed:
if a == b:
print(format_task(a))
else:
print(f"{format_task(a)} - {format_task(b)}")
aW1wb3J0IHJlCgoKVEFTS1NfVEVYVCA9ICIiIgp0YXNrMDAxLCB0YXNrMDAyLCB0YXNrMDAzLCB0YXNrMDA0LCB0YXNrMDA1LCB0YXNrMDA2LCB0YXNrMDA3LCB0YXNrMDA4LCB0YXNrMDA5LCB0YXNrMDEwLCB0YXNrMDExLCB0YXNrMDEyLCB0YXNrMDEzLCB0YXNrMDE0LCB0YXNrMDE1LCB0YXNrMDE2LCB0YXNrMDE3LCB0YXNrMDE5LCB0YXNrMDIwLCB0YXNrMDIyLCB0YXNrMDIzLCB0YXNrMDI0LCB0YXNrMDI1LCB0YXNrMDI2LCB0YXNrMDI3LCB0YXNrMDI4LCB0YXNrMDI5LCB0YXNrMDMwLCB0YXNrMDMxLCB0YXNrMDMyLCB0YXNrMDMzLCB0YXNrMDM0LCB0YXNrMDM1LCB0YXNrMDM2LCB0YXNrMDM3LCB0YXNrMDM4LCB0YXNrMDM5LCB0YXNrMDQwLCB0YXNrMDQxLCB0YXNrMDQyLCB0YXNrMDQzLCB0YXNrMDQ0LCB0YXNrMDQ1LCB0YXNrMDQ2LCB0YXNrMDQ3LCB0YXNrMDQ4LCB0YXNrMDQ5LCB0YXNrMDUwLCB0YXNrMDUxLCB0YXNrMDUyLCB0YXNrMDUzLCB0YXNrMDU0LCB0YXNrMDU2LCB0YXNrMDU3LCB0YXNrMDU4LCB0YXNrMDU5LCB0YXNrMDYwLCB0YXNrMDYxLCB0YXNrMDYyLCB0YXNrMDYzLCB0YXNrMDY0LCB0YXNrMDY1LCB0YXNrMDY3LCB0YXNrMDY4LCB0YXNrMDY5LCB0YXNrMDcwLCB0YXNrMDcxLCB0YXNrMDcyLCB0YXNrMDczLCB0YXNrMDc0LCB0YXNrMDc1LCB0YXNrMDc3LCB0YXNrMDc4LCB0YXNrMDc5LCB0YXNrMDgxLCB0YXNrMDgyLCB0YXNrMDgzLCB0YXNrMDg0LCB0YXNrMDg1LCB0YXNrMDg2LCB0YXNrMDg3LCB0YXNrMDg4LCB0YXNrMDg5LCB0YXNrMDkwLCB0YXNrMDkxLCB0YXNrMDkyLCB0YXNrMDkzLCB0YXNrMDk0LCB0YXNrMDk1LCB0YXNrMDk3LCB0YXNrMDk4LCB0YXNrMDk5LCB0YXNrMTAwLCB0YXNrMTAxLCB0YXNrMTAyLCB0YXNrMTAzLCB0YXNrMTA0LCB0YXNrMTA1LCB0YXNrMTA2LCB0YXNrMTA3LCB0YXNrMTA4LCB0YXNrMTA5LCB0YXNrMTEwLCB0YXNrMTExLCB0YXNrMTEyLCB0YXNrMTEzLCB0YXNrMTE0LCB0YXNrMTE1LCB0YXNrMTE2LCB0YXNrMTE3LCB0YXNrMTE4LCB0YXNrMTE5LCB0YXNrMTIwLCB0YXNrMTIxLCB0YXNrMTIyLCB0YXNrMTIzLCB0YXNrMTI0LCB0YXNrMTI1LCB0YXNrMTI2LCB0YXNrMTI3LCB0YXNrMTI4LCB0YXNrMTI5LCB0YXNrMTMwLCB0YXNrMTMxLCB0YXNrMTMyLCB0YXNrMTM0LCB0YXNrMTM1LCB0YXNrMTM2LCB0YXNrMTM3LCB0YXNrMTM4LCB0YXNrMTM5LCB0YXNrMTQwLCB0YXNrMTQxLCB0YXNrMTQyLCB0YXNrMTQzLCB0YXNrMTQ0LCB0YXNrMTQ1LCB0YXNrMTQ2LCB0YXNrMTQ3LCB0YXNrMTQ4LCB0YXNrMTQ5LCB0YXNrMTUwLCB0YXNrMTUxLCB0YXNrMTUyLCB0YXNrMTUzLCB0YXNrMTU0LCB0YXNrMTU1LCB0YXNrMTU2LCB0YXNrMTU3LCB0YXNrMTU5LCB0YXNrMTYwLCB0YXNrMTYxLCB0YXNrMTYyLCB0YXNrMTYzLCB0YXNrMTY0LCB0YXNrMTY1LCB0YXNrMTY2LCB0YXNrMTY3LCB0YXNrMTY4LCB0YXNrMTY5LCB0YXNrMTcwLCB0YXNrMTcxLCB0YXNrMTcyLCB0YXNrMTc0LCB0YXNrMTc1LCB0YXNrMTc2LCB0YXNrMTc3LCB0YXNrMTc4LCB0YXNrMTc5LCB0YXNrMTgwLCB0YXNrMTgxLCB0YXNrMTgzLCB0YXNrMTg1LCB0YXNrMTg2LCB0YXNrMTg3LCB0YXNrMTg4LCB0YXNrMTg5LCB0YXNrMTkwLCB0YXNrMTkxLCB0YXNrMTkyLCB0YXNrMTkzLCB0YXNrMTk0LCB0YXNrMTk1LCB0YXNrMTk2LCB0YXNrMTk3LCB0YXNrMTk4LCB0YXNrMTk5LCB0YXNrMjAwLCB0YXNrMjAxLCB0YXNrMjAzLCB0YXNrMjA0LCB0YXNrMjA1LCB0YXNrMjA2LCB0YXNrMjA3LCB0YXNrMjA4LCB0YXNrMjA5LCB0YXNrMjEwLCB0YXNrMjExLCB0YXNrMjEyLCB0YXNrMjE0LCB0YXNrMjE1LCB0YXNrMjE2LCB0YXNrMjE3LCB0YXNrMjE4LCB0YXNrMjIwLCB0YXNrMjIxLCB0YXNrMjIyLCB0YXNrMjIzLCB0YXNrMjI0LCB0YXNrMjI1LCB0YXNrMjI2LCB0YXNrMjI3LCB0YXNrMjI4LCB0YXNrMjI5LCB0YXNrMjMwLCB0YXNrMjMxLCB0YXNrMjMyLCB0YXNrMjM0LCB0YXNrMjM1LCB0YXNrMjM2LCB0YXNrMjM3LCB0YXNrMjM4LCB0YXNrMjM5LCB0YXNrMjQwLCB0YXNrMjQxLCB0YXNrMjQyLCB0YXNrMjQzLCB0YXNrMjQ0LCB0YXNrMjQ1LCB0YXNrMjQ2LCB0YXNrMjQ3LCB0YXNrMjQ4LCB0YXNrMjQ5LCB0YXNrMjUwLCB0YXNrMjUxLCB0YXNrMjUyLCB0YXNrMjUzLCB0YXNrMjU0LCB0YXNrMjU2LCB0YXNrMjU3LCB0YXNrMjU4LCB0YXNrMjU5LCB0YXNrMjYwLCB0YXNrMjYxLCB0YXNrMjYyLCB0YXNrMjYzLCB0YXNrMjY2LCB0YXNrMjY3LCB0YXNrMjY4LCB0YXNrMjY5LCB0YXNrMjcwLCB0YXNrMjcxLCB0YXNrMjcyLCB0YXNrMjczLCB0YXNrMjc0LCB0YXNrMjc2LCB0YXNrMjc3LCB0YXNrMjc4LCB0YXNrMjc5LCB0YXNrMjgwLCB0YXNrMjgxLCB0YXNrMjgyLCB0YXNrMjgzLCB0YXNrMjg3LCB0YXNrMjg4LCB0YXNrMjg5LCB0YXNrMjkwLCB0YXNrMjkxLCB0YXNrMjkyLCB0YXNrMjkzLCB0YXNrMjk0LCB0YXNrMjk1LCB0YXNrMjk2LCB0YXNrMjk3LCB0YXNrMjk4LCB0YXNrMjk5LCB0YXNrMzAwLCB0YXNrMzAxLCB0YXNrMzAyLCB0YXNrMzAzLCB0YXNrMzA0LCB0YXNrMzA1LCB0YXNrMzA2LCB0YXNrMzA3LCB0YXNrMzA4LCB0YXNrMzA5LCB0YXNrMzEwLCB0YXNrMzExLCB0YXNrMzEyLCB0YXNrMzEzLCB0YXNrMzE0LCB0YXNrMzE1LCB0YXNrMzE2LCB0YXNrMzE3LCB0YXNrMzE4LCB0YXNrMzIwLCB0YXNrMzIxLCB0YXNrMzIyLCB0YXNrMzIzLCB0YXNrMzI1LCB0YXNrMzI2LCB0YXNrMzI3LCB0YXNrMzI5LCB0YXNrMzMwLCB0YXNrMzMxLCB0YXNrMzMyLCB0YXNrMzMzLCB0YXNrMzM0LCB0YXNrMzM1LCB0YXNrMzM2LCB0YXNrMzM3LCB0YXNrMzM4LCB0YXNrMzM5LCB0YXNrMzQwLCB0YXNrMzQxLCB0YXNrMzQyLCB0YXNrMzQzLCB0YXNrMzQ0LCB0YXNrMzQ1LCB0YXNrMzQ2LCB0YXNrMzQ3LCB0YXNrMzQ4LCB0YXNrMzUwLCB0YXNrMzUyLCB0YXNrMzUzLCB0YXNrMzU0LCB0YXNrMzU1LCB0YXNrMzU2LCB0YXNrMzU3LCB0YXNrMzU5LCB0YXNrMzYwLCB0YXNrMzYxLCB0YXNrMzYyLCB0YXNrMzY1LCB0YXNrMzY4LCB0YXNrMzY5LCB0YXNrMzcxLCB0YXNrMzcyLCB0YXNrMzczLCB0YXNrMzc0LCB0YXNrMzc1LCB0YXNrMzc2LCB0YXNrMzc4LCB0YXNrMzgwLCB0YXNrMzgxLCB0YXNrMzg0LCB0YXNrMzg1LCB0YXNrMzg2LCB0YXNrMzg4LCB0YXNrMzg5LCB0YXNrMzkwLCB0YXNrMzkxLCB0YXNrMzkzLCB0YXNrMzk0LCB0YXNrMzk1LCB0YXNrMzk4LCB0YXNrMzk5LCB0YXNrNDAwIiIiCgoKZGVmIGNvbXByZXNzX3JhbmdlcyhudW1zKToKICAgIGlmIG5vdCBudW1zOgogICAgICAgIHJldHVybiBbXQoKICAgIG51bXMgPSBzb3J0ZWQobnVtcykKICAgIHJhbmdlcyA9IFtdCiAgICBzdGFydCA9IG51bXNbMF0KICAgIHByZXYgPSBudW1zWzBdCgogICAgZm9yIG4gaW4gbnVtc1sxOl06CiAgICAgICAgaWYgbiA9PSBwcmV2ICsgMToKICAgICAgICAgICAgcHJldiA9IG4KICAgICAgICBlbHNlOgogICAgICAgICAgICByYW5nZXMuYXBwZW5kKChzdGFydCwgcHJldikpCiAgICAgICAgICAgIHN0YXJ0ID0gcHJldiA9IG4KCiAgICByYW5nZXMuYXBwZW5kKChzdGFydCwgcHJldikpCiAgICByZXR1cm4gcmFuZ2VzCgoKZGVmIGZvcm1hdF90YXNrKG4pOgogICAgcmV0dXJuIGYidGFza3tuOjAzZH0iCgoKcHJlc2VudCA9IHtpbnQoeCkgZm9yIHggaW4gcmUuZmluZGFsbChyInRhc2soXGR7M30pIiwgVEFTS1NfVEVYVCl9CmFsbF90YXNrcyA9IHNldChyYW5nZSgxLCA0MDEpKQptaXNzaW5nID0gc29ydGVkKGFsbF90YXNrcyAtIHByZXNlbnQpCgpwcmludChmIlByZXNlbnQ6IHtsZW4ocHJlc2VudCl9IikKcHJpbnQoZiJNaXNzaW5nOiB7bGVuKG1pc3NpbmcpfSIpCgpjb21wcmVzc2VkID0gY29tcHJlc3NfcmFuZ2VzKG1pc3NpbmcpCgpwcmludCgiXG5NaXNzaW5nIHRhc2tzOiIpCmZvciBhLCBiIGluIGNvbXByZXNzZWQ6CiAgICBpZiBhID09IGI6CiAgICAgICAgcHJpbnQoZm9ybWF0X3Rhc2soYSkpCiAgICBlbHNlOgogICAgICAgIHByaW50KGYie2Zvcm1hdF90YXNrKGEpfSAtIHtmb3JtYXRfdGFzayhiKX0iKQ==