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);

