From bc8ebae440dfab6f1ffdc7fccea5158c3de5784a Mon Sep 17 00:00:00 2001 From: Parnic Date: Thu, 9 Jun 2022 08:23:34 -0500 Subject: [PATCH] Day 4 solution Plenty of room for optimization here, but it's enough for my needs for now. --- days/04.go | 116 +++++++++++++++++++++++++++++++++++++++++++++++++ inputs/04p.txt | 1 + main.go | 1 + 3 files changed, 118 insertions(+) create mode 100644 days/04.go create mode 100644 inputs/04p.txt diff --git a/days/04.go b/days/04.go new file mode 100644 index 0000000..3b3e333 --- /dev/null +++ b/days/04.go @@ -0,0 +1,116 @@ +package days + +import ( + "fmt" + "strconv" + "strings" + + "parnic.com/aoc2019/utilities" +) + +type Day04 struct { + max int + min int +} + +func (d *Day04) Parse() { + contents := utilities.GetStringContents("04p") + vals := strings.Split(contents, "-") + d.min, _ = strconv.Atoi(vals[0]) + d.max, _ = strconv.Atoi(vals[1]) + + d.test() +} + +func (d Day04) Num() int { + return 4 +} + +func (d Day04) test() { + if !d.isValidP2(112233) { + panic("112233") + } + if d.isValidP2(123444) { + panic("123444") + } + if !d.isValidP2(111122) { + panic("111122") + } + if !d.isValidP2(112222) { + panic("112222") + } +} + +func (d Day04) isValidP1(num int) bool { + // if num < d.min || num > d.max { + // return false + // } + + numStr := strconv.Itoa(num) + lastNum := -1 + for _, ch := range numStr { + thisNum, _ := strconv.Atoi(string(ch)) + if lastNum > -1 && thisNum < lastNum { + return false + } + lastNum = thisNum + } + + foundDouble := false + for idx := range numStr { + if idx == 0 { + continue + } + if numStr[idx-1] == numStr[idx] { + foundDouble = true + break + } + } + + return foundDouble +} + +func (d Day04) isValidP2(num int) bool { + if !d.isValidP1(num) { + return false + } + + numStr := strconv.Itoa(num) + for i := 0; i < len(numStr); i++ { + consec := 1 + for j := i + 1; j < len(numStr) && numStr[j] == numStr[i]; j++ { + consec++ + i = j + } + if consec == 2 { + return true + } + } + + return false +} + +// these could be sped up quite a bit by intelligently jumping to the +// next valid number when encountering an invalid one, rather than +// simply incrementing by 1 +func (d *Day04) Part1() string { + numValid := 0 + for x := d.min; x <= d.max; x++ { + if d.isValidP1(x) { + numValid++ + } + } + + return fmt.Sprintf("Total valid passwords: %s%d%s", utilities.TextBold, numValid, utilities.TextReset) +} + +func (d *Day04) Part2() string { + numValid := 0 + for x := d.min; x <= d.max; x++ { + if d.isValidP2(x) { + numValid++ + } + } + + return fmt.Sprintf("Total valid passwords: %s%d%s", utilities.TextBold, numValid, utilities.TextReset) +} diff --git a/inputs/04p.txt b/inputs/04p.txt new file mode 100644 index 0000000..ce5f198 --- /dev/null +++ b/inputs/04p.txt @@ -0,0 +1 @@ +147981-691423 \ No newline at end of file diff --git a/main.go b/main.go index ffa2ec4..9e379f2 100644 --- a/main.go +++ b/main.go @@ -28,6 +28,7 @@ var dayMap = []day{ &days.Day01{}, &days.Day02{}, &days.Day03{}, + &days.Day04{}, } func main() {