# Advent of Code: 2024 Solutions

This article contains solutions to the Advent of Code 2024 Christmas coding challenges.

Check out Advent of Code here: [https://adventofcode.com/2024](https://adventofcode.com/2024)

All solutions will be available in this GitHub repository:  
[https://github.com/redtrib3/advent-of-code-solutions.git](https://github.com/redtrib3/advent-of-code-solutions.git)

---

# Day 1: Historian Hysteria

[https://adventofcode.com/2024/day/1](https://adventofcode.com/2024/day/1)

### 👉 Part 1:

Part 1 gives us an input in the following format:

```plaintext
3   4
4   3
2   5
1   3
3   9
3   3
```

As per the Description, we are required to pair up the numbers in left and right list in an ascending order. and Find the **Difference** between them. Add up the Difference and that is the solution.

> Algorithm:
> 
> * Read the input file, split by lines.
>     
> * Split the left and right integers into two lists: left and right
>     
> * Sort both the list in ascending order.
>     
> * Iterate through both the list at once, Subtract integers in same index.
>     
> * Add the subtracted difference to a Variable, that is the solution.
>     

#### Code:

```python
#!/usr/bin/env python3

with open('input.txt', 'r') as f:
    lines = [i.strip() for i in f.readlines()]

left = []
right = []

for i in lines:
    l, r = i.split()
    left.append(int(l))
    right.append(int(r))

left = sorted(left)
right = sorted(right)

final_sum = 0
for i in range(len(left)):
    diff = max(left[i], right[i]) - min(left[i], right[i])
    final_sum += diff

print(final_sum)
```

### 👉 Part 2:

Part 2 gives us the same input.txt file.

This part requires us to find the frequency of each item in the left list in the right list. Multiply that frequency with the left list item. Add up these multiplied values to get the final **“Similarity Score**”, which is the solution.

> Algorithm:
> 
> * Do as in part 1 to divide the integers into pair list: left and right.
>     
> * For each item in left list, multiply it with the number of times it appears in right list to get a score. use count() for this.
>     
> * Add up these “scores” to get the final similarity score.
>     

#### Code:

```python
#!/usr/bin/env python3

with open("input.txt", 'r') as f:
    lines = [i.strip() for i in f.readlines()]

left = []
right = []

for i in lines:
    l, r = i.split()
    left.append(int(l))
    right.append(int(r))


similarity_score = 0
for i in range(len(left)):
    score = left[i] * right.count(left[i])
    similarity_score += score

print(similarity_score)
```

# Day 2: Red-Nosed Reports

## PART 1:

```python
#!/usr/bin/env python3

with open('input.txt', 'r') as f:
    lines = [i.strip() for i in f.readlines()]

lvls = []
for line in lines:
    lvls.append(list(map(int, line.split())))

# find if the list is valid-increasing or decreasing only.
def is_incr_or_decr(level):
    increasing = all(level[i] < level[i+1] for i in range(len(level)-1))
    decreasing = all(level[i] > level[i+1] for i in range(len(level)-1))

    if increasing or decreasing:
        return True
    return False

def is_safe(level):

    if not is_incr_or_decr(level):
        return False

    for i in range(len(level)-1):

        adj_diff = abs(level[i] - level[i+1])
#        print(level,f'{level[i]}, adj_diff= {adj_diff}')

        if adj_diff not in [1,2,3]:
            return False

    return True

safe_lvls = 0

for lvl in lvls:
    if is_safe(lvl):
        safe_lvls += 1

print(safe_lvls)
```

# Day 3: Mull It Over

## Part 1:

```python
import re

with open('input.txt','r') as f:
    input = f.read()

mul = lambda x,y: x*y

all_finds = re.findall(r'mul\(\d*,\d*\)', input)
print(sum([eval(i.strip()) for i in all_finds]))
```

## Part 2:

```python
import re

with open('input.txt','r') as f:
    input = f.read()

mul = lambda x,y: x*y

all_finds = re.findall(r'mul\(\d*,\d*\)|don\'t\(\)|do\(\)', input)
#print(all_finds)

do = 1
final_res = 0
for i in all_finds:

    if i == "don\'t()":
        do = 0
        continue

    if i == "do()":
        do = 1
        continue

    if do:
        final_res += eval(i)
        continue


print(final_res)
```

# Day 6: Guard Gallivant

## Part 1:

```python
#!/usr/bin/python3

# sample input for testing
input = '''
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...'''.strip()

# problem input
with open('input.txt', 'r') as f:
    input = [i.strip() for i in f.readlines()]


# clean the input into a matrix
row,map = [],[]
for i in input:
    for j in i:
        row.append(j)
    map.append(row)
    row = []


# for tracking the positions (not unique)
position_track = []
CURR_GUARD_STANCE = "^"


def move_up(x, y):

    global CURR_GUARD_STANCE

    position_track.append((x, y))

    if map[x-1][y] == "#":
        CURR_GUARD_STANCE = '^'
        return

    map[x][y] = '.'
    map[x-1][y] = "^"

    move_up(x-1, y)


def move_right(x, y):

    global CURR_GUARD_STANCE

    position_track.append((x,y))

    if map[x][y+1] == "#":
        CURR_GUARD_STANCE = '>'
        return

    map[x][y] = '.'
    map[x][y+1] = "^"

    move_right(x, y+1)

def move_down(x, y):

    global CURR_GUARD_STANCE

    position_track.append((x,y))

    if map[x+1][y] == "#":
        CURR_GUARD_STANCE = "v"
        return

    map[x][y] = '.'
    map[x+1][y] = '^'

    move_down(x+1, y)

def move_left(x, y):

    global CURR_GUARD_STANCE

    position_track.append((x,y))

    if map[x][y-1] == "#":

        CURR_GUARD_STANCE = "<"
        return

    map[x][y] = '.'
    map[x][y-1] = '^'
    move_left(x, y-1)



# AI generated function
def find_next_move(curr_guard_stance, x, y):
    # Define relative direction mapping based on current stance
    relative_directions = {
        "^": [("up", x-1, y), ("right", x, y+1), ("down", x+1, y), ("left", x, y-1)],
        ">": [("right", x, y+1), ("down", x+1, y), ("left", x, y-1), ("up", x-1, y)],
        "v": [("down", x+1, y), ("left", x, y-1), ("up", x-1, y), ("right", x, y+1)],
        "<": [("left", x, y-1), ("up", x-1, y), ("right", x, y+1), ("down", x+1, y)],
    }

    # Get possible moves based on current stance
    directions = relative_directions[curr_guard_stance]

    # Check for a valid move
    for move, new_x, new_y in directions:
        if 0 <= new_x < len(map) and 0 <= new_y < len(map[0]) and map[new_x][new_y] != "#":
            return move

    return "stop"  # No valid moves


# find the current position of the guard.
get_curr_pos = lambda map: [(map.index(i),i.index('^')) for i in map if '^' in i][0]


def play_game():
    try:
        while True:
            x, y = get_curr_pos(map)
            next_move = find_next_move(CURR_GUARD_STANCE, x, y)

            if next_move == "up":
                move_up(x, y)
            elif next_move == "down":
                move_down(x, y)
            elif next_move == "right":
                move_right(x, y)
            elif next_move == "left":
                move_left(x, y)
    except IndexError:
        print("IndexError:: Guard moved out of map")
    finally:
        print("Total moves:", len(set(position_track)))

if __name__ == "__main__":
    play_game()
```
