07
https://adventofcode.com/2024/day/7
Prob1
題目
給一串數字
- 把
的前面兩個數字拿出來相加,再放回 前面 - 把
的前面兩個數字拿出來相乘,再放回 前面
輸入會給很多組數字和其對應的
範例
Input
100: 10 10
191: 19 10
120: 10 2 10
Output
- 100 是可行的
- 191 是不可行的
- 120 是可行的
220
解法
直接搜索無法剪枝,所以從尾巴逆著搜索,可以用結果是否不小於數字或整除數字來判斷。
python
import sys
from typing import List
def test(target: int, xs: List[int]) -> bool:
if len(xs) == 1:
return target == xs[0]
if target < xs[0]:
return False
if xs[0] > 0 and target % xs[0] == 0:
if test(target//xs[0], xs[1:]):
return True
return test(target - xs[0], xs[1:])
ans = 0
for line in sys.stdin:
target, xs_str = line.strip().split(':')
target = int(target)
xs = list(map(int, xs_str.strip().split(' ')))
xs.reverse()
if test(target, xs):
ans += target
print(ans)
Prob2
題目
給一串數字
- 把
的前面兩個數字拿出來相加,再放回 前面 - 把
的前面兩個數字拿出來相乘,再放回 前面 - 把
的前面兩個數字拿出來用字串組合的方式加起來,再放回 前面 ( "1" + "2" = "12"
)
輸入會給很多組數字和其對應的
範例
Input
100: 10 10
191: 19 10
1020: 10 2 10
Output
- 100 是可行的
- 191 是不可行的
- 1020 是可行的
1120
解法
一樣從尾巴逆著搜索,字串組合更好剪。
python
import sys
from typing import List
def test(target: int, xs: List[int]) -> bool:
if len(xs) == 1:
return target == xs[0]
if target < xs[0]:
return False
if xs[0] > 0 and target % xs[0] == 0:
if test(target//xs[0], xs[1:]):
return True
if target != xs[0] and str(target).endswith(str(xs[0])):
new_target = int(str(target).removesuffix(str(xs[0])))
if test(new_target, xs[1:]):
return True
return test(target - xs[0], xs[1:])
ans = 0
for line in sys.stdin:
target, xs_str = line.strip().split(':')
target = int(target)
xs = list(map(int, xs_str.strip().split(' ')))
xs.reverse()
if test(target, xs):
ans += target
print(ans)