#advent of code 2025
1 messages ยท Page 7 of 1
u got this
yeah i know
it's just classic exploration
and we can do breadth first or depth first, doesn't even matter
annoying algo to write tho
oh wait @lusty atlas i got an IDEA
||as soon as i reach the final splitter i blacklist its left side and when i reiterate it itโs forced to use the right side and then blacklist the left side of the parent splitter and all||
overcomplicating
Breadth-first search (BFS) is an algorithm for searching a tree data structure for a node that satisfies a given property. It starts at the tree root and explores all nodes at the present depth prior to moving on to the nodes at the next depth level. Extra memory, usually a queue, is needed to keep track of the child nodes that were encountered ...
new output
actually if i do DFS and don't want time to explode i have to like memoize and shit
and do recursive stuff
and i hate that
so time for dynamic BFS programming
@robust yacht you love
yop
you also love my shell prompt
maybe
looks worse there bc no ide has a good looking terminal
vibecoded
alr the BFS wasn't as bad as i tought
did someone do DFS with the whole recursive and memoization stuff ?
aoc/solver/src/commonMain/kotlin/solver/solutions/Day07.kt: Lines 16-28
||```kt
part2(expected = 40941112789504) {
val manifold = Grid.charGrid(input)
val cache = mutableMapOf<Point, Long>()
fun search(point: Point): Long = cache.getOrPut(point) {
when(manifold.getOrNull(point.down)) {
'^' -> search(point.left) + search(point.right)
'.' -> search(point.down)
else -> 1
}
}
search(manifold.pointOfFirst { it == 'S' })
}
i'm pretty sure that BFS is faster than DFS cause BFS is O(row*col) and DFS is O(solution) (at max but can go lower thanks to memoization)
that's BFS
isn't it ?
yeah it is
idk maybe
i mean no actually
i didn't map out how it searched
you're doing DFS
recursion makes me always confused
iteration is a fancy form of recursion
might ask ai for d7p2
don't
don't give up
jkjk i dont use AI you know you know
you have 2 both valid choices
look at our solutions before if you're really that stuck
i have a plan
BFS like me and dynamic programming
or DFS like wingd with recursion and memoization
both are actually fast if you aren't stupid
this is dfs
recursion is super clean here
i used DFS
with recursion too
that seems to just be the easier solution
yeah I've done meth
i mean my DFS is very clean imo https://github.com/Vendicated/AdventOfCode/blob/main/2025/day7/solution.cr
nope
i think iโve heard you praise it previously
yesss
the typing is very out of your way and mostly inferred, you hardly ever have to specify types
only when creating empty hash, array etc
def add(a, b)
a + b
end
add 1, 2 # => 3
add "foo", "bar" # => "foobar"
i liked this example
i canโt think of what itโd actually be used for though, other than stuff like print
alr done both BFS and DFS now
note don't try to use a tuple as a key for a map in javascript
biggest dsa nerd
it doesn't go well
yeah lmao
just stringify it or smth xD
x_y
hmm crystals pattern matching looks lackluster
yeah so there's kinda no contest here
i didn't forget to do warmup iterations btw
yeah i did, x,y
is it better in ruby?
i donโt know ruby
but i doubt it matches rust or ocaml, of which i really enjoy using
make ur own pattern matching macro
ok so actually my BFS was only slower cause of my key being a string, but they are actually the same
also actually i didn't read that, but thanks
proud to be
oops forgor spoiler
what does dp stand for
die wing die
DISTANCE
i already hate this
ok i literally do not undersatnd this what the fuck
Dynamic programming
@native maple n part 1 what happens if i get boxes a and b where a is already present in one circuit and b is present in another?
do i merge the circuits?
oh ur asleep
i can successfully get the distance between any two coordinates (||using euclidean||) just don't know how to sort them
do i need to get every possible pair?
||i dont think sort is necessary. i think you have to find the closest junctions on each iteration||
||so just iterate through the list and find the closest to each item?||
||thats what im trying||
im able to get the first closest pair
wait
im close
nvm
Display port
@pale stirrup have you figured ito ut
i feel like im close
io cant figure out the condition i need to skip
has nun of u done it yet is it that hard
i havenโt rly read the problem i just read โx, y, zโ and closed the tab
@pale stirrup idk what to do help
are u supposed to like find the shortest pair of boxes every iteration?
how do u do it efficently 
ok apparently there's a data structure that works for this: ||disjoint set union||
@native maple
stupid Day
like
the problem isnt described in the puzzle description
@native maple and whoever else didnt do it yet, im not spoilering it because its not described in the puzzle description but an integral part of what youre supposed to do
see c and d, connect them
see a and c, add to [c, d]
see b and d, add to [c, d, a]
see a and b, do nothing, still increment the counter
see a and b, do nothing, dont increment the counter
@pale stirrup hi
im very confused
guh i dont know how to apply ||DSU|| to this
i hate mathematical problems
wtf some of hte solutions are so much simpler
my solution so far generated circuits with 3 items
are you still doing it
me too
@terse edge can you send me all the circuits for the example input so that i can debug my solution
16.902: [162, 817, 812] - [425, 690, 689]
321.560: [162, 817, 812] - [431, 825, 988]
322.369: [906, 360, 560] - [805, 96, 715]
328.119: [431, 825, 988] - [425, 690, 689]
333.656: [862, 61, 35] - [984, 92, 344]
338.339: [52, 470, 668] - [117, 168, 530]
344.389: [819, 987, 18] - [941, 993, 340]
347.599: [906, 360, 560] - [739, 650, 466]
350.786: [346, 949, 466] - [425, 690, 689]
352.936: [906, 360, 560] - [984, 92, 344]
Guh how bad is d8
this is all the connections you have to make
note how 431 y z and 425 y z appear twice each
ye
@native maple hii
i spent 2h ours and havent made any progress
roie will solve in < 10 minutes
is this the prophesized ramp up in difficulty
rosie
the description is retarded
its not that hard
its just hard to understand
if you guess right at the start yuo win
i have this so im definitely doing something wrong
we had ppl do it in 3 mins and i have this
interesting
@native maple
@pale stirrup
@robust yacht
@terse edge
@robust yacht @pale stirrup @native maple doing nothing counts as connecting two cables if you havent seen that exact pair of cables before (even if theyve appeared before and you added them to circuits)
i do that separately in a second step
make it so it prints that
then compare
what would I even store my connections as
why do you have more than 10 connections
irrelevant
my second step generates a list of circuits
i store a MutableList<HashSet<Point3D>>
I'm stuck with knowing what points to skip
yeah im gonna pause for now
i haven't read the problem yet so atm you just sound schizo
hold on lol
don't wake up until after 12
in exampe youre supposed to make 8 or 9 connections
not 10
even tho it says 10
oh
ur supposed to count doing nothing as making connections
nothing happens BESIDES your counter getting incremented
I make connections then calculate seperate
this is what I'm stuck on
how do you determine when to skip
if both a and b are already in any other circuits, i skip?
if I do skip when ciruits.any { a in it || b in it} I get stuck in loop
it keeps finding the same closest points
eagely teach me your wisdom
you merge the circuits
if a and b are in different circuits, they become the same circuit
because yuo connected a and b
that's what I'm missing yea
I was getting like 20 circuits
with the example
you cant use hashset<circuit>, if you remove circuit to merge it hashset wont remove it sometimes idk why
use mutablelist<circuit>
i wasted an hour on that
print the circuits at the end
i do
are you running 11 times maybe
im not running a fixed amount of times
(40, [862-61-35, 739-650-466, 984-92-344, 805-96-715, 906-360-560]
[346-949-466, 431-825-988, 425-690-689, 162-817-812]
[117-168-530, 52-470-668]
[941-993-340, 819-987-18]
[57-618-57]
[592-479-940]
[352-342-300]
[466-668-158]
[542-29-236]
[216-146-977]
[970-615-88])
huh
yuore supposed to run 10 times
mine just has a queue and finds the next closest circuit on each iteration
where does it say that
@native maple @pale stirrup @robust yacht https://codeberg.org/eagely/adventofcode-kotlin/src/branch/main/src/main/kotlin/solutions/y2025/Day8.kt
u can just ||make list of 1000 sets of size 1 each with a point, iterate over lines sorted by distances take first 1000 and merge||
NOT A BUG
I'll try later
gn
did u account for doing nothing still counting immediately
@native maple i prefer 6am over 10am
2nd day in a row that someone wanted to do smth at 10am
yday my aunt came over while i was doing aoc
today i was gonna go to the barber at 10 if it wasnt for aoc
@frigid socket
@native maple i found issue with my 7p2
no AI needed to fix
That's the right answer! You are one gold star closer to decorating the North Pole.
You have completed Day 7! You can [Share] this victory or [Return to Your Advent Calendar].
@pale stirrup is my only way out of d8 to bruteforce
might be tbh
idk i haven't solved yet
i would do typescript (not types the language) but i have a no JS/TS rule
why does go not have tuples
array
@lusty atlas is there good crystal lsp
ig ill have to do without lsp
who thought it was a good idea to make slice.append(el) a global function append(slice, el)
me
thats why rust is better ๐
might ban @verbal parrot soon ykyk
at least you have a lsp @verbal parrot
and i do not
it kinda works
faint@faints-MacBook-Pro 08 % go run 08.go
[{{162 817 812} {425 690 689}} {{162 817 812} {431 825 988}}
i got the first shortest paths correctly
if only i didnt start solving it six hours after it started
no lsp is fine
i didnt have one when i was doing it in elixir
cuz the lsp expected me to have an elixir project and i was just doing it single file 
do d8
ykyk just fmt.Println(slice) ykyk
@terse edge what is the example supposed to output?
this so dumb like why do they only show output for first 10 shortest ones
if the example is fucking 20 boxes
holy fuck my shit so fast
Benchmark 1: go run 08.go
Time (mean ยฑ ฯ): 15.441 s ยฑ 7.807 s [User: 15.152 s, System: 0.168 s]
Range (min โฆ max): 0.294 s โฆ 19.522 s 10 runs```
@frigid socket holy sh*t man it works with the example
40```
but it doesnt with the actual input ๐ญ
guh idek what cud be wrong
๐๐๐๐๐๐๐๐๐๐
oh wait im dumb it says i need to combine 1000 pairs
pairs
@terse edge how long does yours take
and what does that mean
i have 1000 boxes
1000 boxes โ 1000 pairs
explain
you cannot make 1000 pairs from 1000 boxes
yes you can?
vai Equipped with a new understanding of teleporter maintenance, you confidently step onto the repaired teleporter pad.
You rematerialize on an unfamiliar teleporter pad and find yourself in a vast underground space which contains a giant playground!
Across the playground, a group of Elves are working on setting up an ambitious Christmas decoration project. Through careful rigging, they have suspended a large number of small electrical junction boxes.
Their plan is to connect the junction boxes with long strings of lights. Most of the junction boxes don't provide electricity; however, when two junction boxes are connected by a string of lights, electricity can pass between those two junction boxes.
The Elves are trying to figure out which junction boxes to connect so that electricity can reach every junction box. They even have a list of all of the junction boxes' positions in 3D space (your puzzle input).
For example:
162,817,812
57,618,57
906,360,560
592,479,940
352,342,300
466,668,158
542,29,236
431,825,988
739,650,466
52,470,668
216,146,977
819,987,18
117,168,530
805,96,715
346,949,466
970,615,88
941,993,340
862,61,35
984,92,344
425,690,689
This list describes the position of 20 junction boxes, one per line. Each position is given as X,Y,Z coordinates. So, the first junction box in the list is at X=162, Y=817, Z=812.
To save on string lights, the Elves would like to focus on connecting pairs of junction boxes that are as close together as possible according to straight-line distance. In this example, the two junction boxes which are closest together are 162,817,812 and 425,690,689.
By connecting these two junction boxes together, because electricity can flow between them, they become part of the same circuit. After connecting them, there is a single circuit which contains two junction boxes, and the remaining 18 junction boxes remain in their own individual circuits.
Now, the two junction boxes which are closest together but aren't already directly connected are 162,817,812 and 431,825,988. After connecting them, since 162,817,812 is already connected to another junction box, there is now a single circuit which contains three junction boxes and an additional 17 circuits which contain one junction box each.
The next two junction boxes to connect are 906,360,560 and 805,96,715. After connecting them, there is a circuit containing 3 junction boxes, a circuit containing 2 junction boxes, and 15 circuits which contain one junction box each.
The next two junction boxes are 431,825,988 and 425,690,689. Because these two junction boxes were already in the same circuit, nothing happens!
This process continues for a while, and the Elves are concerned that they don't have enough extension cables for all these circuits. They would like to know how big the circuits will be.
After making the ten shortest connections, there are 11 circuits: one circuit which contains 5 junction boxes, one circuit which contains 4 junction boxes, two circuits which contain 2 junction boxes each, and seven circuits which each contain a single junction box. Multiplying together the sizes of the three largest circuits (5, 4, and one of the circuits of size 2) produces 40.
Your list contains many junction boxes; connect together the 1000 pairs of junction boxes which are closest together. Afterward, what do you get if you multiply together the sizes of the three largest circuits?
explain shortly cant bother to read
v- no ai
delete
The problem describes connecting junction boxes in 3D space to form electrical circuits.
Here's the gist:
- You're given 3D coordinates for many junction boxes.
- Calculate the straight-line distance between every possible pair of junction boxes.
- Connect the 1000 pairs that are closest together. When two boxes are connected, they become part of the same circuit. If boxes already in the same circuit are connected, it doesn't change anything.
- After making these 1000 connections, identify all the distinct circuits that have formed.
- Find the sizes of the three largest circuits and multiply those three sizes together.
-# Response generated by gemini-2.5-flash. AI may be incorrect or misleading.
THIS IS NOT SPOILER
oh
Okay I managed to get this down to 348 bytes (with a big ugly blob of extra garbage output): ||```py
S=[]
Z=sorted
for L in open(n:=0):S+=[map(int,L.split(',')),len(S)],
T=1000
D,=V=[-1]T
R=lambda v:R(V[v])if-1<V[v]else v
for _,i,j in Z((sum((a-b)**2 for a,b in zip(I,J)),i,j)forI,i in S forJ,j in S[:i]):
if n==T:_,p,q,r=Z(dv for d,v in zip(D,V));k=pq*r
A,B=R(i),R(j);n+=1
if A!=B:V[A]=B;D[B]+=D[A]
if-T==D[B]:-print(k,S[i][0]*S[j][0])
you have lost it
@frigid socket idk if u were being serious about "u cant make 1000 pairs from 1000 boxes" but imagine u have 4 boxes [a,b,c,d]. these are the pairs u can make with them: [(a,b), (a,c), (a,d), (b,c), (c,d)]
for puzzle input yes
WHY ASK THAT
The next two junction boxes are 431,825,988 and 425,690,689. Because these two junction boxes were already in the same circuit, nothing happens!
somehow without this condition my example output is correct but without it it's incorrect
if youโre gay it gives you gay
@hoary mirage furrykafasi
die
how fast
I think one of those withouts isn't supposed to be a without
About 2s
oh true lol
somehow without this condition my example output is correct but with it it's incorrect
The top rankers were at 660us/330us last I checked
how do u check if there's no public leaderboard anymore 
probably top rankers for solution speed not solve speed
yeah but still how do u see this without global leaderboard
im assuming that solution uses a disjoint set or union or whatever
Many discords have their own leaderboards
oh thought so
So there's no way to know the actual global fastest
@verbal parrot so
||
- find the closest ranking boxes
- put them in the same circuit
- find the closest ranking boxes that aren't in an identical circuit
- do that 1000 times
||
is this sane
i would use a disjoint set union whatever but that doesnt exist in elle
rosieeeeee
i dont have scipy or nx or whatever
faint ghosting me
wait
would it be faster to use a min heap than to sort by distance
@quartz aurora do you see any way to optimize
try following this i guess #1444763777437536368 message
?remind 5pm
Alright @frigid socket, in 9 hours, 30 minutes and 30 seconds: โฆ
i guess "counter" is supposed to be for p2 though
The HashSet::from(circuits).size() part looks pretty slow
also looking at eagely's delta time i assume p2 is like really easy? can someone confirm
Some people also ||spatially partition the inputs so they don't need to generate all the pairs||
that part is actually not very slow
the slowest part is the computation of the dists array
Yeah
how do you see delta time @verbal parrot
its an extension
actually
i think i know how to make this faster
i did this in a very fucked up way
position_with is O(n)
i can just do a double for loop with .enumerate instead of using T[].combinations
and use the indexes from there directly isntead of computing them every time
if index1 != -1 && index2 != -1 {
fmt.Println(pair)
continue
}
faint@faints-MacBook-Pro 08 % go run 08.go
{{431 825 988} {425 690 689}}
{{906 360 560} {984 92 344}}
24
if index1 != -1 && index2 != -1 {
// continue
}```
faint@faints-MacBook-Pro 08 % go run 08.go
30
whyyy ๐ญ
OH WAIT
it says "in the same circuit"
omfg
ok thats better
what does this mean
||Divide input into for example 25x25x25 chunks and only generate pairs within neighboring chunks||
||And assume that there's enough points in those to fulfill both tasks' conditions, so that the missing pairs don't matter||
how is there single circuits if all of them connect to shortest one to them
because you dont need to go thru each pair. it says to only go thru first 10/1000 pairs which means there will be untouched pairs thus not added to circuits and by default they are in a circuit which len is 1
so slow
@native maple according to my calculations my solution will take 1 hour 33 minutes
ig I can sort
sorting is always good option
mantikafasi mental illness
A friend advised me that map(int,L.split(',')) can be more succinctly written as ||eval(L)||, which is extremely based
few ms i think
i posted it somewhere above
also make sure ur handling the case where both cables exist in the same box
u should count the first time u see them but not the second time
the first time you see that exact pair counts
if a cable has appeared before but in a different pair it doesnt count
THAT IS AWFUL
test perf because you don't do anything special to optimize and mine is 480ms with a similar solution
i love a well formatted and documented function
/**
* Calculates the straight-line distance between this and another [point]
* in 3-dimensional space, see [euclideanDistance] for 2D points
*
* https://en.wikipedia.org/wiki/Euclidean_distance
*/
fun Point3D.distanceTo(point: Point3D): Double {
return sqrt(
/* x */ (point.x.toDouble() - x.toDouble()).pow(2) +
/* y */ (point.y.toDouble() - y.toDouble()).pow(2) +
/* z */ (point.z.toDouble() - z.toDouble()).pow(2)
)
}
why do you need all of that for a euclidean distance ๐ญ
?
nin0 is caveman
vlang is high level yk
solution.le: Lines 19-22
for i, box1 in boxes.iter().enumerate() {
for j, box2 in boxes.iter().enumerate() {
if i >= j { continue; }
dist := box1.to_vec3().sub(box2.to_vec3()).length_sq();
rate
you don't even need the whole distance it's enough to use the distance squared
i have it extracted to a util so it needs to work for more than just this one puzzle
maze tomorrow ๐ค
these are all the cases im handling isnt it enough
||```go
if len(circuits) == 0 {
circuits = append(circuits, make([]Vec3, 2))
circuits[0][0] = pair.a
circuits[0][1] = pair.b
continue
}
index1 := find(&circuits, pair.a)
index2 := find(&circuits, pair.b)
if index1 == -1 && index2 == -1 {
circuits = append(circuits, make([]Vec3, 2))
circuits[len(circuits)-1][0] = pair.a
circuits[len(circuits)-1][1] = pair.b
continue
}
if index1 == index2 {
continue
}
if index1 != -1 {
circuits[index1] = append(circuits[index1], pair.b)
} else if index2 != -1 {
circuits[index2] = append(circuits[index2], pair.a)
}
smart peopll #HELP
asking the wrong server ykyk
erm
see a and b, do nothing, still increment the counter
see a and b, do nothing, dont increment the counter
wait im kinda confused how can u encounter the same pair twice?
a, b and b, a
dont increment the counter = dont count the current pair to these 10 pairs?
or well 1000 for the real input
honestly idk what counter eagely was talking about
why does it not work ๐ญ
||```go
type Vec3 struct {
x, y, z int
}
type Pair struct {
a, b Vec3
}
func (v1 Vec3) distance(v2 Vec3) int {
sum := (v1.x-v2.x)(v1.x-v2.x) + (v1.y-v2.y)(v1.y-v2.y) + (v1.z-v2.z)*(v1.z-v2.z)
return int(math.Abs(math.Sqrt(float64(sum))))
}
func pairs(fileName string) []Pair {
var vecs []Vec3
var pairs []Pair
file, _ := os.Open(fileName)
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
xyz := strings.Split(scanner.Text(), ",")
x, _ := strconv.Atoi(xyz[0])
y, _ := strconv.Atoi(xyz[1])
z, _ := strconv.Atoi(xyz[2])
vecs = append(vecs, Vec3{x, y, z})
}
for index, vec := range vecs {
for j := index + 1; j < len(vecs); j++ {
pairs = append(pairs, Pair{vec, vecs[j]})
}
}
return pairs
}
func sort_pairs(pairs []Pair) {
sort.Slice(pairs, func(i, j int) bool {
return pairs[i].a.distance(pairs[i].b) < pairs[j].a.distance(pairs[j].b)
})
}
type Circuits struct {
dict map[int]int
}
func find(circuits *[][]Vec3, vec Vec3) int {
for i, circuit := range *circuits {
if slices.Contains(circuit, vec) {
return i
}
}
return -1
}
func puzzle(pairs *[]Pair) int {
var circuits [][]Vec3
for i, pair := range *pairs {
if i > 9 {
break
}
if len(circuits) == 0 {
circuits = append(circuits, make([]Vec3, 2))
circuits[0][0] = pair.a
circuits[0][1] = pair.b
continue
}
index1 := find(&circuits, pair.a)
index2 := find(&circuits, pair.b)
if index1 == -1 && index2 == -1 {
circuits = append(circuits, make([]Vec3, 2))
circuits[len(circuits)-1][0] = pair.a
circuits[len(circuits)-1][1] = pair.b
continue
}
if index1 == index2 {
continue
}
if index1 != -1 {
circuits[index1] = append(circuits[index1], pair.b)
} else if index2 != -1 {
circuits[index2] = append(circuits[index2], pair.a)
}
}
sort.Slice(circuits, func(i, j int) bool {
return len(circuits[i]) > len(circuits[j])
})
return len(circuits[0]) * len(circuits[1]) * len(circuits[2])
}
func main() {
pairs := pairs("input")
sort_pairs(pairs)
fmt.Println(puzzle(&pairs))
}
i don't have a counter
this is what it looks like for me for example input (first line is the current pair, next line is lengths of circuits X times)
{{162 817 812} {425 690 689}}
2
{{162 817 812} {431 825 988}}
3
{{906 360 560} {805 96 715}}
3 2
{{431 825 988} {425 690 689}}
3 2
{{862 61 35} {984 92 344}}
3 2 2
{{52 470 668} {117 168 530}}
3 2 2 2
{{819 987 18} {941 993 340}}
3 2 2 2 2
{{906 360 560} {739 650 466}}
3 3 2 2 2
{{346 949 466} {425 690 689}}
4 3 2 2 2
{{906 360 560} {984 92 344}}
4 4 2 2 2
{{592 479 940} {425 690 689}}
4 4 2 2 2```
which kinda... makes sense to me?
but it seems to be wrong
but if i remove the if index1 == index2 { continue } it works
fucking how
visited set to make sure u dont
or just take only the first thousand pairs and loop over them
Made fancy loading indicator
oh my fucking god finally
That's the right answer! You are one gold star closer to decorating the North Pole. [Continue to Part Two]
this was the case i didnt handle right (or didnt handle entirely):
||go if index1 != -1 && index2 != -1 { circuits[index1] = append(circuits[index1], circuits[index2]...) circuits[index2] = make([]Vec3, 0) continue }||
wing cheating
i did just copy one of eagely's utils actually (credited though)
guh
p2 done!!!
That's the right answer! You are one gold star closer to decorating the North Pole.
You have completed Day 8! You can [Share] this victory or [Return to Your Advent Calendar].
THATS MORE LIKE IT
also i now get what eagely meant by counter
i should look up how to do closest pair efficiently
too slow still
faint@faints-MacBook-Pro 08 % hyperfine -N 'go run 08.go'
Benchmark 1: go run 08.go
Time (mean ยฑ ฯ): 184.9 ms ยฑ 93.8 ms [User: 155.0 ms, System: 73.2 ms]
Range (min โฆ max): 153.2 ms โฆ 451.9 ms 10 runs
wait how did it get so fast my p1 only code was 15s 
my next lang is pascal 
I haven't finished
@native maple still hasnt calculated
waiting
it should finish soon
I could just make a array for smallest 1000 connections but too lazy
goddamit bubble sort
is that 350 seconds ๐ญ
yes
IS TODAY DIJKSTRA DAY
nah
not yet
never i hope
my algo is peak
HOW IS IT ALREADY FASTER THAN MINE
elle slow rosie
well i think its partly my stuff heap allocating
impossible
@lusty atlas how fast mine on your machine https://github.com/acquitelol/aoc2025/blob/mistress/solutions/08/solution.le
My Advent of Code 2025 solutions in Elle. Contribute to acquitelol/aoc2025 development by creating an account on GitHub.
wtf
?????? its ssa what do you expect
?
idk what ssa is
single static assignment
idk what that is
compiler optimization
basically it keeps every mutation in a new variable (not quite but that's the basic idea)
anyways i should use stdlib's qsort more often
it's way too helpful
and takes a comparison function too
and __compar_fn_t takes in 2 void* params and outputs -1, 0 or +1
incredible
go to your qbe clone, go to all.h, make NString bigger, make again and replace ur qbe
anyways -Ofast helps a bit too
i thought you meant each part takes this long
yes my lord
i could have worded that better
i dont like installing system packages like this
honestly even though my solution is slower by 20ms i think i prefer the elegance of being able to do this ||https://github.com/acquitelol/aoc2025/blob/mistress/solutions/08/solution.le#L40-L49||
solution.le: Lines 40-49
if step == 999 {
counts := HashMap::new<i64, i64>();
for c in 0..boxes.len() {
root := find(circuits, c);
counts[root] = counts.get(root).unwrap_or(0) + 1;
}
largest := counts.iter().collect().sort_with(fn(a, b) b.y - a.y).slice(0, 3);
total[0] = largest.iter().map(fn(c) c.y).product();
}
oh you didn't already do that?
i forget some people just install qbe blindly
i basically did that but more verbose
it's fine building it yourself is like dead easy if ur on linux
elle should maybe submodule qbe if qbe is gonna be broken like that
i need to do that yes
i will
qbe in elle when
because that way i can also add inline asm
i don't think i've ever used the qsort function until now
yeah i think i'll take the 20ms hit for the simplicity tbh
worth tbh
also can you try to run it on your computer too
with -Ofast -lm
sure hold on
pass a file
give your input i dont have mine solved yet
it takes the file from args[1] i didn't bother to add help message
@native maple@native maple make a aoc solution wrapper thing
mine are all contained as one program
inputs are stored in the resources
inputt @native maple give
i dont commit the input
SLOW
ill try your solution when i get in the car hold on
do you have updated elle
dont drive and code
yes
guh
yes
can you send bt
you just need to gdb ./solution then r input.txt then when it crashes bt and send
uhhhh you don't
oh okay
good luck interpreting this
#0 0x00007ffff7da82e4 in ?? () from /usr/lib/libc.so.6
#1 0x000055555555f945 in ArenaAllocator.realloc ()
#2 0x0000555555564b3a in ArbitraryAllocator.realloc ()
#3 0x000055555555977b in Array.resize.0.Triple.0.13.7.7.1.1 ()
#4 0x000055555555c607 in Array.push.0.Triple.0.13.7.7.1.1 ()
#5 0x00005555555560c0 in MinHeap.push.0.Triple.0.13.7.7.1.1 ()
#6 0x000055555555582f in solve ()
#7 0x000055555555b388 in __internal.elle.__main__ ()
#8 0x000055555555741c in main ()
because that means it's fucking up when reallocating an arena region to be bigger, maybe you OOM
try add use std/heap_allocator; at the top and then #set_allocator(HeapAllocator::new()); at the start of main() and see if it works
i can probably reproduce on my machine hold on
use std/heap_allocator;
zt doesn't realise he got scammed and his ram is really only 8gb but manipulated to report itself as 64gb
oh
he is 8000$ in loss
rosie doesn't know her own language
roie fail
oh im restarted
use std/allocators/heap;
in my defense i never use this allocator
and im on mobile
rosie is asking ai how to fix this error @robust yacht
vai how to fix this error please?
@native maple
The error you're encountering has two main parts:
-
"Could not load module
std/allocators/heap_allocator: No such file or directory (os error 2)"
This indicates that the compiler or runtime cannot find theheap_allocatormodule, likely because it's missing, misplaced, or the path to it is incorrect. This is similar to a "ModuleNotFoundError" in other languages. -
"Identifier 'HeapAllocator' isn't a struct or primitive type."
This means theHeapAllocatortype is not recognized in the scope where it's being used. This could be due to:- Incorrect spelling (though the error asks if you spelled it correctly, it's worth double-checking).
- The module containing
HeapAllocatornot being properly imported or linked. HeapAllocatornot being a public or exported type from its module.- Version compatibility issues if using external libraries.
To fix this, consider the following:
- Check Module Availability and Path: Ensure that the
std/allocators/heap_allocatormodule actually exists at the expected location. If it's part of a library, confirm the library is correctly installed and accessible by your build system. - Correct Imports/Includes: Verify that you have the necessary
importstatements orincludedirectives for theHeapAllocatortype and its module in yoursolution.lefile. - Build System Configuration: If you are using a build system (like Cargo for Rust, which sometimes uses "alloc" or "heap" crates), ensure it's configured to include and link against the
std/allocatorsmodule or the specificHeapAllocatortype. - Spelling and Casing: Double-check that
HeapAllocatoris spelled and cased exactly as defined in its source. - Compatibility: If
HeapAllocatoris from an external source, ensure its version is compatible with your project's other dependencies and compiโฆ
-# Response generated by gemini-2.5-flash. AI may be incorrect or misleading.
vai help me
Hello! How can I help you? I'm here to assist with Vencord-related questions, or anything else you might need. Please tell me what you're looking for!
-# Response generated by gemini-2.5-flash. AI may be incorrect or misleading.
how compile with max optimization
my code works on example
SLOW
HOWEVER ON REAL INPUT IT ALL BECOMES ONE GIANT CIRCUT AT LIKE INDX 993
ok faster now
@native maple help
i just switched to performance plan
did you forget to initialise array again
USING PYTHON
good
nop
wait try run it with arena allocator again
maybe it was just a fluke
just get rid of the heap allocator stuff run with --nogc tho
@hoary mirage
๐ error
@native maple can I not merge circuits
you can
THEN WHY DOES IT ALL BECOME ONE HUGE CIRCIUT
solution.le: Lines 3-9
||```le
fn merge(i64[] circuits, i64 d1, i64 d2) {
c1, c2 := $(circuits[d1], circuits[d2]);
if c1 == c2 { return; }
for i, c in circuits.iter().enumerate() {
if c == c2 { circuits[i] = c1; }
}
}
nop
i did that originally
same thing
UNREADABLE
rosie is allergic to readable variable names
no its pretty readable..
what is the d in d1
wow
well it doesnt work
congrats
rosie fix
arena.le: Lines 69-84
fn ArenaAllocator::realloc(ArenaAllocator *self, void *ptr, i32 _new_size) {
// if nil is passed assume its an allocation instead of reallocation
if !ptr {
return self.alloc(_new_size);
}
// else alloc and copy old data
let new_size = __internal_alloc_align8(_new_size);
let new_ptr = self.alloc(new_size);
// copy memory from old buffer to new buffer
mem::memcpy(new_ptr, ptr, _new_size);
// do NOT free, managed by arena allocator
return new_ptr;
}
okay
thanks
i have a feeling memcpy is somehow causing the crash
since it fails in ?? in libc going straight from ArenaAllocator::realloc
maybe bounds check wrong
i see the issue
memcpy is copying from the old ptr more memory than was allocated
mem::memcpy(new_ptr, ptr, new_size);
FIX
its copying new_size bytes but ptr is smaller than that
idk how to keep track of that
no
is your memcpy(src, dst, size) or dst src size
its dst src size
but ptr is the old buffer
which is smaller than new_ptr
but its copying new_size
so its copying memory out of bounds from ptr
new_size is how many bytes to copy
i know how to fix
yes
but thats new_ptr's size
ptr is smaller which is the src
so its copying extra bytes
thats the callers fault then
no lol because you would call realloc with a bigger size than the old buffer
thats how any dynamic data structure is implemented
idk it seems wrong to me
i just need to copy the size of the old ptr instead and leave the extra space uninitialized
lmao
good results
success
ok @robust yacht pull from elle and rebuild and then try now
cool
i just allocate an extra i64 to store the size of the allocation and then do pointer arithmetic to go back and get that size when you realloc lol
roingaaa ๐ญ
fym do not free ๐ญ
does it keep all allocations until the program exits
That's the right answer! You are one gold star closer to decorating the North Pole.
looove
insane
2.4 sec both parts
slow
ITS PYTHON WHAT DO I DO
idk
only insane if ur huge noob
eric so bad
The next two junction boxes are 431,825,988 and 425,690,689. Because these two junction boxes were already in the same circuit, nothing happens!
this line
worst
you still gotta count it
in doubt, use numpy
Nop
yes
All junction boxes are one circuit
because the program runtime is short
Until merged
the intended use of the arena allocator is to create multiple and free them individually
A connection can merge two existing groups that have no elements in common into one. For example:
- Set 1: {A, B, C}
- Set 2: {D, E, F}
- Instruction: connect C and D
- Result:
- New Set: {A, B, C, D, E, F}
I lost about 4 hours not realizing this. This โhiddenโ but logical rule is not explicitly mentioned anywher...
why even free then
exit without freeing anything
OS will handle ykyk
Elle memory leak
oh do i need to fill the circuits with each junction box initially on its own circuit then merge
IT'S ALREADY MEMORY LEAK BY DESIGN
if you know the DSA
and despite being a nerd, i didn't know today's
i mean i knew ||MST||, hard heard of it, but didn't knew ||DSU|| or ||Kruskal's algorithm||
so today is a wikipedia day for me
do circuits have to be one straight line or can they be funny shape
youre meant to use it like this
fn main() {
// the base arena exists by default
for i in 0..100 { // the iterator allocates
#set_allocator(arena := ArenaAllocator::new());
do_expensive_thing();
arena.free_self();
#reset_allocator();
}
}
``` it just so happens that i dont create any temporary arenas
funni shape
but the intended usecase of them is that
There is no funny shape
share
and if you dont use gc, there is just one big arena by default
there's even a nice visualization on reddit
so you can connect to circuits in the middle
yes
which one
how close
@lusty atlas solve already its been 3 yeras
@hoary mirage solve already its been 4 years
I SOLVED
both parts :)
how fast @hoary mirage
1.6 sec both
husk
hold on ill make a fast python solution quickly
@hoary mirage
rewrote my elle solution into python
this is so funny
if step == 999:
total[0] = math.prod(count for _, count in Counter(find(circuits, c) for c in range(len(circuits))).most_common(3))
guhhh i hate when i get wrong for input but not example
what edge cases does it have
checl this
nop did
https://youtu.be/u0mVnuUh46w @lusty atlas
โโ Awesome T-Shirts! Sponsors! Books! โโ
Episode details: https://github.com/lefticus/cpp_weekly/issues/505
T-SHIRTS AVAILABLE!
โบ The best C++ T-Shirts anywhere! https://jason-turner-shop.fourthwall.com/
WANT MORE JASON?
โบ My Training Classes: http://emptycrate.com/training.html
โบ Follow me on twitter: https://twitter.com/lef...
my solution is correct i am just running into crystal weirdness
ohhhhhhhhh
god how did i not think of this
|| I was using a Map of points to circuit pointers. Then when two points are already different circuits, I just update one of the pointers to the other one's circuit. That worked but now the same circuit was made up of two pointers, so if that same circuit got changed again only some of the pointers got updated ||
@robust yacht you never sent how fast my elle solution is with fixed arena
Blaming the language instead of skills
I would like to tell all my connections I ate yogurt
i cleaned up my p1 and lol i only took 20 seconds to add p2
100ms
okay mine is not that bad
so far on track to get all solutions running in under 1s cumulatively
im at 300ms/1s
only 4 days left
i guess i can make mine faster by using bubble sort. or even better using that data structure queue set something something
whats ur solution in
go
min heap? priority queue?
import "sort"
uh lemme find
i use sort.Slice but im not sure if its bubble sort
there is no way it is bubble sort
there are just better sorts in general
it likely switches between insertion sort and quicksort depending on the size of the array
i hope tomorrow will be easier ๐
I initially had a smarter solution but i decided it's too complicated so I just switched to using one single 2d array and always finding index
yeah i saw
โโโโโโโโโโโโโโโโโโโโ[solution.le:23:14]โโโโโโโโโโโโโโโโโโโโ
Identifier 'MinHeap' isn't a struct or primitive type.
Are you sure you spelt 'MinHeap' correctly?
23 | dists := MinHeap::new<(f32, u64, u64)>(fn(a, b) #cast(i64, a.x - b.x));
^~~~~~~
guhhh do i have to upgrade elle again
yes
bloat
โฏ ellec solution.le --nogc
ERROR: qbe:./.build-solution/target.ssa:4878: identifier too long
Compilation of 'solution.le' finished with errors. (ใฃโโธโ c)
peak
you can just git pull && make install-std install-runtime to update the stdlib
yeah zoot had this I HATE QBE
add to HOMEBREW
elle to winget
vee if you have qbe cloned locally you can just like, double NString to 160 in all.h and rebuild
im gonna start shipping a qbe fork along with elle soon
that way i can build qbe side by side and install both at once
my initial solution was kind of overcomplicated so I remade it to be simpler
This seems way too easy
a functional programmer would spend 3 whole hours explaining this
ikr
almost
stop using clash royale language
crystal nesting so unreadable
on my machine
do you use a smarter method than this
i tried switching to set but same perf
yes
you can actually stop early when the distance gets far enough away from the best distance
wdym?
consider
i use length_sq so i have bdist * 400 but it would be bdist * 20 if you used just euclidean distance
no idea what u just said
i guess try implement this
if dist < bdist { bdist = dist; }
else if dist > bdist * 400 { continue; }
``` and see if its faster
i also use a min heap instead of a normal array with sort at the end, its like 12ms faster for me
wtf is bdist
its inf by default
uhh but change it to bdist * 20 since youre calculating the distance not distance squared
wtf is bdist ๐ญ
best distance holds the smallest square distance between 2 boxes
so if you calculate the distance between the boxes and theyre really far away (relative to the best distance) you can discard that pair early
@native maple hii
the far away ones shouldn't matter because I break before they get checked
they do for the sorting tho
does pruning it really make it that much faster
yes
lmao
why is the sort so slow wtf
oh because it has 499 500 elements LOL
with pruning it has 30293
did u pick this number by random or is there some logic behind it
went up until my solution was still correct
isnt it great
no
oh i got sub 100ms without pruning
turns out sort_by is the same as .map().sort()
sleepy veepy
so dumb
hmm ig there isn't a better way because you need to call the block multiple times otherwise
@robust yacht
d8p1 looking so difficult
vai if 1000 points and I need to calculate the distance between every possible combination how many combinations
1000*1000
To calculate the distance between every possible combination of 1000 points, you would have 499,500 combinations. This is calculated using the formula for combinations "n choose k", which in this case is 1000 choose 2 (1000 * 999 / 2).
-# Response generated by gemini-2.5-flash. AI may be incorrect or misleading.
the answer is 500k combinations

so such a solution will inevitably take ages to resolve
and i canโt use typescript
@frigid socket explain d8 to me
BRO WAS SKIPPING MATH CLASSES ๐๐๐๐
faint insane
@frigid socket, <t:1765196970:R>: โฆ
okay help me
if youโre so smart
faint btw
@verbal parrot ?
or @native maple
i have absolutely no idea on how to write a sane solution
guh i've got a bug i cant find
this is just like ugly, i dont enjoy writing code like this
where are you stuck
create an array containing all possible 500k pairs. sort them by their distance
then loop over it
remind me in an hour im Gaming
wdym
it's fine
you only have to check the first 10k pairs or so
the slowest part is sorting the 500k element array
crystal does it in 80ms
you can cheat by discarding any pairs whose distance is 20x bigger than the smallest distance
still correct solution
why not, it's clean
basically same i wrote
but mine is shorter
tf is Array.blit
lc.g crystal Array.blit
-# <:i:1263593669215256597> labsCore will be shutting down <t:1767265200:R> โข Learn more
is it a custom function or something
made a false assumption ig
ocaml

