Advent of Code (in MiniScript), Day 3
Tags: miniscript, adventofcode, programming
Published: 2022-12-03 20:46:11

Let's tackle the [Day 3](https://adventofcode.com/2022/day/3) [Advent of Code](https://adventofcode.com/) challenge in [MiniScript](https://miniscript.org)!

Again a long story problem hides a relatively simple task: split each string into two equal halves, and find the one letter that occurs in both halves.  Assign a value to that (1 through 26 for lowercase letters, 27 through 52 for uppercase letters), and print out the total.

My MiniScript code for this is nothing fancy... it just loops through the file, doing the task described above.
```
f = file.open("day3-input.txt")
total = 0
while true
	line = f.readLine
	if line == null then break // end of file
	// split the line into our two compartments
	compA = line[:line.len/2]
	compB = line[line.len/2:]
	// find the item that appears in both
	for c in compA
		if compB.indexOf(c) != null then break
	end for
	// find the "priority" value of this item
	if c >= "a" then
		priority = c.code - "a".code + 1
	else
		priority = c.code - "A".code + 27
	end if
	total = total + priority
	print compA + "/" + compB + " --> " + c + " worth " + priority + ", total " + total
end while
```
Core MiniScript doesn't have a "contains" function; you check for a substring by using [`indexOf`](https://miniscript.org/wiki/IndexOf), which returns `null` if the substring is not found.  So to find the common letter, we iterate over each character of `compA`, and (using `indexOf`) see if `compB` contains the same letter.

Finally, note the use of [`.code`](https://miniscript.org/wiki/Code) to get the Unicode code point of each letter.  That lets us subtract the code point for the start of the alphabet, then add the proper offset for lowercase or uppercase letters, to get the priority value for any letter.

Running this produced a bunch of output like
> WsQgstQmvQJnssWsW/PzhRzhBjZBSBRZSnj --> n worth 14, total 8260
> qwCNqFwDrrlDr/FPvRhTSPPzLRz --> F worth 32, total 8292
> bppqwppCddlvfbDN/VgmMmtMfVVmfmVWW --> f worth 6, total 8298

...and the final total, 8298 in my case, was the right answer.

Part B turns out to be basically the same task, except that instead of dividing each line into two halves, we read groups of three lines at a time, and need to find the letter that occurs in all three.  So I just took out my line-splitting code, and instead read in three lines at a time.  To find the common letter, we still just iterate over each character in the first line, but now we check that it's contained in both of the other two lines.

```
f = file.open("day3-input.txt")
total = 0
while true
	// read the next three lines (one "group of elves")
	lineA = f.readLine
	if lineA == null then break // end of file
	lineB = f.readLine
	lineC = f.readLine
	// find the item that appears in all three
	for c in lineA
		if lineB.indexOf(c) != null and lineC.indexOf(c) != null then break
	end for
	// find the "priority" value of this item
	if c >= "a" then
		priority = c.code - "a".code + 1
	else
		priority = c.code - "A".code + 27
	end if
	total = total + priority
	print lineA + "/" + lineB + "/" + lineC + " --> " + c + 
	  " worth " + priority + ", total " + total
end while
```

Running this produced more verbose output (I had to stretch my terminal window out to keep these lines from wrapping!), but the final total, which for me was 2708, was again the right answer.

So!  That's the end of the third day, and we're all caught up.  The next challenge drops tonight, at midnight in New York.  As you've seen, these challenges aren't terribly hard; they're just couched in often confusing story problem.  The trick is to see through all the story, and spot the core task, which (so far, at least) is usually pretty straightforward.

So why not give the next one a try on your own?  [MiniScript](https://miniscript.org) is a great language to do it in.  Build your skills, have some fun, and play along with literally tens of thousands of others!