From: Ben Harris Date: Wed, 5 Jun 2024 19:26:22 +0000 (+0100) Subject: 22b: half-working boundary walking X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~bjharris/git?a=commitdiff_plain;h=a1192b78b7dfec5dacc8c8e81113db6ec229ec23;p=aoc-2022.git 22b: half-working boundary walking We can handle only the case where the next edge is the one we want --- diff --git a/22/22b.bqn b/22/22b.bqn index ce191a8..a9dfbfd 100644 --- a/22/22b.bqn +++ b/22/22b.bqn @@ -13,20 +13,60 @@ TR←{⟨1,¯1⟩×⌽𝕩} Main←{𝕊⟨map,path⟩: sidelen←√(+´⥊' '≠map)÷6 Pad←{ ⟨h,w⟩←≢𝕩 ⋄ »⍟sidelen˘»⍟sidelen(w+2×sidelen)↑˘(h+2×sidelen)↑𝕩 } - map ↩ Pad map + •Show map ↩ Pad map Move←{ 'L' 𝕊 ⟨pos,dir⟩: ⟨pos,TL dir⟩; 'R' 𝕊 ⟨pos,dir⟩: ⟨pos,TR dir⟩; n 𝕊 ⟨pos,dir⟩: Advance⍟n⟨pos,dir⟩ } Advance←{𝕊⟨pos,dir⟩: - dest←(≢map)|pos+dir - dest↩{ (≢map)|𝕩+dir } •_while_ { ' '=𝕩⊑map } dest - ⟨('.'=dest⊑map)⊑⟨pos,dest⟩,dir⟩ + ⟨dpos,ddir⟩←⟨(≢map)|pos+dir,dir⟩ + ⟨dpos,ddir⟩ CubeJump ⍟ (' '=dpos⊑map) ↩ + ('.'=dpos⊑map)⊑⟨⟨pos,dir⟩,⟨dpos,ddir⟩⟩ + } + # To find the where we end up after walking off the boundary of the + # net, we walk around that boundary. On the cube, the cut edges + # form a tree, and walking around the boundary forms a depth-first + # search of that tree. When that DFS returns to its starting point, + # we've reached the edge we're looking for. + # + # We can tell whether a particular edge on the boundary goes up or + # down the tree by counting faces around each vertex. If we've seen + # one or two faces at a vertex, the edge by which we leave it will + # go down. If we've seen three, we're returning up an edge we've + # already seen and we're going up the tree and back to another + # vertex we've already seen. + # + # To move from one edge to the next, we reflect our position and + # orientation in an axis passing through the current vertex. Which + # axis it is is dependent on how many faces there are at this + # vertex, and we can work that out by trying all the axes and seeing + # how many land us on a face. Because we visit each edge in the + # tree twice, there must be an odd number of reflections before we + # get back to the start, and therefore we'll end up in the proper + # place on the target edge. + CubeJump←{𝕊 ⟨pos,dir⟩: + ⟨pos,dir⟩↩CubeWalk ⟨pos-dir,dir⟩ # Step back, walk sideways around edge. + ⟨pos,-dir⟩ # And then turn around and continue. + } + CubeWalk←{𝕊 ⟨pos,dir⟩: + •Show map Mark ⟨pos,dir⟩ + cv←⌈⌾((÷⟜(sidelen×dir+TR dir))∘(0.5⊸+)) pos # Current vertex (ahead/right) + •Show cv + axes←(⊣∾-)⟨[0‿1,1‿0],[1‿0,0‿¯1]⟩ + Reflect←+˝∘× + dests←{ + ⟨(𝕩⊸Reflect)⌾(-⟜cv) pos, 𝕩 Reflect dir⟩ + }¨axes + •Show map⊸Mark¨dests + "Excessively interesting vertex" ! 3=+´' '≠(⊑¨dests)⊑map + # Find destination that is on the map but looking off it. + ⊑({𝕊⟨pos,dir⟩:∧´⟨0,1⟩=' '=⟨pos,pos+dir⟩⊑map}¨dests)/dests } pos←⟨sidelen,⊑(sidelen⊏map)⊐'.'⟩ dir←⟨0,1⟩ ⟨⟨r,c⟩,d⟩ ← ⟨pos,dir⟩ Move´ ⌽path + •Show ⟨⟨r,c⟩,d⟩ (1000×r+1-sidelen) + (4×c+1-sidelen) + (|1-˜+´⟨2,1⟩×d) }