82 lines
1.4 KiB
Go
82 lines
1.4 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
|
||
|
h "git.bullercodeworks.com/brian/adventofcode/helpers"
|
||
|
)
|
||
|
|
||
|
func main() {
|
||
|
inp := h.StdinToStringSlice()
|
||
|
part1(inp)
|
||
|
}
|
||
|
|
||
|
func part1(inp []string) {
|
||
|
fmt.Println("# Part 1")
|
||
|
keys, locks := parseInput(inp)
|
||
|
var pairs int
|
||
|
for k := range keys {
|
||
|
for l := range locks {
|
||
|
if fits(keys[k], locks[l]) {
|
||
|
pairs++
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
fmt.Println("Unique Pairs:", pairs)
|
||
|
}
|
||
|
|
||
|
func parseInput(inp []string) ([][]int, [][]int) {
|
||
|
var keys, locks [][]int
|
||
|
for i := 0; i < len(inp); i += 8 {
|
||
|
switch inp[i] {
|
||
|
case "#####":
|
||
|
locks = append(locks, findPinDepths(inp[i:i+7]))
|
||
|
case ".....":
|
||
|
keys = append(keys, findToothDepths(inp[i:i+7]))
|
||
|
}
|
||
|
}
|
||
|
return keys, locks
|
||
|
}
|
||
|
|
||
|
func findPinDepths(inp []string) []int {
|
||
|
pins := make(map[int]int)
|
||
|
for i := range inp {
|
||
|
for pin := range inp[i] {
|
||
|
if _, ok := pins[pin]; !ok {
|
||
|
if inp[i][pin] == '.' {
|
||
|
pins[pin] = i - 1
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ret := []int{pins[0], pins[1], pins[2], pins[3], pins[4]}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func findToothDepths(inp []string) []int {
|
||
|
teeth := make(map[int]int)
|
||
|
for i := range inp {
|
||
|
for tooth := range inp[i] {
|
||
|
if _, ok := teeth[tooth]; !ok {
|
||
|
if inp[i][tooth] == '#' {
|
||
|
teeth[tooth] = 6 - i
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
ret := []int{teeth[0], teeth[1], teeth[2], teeth[3], teeth[4]}
|
||
|
return ret
|
||
|
}
|
||
|
|
||
|
func fits(key, lock []int) bool {
|
||
|
if len(key) != len(lock) {
|
||
|
return false
|
||
|
}
|
||
|
for i := 0; i < len(key); i++ {
|
||
|
if key[i]+lock[i] > 5 {
|
||
|
return false
|
||
|
}
|
||
|
}
|
||
|
return true
|
||
|
}
|