Callista Krebs

Home Projects Contact

Advent of Code - Day 6

< Prev Day Next Day >

Part 1

My Code

import copy

with open("day6.txt") as f:
    map = f.read().split("\n")
    map = [list(row) for row in map]

    route = copy.deepcopy(map)
    
    for i in range(len(map)):
        for j in range(len(map[i])):
            if map[i][j] == "^":
                start = (i,j)
                route[i][j] = "X"
 
    i, j = start
    curr_direction = "up"
    count = 0
    while i < len(map) and j < len(map[i]) and i >= 0 and j >= 0:
        if map[i][j] == "#":
            if curr_direction == "up":
                i += 1
                curr_direction = "right"
            elif curr_direction == "right":
                j -= 1
                curr_direction = "down"
            elif curr_direction == "down":
                i -= 1
                curr_direction = "left"
            elif curr_direction == "left":
                j += 1
                curr_direction = "up"
        else:
            route[i][j] = "X"
        
        if curr_direction == "up":
            i -= 1
        if curr_direction == "down":
            i += 1
        if curr_direction == "left":
            j -= 1
        if curr_direction == "right":
            j += 1

count = 0 
for line in route:
    for j in range(len(route)):
        if line[j] == "X":
            count+=1

print(count)

ChatGPT’s Not So Improved Version…

At first attempt, ChatGPT output the code below, however, I noticed that this code made the same mistake I had during my developing… once the guard comes across an “X”, its next move continues from the index of the X and not the guard’s previous position.

with open("day6.txt") as f:
    grid = [list(row) for row in f.read().splitlines()]

# Locate the starting point
for i, row in enumerate(grid):
    for j, cell in enumerate(row):
        if cell == "^":
            start = (i, j)
            break

# Direction mappings: (row_delta, col_delta) for each direction
directions = {
    "up": (-1, 0),
    "right": (0, 1),
    "down": (1, 0),
    "left": (0, -1),
}
order = ["up", "right", "down", "left"]  # Order of direction rotation

# Traverse the grid
i, j = start
curr_direction = "up"

while 0 <= i < len(grid) and 0 <= j < len(grid[0]):
    # Mark the route
    if grid[i][j] != "#":
        grid[i][j] = "X"
    else:
        # Rotate direction clockwise if hitting a wall
        curr_idx = order.index(curr_direction)
        curr_direction = order[(curr_idx + 1) % 4]

    # Move in the current direction
    di, dj = directions[curr_direction]
    i += di
    j += dj

# Count all the "X" marks
count = sum(row.count("X") for row in grid)
print(count)

ChatGPT’s Improved Code

After pointing this out to ChatGPT, he output the following, actually improved code:

with open("day6.txt") as f:
    grid = [list(row) for row in f.read().splitlines()]

# Locate the starting point
for i, row in enumerate(grid):
    for j, cell in enumerate(row):
        if cell == "^":
            start = (i, j)
            break

# Direction mappings: (row_delta, col_delta) for each direction
directions = {
    "up": (-1, 0),
    "right": (0, 1),
    "down": (1, 0),
    "left": (0, -1),
}
order = ["up", "right", "down", "left"]  # Order of direction rotation

# Traverse the grid
i, j = start
curr_direction = "up"

while 0 <= i < len(grid) and 0 <= j < len(grid[0]):
    # Check if current cell is a wall
    if grid[i][j] == "#":
        # Rotate direction clockwise
        curr_idx = order.index(curr_direction)
        curr_direction = order[(curr_idx + 1) % 4]

        # Undo the previous movement
        di, dj = directions[curr_direction]
        i -= di
        j -= dj
        continue

    # Mark the route
    grid[i][j] = "X"

    # Move in the current direction
    di, dj = directions[curr_direction]
    i += di
    j += dj

# Count all the "X" marks
count = sum(row.count("X") for row in grid)
print(count)

Part 2

My Code

import copy

with open("day6.txt") as f:
    map = f.read().split("\n")
    map = [list(row) for row in map]

    route = copy.deepcopy(map)
    
    for i in range(len(map)):
        for j in range(len(map[i])):
            if map[i][j] == "^":
                start = (i,j)
                # route[i][j] = "X"

    i, j = start
    curr_direction = "up"

    count = 0
    for k in range(len(map)):
        for m in range(len(map[k])):
            route = copy.deepcopy(map)
            i, j = start
            curr_direction = "up"
            loop = False
            barriers_found = {}
            while i < len(map) and j < len(map[i]) and i >= 0 and j >= 0 and not loop:
                if (i,j) in barriers_found and barriers_found[(i,j)] == curr_direction:
                    # we are at a barrier we have hit before
                    loop = True
                    count += 1
                
                else:
                    if map[i][j] == "#" or (i,j) == (k,m):
                        barriers_found[(i,j)] = curr_direction
                        if curr_direction == "up":
                            i += 1
                            curr_direction = "right"
                        elif curr_direction == "right":
                            j -= 1
                            curr_direction = "down"
                        elif curr_direction == "down":
                            i -= 1
                            curr_direction = "left"
                        elif curr_direction == "left":
                            j += 1
                            curr_direction = "up"
                    else:
                        if curr_direction == "left" or curr_direction == "right":
                            if route[i][j] == ".":
                                route[i][j] = "-"
                                
                            if route[i][j] == "|":
                                route[i][j] = "+"

                        if curr_direction == "up" or curr_direction == "down":
                            if route[i][j] == ".":
                                route[i][j] = "|"

                            if route[i][j] == "-":
                                route[i][j] = "+"


                    if curr_direction == "up":
                        i -= 1
                    if curr_direction == "down":
                        i += 1
                    if curr_direction == "left":
                        j -= 1
                    if curr_direction == "right":
                        j += 1

print(count)

ChatGPT’s Improved Code

with open("day6.txt") as f:
    grid = [list(row) for row in f.read().splitlines()]

# Locate the starting point
for i, row in enumerate(grid):
    for j, cell in enumerate(row):
        if cell == "^":
            start = (i, j)
            break

directions = {
    "up": (-1, 0),
    "right": (0, 1),
    "down": (1, 0),
    "left": (0, -1),
}
direction_order = ["up", "right", "down", "left"]

count = 0

# Iterate over each possible barrier position
for k in range(len(grid)):
    for m in range(len(grid[0])):
        visited_states = set()
        i, j = start
        curr_direction = "up"
        loop_detected = False

        while 0 <= i < len(grid) and 0 <= j < len(grid[0]) and not loop_detected:
            # State includes position and direction
            state = (i, j, curr_direction)

            # Detect loop
            if state in visited_states:
                loop_detected = True
                count += 1
                break
            visited_states.add(state)

            # Handle barriers (including potential temporary barrier at (k, m))
            if grid[i][j] == "#" or (i, j) == (k, m):
                # Rotate direction clockwise
                curr_idx = direction_order.index(curr_direction)
                curr_direction = direction_order[(curr_idx + 1) % 4]
            else:
                # Move in the current direction
                di, dj = directions[curr_direction]
                i += di
                j += dj

print(count)

What I learned

Definition of a Shallow Copy

Clever Use of % To Rotate 90 degrees

Use Direction Vectors

Don’t _____ when you don’t need to


Callista Krebs, 2024