Run
aoc_source(day = 2, part = 1)
input = aoc_read(day = 2)
aoc_run(solve_day2_part1(input))Elapsed: 11.187 seconds
Memory: 19687 KB
Learning from my issues with floor division on day 1, I went straight to trying every possible string chunk for day 2. Good enough! After seeing the simplicity of regex solutions later, I went ahead and replaced my part 2 solution with that.
I do find “brute force” to be easier with Python than R, but I guess my brain jumps to for loops too much before vectorised and *apply/map operations. It feels easier to me to reason about an item/index in an iterable.
solve_day2_part1 <- function(input) {
# back to one line
ranges <- paste0(input, collapse = "")
ranges <- strsplit(ranges, ",", fixed = TRUE) |>
unlist()
ranges <- strsplit(ranges, "-", fixed = TRUE)
invalid_total <- 0L
for (range in ranges) {
ids <- range[[1]]:range[[2]]
is_invalid <- vapply(ids, is_invalid, logical(1))
invalid_total <- invalid_total + sum(ids[is_invalid])
}
invalid_total
}
is_invalid <- function(id) {
nchars <- nchar(id)
if (nchars %% 2 == 1) {
return(FALSE)
}
split <- nchars %/% 2
substr(id, 1, split) == substr(id, split + 1, nchars)
}aoc_source(day = 2, part = 1)
input = aoc_read(day = 2)
aoc_run(solve_day2_part1(input))Elapsed: 11.187 seconds
Memory: 19687 KB
solve_day2_part2 <- function(input) {
ranges <- paste0(input, collapse = "")
ranges <- strsplit(ranges, ",", fixed = TRUE) |>
unlist()
ranges <- strsplit(ranges, "-", fixed = TRUE)
invalid_total <- 0
ids <- lapply(ranges, \(x) x[[1L]]:x[[2L]]) |>
unlist()
is_invalid <- stringi::stri_detect(ids, regex = "^(\\d+)\\1+$")
sum(ids[is_invalid])
}aoc_source(day = 2, part = 2)
input = aoc_read(day = 2)
aoc_run(solve_day2_part2(input))Elapsed: 2.842 seconds
Memory: 44815 KB
def solve_day2_part1(text):
ranges = text[0].split(",")
ranges = [str.split("-") for str in ranges]
invalid_total = 0
for nums in ranges:
for i in range(int(nums[0]), int(nums[1])+1):
i = str(i)
nchars = len(i)
if (nchars % 2 != 0):
continue
split = nchars // 2
if i[:split] == i[split:]:
invalid_total += int(i)
return(invalid_total)def solve_day2_part2(text):
ranges = text[0].split(",")
ranges = [str.split("-") for str in ranges]
invalid_total = 0
for nums in ranges:
for num in range(int(nums[0]), int(nums[1])+1):
if invalid(num):
invalid_total += num
return(invalid_total)
def invalid(num):
num = str(num)
nchars = len(num)
for str_len in range(1, len(num)//2 + 1):
invalid = True
if (nchars - str_len) < 0 :
break
if (nchars % str_len) != 0:
continue
substr_chars = num[:str_len]
count_to_check = (nchars - str_len) // str_len + 1
for multi in range(1, count_to_check):
step = multi * str_len
if num[step:step+str_len] != substr_chars:
invalid = False
break
if invalid:
return(True)
return(False)