You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
72 lines
2.3 KiB
72 lines
2.3 KiB
4 years ago
|
bignum = require "_openssl.bignum"
|
||
|
|
||
|
function find(card, deck, times)
|
||
|
local revert = false
|
||
|
local increment = bignum.new(0)
|
||
|
local multiply = bignum.new(1)
|
||
|
for line in io.lines(arg[1]) do
|
||
|
if line:find("^deal into new stack$") then
|
||
|
revert = not revert
|
||
|
elseif line:find("^cut %-?%d+$") then
|
||
|
local val = tonumber(line:match("^cut (%-?%d+)$"))
|
||
|
if not revert then
|
||
|
increment = (increment - val) % deck
|
||
|
else
|
||
|
increment = (increment + val) % deck
|
||
|
end
|
||
|
elseif line:find("^deal with increment %d+$") then
|
||
|
local val = tonumber(line:match("^deal with increment (%d+)$"))
|
||
|
multiply = (multiply * val) % deck
|
||
|
increment = (increment * val) % deck
|
||
|
if revert then
|
||
|
increment = (increment + (val - 1)) % deck
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
print(card, multiply, increment, deck)
|
||
|
card = (card * multiply * times + increment * times) % deck
|
||
|
if revert then
|
||
|
card = deck - (card + 1)
|
||
|
end
|
||
|
return card
|
||
|
end
|
||
|
|
||
|
function revfind(card, deck, times)
|
||
|
local revert = false
|
||
|
local increment = bignum.new(0)
|
||
|
local multiply = bignum.new(1)
|
||
|
for line in io.lines(arg[1]) do
|
||
|
if line:find("^deal into new stack$") then
|
||
|
revert = not revert
|
||
|
elseif line:find("^cut %-?%d+$") then
|
||
|
local val = tonumber(line:match("^cut (%-?%d+)$"))
|
||
|
if not revert then
|
||
|
increment = (increment - val) % deck
|
||
|
else
|
||
|
increment = (increment + val) % deck
|
||
|
end
|
||
|
elseif line:find("^deal with increment %d+$") then
|
||
|
local val = tonumber(line:match("^deal with increment (%d+)$"))
|
||
|
multiply = (multiply * val) % deck
|
||
|
increment = (increment * val) % deck
|
||
|
if revert then
|
||
|
increment = (increment + (val - 1)) % deck
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
print(card, multiply, increment, deck)
|
||
|
card = (card * multiply * times + increment * times) % deck
|
||
|
if revert then
|
||
|
card = deck - (card + 1)
|
||
|
end
|
||
|
return card
|
||
|
end
|
||
|
|
||
|
print("Part 1:", find(2019, 10007, 1))
|
||
|
print("Part 2:", find(2020, 119315717514047, 101741582076661))
|
||
|
|
||
|
print("Part 1:", revfind(7744, 10007, 1))
|
||
|
print("Part 2:", revfind(2020, 119315717514047, 101741582076661))
|