Quantcast
Viewing all articles
Browse latest Browse all 5320

Teaching and learning resources • Re: Advent of Code 2023

Is anyone else still working on these problems?
I've been done for a while, but always on the lookout for better solutions. Days 23 and 25 in particular need speedier algorithms.
I'll let you know when I get there.

Next up is day 17. Tails are wagging because the priority queue that was coded for day 10 finally has a practical use.

Code:

julia> include("day17.jl") # Pi Zero 700 MHzAdvent of Code 2023 Day 17 Clumsy CruciblePart 1 The least heat loss is 1004Part 2 Ultra crucible heat loss is 1171Total execution time 54.888552316 seconds.julia> main()Advent of Code 2023 Day 17 Clumsy CruciblePart 1 The least heat loss is 1004Part 2 Ultra crucible heat loss is 1171Total execution time 56.025290804 seconds.julia> main()Advent of Code 2023 Day 17 Clumsy CruciblePart 1 The least heat loss is 1004Part 2 Ultra crucible heat loss is 1171Total execution time 56.283473324 seconds.
This is the first time I've seen the warmed-up code finish slower than the initial run. Although I suspect this part of an evil plan to obtain more dog treats, I've opened a ticket for software revision. The fine print says the deliverable must meet the 15 second cutoff, but I'm more interested in why Julia slows down after the first run.

The current code is

Code:

#=  Advent of Code 2023 Day 17 Clumsy Crucible    Written 2024 by Eric Olson =#struct DoExit <: Exceptionendmutable struct Node    p::Vector{Int}    d::Int    h::Intendfunction mkpriority()    heap=Node[]    function enqueue(p::Node)        push!(heap,p)        r=length(heap)        while true            s=r÷2            if s<1 break end            if heap[s].h<=p.h break end            heap[r]=heap[s]            r=s        end        heap[r]=p    end    function dequeue()::Node        if length(heap)==0            println("Tried to remove nonexistent point!\n")            throw(DoExit())        end        t=pop!(heap)        if length(heap)==0 return t end        p=heap[1]        s0=1        while true            r0=2*s0; r1=r0+1            if r0>length(heap) break end            s1=r0            if r1<=length(heap)                if heap[r0].h>heap[r1].h                    s1=r1                end            end            if t.h<=heap[s1].h break end            heap[s0]=heap[s1]            s0=s1        end        heap[s0]=t        return p    end    return enqueue,dequeueend@isdefined(dirs) || const dirs=[[0,1],[-1,0],[0,-1],[1,0]]function part1(data::Vector{String})::Int    M=length(data)    N=length(data[1])    function inbound(p::Vector{Int})::Bool        if p[1]<1||p[1]>M return false end        if p[2]<1||p[2]>N return false end        return true    end    H=[parse(Int,data[i][j]) for i=1:M,j=1:N]    W=[[typemax(Int),typemax(Int)] for i=1:M,j=1:N]    enq,deq=mkpriority()    enq(Node([1,1],1,0)); enq(Node([1,1],4,0))    W[1,1]=[0,0]    while length(enq.heap)>0        v=deq()        p=copy(v.p)        h=v.h        for i=1:3            p+=dirs[v.d]            if inbound(p)                h+=H[p...]                d=v.d%4+1                if h<W[p...][d%2+1]                    W[p...][d%2+1]=h                    enq(Node(p,d,h))                    d=(d+1)%4+1                    enq(Node(p,d,h))                end            end        end    end    return minimum(W[M,N])endfunction part2(data::Vector{String})::Int    M=length(data)    N=length(data[1])    function inbound(p::Vector{Int})::Bool        if p[1]<1||p[1]>M return false end        if p[2]<1||p[2]>N return false end        return true    end    H=[parse(Int,data[i][j]) for i=1:M,j=1:N]    W=[[typemax(Int),typemax(Int)] for i=1:M,j=1:N]    enq,deq=mkpriority()    enq(Node([1,1],1,0)); enq(Node([1,1],4,0))    W[1,1]=[0,0]    while length(enq.heap)>0        v=deq()        p=copy(v.p)        h=v.h        for i=1:10            p+=dirs[v.d]            if inbound(p)                h+=H[p...]                if i>=4                    d=v.d%4+1                    if h<W[p...][d%2+1]                        W[p...][d%2+1]=h                        enq(Node(p,d,h))                        d=(d+1)%4+1                        enq(Node(p,d,h))                    end                end            end        end    end    return minimum(W[M,N])endfunction doinit()    data=[]    open("day17.txt","r") do fp        data=readlines(fp)    end    p1=part1(data)    p2=part2(data)    println("Part 1 The least heat loss is ",p1)    println("Part 2 Ultra crucible heat loss is ",p2)endfunction main()    t=@elapsed try        println("Advent of Code 2023 Day 17 Clumsy Crucible\n")        doinit()        throw(DoExit())    catch r        if !isa(r,DoExit)            rethrow(r)        end    end    println("\nTotal execution time ",t," seconds.")end main()
Can anyone see why the warmed up code would be slower than the first run? I suspect the garbage collector. Could there be too much garbage?

Statistics: Posted by ejolson — Sun Jan 14, 2024 4:54 am



Viewing all articles
Browse latest Browse all 5320

Trending Articles