From bb22002cb96dd72364d1e206335b9e0a554dc197 Mon Sep 17 00:00:00 2001 From: alexchao26 Date: Sat, 26 Dec 2020 02:18:04 -0500 Subject: [PATCH] 2015-day05: string validation --- 2015/day05/main.go | 87 +++++++++++++++++++++++++++++++++++++++++ 2015/day05/main_test.go | 41 +++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 2015/day05/main.go create mode 100644 2015/day05/main_test.go diff --git a/2015/day05/main.go b/2015/day05/main.go new file mode 100644 index 0000000..b8aa2d4 --- /dev/null +++ b/2015/day05/main.go @@ -0,0 +1,87 @@ +package main + +import ( + "flag" + "fmt" + "regexp" + "strings" + + "github.com/alexchao26/advent-of-code-go/util" +) + +func main() { + var part int + flag.IntVar(&part, "part", 1, "part 1 or 2") + flag.Parse() + fmt.Println("Running part", part) + + var ans int + if part == 1 { + ans = part1(util.ReadFile("./input.txt")) + } else { + ans = part2(util.ReadFile("./input.txt")) + } + fmt.Println("Output:", ans) +} + +func part1(input string) int { + var nice int + + disallowPattern := regexp.MustCompile("(ab|cd|pq|xy)") + for _, line := range strings.Split(input, "\n") { + var vowels int + for _, char := range line { + if strings.ContainsRune("aeiou", char) { + vowels++ + } + } + var hasDouble bool + for i := 0; i < len(line)-1; i++ { + if line[i] == line[i+1] { + hasDouble = true + break + } + } + if vowels >= 3 && !disallowPattern.MatchString(line) && hasDouble { + nice++ + } + } + + return nice +} + +func part2(input string) int { + var nice int + + // put a double for loop check inside of a separate function b/c it makes + // returning out of both loops possible, and avoids using a label which + // makes me sad + passesRule1 := func(line string) bool { + for i := 0; i < len(line)-2; i++ { + toMatch := line[i : i+2] + for j := i + 2; j < len(line)-1; j++ { + if line[j:j+2] == toMatch { + return true + } + } + } + return false + } + + for _, line := range strings.Split(input, "\n") { + rule1 := passesRule1(line) + + var rule2 bool + for i := 0; i < len(line)-2; i++ { + if line[i] == line[i+2] { + rule2 = true + break + } + } + if rule1 && rule2 { + nice++ + } + } + + return nice +} diff --git a/2015/day05/main_test.go b/2015/day05/main_test.go new file mode 100644 index 0000000..5da6cec --- /dev/null +++ b/2015/day05/main_test.go @@ -0,0 +1,41 @@ +package main + +import ( + "testing" + + "github.com/alexchao26/advent-of-code-go/util" +) + +func Test_part1(t *testing.T) { + tests := []struct { + name string + input string + want int + }{ + {"actual", util.ReadFile("input.txt"), 238}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := part1(tt.input); got != tt.want { + t.Errorf("part1() = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_part2(t *testing.T) { + tests := []struct { + name string + input string + want int + }{ + {"actual", util.ReadFile("input.txt"), 69}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := part2(tt.input); got != tt.want { + t.Errorf("part2() = %v, want %v", got, tt.want) + } + }) + } +}