Added everything into a global test suite

This commit is contained in:
Ceferino Patino 2024-12-08 02:14:22 -06:00
commit bd331a2068
Signed by: c4patino
SSH key fingerprint: SHA256:Wu+cU1t+7zVT9wzew/4meNmeulo66NzMqc22MdDBgXI
34 changed files with 401 additions and 150 deletions

View file

@ -1,9 +1,7 @@
package main
package day1
import (
"bufio"
"flag"
"fmt"
"math"
"os"
"slices"
@ -37,15 +35,7 @@ func Part2(firstCol []int, secondCol []int) int {
return sum
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -78,9 +68,8 @@ func main() {
panic(err)
}
answer := Part1(firstCol, secondCol)
fmt.Println(answer)
part1 := Part1(firstCol, secondCol)
part2 := Part2(firstCol, secondCol)
answer = Part2(firstCol, secondCol)
fmt.Println(answer)
return part1, part2
}

25
2024/day1/day1_test.go Normal file
View file

@ -0,0 +1,25 @@
package day1
import (
"os"
"testing"
)
func TestDay1(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 11
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 31
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

6
2024/day1/test.txt Normal file
View file

@ -0,0 +1,6 @@
3 4
4 3
2 5
1 3
3 9
3 3

View file

@ -1,9 +1,7 @@
package main
package day2
import (
"bufio"
"flag"
"fmt"
"math"
"os"
"strconv"
@ -73,15 +71,7 @@ func Part2(rows [][]int) int {
return safe
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -111,9 +101,8 @@ func main() {
panic(err)
}
answer := Part1(rows)
fmt.Println(answer)
part1 := Part1(rows)
part2 := Part2(rows)
answer = Part2(rows)
fmt.Println(answer)
return part1, part2
}

25
2024/day2/day2_test.go Normal file
View file

@ -0,0 +1,25 @@
package day2
import (
"os"
"testing"
)
func TestDay2(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 2
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 4
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

6
2024/day2/test.txt Normal file
View file

@ -0,0 +1,6 @@
7 6 4 2 1
1 2 7 8 9
9 7 6 2 1
1 3 2 4 5
8 6 4 4 1
1 3 6 7 9

View file

@ -1,8 +1,7 @@
package main
package day3
import (
"bufio"
"flag"
"fmt"
"os"
"regexp"
@ -32,7 +31,6 @@ func (q *Queue[T]) Peek() T {
}
func Part1(text string) int {
// Regex to match mul(x, y)
mulRe := regexp.MustCompile(`(?i)mul\((\d+),(\d+)\)`)
mulReMatches := mulRe.FindAllStringIndex(text, -1)
@ -55,38 +53,40 @@ func Part1(text string) int {
}
func Part2(text string) int {
// Regex to match mul(x, y)
mulRe := regexp.MustCompile(`(?i)mul\((\d+),(\d+)\)`)
mulReMatches := mulRe.FindAllStringIndex(text, -1)
// Regex to match do quoted strings
doRe := regexp.MustCompile("(?i)do\\(\\)")
doQueue := Queue[int]{}
for _, match := range doRe.FindAllStringIndex(text, -1) {
doQueue.Enqueue(match[0])
}
doReMatches := doRe.FindAllStringIndex(text, -1)
// Regex to match do quoted strings
dontRe := regexp.MustCompile("(?i)don't\\(\\)")
dontQueue := Queue[int]{}
for _, match := range dontRe.FindAllStringIndex(text, -1) {
dontQueue.Enqueue(match[0])
}
dontReMatches := dontRe.FindAllStringIndex(text, -1)
lastDoIndex := 0
lastDontIndex := 0
result := 0
for _, match := range mulReMatches {
// Find the last instance of do before the current match
for !doQueue.IsEmpty() && doQueue.Peek() < match[0] {
_ = doQueue.Dequeue()
lastDo := -1
for i := lastDoIndex; i < len(doReMatches); i++ {
m := doReMatches[i]
if match[0] < m[0] {
break
}
lastDo = m[0]
lastDoIndex = i
}
// Find the last instance of don't before the current match
for !dontQueue.IsEmpty() && dontQueue.Peek() < match[0] {
_ = dontQueue.Dequeue()
lastDont := -1
for i := lastDontIndex; i < len(dontReMatches); i++ {
m := dontReMatches[i]
if match[0] < m[0] {
break
}
lastDont = m[0]
lastDontIndex = i
}
// If the previous don't is after the previous do, skip this match
if !dontQueue.IsEmpty() && !doQueue.IsEmpty() && dontQueue.Peek() < doQueue.Peek() {
if lastDont > lastDo {
continue
}
@ -105,15 +105,7 @@ func Part2(text string) int {
return result
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -130,9 +122,9 @@ func main() {
panic(err)
}
answer := Part1(text)
fmt.Println(answer)
part1 := Part1(text)
answer = Part2(text)
fmt.Println(answer)
part2 := Part2(text)
return part1, part2
}

25
2024/day3/day3_test.go Normal file
View file

@ -0,0 +1,25 @@
package day3
import (
"os"
"testing"
)
func TestDay3(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 161
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 48
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

1
2024/day3/test.txt Normal file
View file

@ -0,0 +1 @@
xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))

View file

@ -1,9 +1,7 @@
package main
package day4
import (
"bufio"
"flag"
"fmt"
"os"
"strings"
)
@ -132,15 +130,7 @@ func Part2(text [][]string) int {
return count
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -159,9 +149,8 @@ func main() {
panic(err)
}
answer := Part1(text)
fmt.Println(answer)
part1 := Part1(text)
part2 := Part2(text)
answer = Part2(text)
fmt.Println(answer)
return part1, part2
}

25
2024/day4/day4_test.go Normal file
View file

@ -0,0 +1,25 @@
package day4
import (
"os"
"testing"
)
func TestDay4(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 18
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 9
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

10
2024/day4/test.txt Normal file
View file

@ -0,0 +1,10 @@
MMMSXXMASM
MSAMXMSMSA
AMXSXMAAMM
MSAMASMSMX
XMASAMXAMM
XXAMMXXAMA
SMSMSASXSS
SAXAMASAAA
MAMMMXMMMM
MXMXAXMASX

View file

@ -1,9 +1,7 @@
package main
package day5
import (
"bufio"
"flag"
"fmt"
"os"
"strconv"
"strings"
@ -145,15 +143,7 @@ func Part2(rules, updates [][]int) int {
return middleSum.resource
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -200,9 +190,8 @@ func main() {
panic(err)
}
answer := Part1(rules, updates)
fmt.Println(answer)
part1 := Part1(rules, updates)
part2 := Part2(rules, updates)
answer = Part2(rules, updates)
fmt.Println(answer)
return part1, part2
}

25
2024/day5/day5_test.go Normal file
View file

@ -0,0 +1,25 @@
package day5
import (
"os"
"testing"
)
func TestDay5(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 143
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 123
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

28
2024/day5/test.txt Normal file
View file

@ -0,0 +1,28 @@
47|53
97|13
97|61
97|47
75|29
61|13
75|53
29|13
97|29
53|29
61|53
97|53
61|29
47|13
75|47
97|75
47|61
75|61
47|29
75|13
53|13
75,47,61,53,29
97,61,53,29,13
75,29,13
75,97,47,61,53
61,13,29
97,13,75,29,47

View file

@ -1,9 +1,7 @@
package main
package day6
import (
"bufio"
"flag"
"fmt"
"os"
"sync"
)
@ -174,15 +172,7 @@ func Part2(grid [][]string, initial Location) int {
return total
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -212,9 +202,8 @@ func main() {
panic(err)
}
answer := Part1(grid, initialLocation)
fmt.Println(answer)
part1 := Part1(grid, initialLocation)
part2 := Part2(grid, initialLocation)
answer = Part2(grid, initialLocation)
fmt.Println(answer)
return part1, part2
}

25
2024/day6/day6_test.go Normal file
View file

@ -0,0 +1,25 @@
package day6
import (
"os"
"testing"
)
func TestDay6(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 41
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 6
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

10
2024/day6/test.txt Normal file
View file

@ -0,0 +1,10 @@
....#.....
.........#
..........
..#.......
.......#..
..........
.#..^.....
........#.
#.........
......#...

View file

@ -1,9 +1,7 @@
package main
package day7
import (
"bufio"
"flag"
"fmt"
"os"
"strconv"
"strings"
@ -116,15 +114,7 @@ func Part2(equations []Equation) int {
return sum
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -161,9 +151,8 @@ func main() {
panic(err)
}
answer := Part1(equations)
fmt.Println(answer)
part1 := Part1(equations)
part2 := Part2(equations)
answer = Part2(equations)
fmt.Println(answer)
return part1, part2
}

25
2024/day7/day7_test.go Normal file
View file

@ -0,0 +1,25 @@
package day7
import (
"os"
"testing"
)
func TestDay7(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 3749
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 11387
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

9
2024/day7/test.txt Normal file
View file

@ -0,0 +1,9 @@
190: 10 19
3267: 81 40 27
83: 17 5
156: 15 6
7290: 6 8 6 15
161011: 16 10 13
192: 17 8 14
21037: 9 7 18 13
292: 11 6 16 20

View file

@ -1,9 +1,7 @@
package main
package day8
import (
"bufio"
"flag"
"fmt"
"os"
)
@ -54,12 +52,11 @@ func Part2(grid map[rune][]Point, rows, cols int) int {
for i := 0; i < len(antennas); i++ {
for j := i + 1; j < len(antennas); j++ {
a1, a2 := antennas[i], antennas[j]
dx, dy := a2.x-a1.x, a2.y-a1.y
antinodes[a1] = true
antinodes[a2] = true
dx, dy := a2.x-a1.x, a2.y-a1.y
forward := Point{a1.x - dx, a1.y - dy}
for isValid(forward, rows, cols) {
antinodes[forward] = true
@ -78,15 +75,7 @@ func Part2(grid map[rune][]Point, rows, cols int) int {
return len(antinodes)
}
func main() {
flag.Parse()
if len(flag.Args()) == 0 {
panic("Please provide a filename")
}
filename := flag.Args()[0]
func Run(filename string) (int, int) {
file, err := os.Open(filename)
if err != nil {
panic(err)
@ -113,9 +102,8 @@ func main() {
panic(err)
}
answer := Part1(grid, rows, cols)
fmt.Println(answer)
part1 := Part1(grid, rows, cols)
part2 := Part2(grid, rows, cols)
answer = Part2(grid, rows, cols)
fmt.Println(answer)
return part1, part2
}

25
2024/day8/day8_test.go Normal file
View file

@ -0,0 +1,25 @@
package day8
import (
"os"
"testing"
)
func TestDay8(t *testing.T) {
filename := "test.txt"
if _, err := os.Stat(filename); os.IsNotExist(err) {
t.Fatalf("test file does not exist: %v", filename)
}
part1, part2 := Run(filename)
expectedPart1 := 14
if part1 != expectedPart1 {
t.Fatalf("unexpected part1:\nwant:\t%d\ngot:\t%d", expectedPart1, part1)
}
expectedPart2 := 34
if part2 != expectedPart2 {
t.Fatalf("unexpected part2:\nwant:\t%d\ngot:\t%d", expectedPart2, part2)
}
}

12
2024/day8/test.txt Normal file
View file

@ -0,0 +1,12 @@
............
........0...
.....0......
.......0....
....0.......
......A.....
............
............
........A...
.........A..
............
............

View file

@ -1,3 +1,3 @@
module cpatino.com/advent-of-code
module cpatino.com/advent-of-code/2024
go 1.23.3

55
2024/main.go Normal file
View file

@ -0,0 +1,55 @@
package main
import (
"flag"
"fmt"
"strconv"
"cpatino.com/advent-of-code/2024/day1"
"cpatino.com/advent-of-code/2024/day2"
"cpatino.com/advent-of-code/2024/day3"
"cpatino.com/advent-of-code/2024/day4"
"cpatino.com/advent-of-code/2024/day5"
"cpatino.com/advent-of-code/2024/day6"
"cpatino.com/advent-of-code/2024/day7"
"cpatino.com/advent-of-code/2024/day8"
)
func main() {
flag.Parse()
if len(flag.Args()) != 2 {
panic("Usage: go run . <day> <input file>")
}
day, inputFile := flag.Args()[0], flag.Args()[1]
if _, err := strconv.Atoi(day); err != nil {
panic("Please provide a valid numeric day")
}
fmt.Printf("Day: %s, Input File: %s\n", day, inputFile)
var part1, part2 int
switch day {
case "1":
part1, part2 = day1.Run(inputFile)
case "2":
part1, part2 = day2.Run(inputFile)
case "3":
part1, part2 = day3.Run(inputFile)
case "4":
part1, part2 = day4.Run(inputFile)
case "5":
part1, part2 = day5.Run(inputFile)
case "6":
part1, part2 = day6.Run(inputFile)
case "7":
part1, part2 = day7.Run(inputFile)
case "8":
part1, part2 = day8.Run(inputFile)
}
fmt.Printf("Part 1: %d\n", part1)
fmt.Printf("Part 2: %d\n", part2)
}