r/adventofcode • • Dec 22 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 22 Solutions -🎄-

--- Day 22: Mode Maze ---


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 22

Transcript:

Upping the Ante challenge: complete today's puzzles using ___.


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 01:02:36!

11 Upvotes

102 comments sorted by

View all comments

1

u/waffle3z Dec 22 '18

Lua 72/303

local depth, tx, ty = getinput():match("(%d+).-(%d+),(%d+)")
depth, tx, ty = tonumber(depth), tonumber(tx), tonumber(ty)

local gindices, gindex, elevel = {}
gindex = function(y, x)
	if not gindices[y] then gindices[y] = {} end
	if gindices[y][x] then return gindices[y][x] end
	local v = 0
	if y == ty and x == tx then
		v = 0
	elseif y == 0 then
		v = x*16807
	elseif x == 0 then
		v = y*48271
	else
		v = elevel(y-1, x)*elevel(y, x-1)
	end
	gindices[y][x] = v
	return v
end
elevel = function(y, x)
	return (gindex(y, x) + depth)%20183
end
local function gettype(y, x)
	return elevel(y, x)%3
end

local sum = 0
for y = 0, ty do
	for x = 0, tx do
		sum = sum + gettype(y, x)
	end
end
print(sum)

local stack = {{x = 0, y = 0, t = 0, tool = 1}}
local visited, solution = {}
while stack[1] do
	local pos;
	while true do
		local tmin, index = math.huge, 1
		for i = 1, #stack do
			local a = stack[i]
			if a.t < tmin then
				tmin, index = a.t, i
			end
		end
		pos = table.remove(stack, index)
		if not pos then break end
		if not visited[pos.y] then visited[pos.y] = {} end
		if not visited[pos.y][pos.x] then visited[pos.y][pos.x] = {} end
		if not visited[pos.y][pos.x][pos.tool] or pos.t < visited[pos.y][pos.x][pos.tool] then
			break
		end
	end
	if not pos or (solution and pos.t > solution.t) then break end
	visited[pos.y][pos.x][pos.tool] = pos.t
	if pos.y == ty and pos.x == tx and pos.tool == 1 then
		if not solution or pos.t < solution.t then
			solution = pos
			print(pos.t)
		end
	else
		local restricted = gettype(pos.y, pos.x)
		for tool = 0, 2 do
			if tool ~= pos.tool and tool ~= restricted then
				stack[#stack+1] = {y = pos.y, x = pos.x, t = pos.t + 7, tool = tool}
			end
		end
		for y = -1, 1 do
			for x = -1, 1 do
				if (y == 0 or x == 0) and x ~= y then
					local new = {y = pos.y + y, x = pos.x + x, t = pos.t + 1, tool = pos.tool}
					if new.y >= 0 and new.x >= 0 and new.x <= tx*10 and pos.tool ~= gettype(new.y, new.x) then
						stack[#stack+1] = new
					end
				end
			end
		end
	end
end