Quantcast
Viewing all articles
Browse latest Browse all 5216

Teaching and learning resources • Re: Advent of Code 2023

Since the 700 MHz Pi Zero took 9504 seconds on day 21, then

9504 / 159 = 59.8

implies the Pi 5 is almost 60 times faster than the Zero.
As there is still no Pi 5 for me, here is day 22 on the Zero.

Code:

julia> include("day22.jl") # Pi Zero 700 MHzAdvent of Code 2023 Day 22 Sand SlabsPart 1 There are 459 safe bricksPart 2 There are 75784 bricks that fallTotal execution time 19.680736116 seconds.julia> main()Advent of Code 2023 Day 22 Sand SlabsPart 1 There are 459 safe bricksPart 2 There are 75784 bricks that fallTotal execution time 5.751008091 seconds.julia> main()Advent of Code 2023 Day 22 Sand SlabsPart 1 There are 459 safe bricksPart 2 There are 75784 bricks that fallTotal execution time 5.67593156 seconds.
It took me a while to realize the blocks in the input where not arranged in z order. After sorting, the blocks are dropped one unit at a time until they land on something. Compared to day 21 the program is quite speedy and the warmed up execution time is under the 15 second limit. As I'm again out of dog treats the dog developer refused to optimize the solution further.

The Julia source code is

Code:

#=  Advent of Code 2023 Day 22 Sand Slabs    Written 2024 by Eric Olson =#struct DoExit <: Exceptionendfunction gobble(s::String,m::String)::Tuple{String,Bool}    if length(s)<length(m)        return s,false    end    if s[1:length(m)]==m        return s[length(m)+1:end],true    end    return s,falseendfunction wskip(s::String)::String    for i=1:length(s)        if !isspace(s[i])            return s[i:end]        end    end    return ""endfunction vskip(data,i::Int)::Int    while i<=length(data)&&length(data[i])==0        i+=1    end    return iend function getalpha(s::String)::Tuple{String,String}    for i=1:length(s)        if !isletter(s[i])            return s[i:end],s[1:i-1]        end    end    return "",sendfunction getint(s::String)::Tuple{String,Int64}    n=Int64(0)    for i=1:length(s)        if s[i]>='0'&&s[i]<='9'            n=n*10+Int64(s[i]-'0')        else            return s[i:end],n        end    end    return "",nendmutable struct Point    x::Int    y::Int    z::Intendmutable struct Block    a::Point    b::Point    u::Set{Int}    d::Set{Int}    Block(a,b)=new(a,b,Set{Int}(),Set{Int}())endfunction getblock(s::String)::Block    r=s    s,ax=getint(s); ax+=1    if begin s,f=gobble(s,","); !f end        println(r,"\nCan't find comma after a.x coordinate!")        throw(DoExit())    end    s,ay=getint(s); ay+=1    if begin s,f=gobble(s,","); !f end        println(r,"\nCan't find comma after a.y coordinate!")        throw(DoExit())    end    s,az=getint(s)    if begin s,f=gobble(s,"~"); !f end        println(r,"\nCan't find tilde after a.z coordinate!")        throw(DoExit())    end    s,bx=getint(s); bx+=1    if begin s,f=gobble(s,","); !f end        println(r,"\nCan't find comma after b.x coordinate!")        throw(DoExit())    end    s,by=getint(s); by+=1    if begin s,f=gobble(s,","); !f end        println(r,"\nCan't find comma after b.y coordinate!")        throw(DoExit())    end    s,bz=getint(s)    if length(s)>0        println(r,"\nCharacters after at end of location!")        throw(DoExit())            end    return Block(Point(ax,ay,az),Point(bx,by,bz))endmutable struct Visible    k::Int    z::Intendfunction drop(topo::Matrix{Visible},block::Block,b::Int)::Bool    dx=block.b.x-block.a.x    dy=block.b.y-block.a.y    dz=block.b.z-block.a.z    imax=abs(dx)    if imax<abs(dy) imax=abs(dy) end    if imax<abs(dz) imax=abs(dz) end    f=false    for i=0:imax        x=block.a.x+i*sign(dx)        y=block.a.y+i*sign(dy)        z=block.a.z+i*sign(dz)        if topo[x,y].z>=z-1            f=true            push!(block.d,topo[x,y].k)        end    end    if f        for i=0:imax            x=block.a.x+i*sign(dx)            y=block.a.y+i*sign(dy)            z=block.a.z+i*sign(dz)            topo[x,y].k=b            if topo[x,y].z<z                 topo[x,y].z=z            end        end    end    return fendfunction part1(blocks::Vector{Block})::Int64    K=length(blocks)    disint=ones(Bool,K)    for k=2:K        if length(blocks[k].d)==1            for i in blocks[k].d                disint[i]=false            end        end    end    return sum(disint)endfunction part2(blocks::Vector{Block})::Int64    K=length(blocks)    function poof(k::Int,disint::Set{Int})::Int        push!(disint,k)        r=1        for i in blocks[k].u            d=setdiff(blocks[i].d,disint)            if length(d)==0                r+=poof(i,disint)            end        end        return r    end    s=0    for k=2:K        s+=poof(k,Set{Int}())-1    end    return sendfunction doinit()    data=String[]    open("day22.txt","r") do fp        data=readlines(fp)    end    M=0; N=0; K=length(data)+1    blocks=Vector{Block}(undef,K)    blocks[1]=Block(Point(1,1,0),Point(0,0,0))    for k=2:K        s=data[k-1]        r=getblock(s)        if M<r.a.x M=r.a.x end        if N<r.a.y N=r.a.y end        if M<r.b.x M=r.b.x end        if N<r.b.y N=r.b.y end        blocks[k]=r    end    blocks[1].b.x=M; blocks[1].b.y=N    P=sortperm([blocks[k].a.z for k=1:K])    blocks=blocks[P]    topo=Matrix{Visible}(undef,M,N)    for j=1:N        for i=1:M            topo[i,j]=Visible(1,0)        end    end    for k=2:K        while !drop(topo,blocks[k],k)            blocks[k].a.z-=1            blocks[k].b.z-=1        end        for i in blocks[k].d            push!(blocks[i].u,k)        end    end    p1=part1(blocks)    p2=part2(blocks)    println("Part 1 There are ",p1," safe bricks")    println("Part 2 There are ",p2," bricks that fall")endfunction main()    t=@elapsed try        println("Advent of Code 2023 Day 22 Sand Slabs\n")        doinit()        throw(DoExit())    catch r        if !isa(r,DoExit)            rethrow(r)        end    end    println("\nTotal execution time ",t," seconds.")end main()
Other than the inefficient way mentioned already in which the blocks are dropped, it's notable that the graph was created using indices into an array rather than pointers. Julia's built-in sets and set difference operators keep track of the edges in the graph and which blocks fall in part 2.

Statistics: Posted by ejolson — Sun Feb 04, 2024 7:34 am



Viewing all articles
Browse latest Browse all 5216

Trending Articles