package main
import (
"bufio"
"fmt"
"log"
"os"
"regexp"
"strconv"
)
type pwData struct {
min int
max int
ch rune
hash string
}
func main() {
if err := realMain(); err != nil {
log.Println(err)
}
}
func realMain() error {
data, err := readInput("input.txt")
if err != nil {
return err
}
validold, err := countValidOld(data)
if err != nil {
return err
}
log.Println("VALID old:", validold)
validnew, err := countValidNew(data)
if err != nil {
return err
}
log.Println("VALID new:", validnew)
return nil
}
func countValidNew(data []pwData) (int, error) {
var valid int
for _, pw := range data {
if pw.hash[pw.min-1] == byte(pw.ch) && pw.hash[pw.max-1] != byte(pw.ch) {
valid++
} else if pw.hash[pw.max-1] == byte(pw.ch) && pw.hash[pw.min-1] != byte(pw.ch) {
valid++
}
}
return valid, nil
}
func countValidOld(data []pwData) (int, error) {
var valid int
for _, pw := range data {
var count int
for _, c := range pw.hash {
if c == pw.ch {
count++
}
}
if count <= pw.max && count >= pw.min {
valid++
}
}
return valid, nil
}
func readInput(f string) ([]pwData, error) {
var ret []pwData
fd, err := os.Open(f)
if err != nil {
return nil, err
}
defer fd.Close()
re := regexp.MustCompile(`(.*)-(.*) (\w): (.*)`)
buff := bufio.NewScanner(fd)
for buff.Scan() {
curr := pwData{}
res := re.FindStringSubmatch(buff.Text())
if len(res) != 5 {
return nil, fmt.Errorf("unexpected slice length")
}
curr.min, err = strconv.Atoi(res[1])
if err != nil {
return nil, err
}
curr.max, err = strconv.Atoi(res[2])
if err != nil {
return nil, err
}
curr.ch = rune(res[3][0])
curr.hash = res[4]
ret = append(ret, curr)
}
return ret, nil
}