Compare commits
2 Commits
687b84d9a7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94b16e049f | ||
|
|
389ce7248c |
4
.envrc
4
.envrc
@@ -1,5 +1,5 @@
|
|||||||
export DIRENV_WARN_TIMEOUT=20s
|
export DIRENV_WARN_TIMEOUT=20s
|
||||||
|
|
||||||
eval "$(devenv direnvrc)"
|
# eval "$(devenv direnvrc)"
|
||||||
|
|
||||||
use flake --no-pure-eval
|
use flake . --no-pure-eval
|
||||||
|
|||||||
90
solutions/04.sql
Normal file
90
solutions/04.sql
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
create or replace table day04_data as
|
||||||
|
select
|
||||||
|
row_number() over() as row,
|
||||||
|
column0
|
||||||
|
from
|
||||||
|
read_csv(
|
||||||
|
'inputs/04/input.txt',
|
||||||
|
header = false
|
||||||
|
);
|
||||||
|
create or replace table day04_test as
|
||||||
|
select
|
||||||
|
row_number() over() as row,
|
||||||
|
column0
|
||||||
|
from
|
||||||
|
read_csv(
|
||||||
|
'inputs/04/test.txt',
|
||||||
|
header = false
|
||||||
|
);
|
||||||
|
|
||||||
|
create or replace table day04_clean as
|
||||||
|
select
|
||||||
|
row,
|
||||||
|
idx + 1 as col
|
||||||
|
from
|
||||||
|
day04_data
|
||||||
|
cross join unnest(range(length(column0))) as t(idx)
|
||||||
|
where substr(column0, idx + 1, 1) = '@';
|
||||||
|
|
||||||
|
create or replace table day04_neighbors as
|
||||||
|
select
|
||||||
|
c.row * 1000 + c.col as node,
|
||||||
|
a.row * 1000 + a.col as neighbor
|
||||||
|
from day04_clean as c
|
||||||
|
left join day04_clean as a
|
||||||
|
on a.row between (c.row - 1) and (c.row + 1)
|
||||||
|
and a.col between (c.col - 1) and (c.col + 1)
|
||||||
|
;
|
||||||
|
|
||||||
|
with neighbors_count as (
|
||||||
|
select node, count(1) as nb_neighbors
|
||||||
|
from day04_neighbors
|
||||||
|
group by node
|
||||||
|
)
|
||||||
|
select count_if(nb_neighbors <= 4) as part1
|
||||||
|
from neighbors_count
|
||||||
|
;
|
||||||
|
|
||||||
|
with recursive seq as (
|
||||||
|
with agg as (
|
||||||
|
select
|
||||||
|
node,
|
||||||
|
count(1) neighbors
|
||||||
|
from day04_neighbors
|
||||||
|
group by node
|
||||||
|
having neighbors > 4
|
||||||
|
)
|
||||||
|
select
|
||||||
|
node,
|
||||||
|
s.neighbor,
|
||||||
|
(select count(distinct node) from agg) as remaining,
|
||||||
|
0 as step
|
||||||
|
from day04_neighbors as s
|
||||||
|
inner join agg as a1 using (node)
|
||||||
|
inner join agg as a2 on a2.node = s.neighbor
|
||||||
|
|
||||||
|
union all
|
||||||
|
|
||||||
|
(
|
||||||
|
with agg2 as (
|
||||||
|
select node, step, count(distinct neighbor) as neighbors
|
||||||
|
from seq
|
||||||
|
group by node, step
|
||||||
|
having step = (select max(step) from seq)
|
||||||
|
and neighbors > 4
|
||||||
|
)
|
||||||
|
select
|
||||||
|
s.node,
|
||||||
|
s.neighbor,
|
||||||
|
(select count(distinct node) from agg2) as remaining,
|
||||||
|
s.step + 1 as step
|
||||||
|
from seq s
|
||||||
|
inner join agg2 as a1 using(node)
|
||||||
|
inner join agg2 as a2 on a2.node = s.neighbor
|
||||||
|
where (
|
||||||
|
select count(distinct node) from agg2) < (select min(remaining) from seq
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
select (select count(distinct node) from day04_neighbors) - (select min(remaining) from seq) as part2;
|
||||||
|
|
||||||
82
solutions/05.sql
Normal file
82
solutions/05.sql
Normal 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
78
solutions/06.sql
Normal 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
59
solutions/07.sql
Normal 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;
|
||||||
Reference in New Issue
Block a user