Compare commits

...

6 Commits

Author SHA1 Message Date
sejo 069a32cc82 removed inputs 2023-12-06 21:23:51 +01:00
sejo 4833d1593a created new README 2023-12-06 21:22:59 +01:00
sejo 80822c8d5f added gitignore 2023-12-06 21:22:47 +01:00
sejo 8864dea301 added 12023 files so far 2023-12-06 21:12:03 +01:00
sejo 96bcfd7553 added 12022 directory 2023-12-06 21:10:48 +01:00
sejo e5edc774dd created 12021 directory 2023-12-06 21:08:10 +01:00
157 changed files with 6776 additions and 48 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*/*/input

51
12021/README.md Normal file
View File

@ -0,0 +1,51 @@
# awk aoc 2021
got caught in the thrill of wanting to solve the puzzles fast :)
[advent of code 2021: awk](https://compudanzas.net/advent_of_code_2021.html)
the `NUM.awk` and `NUM_2.awk` files are the original ones written under pressure. the `*_new.awk` files are improved versions written afterwards.
you can see the puzzles and get the input files at [advent of code 2021](https://adventofcode.com/2021/)
# run
to run a program, e.g. `01.awk`:
```
awk -f 01.awk inputfile
```
if using gawk, you should be able to use compatibility/traditional mode (except for day 03, and 09)
```
awk -c -f 01.awk inputfile
```
# stats
```
-------Part 1-------- -------Part 2--------
Day Time Rank Score Time Rank Score
22 00:19:18 1596 0 - - -
21 00:29:17 3064 0 - - -
20 12:59:28 11947 0 13:14:02 11669 0 --- same as 18
18 >24h 16659 0 >24h 16484 0 --- solved it afterwards
17 00:41:03 2839 0 00:56:57 2841 0
16 00:34:15 550 0 02:21:09 3657 0
15 16:52:00 24420 0 17:30:02 20656 0 --- thanks alderwick for your help!
14 00:27:53 4878 0 01:07:47 3311 0
13 02:02:33 9507 0 02:19:53 9225 0 --- started late
12 01:57:59 7241 0 02:16:49 6447 0
11 00:46:21 4284 0 00:49:55 4145 0
10 00:19:04 4202 0 00:28:32 3347 0
9 00:12:52 2598 0 00:55:08 4504 0
8 00:06:26 580 0 01:02:03 2196 0
7 00:06:50 2657 0 00:12:29 2665 0
6 00:10:35 3339 0 00:36:30 4445 0
5 00:08:39 464 0 00:19:44 917 0
4 00:42:46 4241 0 00:45:01 3008 0
3 00:12:37 4213 0 00:38:29 3758 0
2 00:02:08 324 0 00:06:30 1842 0
1 00:03:11 1556 0 00:08:18 1774 0
```

13
12022/01/01.fnl Normal file
View File

@ -0,0 +1,13 @@
(io.input "input")
(var calories [0])
(each [line (io.lines)]
(if (= line "") (table.insert calories 0)
(let [i (length calories)]
(tset calories i (+ (tonumber line) (. calories i))))))
(table.sort calories (λ [a b] (> a b)))
(print "part 1" (. calories 1))
(print "part 2" (let [c calories] (+ (. c 1) (. c 2) (. c 3))))

47
12022/01/01.lua Normal file
View File

@ -0,0 +1,47 @@
io.input("test")
io.input("input")
calories = {0}
i = #calories
for line in io.lines() do
if line ~= "" then
calories[i] = calories[i] + tonumber(line)
else
table.insert(calories, 0)
i = #calories
end
end
max = 0
maxa, maxb, maxc = 0, 0, 0
for i, c in ipairs(calories) do
if c>max then
max = c
end
if c>maxa then
maxc = maxb
maxb = maxa
maxa = c
elseif c>maxb then
maxc = maxb
maxb = c
elseif c>maxc then
maxc = c
end
-- print(c)
end
part1 = maxa
part2 = maxa+maxb+maxc
assert(part1==71506)
assert(part2==209603)
print("part 1", part1)
print("part 2", part2)
-- using table.sort
table.sort(calories, function(a,b) return (a>b) end)
part1 = calories[1]
part2 = calories[1]+calories[2]+calories[3]
print("part 1", part1)
print("part 2", part2)

22
12022/01/01_copy.fnl Normal file
View File

@ -0,0 +1,22 @@
(io.input "input")
(local n 3)
(var max [0 0 0]) ; greatest is position 1, then 2, last 3
(var calories-sum 0)
(each [line (io.lines)]
(let [num (tonumber line)]
(if (not num)
(let [ s calories-sum
; count to how many "max" the new sum is greater than
greater-than
(accumulate [sum 0 _ m (ipairs max)] (+ sum (if (> s m) 1 0)))]
(set calories-sum 0)
(when (> greater-than 0)
(table.insert max (- (+ n 1) greater-than) s) ; insert new max
(table.remove max))) ; remove last element
(set calories-sum (+ calories-sum num)))))
(print "part 1" (. max 1))
(print "part 2" (accumulate [sum 0 _ m (ipairs max)] (+ sum m)))

14
12022/01/test Normal file
View File

@ -0,0 +1,14 @@
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000

28
12022/02/02.fnl Normal file
View File

@ -0,0 +1,28 @@
(io.input "input")
; rock, paper, scissors
(local own-scores-1 {:X 1 :Y 2 :Z 3})
(local game-scores {:X {:A 3 :B 0 :C 6}
:Y {:A 6 :B 3 :C 0}
:Z {:A 0 :B 6 :C 3}})
; lose, draw, win
(local own-scores-2 {:X 0 :Y 3 :Z 6})
(local game-moves {:X {:A 3 :B 1 :C 2}
:Y {:A 1 :B 2 :C 3}
:Z {:A 2 :B 3 :C 1}})
(var score-1 0)
(var score-2 0)
(each [line (io.lines)]
(let [(other you) (string.match line "(%a+) (%a)")
move-score (. own-scores-1 you)
round-score (. (. game-scores you) other)
own-score-2 (. own-scores-2 you)
move-score-2 (. (. game-moves you) other)]
(set score-1 (+ score-1 move-score round-score))
(set score-2 (+ score-2 own-score-2 move-score-2))))
(print "part 1" score-1)
(print "part 2" score-2)

25
12022/02/02.lua Normal file
View File

@ -0,0 +1,25 @@
io.input("test")
io.input("input")
-- Rock, paper, scisors
own_scores = { X=1, Y=2, Z=3 }
game_scores = { X = { A=3, B=0, C=6},
Y = { A=6, B=3, C=0},
Z = { A=0, B=6, C=3}}
-- lose, draw, win
own_scores_2 = { X=0, Y=3, Z=6 }
game_moves = { X = { A=3, B=1, C=2}, -- lose
Y = { A=1, B=2, C=3}, -- draw
Z = { A=2, B=3, C=1}} -- win
score = 0
score_2 = 0
for line in io.lines() do
other, you = string.match(line, "(%a+) (%a+)")
score = own_scores[you] + game_scores[you][other] + score
score_2 = own_scores_2[you] + game_moves[you][other] + score_2
-- print(you, own_scores[you], game_scores[you][other], other)
-- print(you, own_scores_2[you], game_moves[you][other], other)
end
print("part 1", score)
print("part 2", score_2)

3
12022/02/test Normal file
View File

@ -0,0 +1,3 @@
A Y
B X
C Z

52
12022/03/03.lua Normal file
View File

@ -0,0 +1,52 @@
io.input("test")
io.input("input")
function getPriority(c)
if c>='a' and c<='z' then
return string.byte(c) - string.byte('a') + 1
else
return string.byte(c) - string.byte('A') + 27
end
end
-- for part 1
local sum = 0
local linecount = 0
-- for part 2
local common = {}
local sumBadges = 0
for line in io.lines() do
local h = {}
local i = 0
local repeated = nil
for c in string.gmatch(line, "%a") do
-- part 1
if i<#line/2 then
h[c] = (h[c] or 0) + 1
elseif not repeated and h[c] then
repeated = c
end
i = i + 1
-- part 2
if linecount==0 then
common[c] = 1
elseif common[c] and linecount==1 then
common[c] = 2
elseif common[c]==2 then -- 2
common[c] = 3
sumBadges = sumBadges + getPriority(c)
end
end
-- part 1
local priority = getPriority(repeated)
sum = sum + priority
-- part 2
if linecount==2 then common = {} end
linecount = (linecount + 1)%3
end
print("part 1", sum)
print("part 2", sumBadges)

6
12022/03/test Normal file
View File

@ -0,0 +1,6 @@
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw

19
12022/04/04.fnl Normal file
View File

@ -0,0 +1,19 @@
(io.input "input")
(var sum1 0)
(var sum2 0)
(each [line (io.lines)]
(let [(a b c d) (string.match line "(%d+)-(%d+),(%d+)-(%d+)")
ri1 (tonumber a) rf1 (tonumber b)
ri2 (tonumber c) rf2 (tonumber d)]
(when (or (and (>= ri1 ri2) (<= rf1 rf2))
(and (>= ri2 ri1) (<= rf2 rf1)))
(set sum1 (+ sum1 1)))
(when (and (>= rf1 ri2) (<= ri1 rf2))
(set sum2 (+ sum2 1)))))
; (when (or (and (>= rf1 ri2) (<= ri1 ri2))
; (and (>= rf2 ri1) (<= ri2 ri1)))
; (set sum2 (+ sum2 1)))))
(print "part 1" sum1)
(print "part 2" sum2)

36
12022/04/04.lua Normal file
View File

@ -0,0 +1,36 @@
io.input("test")
io.input("input")
local sum = 0
local sum2 = 0
for line in io.lines() do
local ri1, rf1, ri2, rf2 = string.match(line, "(%d+)-(%d+),(%d+)-(%d+)")
ri1=tonumber(ri1)
rf1=tonumber(rf1)
ri2=tonumber(ri2)
rf2=tonumber(rf2)
--[[
local r = {}
for n in string.gmatch(line,"%d+") do
table.insert(r, tonumber(n))
end
local ri1=r[1]
local rf1=r[2]
local ri2=r[3]
local rf2=r[4]
]]
-- part 1
if (ri1>=ri2 and rf1<=rf2) or (ri2>=ri1 and rf2<=rf1) then
sum = sum + 1
end
-- part 2
if (rf1>=ri2 and ri1<=rf2) then-- or (rf2>=ri1 and ri2<=ri1) then
sum2 = sum2 + 1
-- print(ri1, rf1, ri2, rf2)
end
end
print("part 1", sum)
print("part 2", sum2)

19
12022/04/04_2.fnl Normal file
View File

@ -0,0 +1,19 @@
(io.input "input")
(var sum1 0)
(var sum2 0)
(each [line (io.lines)]
(let [pattern "(%d+)-(%d+),(%d+)-(%d+)"
[ri1 rf1 ri2 rf2]
(icollect [_ n (-> line (string.match pattern) (table.pack) (ipairs))]
; (-> ...) equivalent to:
; (ipairs (table.pack (string.match line pattern)))]
(tonumber n))]
(when (or (and (>= ri1 ri2) (<= rf1 rf2))
(and (>= ri2 ri1) (<= rf2 rf1)))
(set sum1 (+ sum1 1)))
(when (and (>= rf1 ri2) (<= ri1 rf2))
(set sum2 (+ sum2 1)))))
(print "part 1" sum1)
(print "part 2" sum2)

6
12022/04/test Normal file
View File

@ -0,0 +1,6 @@
2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8

74
12022/05/05.lua Normal file
View File

@ -0,0 +1,74 @@
io.input("test")
io.input("input")
stacks = {}
stacks2 = {}
instructions = {}
count = 0
function printStacks()
for i,stack in ipairs(stacks) do
local s = ""
for _,j in ipairs(stack) do
s = s .. j
end
print(i, s)
end
end
-- parsing
for line in io.lines() do
if string.find(line, "%[%a%]") then
local nstacks = #line//4 + 1 -- 1 5 9
for i = 1,nstacks do
if count == 0 then
stacks[i] = {}
stacks2[i] = {}
end
local index = 1 + (i-1)*4 -- 1, 5, 9
local s = string.sub(line, index, index+3)
local t = string.match(s, "%[(%a)%]")
table.insert( stacks[i], 1, t )
table.insert( stacks2[i], 1, t )
end
elseif string.find(line, "^move") then
local pattern = "^move (%d+) from (%d+) to (%d+)$"
local tt = table.pack(string.match(line, pattern))
local t = {}
for j, v in ipairs(tt) do t[j] = tonumber(v) end
table.insert(instructions, t)
end
count = count + 1
end
-- moves
for i, t in ipairs(instructions) do
q, src, dst = table.unpack(t)
-- part 1
for n = 1,q do
local crate = table.remove( stacks[src] )
table.insert( stacks[dst], crate )
end
-- part 2
local crates = {}
for n = 1,q do
crates[q-n+1] = table.remove( stacks2[src] )
end
for n = 1,q do
table.insert( stacks2[dst], crates[n] )
end
end
-- result
local result = ""
for _, stack in ipairs(stacks) do
result = result .. stack[#stack]
end
print("part 1", result)
result = ""
for _, stack in ipairs(stacks2) do
result = result .. stack[#stack]
end
print("part 2", result)

63
12022/05/05_part2.lua Normal file
View File

@ -0,0 +1,63 @@
io.input("test")
io.input("input")
stacks = {}
instructions = {}
count = 0
function printStacks()
for i,stack in ipairs(stacks) do
local s = ""
for _,j in ipairs(stack) do
s = s .. j
end
print(i, s)
end
end
-- parsing
for line in io.lines() do
if string.find(line, "%[%a%]") then
local nstacks = #line//4 + 1 -- 1 5 9
print(nstacks)
for i = 1,nstacks do
if count == 0 then
stacks[i] = {}
end
local index = 1 + (i-1)*4 -- 1, 5, 9
local s = string.sub(line, index, index+3)
local t = string.match(s, "%[(%a)%]")
table.insert( stacks[i], 1, t )
end
elseif string.find(line, "^move") then
local pattern = "^move (%d+) from (%d+) to (%d+)$"
local t = table.pack(string.match(line, pattern))
table.insert(instructions,t)
end
count = count + 1
end
-- moves
for i, t in ipairs(instructions) do
local tt = {}
for j, v in ipairs(t) do tt[j] = tonumber(v) end
q, src, dst = table.unpack(tt)
local crates = {}
for n = 1,q do
crates[q-n+1] = table.remove( stacks[src] )
end
for n = 1,q do
table.insert( stacks[dst], crates[n] )
end
end
printStacks()
-- result
local result = ""
for _, stack in ipairs(stacks) do
result = result .. stack[#stack]
end
print("part 2", result)

9
12022/05/test Normal file
View File

@ -0,0 +1,9 @@
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2

16
12022/06/06.fnl Normal file
View File

@ -0,0 +1,16 @@
(io.input "test")
(λ repeats [s]
(let [chars {}]
(for [i 1 (length s)]
(let [c (string.sub s i i)]
(if (. chars c) true (tset chars c true)))))
false)
(λ end-of-marker [s n]
(for [i 1 (length s)]
(let [window (string.sub s i (+ i (- n 1)))]
(print window))))
(end-of-marker (io.read "a") 4)
(print (repeats "aacd"))

25
12022/06/06.lua Normal file
View File

@ -0,0 +1,25 @@
io.input("test")
io.input("input")
local s = io.read("a")
function endOfMarker( n ) -- n is the window size
local i=1
repeat
local window = string.sub(s,i,i+n-1)
local repeats = false
local chars = {}
for j=1,n do
local c = string.sub(window,j,j)
if chars[c] then
repeats = true
break
else chars[c] = true
end
end
i = i + 1
until not repeats or i>#s
return i+n-2
end
print("part 1", endOfMarker(4))
print("part 2", endOfMarker(14))

1
12022/06/test Normal file
View File

@ -0,0 +1 @@
mjqjpqmgbljsphdztnvjfqwrcgsmlb

92
12022/07/07.lua Normal file
View File

@ -0,0 +1,92 @@
io.input("test")
io.input("input")
function createDir( dirname )
return { name = dirname, children = {}, localsize = 0}
end
function insertDirIntoWD( dirname )
-- if it already exists, return it
for _, d in ipairs( wd.children ) do
if d.name == dirname then return d end
end
-- print("inserting", dirname, "into", wd.name)
-- create it otherwise
local newdir = createDir(dirname)
table.insert( wd.children, newdir )
table.insert( dirs, newdir )
return newdir
end
-- initialize
root = createDir("/")
dirs = {root}
stack = {root}
wd = root -- working directory
local listing = false
for line in io.lines() do
if listing then
if string.find(line, "^%$") then
listing = false
else -- listing
local pattern = "^(.+) (.+)$"
local info, name = string.match( line, pattern )
if info == "dir" then
insertDirIntoWD( name )
else -- file
local size = tonumber(info)
wd.localsize = wd.localsize + size
end
end
end -- if listing
if not listing then
if string.find(line, "^%$ ls") then
listing = true
else -- change directory
local dirname = string.match(line, "^%$ cd (.+)$")
if dirname == "/" then
wd = root
stack = {root}
elseif dirname == ".." then
wd = table.remove( stack ) -- pop from stack
else -- go to named dir
table.insert( stack, wd ) -- push wd into stack
wd = insertDirIntoWD( dirname )
end -- if dirname
end -- if $ ls
end -- if not listing
end -- for line
function totalSize( dir )
local sum = dir.localsize
for i, d in ipairs( dir.children ) do
sum = sum + totalSize( d )
end
return sum
end
-- part 1
local result1 = 0
-- part 2
local total = totalSize(dirs[1])
local unused = 70000000 - total
local needed = 30000000 - unused
local minGreaterThanNeeded = total
for i, d in ipairs(dirs) do
local size = totalSize(d)
-- part 1
if size <= 100000 then
result1 = result1 + size
end
-- part 2
if size >= needed and size < minGreaterThanNeeded then
minGreaterThanNeeded = size
end
end
print("part 1", result1)
print("part 2", minGreaterThanNeeded)

94
12022/07/07_upgrade.lua Normal file
View File

@ -0,0 +1,94 @@
io.input("test")
io.input("input")
function createDir( dirname )
return { name = dirname, children = {}, localsize = 0 }
end
function insertDirIntoWD( dirname )
-- if it already exists, return it
for _, d in ipairs( wd.children ) do
if d.name == dirname then return d end
end
-- print("inserting", dirname, "into", wd.name)
-- create it otherwise
local newdir = createDir(dirname)
table.insert( wd.children, newdir )
table.insert( dirs, newdir )
return newdir
end
-- initialize
root = createDir("/")
dirs = {root}
stack = {root}
wd = root -- working directory
local listing = false
for line in io.lines() do
if listing then
if string.find(line, "^%$") then
listing = false
else -- listing
local pattern = "^(.+) (.+)$"
local info, name = string.match( line, pattern )
if info == "dir" then
insertDirIntoWD( name )
else -- file
local size = tonumber(info)
wd.localsize = wd.localsize + size
end
end
end -- if listing
if not listing then
if string.find(line, "^%$ ls") then
listing = true
else -- change directory
local dirname = string.match(line, "^%$ cd (.+)$")
if dirname == "/" then
wd = root
stack = {root}
elseif dirname == ".." then
wd = table.remove( stack ) -- pop from stack
else -- go to named dir
table.insert( stack, wd ) -- push wd into stack
wd = insertDirIntoWD( dirname )
end -- if dirname
end -- if $ ls
end -- if not listing
end -- for line
function totalSize( dir )
if dir.totalsize then return dir.totalsize end
local sum = dir.localsize
for i, d in ipairs( dir.children ) do
sum = sum + totalSize( d )
end
dir.totalsize = sum
return sum
end
-- part 1
local result1 = 0
-- part 2
local total = totalSize(dirs[1])
local unused = 70000000 - total
local needed = 30000000 - unused
local minGreaterThanNeeded = total
for i, d in ipairs(dirs) do
local size = totalSize(d)
-- part 1
if size <= 100000 then
result1 = result1 + size
end
-- part 2
if size >= needed and size < minGreaterThanNeeded then
minGreaterThanNeeded = size
end
end
print("part 1", result1)
print("part 2", minGreaterThanNeeded)

25
12022/07/test Normal file
View File

@ -0,0 +1,25 @@
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k
$ cd ..
$ cd a

98
12022/08/08.lua Normal file
View File

@ -0,0 +1,98 @@
io.input("test")
io.input("input")
function addTree( r, c, height )
local visible = nil
if r==1 or c==1 or r==n or c==n then
visible = true
end
local tree = { h = height, v = visible, s = 1 }
trees[r][c] = tree
return tree
end
trees = {}
n = 0
local row = 1
for line in io.lines() do
n = #line
local col = 1
trees[row] = {}
for height in string.gmatch(line, "%d") do
local tree = addTree( row, col, height )
if row>1 and col>1 then
local allLess = true
local s = 0
for r=row-1,1,-1 do
s = s+1
if trees[r][col].h >= tree.h then
allLess = false
break
end
end
if allLess then tree.v = true end
tree.s = s*tree.s
allLess = true
s = 0
for c=col-1,1,-1 do
s = s + 1
if trees[row][c].h >= tree.h then
allLess = false
break
end
end
if allLess then tree.v = true end
tree.s = s*tree.s
end
col = col + 1
end
row = row + 1
end
-- second pass, other direction
for row = n-1, 2, -1 do
for col = n-1, 2, -1 do
local tree = trees[row][col]
local allLess = true
local s = 0
for r=row+1,n do
s = s + 1
if trees[r][col].h >= tree.h then
allLess = false
break
end
end
if allLess then tree.v = true end
tree.s = tree.s*s
allLess = true
s = 0
for c=col+1,n do
s = s + 1
if trees[row][c].h >= tree.h then
allLess = false
break
end
end
if allLess then tree.v = true end
tree.s = tree.s*s
end
end
local sum = 0
local maxscore = 0
for i, row in ipairs(trees) do
for j, tree in ipairs(row) do
-- part 1
if tree.v then sum = sum + 1 end
-- part 2
if tree.s > maxscore and i>1 and i<n and j>1 and j<n then
maxscore = tree.s
end
end
end
print("part 1", sum )
print("part 2", maxscore )

5
12022/08/test Normal file
View File

@ -0,0 +1,5 @@
30373
25512
65332
33549
35390

56
12022/09/09.lua Normal file
View File

@ -0,0 +1,56 @@
io.input("test")
io.input("input")
function pos2index( pos )
return pos.x*10000 + pos.y
end
function constrain( n, min, max )
local min = min or -1
local max = max or 1
if n < min then return min
elseif n > max then return max
else return n
end
end
local head = { x=1, y=1 }
local tail = { x=1, y=1 }
local visited = { [pos2index(tail)] = true }
for line in io.lines() do
local dir, q = string.match(line, "^(%a) (%d+)$")
q = tonumber(q)
for step = 1,q do
if dir == "R" then
head.x = head.x + 1
elseif dir == "L" then
head.x = head.x - 1
elseif dir == "U" then
head.y = head.y + 1
elseif dir == "D" then
head.y = head.y - 1
end
local dif = { x=head.x-tail.x, y=head.y-tail.y }
if dif.x == 0 and math.abs(dif.y) > 1 then
tail.y = tail.y + constrain(dif.y)
elseif dif.y == 0 and math.abs(dif.x) > 1 then
tail.x = tail.x + constrain(dif.x)
elseif math.abs(dif.x)>1 or math.abs(dif.y)>1 then
tail.y = tail.y + constrain(dif.y)
tail.x = tail.x + constrain(dif.x)
end
print( tail.x, tail.y, head.x, head.y, dif.x, dif.y)
visited[ pos2index(tail) ] = true
end
end
local result = 0
for k, v in pairs(visited) do
print(k)
result = result + 1
end
print("part 1", result)

89
12022/09/09_2.lua Normal file
View File

@ -0,0 +1,89 @@
io.input("test2")
io.input("input")
function pos2index( pos )
return pos.x*10000 + pos.y
end
function constrain( n, min, max )
-- returns converted n, and if it was converted
local min = min or -1
local max = max or 1
if n < min then return min, true
elseif n > max then return max, true
else return n, false
end
end
local head = { x=1, y=1 }
local n = 9
local tail = {}
for i=1,n do tail[i] = { x=1, y=1 } end
local visitedP1 = { [pos2index(tail[1])] = true }
local visitedP2 = { [pos2index(tail[n])] = true }
local resultP1 = 1
local resultP2 = 1
for line in io.lines() do
local dir, q = string.match(line, "^(%a) (%d+)$")
q = tonumber(q)
for step = 1,q do
if dir == "R" then
head.x = head.x + 1
elseif dir == "L" then
head.x = head.x - 1
elseif dir == "U" then
head.y = head.y + 1
elseif dir == "D" then
head.y = head.y - 1
end
-- loop through tails
for i=1,n do
local h = head
if i>1 then h = tail[i-1] end
local t = tail[i]
local dif = { x=h.x-t.x, y=h.y-t.y }
-- gx, gy indicate if the abs diff was greater than 1
local dx, gx = constrain(dif.x)
local dy, gy = constrain(dif.y)
if dif.x == 0 and gy then -- vertical
t.y = t.y + dy
elseif dif.y == 0 and gx then -- horizontal
t.x = t.x + dx
elseif gx or gy then -- diagonal further away
t.y = t.y + dy
t.x = t.x + dx
end
end
-- part 1
local index = pos2index(tail[1])
if not visitedP1[index] then
visitedP1[index] = true
resultP1 = resultP1 + 1
end
-- part 2
local index = pos2index(tail[n])
if not visitedP2[index] then
visitedP2[index] = true
resultP2 = resultP2 + 1
end
-- visitedP1[ pos2index(tail[1]) ] = true
-- visitedP2[ pos2index(tail[n]) ] = true
end
end
print("part 1", resultP1)
print("part 2", resultP2)
local result = 0
for k, v in pairs(visitedP1) do
result = result + 1
end
print("part 1", result, resultP1)
local result = 0
for k, v in pairs(visitedP2) do
result = result + 1
end
print("part 2", result, resultP2)

Some files were not shown because too many files have changed in this diff Show More