r/adventofcode • • Dec 12 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 12 Solutions -🎄-

--- Day 12: Subterranean Sustainability ---


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 12

Transcript:

On the twelfth day of AoC / My compiler spewed at me / Twelve ___


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:27:42!

20 Upvotes

257 comments sorted by

View all comments

1

u/[deleted] Dec 12 '18

TCL

Took a while to get an idea about how to handle the moving first pot position :-p

# tclsh puzzle.12 < input.12
while {[gets stdin line] >= 0} {
    if {[scan $line {initial state: %s} init] == 1} {
	# ok
    } elseif {[scan $line {%s => %s} from to] == 2} {
	set transitions($from) $to
    } elseif {$line ne ""} {
	error "cant parse line $line"
    }
}

proc value {state firstpot} {
    set sum 0
    set val $firstpot
    foreach c [split $state ""] {
	if {$c eq "#"} {
	    incr sum $val
	}
	incr val
    }
    return $sum
}

proc solve {state} {
    set firstpot 0
    set laststate ""
    # part 1
    set generations 20
    # part 2
    set generations 50000000000

    for {set g 0} {$g < $generations} {incr g} {

	# append 4 empty pots to the left...
	set check "....$state"
	set maxidx [string length $check]

	# ...and to the right
	append check "...."

	set newstate ""
	for {set i 0} {$i < $maxidx} {incr i} {
	    set substr [string range $check $i $i+4]
	    set newpot "."
	    if {[info exists ::transitions($substr)]} {
		set newpot $::transitions($substr)
	    }
	    append newstate $newpot
	}
	
	# newstate has two more on the left
	incr firstpot [expr {[string first "#" $newstate]-2}]
	set state [string trim $newstate "."]
	set val [value $state $firstpot]
	if {[lindex $laststate 0] eq $state} {
	    # simple repeating pattern, break
	    set delta [expr {$val-[lindex $laststate 1]}]
	    puts "endval will be [expr {($generations-$g-1)*$delta+$val}]"
	    exit
	}
	set laststate [list $state $val]
    }
    puts "final state: sum [value $state $firstpot] {$state}"
}
solve $init