Advent of Code 2023题解 [Mathematica/Python]

发布时间 2023-12-01 14:39:32作者: yhm138

Day 1

Part 1

(*读取文件*)lines = ReadList["E:\\ExplorerDownload\input.txt", String];

(*计算校准值*)
calibrationValues = 
  ToExpression[
     StringJoin[#[[1]], #[[-1]]]] & /@ (StringCases[#, 
       DigitCharacter] & /@ lines);

(*打印总和*)
Print[Total[calibrationValues]]

Part 2

import re

# 英文数字词对应的字典
word_to_num = {
    'one': 1,
    'two': 2,
    'three': 3,
    'four': 4,
    'five': 5,
    'six': 6,
    'seven': 7,
    'eight': 8,
    'nine': 9
    # ,
    # 'ten': 10,
    # 'eleven': 11,
    # 'twelve': 12,
    # 'thirteen': 13,
    # 'fourteen': 14,
    # 'fifteen': 15,
    # 'sixteen': 16,
    # 'seventeen': 17,
    # 'eighteen': 18,
    # 'nineteen': 19,
    # 'twenty': 20,
    # 'thirty': 30,
    # 'forty': 40,
    # 'fifty': 50,
    # 'sixty': 60,
    # 'seventy': 70,
    # 'eighty': 80,
    # 'ninety': 90,
    # 'hundred': 100,
    # 'thousand': 1000,
    # 'million': 1000000,
    # 'billion': 1000000000,
}

# 输入的字符串
# input_strs = [
#     'two1nine',
#     'eightwothree',
#     'abcone2threexyz',
#     'xtwone3four',
#     '4nineeightseven2',
#     'zoneight234',
#     '7pqrstsixteen'
# ]
# 从文件中读取输入的字符串
with open('input_part2.txt', 'r') as f:
    input_strs = [line.strip() for line in f]


# 抽取英文数字词和它们的位置
word_num_positions = []
for i, s in enumerate(input_strs):
    for word, num in word_to_num.items():
        for match in re.finditer(word, s):
            start, end = match.span()
            word_num_positions.append((i, start, end, word, num))

# 抽取所有的数字和它们的位置
digit_positions = []
for i, s in enumerate(input_strs):
    for match in re.finditer(r'\d', s):
        start, end = match.span()
        digit_positions.append((i, start, end, int(s[start:end])))

# 输出结果
# print('Word numbers and their positions:')
# for pos in word_num_positions:
#     print(f'String index: {pos[0]}, Start: {pos[1]}, End: {pos[2]}, Word: {pos[3]}, Number: {pos[4]}')
#
# print('\nDigits and their positions:')
# for pos in digit_positions:
#     print(f'String index: {pos[0]}, Start: {pos[1]}, End: {pos[2]}, Digit: {pos[3]}')

# for [StringIndex, Start, End, Word, Number] in word_num_positions:
#     print(f"{StringIndex=} {Start=} {End=} {Number=}")
# for [StringIndex, Start, End, Digit] in digit_positions:
#     print(f"{StringIndex=} {Start=} {End=} {Digit=}")

# 英文数字词和数字的位置
word_num_positions.sort()
digit_positions.sort()

# 创建存储每个StringIndex最小Start和最大End的字典
start_dict = {}
end_dict = {}

# 找到每个StringIndex的最小Start
for i, s, e, w, n in word_num_positions:
    if i in start_dict:
        start_dict[i] = min(start_dict[i], (s, n))
    else:
        start_dict[i] = (s, n)

for i, s, e, d in digit_positions:
    if i in start_dict:
        start_dict[i] = min(start_dict[i], (s, d))
    else:
        start_dict[i] = (s, d)

# 找到每个StringIndex的最大End
for i, s, e, w, n in word_num_positions[::-1]:
    if i in end_dict:
        end_dict[i] = max(end_dict[i], (e, n))
    else:
        end_dict[i] = (e, n)

for i, s, e, d in digit_positions[::-1]:
    if i in end_dict:
        end_dict[i] = max(end_dict[i], (e, d))
    else:
        end_dict[i] = (e, d)

# 输出每个StringIndex的二位数
total=0
for i in range(len(input_strs)):
    start_num = start_dict.get(i, (None, 0))[1]
    end_num = end_dict.get(i, (None, 0))[1]
    total+=(start_num * 10 + end_num)
    print(f'String index: {i}, Number: {start_num * 10 + end_num}')
print(f"{total=}")