Quantcast
Viewing all articles
Browse latest Browse all 5402

Teaching and learning resources • Re: Advent of Code 2023

Every year the same classic Dijkstra's algorithm for optimizing cost is featured. This year introduces the Shoelace formula.
I remember discussing the same formula on this forum a couple years ago but don't remember the context. Anyway, here is day 18 on the Pi Zero at 700 MHz.

Code:

julia> include("day18.jl")Advent of Code 2023 Day 18 Lavaduct LagoonPart 1 The size of the trench is 38188Part 2 The correct trench size is 93325849869340Total execution time 2.198000167 seconds.julia> main()Advent of Code 2023 Day 18 Lavaduct LagoonPart 1 The size of the trench is 38188Part 2 The correct trench size is 93325849869340Total execution time 0.335248827 seconds.julia> main()Advent of Code 2023 Day 18 Lavaduct LagoonPart 1 The size of the trench is 38188Part 2 The correct trench size is 93325849869340Total execution time 0.342493809 seconds.
For reference the code is

Code:

#=  Advent of Code 2023 Day 18 Lavaduct Lagoon    Written 2023 by Eric Olson =#struct DoExit <: Exceptionendmutable struct pspec    i::Int    j::Intendstruct dp    di::Int    dj::Intend@isdefined(dirs) || const dirs=Dict('R'=>dp(0,1),'D'=>dp(1,0),    'L'=>dp(0,-1),'U'=>dp(-1,0))@isdefined(dlist) || const dlist=[dp(0,1),dp(1,0),    dp(0,-1),dp(-1,0)]struct dspec    r::dp    d::Int    r2::dp    d2::Intendfunction getcolor(s::AbstractString)::Tuple{dp,Int}    if length(s)!=9        println(s,"\nColor field is the wrong length!")        throw(doExit())    end    if s[1:2]!="(#"||s[9:9]!=")"        println(2,"\nColor field delimiters wrong!")        throw(doExit())    end    c2=tryparse(Int,s[8:8],base=16)    d2=parse(Int,s[3:7],base=16)    if c2==nothing||d2==nothing        println(data[i],"\nUnable to parse color field!")        throw(DoExit())    end    return dlist[c2+1],d2endfunction digparse(data::Vector{String})::Vector{dspec}    dig=Vector{dspec}(undef,length(data))    for i=1:length(data)        v=split(data[i])        if length(v)!=3            println(data[i],"\nDid not have three entries!")            throw(DoExit())        end        if length(v[1])!=1            println(data[i],"\nCould not find direction!")            throw(DoExit())        end        c=v[1][1]        r=get(dirs,c,nothing)        if r==nothing            println(data[i],"\nInvalid direction!")            throw(DoExit())        end        d=tryparse(Int,v[2])        if d==nothing            println(data[i],"\nUnable to parse distance field!")            throw(DoExit())        end        r2,d2=getcolor(v[3])        dig[i]=dspec(r,d,r2,d2)    end    return digendfunction getdim(dig::Vector{dspec})::Tuple{pspec,pspec}    p=pspec(0,0)    pmin=pspec(0,0)    pmax=pspec(0,0)    for i=1:length(dig)        d=dig[i].d; r=dig[i].r        p.i+=d*r.di; p.j+=d*r.dj        if p.i<pmin.i pmin.i=p.i end        if p.j<pmin.j pmin.j=p.j end        if p.i>pmax.i pmax.i=p.i end        if p.j>pmax.j pmax.j=p.j end    end    return pmin,pmaxendfunction dofill(trench::Matrix{Int},p::pspec,v::Int)    if p.i<1||p.i>size(trench)[1]||p.j<1||p.j>size(trench)[2]        return    end    if trench[p.i,p.j]!=0        return    end    trench[p.i,p.j]=v    for k=1:4        z=dlist[k]        dofill(trench::Matrix{Int},pspec(p.i+z.di,p.j+z.dj),v)    endendfunction part1(dig::Vector{dspec})::Int    pmin,pmax=getdim(dig)    p0=pspec(2-pmin.i,2-pmin.j)    M=pmax.i-pmin.i+3    N=pmax.j-pmin.j+3    trench=zeros(Int,M,N)    p=p0    for i=1:length(dig)        d=dig[i].d; r=dig[i].r        for k=1:d            p.i+=r.di; p.j+=r.dj            trench[p.i,p.j]=1        end    end    dofill(trench,pspec(1,1),-1)    s=0    for i=1:size(trench)[1]        for j=1:size(trench)[2]            if trench[i,j]>=0                s+=1            end        end    end    return sendfunction part2(dig::Vector{dspec})::Int64    p0=pspec(0,0)    a::Int64=0    l=2    for i=1:length(dig)        d=dig[i].d2; r=dig[i].r2        p1=pspec(p0.i+d*r.di,p0.j+d*r.dj)        a+=(Int64(p0.j)+Int64(p1.j))*(Int64(p0.i)-Int64(p1.i))        l+=d        p0=p1    end    return abs(a÷2)+abs(l÷2)endfunction doinit()    data=[]    open("day18.txt","r") do fp        data=readlines(fp)    end    dig=digparse(data)    p1=part1(dig)    p2=part2(dig)    println("Part 1 The size of the trench is ",p1)    println("Part 2 The correct trench size is ",p2)endfunction main()    t=@elapsed try        println("Advent of Code 2023 Day 18 Lavaduct Lagoon\n")        doinit()        throw(DoExit())    catch r        if !isa(r,DoExit)            rethrow(r)        end    end    println("\nTotal execution time ",t," seconds.")end main()
Part one is solved using a flood fill as I originally thought the next step was going to be about coloring things. The area in part 2 needed 64-bit integers but otherwise the Pi Zero posed no additional difficulties.

In other news, Fido is whining that I skipped all the puzzles that used Dogstra's algorithm. I wonder whether day 16 could be solved more quickly with a suitable modification.

Statistics: Posted by ejolson — Tue Dec 19, 2023 6:45 am



Viewing all articles
Browse latest Browse all 5402

Trending Articles