112 lines
2.2 KiB
Go
112 lines
2.2 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"AoC2020/helper"
|
||
|
"fmt"
|
||
|
"os"
|
||
|
"regexp"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
var lineBreak = "\n"
|
||
|
|
||
|
type tile struct {
|
||
|
neighbourID [4]int
|
||
|
edges [4]string
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
args := os.Args[1:]
|
||
|
input, err := helper.GetFile(args[0])
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
}
|
||
|
tileInput := strings.Split(input, lineBreak+lineBreak)
|
||
|
fmt.Println(len(tileInput))
|
||
|
tiles := getTiles(tileInput)
|
||
|
corners := findCorners(tiles)
|
||
|
fmt.Println(corners)
|
||
|
product := corners[0]
|
||
|
for _,val := range corners[1:]{
|
||
|
product *= val
|
||
|
}
|
||
|
fmt.Println(product)
|
||
|
}
|
||
|
|
||
|
func getTiles(input []string) map[int][4]string{
|
||
|
var tiles = make(map[int][4]string)
|
||
|
for _, val := range input {
|
||
|
id, edges := getTile(val)
|
||
|
fmt.Printf("ID:%v \n",id )
|
||
|
tiles[id] = edges
|
||
|
}
|
||
|
return tiles
|
||
|
}
|
||
|
|
||
|
func getTile(input string) (int, [4]string) {
|
||
|
tilesRow := strings.Split(input, lineBreak)
|
||
|
var edges [4]string
|
||
|
edges[0] = tilesRow[1]
|
||
|
edges[2] = tilesRow[len(tilesRow)-1]
|
||
|
for _, val := range tilesRow[1:] {
|
||
|
edges[3] = edges[3]+val[0:1]
|
||
|
edges[1] = edges[1]+val[len(val)-1:]
|
||
|
}
|
||
|
r, _ := regexp.Compile("[0-9]{4}")
|
||
|
number, _ := strconv.Atoi(r.FindString(tilesRow[0]))
|
||
|
return number, edges
|
||
|
}
|
||
|
|
||
|
func getAllEdges(tiles map[int][4]string, id int) []string{
|
||
|
var edges []string
|
||
|
for key,val := range tiles {
|
||
|
if key != id {
|
||
|
for _, edge := range val {
|
||
|
edges = append(edges, edge)
|
||
|
edges = append(edges, reverse(edge))
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return edges
|
||
|
}
|
||
|
|
||
|
func findCorners(tiles map[int][4]string) []int{
|
||
|
var cornerIds []int
|
||
|
for key,val := range tiles{
|
||
|
edgesOfOtherTiles := getAllEdges(tiles,key)
|
||
|
fmt.Printf("ID: %v, MatchingEdges: %v \n",key,countMatchingEges(edgesOfOtherTiles,val))
|
||
|
if countMatchingEges(edgesOfOtherTiles,val) <= 2{
|
||
|
cornerIds= append(cornerIds,key)
|
||
|
}
|
||
|
}
|
||
|
return cornerIds
|
||
|
}
|
||
|
|
||
|
func countMatchingEges(allEdges []string, tileEdges [4]string) int{
|
||
|
count := 0
|
||
|
for _, val := range tileEdges{
|
||
|
if hasMatchingEdge(allEdges,val){
|
||
|
count ++
|
||
|
}
|
||
|
}
|
||
|
return count
|
||
|
}
|
||
|
|
||
|
func hasMatchingEdge(edges []string, edge string) bool {
|
||
|
for _, val := range edges {
|
||
|
if val == edge{
|
||
|
return true
|
||
|
}
|
||
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
func reverse(s string) string {
|
||
|
runes := []rune(s)
|
||
|
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
|
||
|
runes[i], runes[j] = runes[j], runes[i]
|
||
|
}
|
||
|
return string(runes)
|
||
|
}
|