feat: add day5 6 7

This commit is contained in:
Xavier Morel
2025-12-09 14:42:24 +01:00
parent 389ce7248c
commit 94b16e049f
4 changed files with 221 additions and 2 deletions

82
solutions/05.sql Normal file
View File

@@ -0,0 +1,82 @@
create or replace table day05_data as
select
if('-' in column0, SPLIT(column0, '-')[1]::long, NULL) as range_start,
if('-' in column0, SPLIT(column0, '-')[2]::long, NULL) as range_end,
if('-' not in column0, column0::long, NULL) as product_id
from read_csv(
'inputs/05/input.txt',
header = false)
where (range_start is not null and range_end is not null) or product_id is not null
;
create or replace table day05_test as
select
if('-' in column0, SPLIT(column0, '-')[1]::long, NULL) as range_start,
if('-' in column0, SPLIT(column0, '-')[2]::long + 1, NULL) as range_end,
if('-' not in column0, column0::long, NULL) as product_id
from read_csv(
'inputs/05/test.txt',
header = false)
where (range_start is not null and range_end is not null) or product_id is not null
;
create or replace table day05_ranges as
select row_number() over (order by range_start) as range_id, range_start, range_end
from day05_data
where product_id is null;
create or replace table day05_products as
select product_id
from day05_data
where product_id is not null;
select count(distinct product_id) as part1
from day05_products
inner join day05_ranges
on product_id between range_start and range_end
;
create or replace table day05_cleaned_ranges as
with recursive seq(step, range_id, range_start, range_end) as (
select 0 as step,
range_id,
range_start,
range_end
from day05_ranges
union all (
with res as (
select distinct
s1.step + 1 as step,
list_min([s1.range_start::long, coalesce(s2.range_start, s1.range_start)]) as range_start,
list_max([s1.range_end, coalesce(s2.range_end, s1.range_end)]) as range_end,
s2.step is not null as changed_smth
from seq s1
left join seq s2
on s1.range_id != s2.range_id and
(s1.range_start between s2.range_start and s2.range_end
or s1.range_end between s2.range_start and s2.range_end)
order by range_start
)
select
step,
row_number() over () as range_id,
range_start,
range_end
from res
where (select count(1) filter (where changed_smth is true) from res) > 0
and step < 20
group by step, range_start, range_end
))
select *
from seq;
;
select *
from day05_cleaned_ranges
order by step, range_start;
select sum(range_end - range_start) as part2
from day05_cleaned_ranges
where step = (select max(step) from day05_cleaned_ranges);

78
solutions/06.sql Normal file
View File

@@ -0,0 +1,78 @@
create or replace table day06_data as
select row_number() over () as line, column0
from read_csv('inputs/06/input.txt', header=false, delim='\n');
create or replace table day06_test as
select row_number() over () as line, column0
from read_csv('inputs/06/test.txt', header=false, delim='\n');
create or replace table day06_input as
with raw as (
select line as y,
array_filter(split(column0, ' '), lambda x: x != '') as s
from day06_data
), splitted as (
select x, y, elem
from raw,
unnest(s) with ordinality as u(elem, x)
), rotated as (
select array_agg(elem order by y) as rot
from splitted
group by x
)
select rot[-1] as op, list_apply(rot[:-2], lambda x: x::int) as num
from rotated;
select sum(
case when op = '+' then list_sum(num)
when op = '*' then list_product(num)
else 0
end
)::long as part1
from day06_input;
create or replace table day06_input2 as
with rotated as (
select
x,
array_agg(elem order by line) rot
from day06_data,
unnest(split(column0, '')) with ordinality as u(elem, x)
group by x
order by x
), cleaned as (
select
x,
any_value(rot[-1]) as op,
reverse(string_agg(n, '')) as num
from rotated, unnest(array_filter(rot[:-2], lambda x: x != ' ')) as u(n)
group by x
), with_breaks as (
select
x, op, num::int as num,
case when lag(x) over (order by x) = x - 1 then 0 else 1 end as is_break
from cleaned
), with_groups as (
select
x, op, num,
sum(is_break) over (order by x rows unbounded preceding) as group_id
from with_breaks
), grouped as (
select
group_id,
max(op) as op,
array_agg(num) as nums
from with_groups
group by group_id
)
select *
from grouped;
select sum(
case when op = '+' then list_sum(nums)
when op = '*' then list_product(nums)
else 0
end
)::long as part2
from day06_input2;

59
solutions/07.sql Normal file
View File

@@ -0,0 +1,59 @@
create or replace table day07_data as
select row_number() over () as line, column0
from read_csv('inputs/07/input.txt', header=false, delim='\n');
create or replace table day07_test as
select row_number() over () as line, column0
from read_csv('inputs/07/test.txt', header=false, delim='\n');
create or replace table day07_input as
select
line as y,
if(c = 'S', x, null) as starter,
if(c = '^', x, null) as splitter
from day07_test,
unnest(split(column0, '')) with ordinality as u(c, x)
where c != '.'
;
with recursive seq(y, x) as (
select
y,
starter as x
from day07_input
where y = 1
union all
select distinct
s.y + 1 as y,
if(m.splitter = s.x, unnest([s.x + 1, s.x - 1]), s.x) as x
from seq as s
left join day07_input as m
on m.y = s.y + 1 and m.splitter = s.x
where s.y <= (select max(y) from day07_input)
)
select count(1) as part1
from seq s
inner join day07_input m on s.y = m.y - 1 and s.x = m.splitter;
with recursive seq(y, x) as (
select
y,
starter as x,
0 as split
from day07_input
where y = 1
union all
select
s.y + 1 as y,
if(m.splitter = s.x, unnest([s.x + 1, s.x - 1]), s.x) as x,
if(m.splitter = s.x, 1, 0) as split
from seq as s
left join day07_input as m
on m.y = s.y + 1 and m.splitter = s.x
where s.y <= (select max(y) from day07_input)
)
select sum(split) as part2
from seq s;