view 13/13.jl @ 20:6160397412c3

Day 13 part 1
author Lewin Bormann <lbo@spheniscida.de>
date Thu, 15 Dec 2022 20:49:53 +0100
parents
children 527acdd2d097
line wrap: on
line source

using ParserCombinator

List = Delayed()
IntOrList() = PInt64() | List
ListElement() = (IntOrList() + E",") | IntOrList()
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 parse_list(s::String)::Element
    r = parse_one(s, IOL; flatten=false);
    any_to_elem(r[1])
end

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

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