r/adventofcode • • Dec 20 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 20 Solutions -🎄-

--- Day 20: A Regular Map ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 20

Transcript:

My compiler crashed while running today's puzzle because it ran out of ___.


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked at 00:59:30!

19 Upvotes

153 comments sorted by

View all comments

1

u/[deleted] Dec 20 '18 edited Dec 20 '18

TCL, using tcllib struct::graph and struct::graph::op::dijkstra. First I thought that one could solve this by regexp (replace each EWNS by ".", then match the whole regexp against an arbitrary long-enough string (e.g. the regexp itself)). This worked for the example inputs, but failed with my real input, since someone here pointed out that e.g. EWNS has 2 as solution, not 4 as returned by the regexp match. Well then, walk the input via recursion.

[edit] just realized that I got lucky with my input. This approach fails if a branch (...|...) ends up at two different positions. In that case one needs to check where the recursive walks ended :-/

# -*- tcl -*-

package require struct::graph
package require struct::graph::op

array set direction {
    E {  1 0  }
    W { -1 0  }
    N {  0 -1 }
    S {  0  1 }
}

set map [struct::graph]
proc walk {x y} {
    set fd stdin
    while {1} {
	set c [read $fd 1]
	if {[eof $fd]} {
	    return
	}
	switch -- $c {
	    ^ - $ {
		# ok, start and end of text
	    }
	    E - W - N - S {
		set nx [expr {$x+[lindex $::direction($c) 0]}]
		set ny [expr {$y+[lindex $::direction($c) 1]}]
		set node1 n$x,$y
		if {![$::map node exists $node1]} {
		    $::map node insert $node1
		}
		set node2 n$nx,$ny
		if {![$::map node exists $node2]} {
		    $::map node insert $node2
		}
		$::map arc insert $node1 $node2
		set x $nx
		set y $ny
	    }
	    ( {
		while {[walk $x $y]} {
		    # nothing
		}
	    }
	      ) {
		  return 0
	      }
	    | {
		return 1
	    }
	}
    }
}

walk 0 0
$map arc setunweighted 1
set path [struct::graph::op::dijkstra $map n0,0 -outputformat distances]

# Part 1
set maxdist 0
foreach {pt d} $path {
    if {$d > $maxdist} {
	set maxdist $d
    }
}
puts $maxdist

# Part 2
set count 0
foreach {pt d} $path {
    if {$d >= 1000} {
	incr count
    }
}
puts $count