with

raw (line, index) as (
    select
        string_split_regex(trim(unnest(line)), '\s+'),
        generate_subscripts(line, 1)
    from (
        select string_split(trim(content, e'\n'), e'\n') as line
        from read_text('data/06.in')
    )
),

grid (value, row, col) as (
    select
        unnest(line),
        index,
        generate_subscripts(line, 1)
    from raw
),

ops (op, col) as (
    select
        value,
        col
    from grid
    where row = (select max(row) from grid)
),

arguments (args, col) as (
    select
        list(cast(value as int64)),
        col
    from grid
    where row < (select max(row) from grid)
    group by col
),

part1 (solution) as (
    select
        sum(
            case when op = '+' then (
                select sum(arg)
                from unnest(args) n (arg)
            ) else (
                select cast(product(arg) as int128)
                from unnest(args) n (arg)
            ) end
        )
    from arguments natural join ops
),

fine_raw (line, index) as (
    select
        string_split(unnest(line), ''),
        generate_subscripts(line, 1)
    from (
        select string_split(trim(content, e'\n'), e'\n') as line
        from read_text('data/06.in')
    )
),

fine_grid (ch, row, col) as (
    select
        unnest(line),
        index as row,
        generate_subscripts(line, 1) as col
    from fine_raw
    order by col asc, row desc
),

fine_ops (op, col) as (
    select
        ch,
        col
    from fine_grid
    where ch = '+' or ch = '*'
),

fine_digits (n, row, col) as (
    select
        cast(ch as int64),
        row,
        col
    from fine_grid
    where ch <> '+' and ch <> '*' and ch <> ' '
),

fine_degrees (degree, start, col) as (
    select
        count(n),
        min(row) as start,
        col
    from fine_digits
    group by col
),

fine_values (value, col) as (
    select
        sum(10 ^ (degree - row + start - 1) * n),
        col
    from fine_digits natural join fine_degrees
    group by col
),

part2 (solution) as (
    select cast(sum(total) as int128) from (
        select
            case
                when op = '+' then sum(value) else product(value)
            end as total
        from fine_values v asof join fine_ops o on o.col <= v.col
        group by op, o.col
    )
)

select
    part1.solution,
    part2.solution
from part1, part2
