Advent of Code solutions

im trolling or something, 2025 day 8

+77
+59
2025/8/p1.sql
··· 1 + DROP DATABASE IF EXISTS year_2025_day_8; 2 + CREATE DATABASE year_2025_day_8; 3 + \c year_2025_day_8 4 + CREATE EXTENSION hstore; 5 + 6 + CREATE TABLE points ( 7 + i bigint primary key generated always as identity, 8 + x double precision not null, 9 + y double precision not null, 10 + z double precision not null, 11 + unique (x, y, z) 12 + ); 13 + 14 + CREATE TABLE edges ( 15 + a bigint not null references points (i), 16 + b bigint not null references points (i), 17 + x1 double precision not null, y1 double precision not null, z1 double precision not null, 18 + x2 double precision not null, y2 double precision not null, z2 double precision not null, 19 + primary key (a, b), 20 + foreign key (x1, y1, z1) references points (x, y, z), 21 + foreign key (x2, y2, z2) references points (x, y, z) 22 + ); 23 + 24 + CREATE INDEX edge_dist ON edges (((x1 - x2) ^ 2 + (y1 - y2) ^ 2 + (z1 - z2) ^ 2)); 25 + 26 + \COPY points (x, y, z) FROM 'sample' WITH (FORMAT csv, HEADER false); 27 + 28 + INSERT INTO edges (a, b, x1, y1, z1, x2, y2, z2) 29 + SELECT a.i, b.i, a.x, a.y, a.z, b.x, b.y, b.z 30 + FROM points a, points b 31 + WHERE a.i < b.i; 32 + 33 + CREATE FUNCTION mul (integer, integer) returns integer AS $$ 34 + SELECT $1 * $2 35 + $$ language sql; 36 + 37 + CREATE AGGREGATE product (integer) ( 38 + sfunc = mul, 39 + stype = integer, 40 + initcond = 1 41 + ); 42 + 43 + WITH RECURSIVE 44 + closest as ( 45 + SELECT hstore(a::text, '1'::text) || hstore(b::text, '1'::text) as s 46 + FROM edges 47 + ORDER BY ((x1 - x2) ^ 2 + (y1 - y2) ^ 2 + (z1 - z2) ^ 2) ASC 48 + LIMIT 10 49 + ), 50 + spans (s, g) as ( 51 + SELECT s, 1 FROM closest 52 + UNION 53 + SELECT a.s || coalesce(b.s, ''), g + 1 54 + FROM spans a, closest b 55 + WHERE a.s ?| akeys(b.s) AND NOT a.s ?& akeys(b.s) 56 + and g < 10 57 + ), 58 + groups as (SELECT array_length(akeys(s), 1) l, s, g FROM spans ORDER BY g desc, array_length(akeys(s), 1) desc limit 3) 59 + SELECT product(l) from groups;
+18
2025/8/p1.tri
··· 1 + import "trilogy:debug" use dbg 2 + import "trilogy:io" use readlines 3 + import "trilogy:parsec" use parse, sep_by, char, integer, per_line 4 + import "trilogy:array" use collect, sort_by, length 5 + import "trilogy:iterator" as it 6 + 7 + func dist [x1, y1, z1]:[x2, y2, z2] = (x1-x2)**2 + (y1-y2)**2 + (z1-z2)**2 8 + func dist_asc a b = dist a < dist b 9 + 10 + proc main!() { 11 + let points = readlines 12 + |> it::map (parse (sep_by (char ',') integer)) 13 + |> it::enumerate 14 + |> collect 15 + dbg!(length points) 16 + let edges = sort_by dist_asc [a:b for i:a in points and j:b in points and is i < j] 17 + dbg!(length edges) 18 + }