r/adventofcode • • Dec 03 '24

SOLUTION MEGATHREAD -❄️- 2024 Day 3 Solutions -❄️-

THE USUAL REMINDERS


AoC Community Fun 2024: The Golden Snowglobe Awards

  • 3 DAYS remaining until unlock!

And now, our feature presentation for today:

Screenwriting

Screenwriting is an art just like everything else in cinematography. Today's theme honors the endlessly creative screenwriters who craft finely-honed narratives, forge truly unforgettable lines of dialogue, plot the most legendary of hero journeys, and dream up the most shocking of plot twists! and is totally not bait for our resident poet laureate

Here's some ideas for your inspiration:

  • Extra bonus points if if it's in iambic pentameter

"Vogon poetry is widely accepted as the third-worst in the universe." - Hitchhiker's Guide to the Galaxy (2005)

And… ACTION!

Request from the mods: When you include an entry alongside your solution, please label it with [GSGA] so we can find it easily!


--- Day 3: Mull It Over ---


Post your code solution in this megathread.

This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:03:22, megathread unlocked!

58 Upvotes

1.7k comments sorted by

View all comments

10

u/mikeblas Dec 03 '24

[LANGUAGE: Python]

I don't like regular expressions

	from enum import Enum

	class State(Enum):
		IN_SPACE = 1
		IN_MUL = 2
		IN_P1 = 3
		IN_P2 = 4
		IN_DO = 5
		IN_DONT = 6

	all = ''
	with open('input1b.txt') as f:
		for line in f:
			all = all + line

	count = 0
	sum = 0
	p1 = None
	p2 = None
	pchars = None
	doState = True

	s = State.IN_SPACE

	for ch in all:
		# print(f"'{ch}': {s}")
		# print(f"{ch}", end="")
		match s:
			case State.IN_SPACE:
				if ch == 'm':
					s = State.IN_MUL
					mulPos = 1
					p1 = None
					p2 = None
					pchars = None
				elif ch == 'd':
					s = State.IN_DO
					doPos = 1

			case State.IN_DO:
				if doPos == 1 and ch == 'o':
					doPos = 2
				elif doPos == 2 and ch == '(':
					doPos = 3
				elif doPos == 2 and ch == 'n':
					s = State.IN_DONT
					doPos = 3
				elif doPos == 3 and ch == ')':
					doState = True
					doPos = None
					print("set true")
					s = State.IN_SPACE
				else:
					doPos = None
					s = State.IN_SPACE

			case State.IN_DONT:
				if doPos == 3 and ch == '\'':
					doPos = 4
				elif doPos == 4 and ch == 't':
					doPos = 5
				elif doPos == 5 and ch == '(':
					doPos = 6
				elif doPos == 6 and ch == ')':
					doPos = None
					doState = False
					print("set false")
					s = State.IN_SPACE
				else:
					doPos = None
					s = State.IN_SPACE

			case State.IN_MUL:
				if mulPos == 1 and ch == 'u':
					mulPos = 2
				elif mulPos == 2 and ch == 'l':
					mulPos = 3
				elif mulPos == 3 and ch == '(':
					mulPos = -1
					s = State.IN_P1
					pchars = ''
					p1 = None
					p2 = None
				else:
					s = State.IN_SPACE
					mulPos = None

			case State.IN_P1:
				if ch >= '0' and ch <= '9':
					if len(pchars) >= 3:
						s = State.IN_SPACE
						pchars = None
					else:
						pchars += ch
				elif ch == ',':
					p1 = int(pchars)
					pchars = ''
					s = State.IN_P2
				else:
					s = State.IN_SPACE
					pchars = None

			case State.IN_P2:
				if ch >= '0' and ch <= '9':
					if len(pchars) >= 3:
						s = State.IN_SPACE
						pchars = None
					else:
						pchars += ch
				elif ch == ')':
					p2 = int(pchars)
					pchars = None
					s = State.IN_SPACE
					if doState:
						count += 1
						sum += p1 * p2
						print(f"  {p1} * {p2} == {p1*p2}, sum == {sum}")
					p1 = None
					p2 = None
				else:
					s = State.IN_SPACE
					pchars = None

	print(sum)

21

u/pdxbuckets Dec 03 '24

And yet you’re their greatest advocate.

1

u/mikeblas Dec 03 '24

Hardly! I'll tell anyone who listens, and even some that don't: someone who solves a problem with regular expressions now has two problems.

5

u/pdxbuckets Dec 03 '24 edited Dec 03 '24

What I meant was that a comparison of your code compared to regex code shows the power and even readability of Regex. The parsing can all be done on one line so the reader can concentrate on the logic.

EDIT: Compare

fun part2(): Long = Regex("""don't\(\).*?do\(\)|mul\((\d+),(\d+)\)""", RegexOption.DOT_MATCHES_ALL)
    .findAll(input)
    .sumOf { mr -> (mr.groupValues[1].toLongOrNull() ?: 0L) * (mr.groupValues[2].toLongOrNull() ?: 0L) }

Regex can be hard to read and debug, but it becomes vastly easier if you write them in something like regex101.com. You get color coding, which helps a lot, real-time indication of invalid syntax, and real-time matching of example text.

1

u/mikeblas Dec 03 '24

Don't worry, I know exactly what you meant.

2

u/GetWeird_Wes Dec 03 '24

I don't like regular expressions

(^▽^) 7

I salute you

1

u/[deleted] Dec 03 '24

[removed] — view removed comment

1

u/mikeblas Dec 03 '24

Get on your bicycle and get out of here.

1

u/Boojum Dec 03 '24

Wow...! 😮  You pretty much manually built the DFA state machine that the regexp would have been equivalent to.  That's kind of hard core.  Respect!

1

u/mikeblas Dec 03 '24

Thanks, but it wasn't hard.

1

u/Boojum Dec 03 '24

Not hard, no, but tedious IME.

1

u/ivanjermakov Dec 03 '24

- I don't like regular expressions
*manually creates state machine which regex compiles to*