Day 4 solution
Plenty of room for optimization here, but it's enough for my needs for now.
This commit is contained in:
116
days/04.go
Normal file
116
days/04.go
Normal file
@ -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)
|
||||
}
|
1
inputs/04p.txt
Normal file
1
inputs/04p.txt
Normal file
@ -0,0 +1 @@
|
||||
147981-691423
|
Reference in New Issue
Block a user