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.Every year the same classic Dijkstra's algorithm for optimizing cost is featured. This year introduces the Shoelace formula.
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.
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()
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