83 lines
2.4 KiB
SQL
83 lines
2.4 KiB
SQL
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);
|
|
|