view 2022/13/13.jl @ 64:c9010e9a5257

Day 12 Part 2 Add memoization implementation for count function
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 23 Dec 2023 15:13:15 +0100
parents 05ddc45b4210
children
line wrap: on
line source

using ParserCombinator

List = Delayed()
IntOrList() = PInt64() | List
ListElement() = (IntOrList() + Repeat(E",", 0, 1))
List.matcher = (E"[" + Repeat(ListElement()) + E"]") |> identity

const Element = Union{Int,Vector};
const IOL = IntOrList();

function any_to_elem(v::Any)::Element
    if isa(v, Vector)
        [any_to_elem(e) for e in v]::Vector
    elseif isa(v, Int)
        v::Int
    end
end

function compare_lists(a::Element, b::Element)::Int
    if isa(a, Int) && isa(b, Int)
        a < b ? -1 : (a == b ? 0 : 1)
    elseif isa(a, Vector) && isa(b, Vector)
        for (i, (x,y)) in enumerate(zip(a::Vector, b::Vector))
            c = compare_lists(x, y);
            if c != 0
                return c;
            end
        end
        return compare_lists(length(a), length(b));
    else
        if isa(a, Int)
            a = [a];
        elseif isa(b, Int)
            b = [b];
        else
            error("unknown types: $a vs $b");
        end
        return compare_lists(a, b);
    end
end

function sort_lists!(e::Vector{Element})
    sort!(e; lt=(a, b) -> compare_lists(a, b) < 0)
end

function parse_list(s::String)::Element
    r = parse_one(s, IOL);
    any_to_elem(r[1])
end

function run_file(f::String)
    open(f; read=true) do fh
        v = Int[];
        m1, m2 = parse_list("[[2]]"), parse_list("[[6]]");
        lists = Element[m1, m2];
        i = 1;
        while !eof(fh)
            l1 = readline(fh);
            l2 = readline(fh);
            _sp = readline(fh);
            a, b = parse_list(l1), parse_list(l2);
            push!(lists, a, b);
            if compare_lists(a, b) < 0
                push!(v, i);
            end
            i += 1
        end
        @show (v, sum(v))

        sort_lists!(lists);
        for (i, l) in enumerate(lists)
            println(i, "  ", l);
        end

        i, j = findfirst((==)(m1), lists), findfirst((==)(m2), lists);
        @show (i, j, i*j);
    end
end

println("PART 1 TEST");
@time run_file("13/test_input.txt");
println("PART 1 INPUT");
@time run_file("13/input.txt");