|
|
|
@ -9,11 +9,12 @@ import ( |
|
|
|
|
"strings" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
var lineBreak = "\n" |
|
|
|
|
var lineBreak = "\r\n" |
|
|
|
|
|
|
|
|
|
type tile struct { |
|
|
|
|
neighbourID [4]int |
|
|
|
|
edges [4]string |
|
|
|
|
picture []string |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func main() { |
|
|
|
@ -23,28 +24,138 @@ func main() { |
|
|
|
|
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 |
|
|
|
|
var tilesWithNeighbours = make(map[int]tile) |
|
|
|
|
for id,tile := range tiles { |
|
|
|
|
tilesWithNeighbours[id] = getNeighboursForTile(id,tile,tiles) |
|
|
|
|
} |
|
|
|
|
var corners = make(map[int]tile) |
|
|
|
|
for key, tile := range tilesWithNeighbours { |
|
|
|
|
pictureEdges := 0 |
|
|
|
|
for _, val := range tile.neighbourID{ |
|
|
|
|
if val == 0 { |
|
|
|
|
pictureEdges++ |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if pictureEdges == 2 { |
|
|
|
|
corners[key] = tile |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
product := 1 |
|
|
|
|
for key,_ := range corners { |
|
|
|
|
product *= key |
|
|
|
|
} |
|
|
|
|
fmt.Println(product) |
|
|
|
|
var picture = make(map[[2]int]int) |
|
|
|
|
picture = getPictureStep(1951,tilesWithNeighbours,[]int{},picture,[2]int{0,0}) |
|
|
|
|
fmt.Println(picture) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getPicture(corners map[int]tile, allTiles map[int]tile) map[[2]int]int { |
|
|
|
|
var picture = make(map[[2]int]int) |
|
|
|
|
//len := math.Sqrt(float64(len(allTiles)))
|
|
|
|
|
fmt.Printf("HI %v \n", getSomeTile(corners)) |
|
|
|
|
currentTileId := 1951 |
|
|
|
|
currentTile := corners[currentTileId] |
|
|
|
|
picture[[2]int{0,0}] = currentTileId |
|
|
|
|
fmt.Println(currentTile.neighbourID) |
|
|
|
|
fmt.Println(currentTile.edges) |
|
|
|
|
printPicture(currentTile.picture) |
|
|
|
|
return picture |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getPictureStep(currentTile int,allTiles map[int]tile,visitedTiles []int, picture map[[2]int]int,position [2]int) map[[2]int]int{ |
|
|
|
|
for len(visitedTiles) < len(allTiles){ |
|
|
|
|
picture[position] = currentTile |
|
|
|
|
visitedTiles = append(visitedTiles,currentTile) |
|
|
|
|
nextTile := 0 |
|
|
|
|
for i, val := range allTiles[currentTile].neighbourID { |
|
|
|
|
if val != 0 && !contains(val,visitedTiles){ |
|
|
|
|
nextTile = val |
|
|
|
|
switch i { |
|
|
|
|
case 0: position = [2]int{position[0],position[1]+1} |
|
|
|
|
case 1: position = [2]int{position[0]+1,position[1]} |
|
|
|
|
case 2: position = [2]int{position[0],position[1]-1} |
|
|
|
|
case 3: position = [2]int{position[0]-1,position[1]} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
currentTile = nextTile |
|
|
|
|
} |
|
|
|
|
return picture |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getTiles(input []string) map[int][4]string{ |
|
|
|
|
var tiles = make(map[int][4]string) |
|
|
|
|
func contains(elem int, array []int) bool{ |
|
|
|
|
for _, val := range array{ |
|
|
|
|
if val == elem{ |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getSomeTile(m map[int]tile) int { |
|
|
|
|
for k := range m { |
|
|
|
|
return k |
|
|
|
|
} |
|
|
|
|
return 0 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func printPicture(input[]string){ |
|
|
|
|
for _, row := range input { |
|
|
|
|
fmt.Println(row) |
|
|
|
|
} |
|
|
|
|
fmt.Println() |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func rotate(tile tile) tile{ |
|
|
|
|
var newPicture [10][10]rune |
|
|
|
|
for i:= 0; i < len(tile.picture); i++ { |
|
|
|
|
for j:= 0; j < len(tile.picture); j++ { |
|
|
|
|
newPicture[i][j] = rune(tile.picture[len(tile.picture)-j-1][i]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
var newNeighbourId [4]int |
|
|
|
|
newNeighbourId[0] = tile.neighbourID[3] |
|
|
|
|
for i,val := range tile.neighbourID[:2]{ |
|
|
|
|
newNeighbourId[i+1] = val |
|
|
|
|
} |
|
|
|
|
tile.neighbourID = newNeighbourId |
|
|
|
|
for i,row := range newPicture { |
|
|
|
|
tile.picture[i] = string(row[:]) |
|
|
|
|
} |
|
|
|
|
return tile |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//0 horizontal
|
|
|
|
|
//1 vertical
|
|
|
|
|
func flip(tile tile, direction int) tile{ |
|
|
|
|
var newPicture []string |
|
|
|
|
if direction == 0{ |
|
|
|
|
for i := len(tile.picture); i >= 0; i--{ |
|
|
|
|
newPicture = append(newPicture,tile.picture[i]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if direction == 1{ |
|
|
|
|
for _,val := range tile.picture { |
|
|
|
|
newPicture = append(newPicture,reverse(val)) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
printPicture(newPicture) |
|
|
|
|
tile.picture = newPicture |
|
|
|
|
return tile |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getTiles(input []string) map[int]tile{ |
|
|
|
|
var tiles = make(map[int]tile) |
|
|
|
|
for _, val := range input { |
|
|
|
|
id, edges := getTile(val) |
|
|
|
|
fmt.Printf("ID:%v \n",id ) |
|
|
|
|
tiles[id] = edges |
|
|
|
|
id, tile := getTile(val) |
|
|
|
|
tiles[id] = tile |
|
|
|
|
} |
|
|
|
|
return tiles |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getTile(input string) (int, [4]string) { |
|
|
|
|
func getTile(input string) (int, tile) { |
|
|
|
|
tilesRow := strings.Split(input, lineBreak) |
|
|
|
|
var edges [4]string |
|
|
|
|
edges[0] = tilesRow[1] |
|
|
|
@ -55,42 +166,57 @@ func getTile(input string) (int, [4]string) { |
|
|
|
|
} |
|
|
|
|
r, _ := regexp.Compile("[0-9]{4}") |
|
|
|
|
number, _ := strconv.Atoi(r.FindString(tilesRow[0])) |
|
|
|
|
return number, edges |
|
|
|
|
return number, tile{[4]int{},edges, tilesRow[1:]} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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)) |
|
|
|
|
} |
|
|
|
|
func getAllPossibleEdgesForTile(tile tile, direction int) []string{ |
|
|
|
|
switch direction { |
|
|
|
|
case -1: |
|
|
|
|
var edges [4]string |
|
|
|
|
for i, edge := range tile.edges { |
|
|
|
|
edges[i] = edge |
|
|
|
|
} |
|
|
|
|
return edges[:] |
|
|
|
|
case 0: |
|
|
|
|
return getAllPossibleEdgesForFlippedTile(tile,0) |
|
|
|
|
case 1: |
|
|
|
|
return getAllPossibleEdgesForFlippedTile(tile,1) |
|
|
|
|
} |
|
|
|
|
return edges |
|
|
|
|
return []string{} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
func getAllPossibleEdgesForFlippedTile(tile tile, direction int) []string{ |
|
|
|
|
var edges [4]string |
|
|
|
|
for i:= 0; i < len(tile.edges); i ++ { |
|
|
|
|
if i % 2 == direction { |
|
|
|
|
edges[i] = reverse(tile.edges[i]) |
|
|
|
|
}else{ |
|
|
|
|
edges[i] = reverse(tile.edges[i]) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return cornerIds |
|
|
|
|
return edges[:] |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func getNeighboursForTile(choosenTile int, tile tile, allTiles map[int]tile) tile{ |
|
|
|
|
var idToPossibleEdges = make(map[int][]string) |
|
|
|
|
for id,tile := range allTiles { |
|
|
|
|
idToPossibleEdges[id] = getAllPossibleEdgesForTile(tile,-1) |
|
|
|
|
idToPossibleEdges[id] = append(idToPossibleEdges[id],getAllPossibleEdgesForTile(tile,0)...) |
|
|
|
|
idToPossibleEdges[id] = append(idToPossibleEdges[id],getAllPossibleEdgesForTile(tile,1)...) |
|
|
|
|
} |
|
|
|
|
for i, edge := range tile.edges { |
|
|
|
|
tile.neighbourID[i] = getFittingTileForEdge(choosenTile,edge,idToPossibleEdges) |
|
|
|
|
} |
|
|
|
|
return tile |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func countMatchingEges(allEdges []string, tileEdges [4]string) int{ |
|
|
|
|
count := 0 |
|
|
|
|
for _, val := range tileEdges{ |
|
|
|
|
if hasMatchingEdge(allEdges,val){ |
|
|
|
|
count ++ |
|
|
|
|
func getFittingTileForEdge(choosenTile int, edge string, idToPossibleEdges map[int][]string) int{ |
|
|
|
|
for id,edges := range idToPossibleEdges { |
|
|
|
|
if choosenTile != id && hasMatchingEdge(edges,edge){ |
|
|
|
|
return id |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return count |
|
|
|
|
return 0 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func hasMatchingEdge(edges []string, edge string) bool { |
|
|
|
@ -109,3 +235,5 @@ func reverse(s string) string { |
|
|
|
|
} |
|
|
|
|
return string(runes) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|