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)
Advent Of Code
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.
AoC 2024
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 |
Rules/Guidelines
- Follow the programming.dev instance rules
- Keep all content related to advent of code in some way
- If what youre posting relates to a day, put in brackets the year and then day number in front of the post title (e.g. [2024 Day 10])
- When an event is running, keep solutions in the solution megathread to avoid the community getting spammed with posts
Relevant Communities
Relevant Links
Credits
Icon base by Lorc under CC BY 3.0 with modifications to add a gradient
console.log('Hello World')
this took me so fucking long and in the end i just went for brute force anyway. there are still remnants of some of previous, overly complicated, failed attempts, like the hideous global removed
. In the end, I realized I was fucking up by using remove() instead of pop(), it was causing cases with duplicates where the removal of one would yield a safe result to count as unsafe.
Elixir
defmodule Day02 do
defp part1(reports) do
reports
|> Enum.map(fn report ->
levels =
report
|> String.split()
|> Enum.map(&String.to_integer/1)
cond do
sequence_is_safe?(levels) ->
:safe
true ->
:unsafe
end
end)
|> Enum.count(fn x -> x == :safe end)
end
defp part2(reports) do
reports
|> Enum.map(fn report ->
levels =
report
|> String.split()
|> Enum.map(&String.to_integer/1)
sequences =
0..(length(levels) - 1)
|> Enum.map(fn i ->
List.delete_at(levels, i)
end)
cond do
sequence_is_safe?(levels) ->
:safe
Enum.any?(sequences, &sequence_is_safe?/1) ->
:safe
true ->
:unsafe
end
end)
|> Enum.count(fn x -> x == :safe end)
end
defp all_gaps_within_max_diff?(numbers) do
numbers
|> Enum.chunk_every(2, 1, :discard)
|> Enum.all?(fn [a, b] -> abs(b - a) <= 3 end)
end
defp is_strictly_increasing?(numbers) do
numbers
|> Enum.chunk_every(2, 1, :discard)
|> Enum.all?(fn [a, b] -> a < b end)
end
defp is_strictly_decreasing?(numbers) do
numbers
|> Enum.chunk_every(2, 1, :discard)
|> Enum.all?(fn [a, b] -> a > b end)
end
defp sequence_is_safe?(numbers) do
(is_strictly_increasing?(numbers) or
is_strictly_decreasing?(numbers)) and all_gaps_within_max_diff?(numbers)
end
def run(data) do
reports = data |> String.split("\n", trim: true)
p1 = part1(reports)
p2 = part2(reports)
IO.puts(p1)
IO.puts(p2)
end
end
data = File.read!("input.in")
Day02.run(data)
python
solution
import re
import aoc
def setup():
return (aoc.get_lines(2), 0)
def safe(data):
order = 0 if data[0] < data[1] else 1
for i in range(0, len(data) - 1):
h = data[i]
t = data[i + 1]
d = abs(h - t)
if d not in [1, 2, 3] or (order == 0 and h >= t) or (
order == 1 and h <= t):
return False
return True
def one():
lines, acc = setup()
for l in lines:
if safe([int(x) for x in re.findall(r'\d+', l)]):
acc += 1
print(acc)
def two():
lines, acc = setup()
for l in lines:
data = [int(x) for x in re.findall(r'\d+', l)]
for i in range(len(data)):
if safe(data[:i] + data[i + 1:]):
acc += 1
break
print(acc)
one()
two()
G'MIC solution
spoiler
it day2
crop. 0,0,0,{h#-1-2}
split. -,{_'\n'}
foreach { replace_str. " ",";" ({t}) rm.. }
safe_0,safe_1=0
foreach {
({h}) a[-2,-1] y
num_of_attempts:=da_size(#-1)+1
store temp
repeat $num_of_attempts {
$temp
if $> eval da_remove(#-1,$>-1) fi
eval "
safe=1;
i[#-1,1]>i[#-1,0]?(
for(p=1,p<da_size(#-1),++p,
if(!inrange(i[#-1,p]-i[#-1,p-1],1,3,1,1),safe=0;break(););
);
):(
for(p=1,p<da_size(#-1),++p,
if(!inrange(i[#-1,p-1]-i[#-1,p],1,3,1,1),safe=0;break(););
);
);
safe;"
rm
if $>
if ${} safe_1+=1 break fi
else
if ${} safe_0,safe_1+=1 break fi
fi
}
}
echo Day" "2:" "${safe_0}" :: "${safe_1}
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
Rust
Turned out alright, I am looking forward to seeing what 2d coordinate grid code I can cannibalize from last year's solutions ๐