Rust
Turned out alright, I am looking forward to seeing what 2d coordinate grid code I can cannibalize from last year's solutions π
Turned out alright, I am looking forward to seeing what 2d coordinate grid code I can cannibalize from last year's solutions π
def is_safe(report: list[int]) -> bool:
global removed
acceptable_range = [_ for _ in range(-3,4) if _ != 0]
diffs = []
if any([report.count(x) > 2 for x in report]):
return False
for i, num in enumerate(report[:-1]):
cur = num
next = report[i+1]
difference = cur - next
diffs.append(difference)
if difference not in acceptable_range:
return False
if len(diffs) > 1:
if diffs[-1] * diffs[-2] <= 0:
return False
return True
with open('input') as reports:
list_of_reports = reports.readlines()[:-1]
count = 0
failed_first_pass = []
failed_twice = []
for reportsub in list_of_reports:
levels = [int(l) for l in reportsub.split()]
original = levels.copy()
if is_safe(levels):
safe = True
count += 1
else:
failed_first_pass.append(levels)
for report in failed_first_pass:
print(report)
working_copy = report.copy()
for i in range(len(report)):
safe = False
working_copy.pop(i)
print("checking", working_copy)
if is_safe(working_copy):
count += 1
safe = True
break
else:
working_copy = report.copy()
print(count)
R (R-Wasm)
input = file('input2024day2.txt',open='r')
lines = readLines(input)
library(stringr)
safe = 0
safe2 = 0
for (ln in lines){
vals = as.numeric(unlist(str_split(ln,' ')))
diffs = diff(vals)
cond1 = min(diffs) > 0 || max(diffs) < 0
cond2 = max(abs(diffs)) < 4
if (cond1 && cond2){
safe = safe + 1
}
else { #Problem Dampener
dampen = FALSE
for (omit in -1:-length(vals)){
diffs = diff(vals[omit])
cond1 = min(diffs) > 0 || max(diffs) < 0
cond2 = max(abs(diffs)) < 4
if (cond1 && cond2){
dampen = TRUE
}
}
if (dampen){
safe2 = safe2 + 1}
}
}
print (safe) #Part 1
print (safe + safe2) #Part 2
Took me a bit longer to get this one but still quite simple overall.
Spent quite some time on getting to know the try
and assert
operators better.
Run with example input here
# Get the indices matching the ascending/
# descending criteria
CheckAsc β β‘Β°β‘β(β£(βΈβ€.ββ.)β£(βΈβ€.βββ.)0)
# Get the indices matching the distance criteria
CheckDist β β‘Β°β‘β(β£(βΈβ€.β 1β:0)0Γββ₯β€1,3β΅β§-)
Split β β(β½β 1)β½,,
PartOne β (
&rs β &fo "input-2.txt"
β(β‘βββ @ .)β @\n.
CheckAsc.
β½
CheckDist
⧻β
)
PartTwo β (
&rs β &fo "input-2.txt"
β(β‘βββ @ .)β @\n.
CheckAsc.
Split
CheckDist.
Split
β(β)
⧻
:
β(β‘(β½:Β°β)βΒ€ββ:β 1β=.β‘⧻.)
β‘(⧻βCheckDistβ½CheckAsc.Β°β‘)
+⧻β΄β
)
&p "Day 2:"
&pf "Part 1: "
&p PartOne
&pf "Part 2: "
&p PartTwo
import kotlin.math.abs
import kotlin.math.sign
data class Report(val levels: List<Int>) {
fun isSafe(withProblemDampener: Boolean): Boolean {
var orderSign = 0.0f // - 1 is descending; +1 is ascending
levels.zipWithNext().forEachIndexed { index, level ->
val difference = (level.second - level.first).toFloat()
if (orderSign == 0.0f) orderSign = sign(difference)
if (sign(difference) != orderSign || abs(difference) !in 1.0..3.0) {
// With problem dampener: Drop either element in the pair or the first element from the original list and check if the result is now safe.
return if (withProblemDampener) {
Report(levels.drop(1)).isSafe(false) || Report(levels.withoutElementAt(index)).isSafe(false) || Report(levels.withoutElementAt(index + 1)).isSafe(false)
} else false
}
}
return true
}
}
fun main() {
fun part1(input: List<String>): Int = input.map { Report(it.split(" ").map { it.toInt() }).isSafe(false) }.count { it }
fun part2(input: List<String>): Int = input.map { Report(it.split(" ").map { it.toInt() }).isSafe(true) }.count { it }
// Or read a large test input from the `src/Day01_test.txt` file:
val testInput = readInput("Day02_test")
check(part1(testInput) == 2)
check(part2(testInput) == 4)
// Read the input from the `src/Day01.txt` file.
val input = readInput("Day02")
part1(input).println()
part2(input).println()
}
The Report#isSafe method essentially solves both parts.
I've had a bit of a trip up in part 2:
I initially only checked, if the report was safe, if either elements in the pair were to be removed. But in the edge case, that the first pair has different monotonic behaviour than the rest, the issue would only be detected by the second pair with indices (2, 3), whilst removing the first element in the list would yield a safe report.
An unofficial home for the advent of code community on programming.dev!
Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.
Solution Threads
M | T | W | T | F | S | S |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 |
Icon base by Lorc under CC BY 3.0 with modifications to add a gradient
console.log('Hello World')