117 lines
2.0 KiB
Go
117 lines
2.0 KiB
Go
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)
|
|
}
|