Jelajahi Sumber

Solve 2022 day 5 part 2

Jonatan Gezelius 3 tahun lalu
induk
melakukan
6a4cda4635
1 mengubah file dengan 96 tambahan dan 0 penghapusan
  1. 96 0
      2022/05/b.py

+ 96 - 0
2022/05/b.py

@@ -0,0 +1,96 @@
+import os, argparse, re
+
+def solve_task(lines):
+    # Extract the initial stacks and instructions from the input
+    (stacks, raw_instructions) = load_stacks(lines)
+
+    #print(f"Stacks: {stacks}\n")
+    #print(f"Instructions: {raw_instructions}")
+    #display_stacks(stacks)
+
+    # Parse the instructions into a list of tuples
+    packed_instructions = pack_instructions(raw_instructions)
+    #print(f"Packed: {packed_instructions}")
+
+    # Perform all instructions
+    for instruction in packed_instructions:
+        perform_instruction(stacks, instruction)
+        #display_stacks(stacks)
+
+    # Get the answer by getting the uppermost (last) element of
+    # each stack. This way has side effects, but we won't need
+    # to preserve the stacks past this line.
+    answer = []
+    for s in stacks:
+        if len(s) != 0:
+            answer.append(s[-1])
+    print("Final answer: " + ''.join(answer))
+
+def display_stacks(stacks):
+    print("Current stacks:")
+    for stack in stacks:
+        print(''.join(stack))
+
+def perform_instruction(stacks, instruction):
+    quantity = int(instruction[0])
+    source = int(instruction[1]) - 1
+    destination = int(instruction[2]) - 1
+
+    # Since lists are mutable, we can manipulate the supplied lists
+    # instead of returning new ones
+    stacks[destination].extend(stacks[source][-quantity:])
+    del stacks[source][-quantity:]
+
+def pack_instructions(instr):
+    # Return a list of instruction-tuples
+    return [get_instruction_tuple(i) for i in instr]
+    
+def get_instruction_tuple(intr_line):
+    # Returns a tuple with three values (quantity, source, destination)
+    m = re.match("move (\d+) from (\d+) to (\d+)", intr_line)
+    return (m.group(1), m.group(2), m.group(3))
+
+def load_stacks(lines):
+    number_of_piles = (len(lines[0])+1)//4
+    piles = [[] for x in range(number_of_piles)]
+    instructions_start_line = 0
+    for linum in range(len(lines)):
+        line = lines[linum]
+        for col in range(len(line)):
+            c = line[col]
+            if col % 4 != 1 or c == ' ':
+                continue
+            if c == '1':
+                instructions_start_line = linum+2
+                break
+            pile = col // 4
+            piles[pile].insert(0, c)
+
+        if instructions_start_line != 0:
+            break
+    return (piles, lines[instructions_start_line:])
+
+
+def read_lines(filename):
+    lines = []
+    with open(filename) as infile:
+        for raw_line in infile:
+            line = raw_line.replace('\n', '')
+            line = line.replace('\r', '')
+            #line = raw_line.rstrip() # Usefull to keep space in this task
+            lines.append(line)
+    return lines
+
+def parse_arguments():
+    parser = argparse.ArgumentParser(description="Script that solves the case",epilog="Have a nice day!")
+    parser.add_argument('filename', nargs='?', default="example.txt", help='Input file')
+    args = parser.parse_args()
+    return args
+
+def main():
+    args = parse_arguments()
+    lines = read_lines(args.filename)
+    solve_task(lines)
+
+if __name__ == "__main__":
+    main()