#AoC 2024 | Day 6 | Solutions & Spoilers
1103 messages ยท Page 2 of 2 (latest)
i'm getting too high a count like this:
# part 1
count = 1
position = start
data[start[0]][start[1]] = "X"
step = ((-1, 0), (0, 1), (1, 0), (0, -1))
step = itertools.cycle(step)
update = next(step)
while True:
try:
next_pos = (position[0] + update[0], position[1] + update[1])
next_char = data[next_pos[0]][next_pos[1]]
#print(f"{next_char}")
if next_char == "#":
update = next(step)
else:
position = next_pos
if next_char != "X":
count += 1
#print(f"{count}")
data[position[0]][position[1]] = "X"
except IndexError:
break
print(count)
``` and i'm not sure i catch why
if you walk over the same tile again you shouldn't count it
actually nvm u account for that
right, that's what i think i'm doing with the if next_char != "X"
works on the test input too, but ofc that doesn't have any weird edge cases
negative indexes dont indexerror
so true
this is why i do dict[complex, bool] instead of arrays
so based
omg that was it, thanks for saving my soul
that's what i get for trying to be fancy
lol
solve part two on the complex plane
you know, my first thought was to rotate the whole grid
but i didn't let the intrusive thoughts win
numpy.rot90(m, k=1, axes=(0, 1))```
Rotate an array by 90 degrees in the plane specified by axes.
Rotation direction is from the first towards the second axis. This means for a 2D array with the default *k* and *axes*, the rotation will be counterclockwise.
I have 3 days worth of language roulette to do after dinner 
i also let 3 days pile up. work interfered with wasting my time
tho hopefully pascal and ada aren't too bad
zsh is pain tho
my solution's compactness depends on defaultdicts
and not yet sure how to do that in zsh
is zsh the one that has built in python
well yeah I could technically python main.py provided i fix imports
that seems like cheating tho
hmm part 2
there must be some alg to introduce cycles in a graph. gonna have to read
or maybe i just brute force it lmao
brute forcing is the easiest lol
Initially I did every empty point - then restricted to just the path points on part 1
it sounds like a good idea but i'll have to check out how you did it. sounds neat though
Hmm working on a solution and its getting the right answer for the test set but not the real data
Ahhh numpy arrays wrap around
https://gist.github.com/i-am-unknown-81514525/58de6a414b39f0c66e4b3d342fa5d098
csharp d6 solve each part in a single chain
you may be thinkign of xonsh
ah oops
@lapis kayak how did you do multiprocessing?
hackily
xargs -P
calling the same script with a special parameter with the position of the extra block, and in this case it runs basicalky the same logic but just prints if it detected there is a loop
day06/run.sh line 52
echo "${uniq_points[@]}" | xargs -P16 -n1 bash run.sh | wc -l```
the general problem would be something like "dynamic strongly connected components"
this might be a simpler case though, where we know we start with a DAG
let me guess, you counted the starting position?
nope
i counted the ending position

well i think at some point i was counting the starting position as well
maybe
idk anymore
oh i meant p1
now i've accidentally counted the starting position
๐
welp
it worked on the test input
time to let it run and see
this is going to take forever
ok rough estimates say that this will take 7 hours without multiprocessing
i'm running 10 cores so hopefully that means i'll get a result in the next hour
if this is wrong idc i'm not rerunning that
#!/bin/zsh
grid=()
x=0
for line in "${(f)"$(<input.txt)"}"; do
y=0
gridline=()
for v in "${(@s::)line}"; do
if [[ $v == "^" ]]; then
gx=$x
gy=$y
fi
if [[ $v == "#" ]]; then
grid+=(1)
else
grid+=(0)
fi
((y++))
done
((x++))
done
height=$x
width=$y
inbound() {
(( 0 <= $1 && $1 < height && 0 <= $2 && $2 < width))
}
get() {
echo ${grid[$((1 + $1 * height + $2))]}
}
typeset -A visited
px=$gx
py=$gy
dx=-1
dy=0
rotate() {
local ddx=$dy
local ddy=$((- dx))
dx=$ddx
dy=$ddy
}
while true; do
visited["${px},${py}"]=1
ppx=$((px + dx))
ppy=$((py + dy))
if ! inbound $ppx $ppy; then
break
elif [[ $(get $ppx $ppy) -eq 1 ]]; then
rotate
else
px=$ppx
py=$ppy
fi
done
echo ${#visited[@]}
isloop() {
IFS=',' read -r bx by <<< $1
bx=${bx#\"}
by=${by%\"}
typeset -A seen
local px=$gx
local py=$gy
local dx=-1
local dy=0
rotate() {
local ddx=$dy
local ddy=$((- dx))
dx=$ddx
dy=$ddy
}
while true; do
if [[ -n ${seen["${px},${py},${dx},${dy}"]} ]]; then
echo 1
return 1
fi
seen["${px},${py},${dx},${dy}"]=1
ppx=$((px + dx))
ppy=$((py + dy))
if ! inbound $ppx $ppy; then
echo 0
return 0
elif [[ $(get $ppx $ppy) -eq 1 || $ppx == $bx && $ppy == $by ]]; then
rotate
else
px=$ppx
py=$ppy
fi
done
}
unset ${visited["${gx},${gy}"]}
blocks=(${(k)visited})
p2=$(echo ${blocks[@]} | tr ' ' '\n' | env_parallel -j 10 isloop | grep -c '^1$')
echo $p2
thank the zsh gods
woot
congrats :DDDD
So this works on the example input but not on the real input and i can't figure out why
def parse() -> list[list[str]]:
with open("day6/input.txt") as file:
return [list(line) for line in file.read().splitlines()]
def walk_route(route: list[list[str]]) -> list[list[str]]:
DIRECTIONS = [
(-1, 0), # up
(0, 1), # right
(1, 0), # down
(0, -1), # left
]
route = [row.copy() for row in route]
visited: set[tuple[int, int, tuple[int, int]]] = set()
direction = (-1, 0) # start by going up
position = [0, 0]
# get the starting position
for x, row in enumerate(route):
if "^" in row:
position = [x, row.index("^")]
break
while True:
try:
# we're walking in circles
if (position[0], position[1], direction) in visited:
raise RecursionError
visited.add((position[0], position[1], direction))
route[position[0]][position[1]] = "X" # mark the map
# turn for obstacles
if route[position[0] + direction[0]][position[1] + direction[1]] == "#":
direction = DIRECTIONS[(DIRECTIONS.index(direction) + 1) % 4]
# walk forward
else:
position[0] = position[0] + direction[0]
position[1] = position[1] + direction[1]
except IndexError:
# walked off the map
break
return route
def part2() -> int:
route = parse()
marked_route = walk_route(route)
total = 0
for x in range(len(marked_route)):
for y in range(len(marked_route[0])):
if marked_route[x][y] == "X" and route[x][y] != "^":
sabotaged_route = [row.copy() for row in route]
sabotaged_route[x][y] = "#"
try:
walk_route(sabotaged_route)
except RecursionError:
total += 1
return total
which part doesn't work?
part2 has a result that's too high
When i try the example input it's correct
When it try the real input it doesnt' work
yeah i had some problems there too. my solution worked on my input but not on another input
The main oversight I can see is that you only turn once when you see an obstacle
Guys this is my code for Part 1
Can you suggest any improvements
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
Please if anyone can help ๐ซ
When it turns it skips the move part and goes to the next loop to turn again
right
aren't you marking even the initial start position with an X? so you're going to end up placing an obstacle there in p2
and route[x][y] != "^" should exclude that but i'll submit it with one lower to check
yeah one lower is stsill not righit
ah, sorry again
I'm just looking for anything clearly wrong
It's frustrating that it works on the example input ๐
Is brute force with some pruning the only optimized way here??
isn't there like a graphs approach for this
@grizzled trail I figured it out