partial d15
This commit is contained in:
		
							parent
							
								
									6a046fdb1c
								
							
						
					
					
						commit
						99242d53d7
					
				
					 6 changed files with 227 additions and 0 deletions
				
			
		
							
								
								
									
										44
									
								
								d15/common.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								d15/common.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | |||
| package d15 | ||||
| 
 | ||||
| import ( | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| func weightNeighbors(in string) (weights, neighbors) { | ||||
| 	weights := make(weights) | ||||
| 	neighbors := make(neighbors) | ||||
| 	lines := strings.Split(strings.TrimSpace(in), "\n") | ||||
| 	height := len(lines) | ||||
| 	width := len(lines[0]) | ||||
| 	for y, line := range lines { | ||||
| 		for x, weight := range strings.Split(line, "") { | ||||
| 			weight, _ := strconv.Atoi(weight) | ||||
| 			weights[node(x+y*height)] = weight | ||||
| 		} | ||||
| 	} | ||||
| 	maxX := width | ||||
| 	maxY := height | ||||
| 	for height >= 0 { | ||||
| 		width = maxX | ||||
| 		for width >= 0 { | ||||
| 			current := node(width + height*maxY) | ||||
| 			if height > 0 { | ||||
| 				neighbors[current] = append(neighbors[current], node(width+(height-1)*maxY)) | ||||
| 			} | ||||
| 			if height < maxY { | ||||
| 				neighbors[current] = append(neighbors[current], node(width+(height+1)*maxY)) | ||||
| 			} | ||||
| 			if width > 0 { | ||||
| 				neighbors[current] = append(neighbors[current], node(width+height*maxY-1)) | ||||
| 			} | ||||
| 			if width < maxX { | ||||
| 				neighbors[current] = append(neighbors[current], node(width+height*maxY+1)) | ||||
| 
 | ||||
| 			} | ||||
| 			width-- | ||||
| 		} | ||||
| 		height-- | ||||
| 	} | ||||
| 	return weights, neighbors | ||||
| } | ||||
							
								
								
									
										51
									
								
								d15/d15_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								d15/d15_test.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| package d15 | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestP1(t *testing.T) { | ||||
| 	result := P1(`1163751742 | ||||
| 1381373672 | ||||
| 2136511328 | ||||
| 3694931569 | ||||
| 7463417111 | ||||
| 1319128137 | ||||
| 1359912421 | ||||
| 3125421639 | ||||
| 1293138521 | ||||
| 2311944581`) | ||||
| 
 | ||||
| 	assert.EqualValues(t, 40, result) | ||||
| } | ||||
| 
 | ||||
| func TestP2(t *testing.T) { | ||||
| 	result := P2(`1163751742 | ||||
| 1381373672 | ||||
| 2136511328 | ||||
| 3694931569 | ||||
| 7463417111 | ||||
| 1319128137 | ||||
| 1359912421 | ||||
| 3125421639 | ||||
| 1293138521 | ||||
| 2311944581`) | ||||
| 
 | ||||
| 	assert.EqualValues(t, 315, result) | ||||
| } | ||||
| 
 | ||||
| func BenchmarkP2(t *testing.B) { | ||||
| 	P2(`1163751742 | ||||
| 1381373672 | ||||
| 2136511328 | ||||
| 3694931569 | ||||
| 7463417111 | ||||
| 1319128137 | ||||
| 1359912421 | ||||
| 3125421639 | ||||
| 1293138521 | ||||
| 2311944581`) | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										58
									
								
								d15/dijkstra.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								d15/dijkstra.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,58 @@ | |||
| package d15 | ||||
| 
 | ||||
| import ( | ||||
| 	"math" | ||||
| 
 | ||||
| 	"golang.org/x/exp/maps" | ||||
| ) | ||||
| 
 | ||||
| type node int | ||||
| 
 | ||||
| type weights map[node]int | ||||
| 
 | ||||
| type neighbors map[node][]node | ||||
| 
 | ||||
| func minDistance(unvisited weights, distances weights) node { | ||||
| 	var min node | ||||
| 	var minDistance = math.MaxInt64 | ||||
| 	for current := range unvisited { | ||||
| 		if distances[current] < minDistance { | ||||
| 			min = current | ||||
| 			minDistance = distances[current] | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return min | ||||
| } | ||||
| 
 | ||||
| func assignMap[M ~map[K]V, K comparable, V any](m M, v V) M { | ||||
| 	n := make(M, len(m)) | ||||
| 	for k := range m { | ||||
| 		n[k] = v | ||||
| 	} | ||||
| 	return n | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| func dijkstra(start node, end node, weights weights, neighbors neighbors) int { | ||||
| 	distances := assignMap(weights, math.MaxInt64) | ||||
| 	unvisited := maps.Clone(weights) | ||||
| 
 | ||||
| 	distances[start] = 0 | ||||
| 
 | ||||
| 	for len(unvisited) != 0 { | ||||
| 		current := minDistance(unvisited, distances) | ||||
| 
 | ||||
| 		delete(unvisited, current) | ||||
| 
 | ||||
| 		for _, neighbor := range neighbors[current] { | ||||
| 			oldDistance := distances[neighbor] | ||||
| 			newDistance := weights[neighbor] + distances[current] | ||||
| 			if newDistance < oldDistance { | ||||
| 				distances[neighbor] = newDistance | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return distances[end] | ||||
| } | ||||
							
								
								
									
										7
									
								
								d15/dijkstra_test.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								d15/dijkstra_test.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,7 @@ | |||
| package d15 | ||||
| 
 | ||||
| import "testing" | ||||
| 
 | ||||
| func TestDijkstra(t *testing.T) { | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										6
									
								
								d15/p1.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								d15/p1.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | |||
| package d15 | ||||
| 
 | ||||
| func P1(in string) int { | ||||
| 	weights, neighbors := weightNeighbors(in) | ||||
| 	return dijkstra(0, node(len(weights)-1), weights, neighbors) | ||||
| } | ||||
							
								
								
									
										61
									
								
								d15/p2.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								d15/p2.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,61 @@ | |||
| package d15 | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| func expand(in [][]int) [][]int { | ||||
| 	height := len(in) | ||||
| 	width := len(in[0]) | ||||
| 
 | ||||
| 	expanded := make([][]int, height*5) | ||||
| 
 | ||||
| 	for y := range expanded { | ||||
| 		expanded[y] = make([]int, width*5) | ||||
| 	} | ||||
| 
 | ||||
| 	for y, line := range in { | ||||
| 		for x, num := range line { | ||||
| 			for i := 0; i < 5; i++ { | ||||
| 				for j := 0; j < 5; j++ { | ||||
| 					expanded[y+(height*i)][x+(width*j)] = (num + i + j) % 9 | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return expanded | ||||
| } | ||||
| 
 | ||||
| func expandMap(in string) string { | ||||
| 	lines := make([][]int, 0) | ||||
| 	for _, line := range strings.Split(strings.TrimSpace(in), "\n") { | ||||
| 		nums := make([]int, 0) | ||||
| 		for _, weight := range strings.Split(line, "") { | ||||
| 			weight, _ := strconv.Atoi(weight) | ||||
| 			nums = append(nums, weight) | ||||
| 		} | ||||
| 		lines = append(lines, nums) | ||||
| 	} | ||||
| 
 | ||||
| 	expanded := expand(lines) | ||||
| 
 | ||||
| 	newMap := "" | ||||
| 
 | ||||
| 	for _, line := range expanded { | ||||
| 		for _, num := range line { | ||||
| 			newMap = newMap + fmt.Sprint(num) | ||||
| 		} | ||||
| 
 | ||||
| 		newMap += "\n" | ||||
| 	} | ||||
| 
 | ||||
| 	return newMap | ||||
| } | ||||
| 
 | ||||
| func P2(in string) int { | ||||
| 	weights, neighbors := weightNeighbors(expandMap(in)) | ||||
| 	return dijkstra(0, node(len(weights)-1), weights, neighbors) | ||||
| } | ||||
		Loading…
	
	Add table
		
		Reference in a new issue