123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875 |
- #!/usr/bin/python3
- import sys
- #i love aocd.
- from aocd import get_data
- from aocd import submit
- ### SHORTCUTS
- def intify(str_list):
- """
- Takes a list of stings that are assumed to refer to integers and returns a list of integers.
- """
- return [int(item) for item in str_list]
- ### REFS
- values = { # i'm not sorry for this at all.
- 'a':1,
- 'b':2,
- 'c':3,
- 'd':4,
- 'e':5,
- 'f':6,
- 'g':7,
- 'h':8,
- 'i':9,
- 'j':10,
- 'k':11,
- 'l':12,
- 'm':13,
- 'n':14,
- 'o':15,
- 'p':16,
- 'q':17,
- 'r':18,
- 's':19,
- 't':20,
- 'u':21,
- 'v':22,
- 'w':23,
- 'x':24,
- 'y':25,
- 'z':26,
- 'A':27,
- 'B':28,
- 'C':29,
- 'D':30,
- 'E':31,
- 'F':32,
- 'G':33,
- 'H':34,
- 'I':35,
- 'J':36,
- 'K':37,
- 'L':38,
- 'M':39,
- 'N':40,
- 'O':41,
- 'P':42,
- 'Q':43,
- 'R':44,
- 'S':45,
- 'T':46,
- 'U':47,
- 'V':48,
- 'W':49,
- 'X':50,
- 'Y':51,
- 'Z':52,
- }
- ### DAYS
- def day_one_solver():
- """
- Returns the answer for day 1.
- """
- loads = day_one_processor(get_data(day=1, year=2022).split("\n"))
- p1 = loads[-1]
- p2 = loads[-1] + loads[-2] + loads[-3]
- return p1, p2
- def day_one_processor(input):
- """
- Returns an int list of summed up pack loads.
- """
- loads = []
- load = 0
- for x in input:
- if x:
- load = load + int(x)
- else:
- loads.append(load)
- load = 0
- loads.sort()
- return loads
- def day_two_solver():
- """
- Returns the answer for day 2.
- """
- sample = ["A Y", "B X", "C Z"]
- data = get_data(day=2, year=2022).split("\n")
- return day_two_processor_a(data), day_two_processor_b(data)
- def day_two_processor_a(input):
- """
- Day 2 part A processor. I'm sure there's a tidier way to write this, but I
- did this fast.
- """
- score = 0
- for x in input:
- (elf, you)= x.split()
- if you == "X":
- score = score + 1
- if elf == "C":
- score = score + 6
- elif elf == "A":
- score = score + 3
- elif you == "Y":
- score = score + 2
- if elf == "A":
- score = score + 6
- elif elf == "B":
- score = score + 3
- else:
- score = score + 3
- if elf == "B":
- score = score + 6
- elif elf == "C":
- score = score + 3
- return score
- def day_two_processor_b(input):
- """
- Day 2 part B processor; yeah, naive.
- """
- score = 0
- for x in input:
- (elf, you)= x.split()
- if you == "X":
- if elf == "C":
- score = score + 2
- elif elf == "A":
- score = score + 3
- else:
- score = score + 1
- elif you == "Y":
- score = score + 3
- if elf == "A":
- score = score + 1
- elif elf == "B":
- score = score + 2
- else:
- score = score + 3
- else:
- score = score + 6
- if elf == "B":
- score = score + 3
- elif elf == "C":
- score = score + 1
- else:
- score = score + 2
- return score
- def day_three_solver():
- """
- Returns the answer for day 3.
- """
- sample = ["vJrwpWtwJgWrhcsFMMfFFhFp",
- "jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL",
- "PmmdzqPrVvPwwTWBwg",
- "wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn",
- "ttgJtRGJQctTZtZT",
- "CrZsJsPPZsGzwwsLwLmpwMDw"]
- data = get_data(day=3, year=2022).split("\n")
- p1 = day_three_processor_a(data)
- p2 = day_three_processor_b(data)
- return p1, p2
- def day_three_processor_a(input):
- score = 0
- for x in input:
- dup = ""
- items = list(x)
- half = int(len(items)/2)
- for y in items[0:half]:
- if y in items[half:]:
- dup = y
- score = score + values.get(dup)
- return score
- def day_three_processor_b(input):
- """
- weeee iterating
- """
- score = 0
- index = 0
- count = 3
- for x in input:
- if count % 3 == 0:
- dup = ""
- items = list(x)
- for y in items:
- if y in list(input[index+1]) and y in list(input[index+2]):
- dup = y
- print(dup)
- score = score + values.get(dup)
- index = index + 1
- count = count + 1
- else:
- index = index + 1
- count = count + 1
- continue
- return score
- def day_four_solver():
- """
- Returns the answer for day 4.
- """
- sample = ["2-4,6-8", "2-3,4-5", "5-7,7-9", "2-8,3-7", "6-6,4-6", "2-6,4-8"]
- data = get_data(day=4, year=2022).split("\n")
- p1 = day_four_processor_a(data)
- p2 = day_four_processor_b(data)
- return p1, p2
- def day_four_processor_a(input):
- """
- do you know how long i took me to realize i forgot to intify and was
- comparing strings, python, is very dirty
- """
- ans = 0
- for pair in input:
- pairs = pair.split(",")
- a = intify(pairs[0].split("-"))
- b = intify(pairs[1].split("-"))
- if a[0] >= b[0] and a[0] <= b[1]:
- if a[1] <= b[1]:
- ans = ans +1
- elif a[0] == b[0]:
- if b[1] <= a[1]:
- ans = ans +1
- elif b[0] >= a[0] and b[0] <= a[1]:
- if b[1] <= a[1]:
- ans = ans +1
- return ans
- def day_four_processor_b(input):
- """
- wow this took me a lot of staring before i realized it was totally trivial.
- """
- ans = 0
- for pair in input:
- pairs = pair.split(",")
- a = intify(pairs[0].split("-"))
- b = intify(pairs[1].split("-"))
- if a[0] >= b[0] and a[0] <= b[1]:
- ans = ans +1
- elif b[0] >= a[0] and b[0] <= a[1]:
- ans = ans +1
- return ans
- def day_five_solver():
- """
- today i was like, fuck it, i'm not parsing that shit, and hand-typed in all
- the stacks. this means i cannot trivially repeat this with other input
- without looking at it and hand-typing and hardcoding in slices.
- one of those days where implementing part b is actually more
- straightforward for me than part a, but probably because i did all the work
- in a way that made it easily reused.
- did a couple passes on tidying up the code after submission. i could do the
- honorable thing and write out a full input parser for my own health, but
- also, the star awarding doesn't care how you get the right answer, and i
- have only so many minutes in my life.
- """
- s_data = """ [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""".split("\n")[5:]
- s_stack = ["ZN", "MCD", "P"]
- data = get_data(day=5, year=2022).split("\n")[10:]
- stack = ["VCDRZGBW", "GWFCBSTV", "CBSNW", "QGMNJVCP", "TSLFDHB", "JVTWMN",
- "PFLCSTG", "BDZ", "MNZW"]
- p1, p2 = "",""
- codes = get_instructions(data)
- for x in codes: # instructions are 1-indexed
- stack = crane_it_a(x[0], x[1]-1, x[2]-1, stack)
- for x in stack:
- p1 += x[-1]
- ## reset the stack for part b WAIT WHY DO I SOMETIMES SAY PART B AND
- ## SOMETIMES SAY P2
- stack = ["VCDRZGBW", "GWFCBSTV", "CBSNW", "QGMNJVCP", "TSLFDHB", "JVTWMN",
- "PFLCSTG", "BDZ", "MNZW"]
- for x in codes: # lol watch your off-by-ones
- stack = crane_it_b(x[0]-1, x[1]-1, x[2]-1, stack)
- for x in stack:
- p2 += x[-1]
- return p1, p2
- def get_instructions(data):
- """
- just parsing out the instructions and returning a list of integers
- """
- codes = []
- for line in data:
- ins = line.split(" ")
- codes.append(intify([ins[1], ins[3], ins[5]]))
- return codes
- def crane_it_a(reps, start, end, stack):
- """
- im still so proud of myself for knowing how to do a good recurse!!!
- """
- if reps > 0:
- stack[end] += stack[start][-1]
- stack[start] = stack[start][0:-1]
- return crane_it_a(reps-1, start, end, stack)
- return stack
- def crane_it_b(reps, start, end, stack):
- """
- so boring no recusion
- """
- stack[end] += stack[start][-1-reps:]
- stack[start] = stack[start][0:-1-reps]
- return stack
- def day_six_solver():
- """
- wow this was....very easy???? had to swat some typos for p2 because i'm
- sreepy.
- did a quick pass to tidy up the processor.
- """
- s_data = "mjqjpqmgbljsphdztnvjfqwrcgsmlb"
- s_data2 = "bvwbjplbgvbhsrlpgdmjqwftvncz"
- data = get_data(day=6, year=2022)
- p1, p2 = "",""
- p1 = day_six_processor(data, 4)
- p2 = day_six_processor(data, 14)
- return p1, p2
- def day_six_processor(input, length):
- ans = 0
- a = 0
- b = length
- for i in range (len(input)-length-1):
- chunk = input[a:b]
- if len(set(chunk)) == length:
- return i+length
- a += 1
- b += 1
- return ans
- def day_seven_solver():
- """
- oh my god parser hell
- i got stuck on p2 all day because i was returning the name of the directory
- and not the size. oops.
- did a little cleanup post-star.
- """
- s_data = """$ 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""".split("\n")
- data = get_data(day=7, year=2022).split("\n")
- p1, p2 = "",""
- root, all_dirs = day_seven_parser(data)
- p1 = day_seven_processor_a(all_dirs)
- p2 = day_seven_processor_b(root, all_dirs)
- return p1, p2
- class Directory:
- def __init__(self, name):
- self.name = name
- self.dirs = {}
- self.size = 0
- def add_file(self, filesize):
- self.size += filesize
- def add_dir(self, dir_name, dir):
- self.dirs.update({dir_name: dir})
- def get_size(self):
- return self.size
- def get_name(self):
- return self.name
- def get_dir(self, dir_name):
- return self.dirs.get(dir_name)
- def day_seven_parser(input):
- home = Directory("root")
- here = home
- last = []
- all_dirs = []
- for i in range(len(input) - 1):
- line = input[i]
- if line[0] == "$":
- cmd = line.split(" ")[1:]
- if cmd[0] == "ls":
- ls = []
- ## slurp up all the ls output
- for j in range(i+1, len(input)):
- if input[j][0] != "$":
- ls.append(input[j])
- else:
- break
- for item in ls:
- if item[0] == 'd':
- dir = item.split(" ")[1]
- new = Directory(dir)
- here.add_dir(dir, new)
- all_dirs.append(new)
- else:
- filesize = int(item.split(" ")[0])
- here.add_file(filesize)
- for parent in last:
- parent.add_file(filesize)
- elif cmd[0] == "cd":
- if cmd[1] == "..":
- here = last.pop()
- elif cmd[1] == "/":
- here = home
- last = []
- else:
- last.append(here)
- here = here.get_dir(cmd[1])
- return home, all_dirs
- def day_seven_processor_a(all_dirs):
- ans = 0
- for x in all_dirs:
- a = x.get_size()
- if x.get_size() <= 100000:
- ans += x.get_size()
- return ans
- def day_seven_processor_b(root, all_dirs):
- disk = 70000000
- needed = 30000000
- free = disk - root.get_size()
- delta = needed - free
- curr = disk
- for x in all_dirs:
- a = x.get_size()
- if a >= delta:
- if a < curr:
- curr = a
- return curr
- def day_eight_solver():
- """
- whew finicky matrix shit.
- """
- s_data = """30373
- 25512
- 65332
- 33549
- 35390""".split("\n")
- data = get_data(day=8, year=2022).split("\n")
- p1, p2 = "",""
- p1 = day_eight_processor_a(data)
- p2 = day_eight_processor_b(data)
- return p1, p2
- def day_eight_processor_a(data):
- grid = []
- for line in data:
- grid.append(intify(list(line)))
- visible = len(grid[0]) * 2 + len(grid) * 2 - 4
- for row in range(1, len(grid[0])-1):
- x = list(grid[row])
- for column in range(1, len(x)-1):
- y = list(x)[column]
- if is_visible(row, column, grid):
- visible += 1
- return visible
- def is_visible(row, column, grid):
- this = grid[row][column]
- ans = False
- for i in range(0, row):
- if grid[i][column] >= this:
- ans = False
- break
- else:
- ans = True
- if ans:
- return True
- for i in range(row+1, len(grid[row])):
- if grid[i][column] >= this:
- ans = False
- break
- else:
- ans = True
- if ans:
- return True
- for i in range(0, column):
- if grid[row][i] >= this:
- ans = False
- break
- else:
- ans = True
- if ans:
- return True
- for i in range(column+1, len(grid)):
- if grid[row][i] >= this:
- ans = False
- break
- else:
- ans = True
- return ans
- def day_eight_processor_b(data):
- grid = []
- for line in data:
- grid.append(intify(list(line)))
- best = 0
- for row in range(1, len(grid[0])-1):
- x = list(grid[row])
- for column in range(1, len(x)-1):
- y = list(x)[column]
- score = calc_score(row, column, grid)
- if score > best:
- best = score
- return best
- def calc_score(row, column, grid):
- this = grid[row][column]
- (u, d, l, r) = 0, 0, 0, 0,
- for i in range(row-1, -1, -1): # UP
- u += 1
- if grid[i][column] >= this:
- break
- for i in range(row+1, len(grid[row])): # DOWN
- d += 1
- if grid[i][column] >= this:
- break
- for i in range(column-1, -1, -1): # LEFT
- l += 1
- if grid[row][i] >= this:
- break
- for i in range(column+1, len(grid)): # RIGHT
- r += 1
- if grid[row][i] >= this:
- break
- return u * d * l * r
- def day_nine_solver():
- """
- """
- s_data = """R 4
- U 4
- L 3
- D 1
- R 4
- D 1
- L 5
- R 2""".split("\n")
- data = get_data(day=9, year=2022).split("\n")
- p1, p2 = "",""
- p1 = day_nine_processor_a(data)
- #p2 = day_nine_processor_b(data)
- return p1, p2
- def day_nine_processor_a(data):
- visited = []
- H = (0,0)
- T = (0,0)
- for inst in data:
- print(inst)
- dir, steps = inst.split(" ")
- ## process head movement
- for x in range(0, int(steps)):
- if dir == "U":
- H = (H[0]+1, H[1])
- if dir == "D":
- H = (H[0]-1, H[1])
- if dir == "L":
- H = (H[0], H[1]-1)
- if dir == "R":
- H = (H[0], H[1]+1)
- print("before scoots")
- print("H: {}".format(H))
- print("T: {}".format(T))
- ## process tail movement
- if T not in visited:
- visited.append(T)
- if T == H:
- print("overlap")
- continue
- elif T[0] == H[0] and abs(T[1] - H[1]) == 1:
- print("adjacent")
- continue
- elif T[1] == H[1] and abs(T[0] - H[0]) == 1:
- print("adjacent")
- continue
- elif abs(T[0] - H[0]) == 1 and abs(T[1] - H[1]) == 1:
- print("kitty")
- elif T[0] == H[0]:
- ## LR scoots
- print("LR scoot")
- if H[1] > T[1]:
- ## scoot right
- T = (T[0], T[1] + 1)
- else:
- ## scoot left
- T = (T[0], T[1] - 1)
- elif T[1] == H[1]:
- ## UD scoots
- print("UD scoot")
- if H[0] > T[0]:
- ## scoot up
- T = (T[0] + 1, T[1])
- else:
- ## scoot down
- T = (T[0] - 1, T[1])
- else:
- ## diagonal scoots
- print("diagonal scoot")
-
- if (H[0] - T[0]) > 1:
- if H[1] > T[1]:
- ## scoot UR
- T = (T[0] + 1, T[1] + 1)
- else:
- ## scoot DR
- T = (T[0] + 1, T[1] - 1)
- elif (H[0] - T [0]) < 1:
- if H[1] > T[1]:
- ## scoot UL
- T = (T[0] - 1, T[1] + 1)
- else:
- ## scoot DL
- T = (T[0] - 1, T[1] - 1)
- elif (H[1] - T [1]) > 1:
- if H[0] > T[0]:
- ## scoot UR
- T = (T[0] + 1, T[1] + 1)
- else:
- ## scoot UL
- T = (T[0] - 1, T[1] + 1)
- elif (H[1] - T [1]) < 1:
- if H[0] > T[0]:
- ## scoot DR
- T = (T[0] + 1, T[1] - 1)
- else:
- ## scoot DL
- T = (T[0] - 1, T[1] - 1)
- print("after scoots")
- print("H: {}".format(H))
- print("T: {}".format(T))
- print(visited)
- return len(visited)
- def day_nine_processor_b(data):
- return 0
- if __name__ == '__main__':
- #day1 = day_one_solver()
- #print("day 01: {}".format(day1))
- #submit(day1[0], part="a", day=1, year=2022)
- #submit(day1[1], part="b", day=1, year=2022)
- #day2 = day_two_solver()
- #print("day 02: {}".format(day2))
- #submit(day2[0], part="a", day=2, year=2022)
- #submit(day2[1], part="b", day=2, year=2022)
- #day3 = day_three_solver()
- #print("day 03: {}".format(day3))
- #submit(day3[0], part="a", day=3, year=2022)
- #submit(day3[1], part="b", day=3, year=2022)
- #day4 = day_four_solver()
- #print("day 04: {}".format(day4))
- #submit(day4[0], part="a", day=4, year=2022)
- #submit(day4[1], part="b", day=4, year=2022)
- #day5 = day_five_solver()
- #print("day 05: {}".format(day5))
- #submit(day5[0], part="a", day=5, year=2022)
- #submit(day5[1], part="b", day=5, year=2022)
- #day6 = day_six_solver()
- #print("day 06: {}".format(day6))
- #submit(day6[0], part="a", day=6, year=2022)
- #submit(day6[1], part="b", day=6, year=2022)
- #day7 = day_seven_solver()
- #print("day 07: {}".format(day7))
- #submit(day7[0], part="a", day=7, year=2022)
- #submit(day7[1], part="b", day=7, year=2022)
- #day8 = day_eight_solver()
- #print("day 08: {}".format(day8))
- #submit(day8[0], part="a", day=8, year=2022)
- #submit(day8[1], part="b", day=8, year=2022)
- day9 = day_nine_solver()
- print("day 09: {}".format(day9))
- submit(day9[0], part="a", day=9, year=2022)
- #submit(day9[1], part="b", day=9, year=2022)
|