Compare commits
	
		
			10 Commits
		
	
	
		
			5e0889010a
			...
			37c999e331
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 37c999e331 | |||
| 378e403c1c | |||
| 06a22511b5 | |||
| a2563b9d31 | |||
| 3c2ea4ed9e | |||
| 1fac5f7b4d | |||
| 1a3374a557 | |||
| 170fecc9f6 | |||
| 58e482b125 | |||
| 7847d11f95 | 
							
								
								
									
										210
									
								
								aoc_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										210
									
								
								aoc_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,210 @@
 | 
			
		||||
package aoc_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/matryer/is"
 | 
			
		||||
	aoc "go.sour.is/advent-of-code"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestReverse(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.Reverse([]int{1, 2, 3, 4}), []int{4, 3, 2, 1})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestLCM(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.LCM([]int{}...), 0)
 | 
			
		||||
	is.Equal(aoc.LCM(5), 5)
 | 
			
		||||
	is.Equal(aoc.LCM(5, 3), 15)
 | 
			
		||||
	is.Equal(aoc.LCM(5, 3, 2), 30)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestReadStringToInts(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.ReadStringToInts([]string{"1", "2", "3"}), []int{1, 2, 3})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRepeat(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.Repeat(5, 3), []int{5, 5, 5})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPower2(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.Power2(0), 1)
 | 
			
		||||
	is.Equal(aoc.Power2(1), 2)
 | 
			
		||||
	is.Equal(aoc.Power2(2), 4)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestABS(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.ABS(1), 1)
 | 
			
		||||
	is.Equal(aoc.ABS(0), 0)
 | 
			
		||||
	is.Equal(aoc.ABS(-1), 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestTranspose(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(
 | 
			
		||||
		aoc.Transpose(
 | 
			
		||||
			[][]int{
 | 
			
		||||
				{1, 1},
 | 
			
		||||
				{0, 0},
 | 
			
		||||
				{1, 1},
 | 
			
		||||
			},
 | 
			
		||||
		),
 | 
			
		||||
		[][]int{
 | 
			
		||||
			{1, 0, 1},
 | 
			
		||||
			{1, 0, 1},
 | 
			
		||||
		},
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestList(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	lis := aoc.NewList[int](nil)
 | 
			
		||||
	lis.Add(5, 0)
 | 
			
		||||
 | 
			
		||||
	a, _ := lis.Head().Value()
 | 
			
		||||
 | 
			
		||||
	is.Equal(a, 5)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPriorityQueue(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	type elem [2]int
 | 
			
		||||
	less := func(a, b elem) bool {
 | 
			
		||||
		return b[0] < a[0]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pq := aoc.PriorityQueue(less)
 | 
			
		||||
 | 
			
		||||
	pq.Enqueue(elem{1, 4})
 | 
			
		||||
	pq.Enqueue(elem{3, 2})
 | 
			
		||||
	pq.Enqueue(elem{2, 3})
 | 
			
		||||
	pq.Enqueue(elem{4, 1})
 | 
			
		||||
 | 
			
		||||
	v, ok := pq.Dequeue()
 | 
			
		||||
	is.True(ok)
 | 
			
		||||
	is.Equal(v, elem{4, 1})
 | 
			
		||||
 | 
			
		||||
	v, ok = pq.Dequeue()
 | 
			
		||||
	is.True(ok)
 | 
			
		||||
	is.Equal(v, elem{3, 2})
 | 
			
		||||
 | 
			
		||||
	v, ok = pq.Dequeue()
 | 
			
		||||
	is.True(ok)
 | 
			
		||||
	is.Equal(v, elem{2, 3})
 | 
			
		||||
 | 
			
		||||
	v, ok = pq.Dequeue()
 | 
			
		||||
	is.True(ok)
 | 
			
		||||
	is.Equal(v, elem{1, 4})
 | 
			
		||||
 | 
			
		||||
	v, ok = pq.Dequeue()
 | 
			
		||||
	is.True(!ok)
 | 
			
		||||
	is.Equal(v, elem{})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSet(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	s := aoc.Set(1, 2, 3)
 | 
			
		||||
	is.True(!s.Has(0))
 | 
			
		||||
	is.True(s.Has(1))
 | 
			
		||||
	is.True(s.Has(2))
 | 
			
		||||
	is.True(s.Has(3))
 | 
			
		||||
	is.True(!s.Has(4))
 | 
			
		||||
 | 
			
		||||
	s.Add(4)
 | 
			
		||||
	is.True(s.Has(4))
 | 
			
		||||
 | 
			
		||||
	items := s.Items()
 | 
			
		||||
	sort.Ints(items)
 | 
			
		||||
	is.Equal(items, []int{1, 2, 3, 4})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// func TestGraph(t *testing.T) {
 | 
			
		||||
// 	g := aoc.Graph[int, uint](7)
 | 
			
		||||
// 	g.AddEdge(0, 1, 2)
 | 
			
		||||
// 	g.AddEdge(0, 2, 6)
 | 
			
		||||
// 	g.AddEdge(1, 3, 5)
 | 
			
		||||
// 	g.AddEdge(2, 3, 8)
 | 
			
		||||
// 	g.AddEdge(3, 4, 10)
 | 
			
		||||
// 	g.AddEdge(3, 5, 15)
 | 
			
		||||
// 	g.AddEdge(4, 6, 2)
 | 
			
		||||
// 	g.AddEdge(5, 6, 6)
 | 
			
		||||
// 	// g.Dijkstra(0)
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
func ExamplePriorityQueue() {
 | 
			
		||||
	type memo struct {
 | 
			
		||||
		pt    int
 | 
			
		||||
		score int
 | 
			
		||||
	}
 | 
			
		||||
	less := func(a, b memo) bool { return a.score < b.score }
 | 
			
		||||
 | 
			
		||||
	adj := map[int][][2]int{
 | 
			
		||||
		0: {{1, 2}, {2, 6}},
 | 
			
		||||
		1: {{3, 5}},
 | 
			
		||||
		2: {{3, 8}},
 | 
			
		||||
		3: {{4, 10}, {5, 15}},
 | 
			
		||||
		4: {{6, 2}},
 | 
			
		||||
		5: {{6, 6}},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pq := aoc.PriorityQueue(less)
 | 
			
		||||
	visited := aoc.Set([]int{}...)
 | 
			
		||||
	dist := aoc.DefaultMap[int](int(^uint(0) >> 1))
 | 
			
		||||
 | 
			
		||||
	dist.Set(0, 0)
 | 
			
		||||
	pq.Enqueue(memo{0, 0})
 | 
			
		||||
 | 
			
		||||
	for !pq.IsEmpty() {
 | 
			
		||||
		m, _ := pq.Dequeue()
 | 
			
		||||
 | 
			
		||||
		u := m.pt
 | 
			
		||||
		if visited.Has(u) {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		visited.Add(u)
 | 
			
		||||
 | 
			
		||||
		du, _ := dist.Get(u)
 | 
			
		||||
 | 
			
		||||
		for _, edge := range adj[u] {
 | 
			
		||||
			v, w := edge[0], edge[1]
 | 
			
		||||
			dv, _ := dist.Get(v)
 | 
			
		||||
 | 
			
		||||
			if !visited.Has(v) && du+w < dv {
 | 
			
		||||
				dist.Set(v, du+w)
 | 
			
		||||
				pq.Enqueue(memo{v, du + w})
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	items := dist.Items()
 | 
			
		||||
	sort.Slice(items, func(i, j int) bool { return items[i].K < items[j].K })
 | 
			
		||||
	for _, v := range items {
 | 
			
		||||
		fmt.Printf("point %d is %d steps away.\n", v.K, v.V)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Output:
 | 
			
		||||
	// point 0 is 0 steps away.
 | 
			
		||||
	// point 1 is 2 steps away.
 | 
			
		||||
	// point 2 is 6 steps away.
 | 
			
		||||
	// point 3 is 7 steps away.
 | 
			
		||||
	// point 4 is 17 steps away.
 | 
			
		||||
	// point 5 is 22 steps away.
 | 
			
		||||
	// point 6 is 19 steps away.
 | 
			
		||||
}
 | 
			
		||||
@ -30,7 +30,6 @@ func TestExample1(t *testing.T) {
 | 
			
		||||
	is.Equal(result.sum, 142)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func TestExample2(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
	scan := bufio.NewScanner(bytes.NewReader(example2))
 | 
			
		||||
 | 
			
		||||
@ -36,11 +36,10 @@ func TestSolution(t *testing.T) {
 | 
			
		||||
	is.NoErr(err)
 | 
			
		||||
 | 
			
		||||
	t.Log(result)
 | 
			
		||||
 is.True(result.valuePT2 < 87286) // first submission
 | 
			
		||||
 is.True(result.valuePT2 < 87292) // second submission
 | 
			
		||||
 is.True(result.valuePT2 < 87287) // third submission
 | 
			
		||||
	is.True(result.valuePT2 < 87286) // first submission
 | 
			
		||||
	is.True(result.valuePT2 < 87292) // second submission
 | 
			
		||||
	is.True(result.valuePT2 < 87287) // third submission
 | 
			
		||||
 | 
			
		||||
	is.Equal(result.valuePT1, 110407)
 | 
			
		||||
	is.Equal(result.valuePT2, 87273)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -32,15 +32,15 @@ func run(scan *bufio.Scanner) (*result, error) {
 | 
			
		||||
 | 
			
		||||
	options := make([]int, 2*(rows+cols)+2)
 | 
			
		||||
	i := 0
 | 
			
		||||
	for j:=0; j<=rows-1; j++ {
 | 
			
		||||
	for j := 0; j <= rows-1; j++ {
 | 
			
		||||
		options[i+0] = runCycle(m, ray{[2]int{j, -1}, RT})
 | 
			
		||||
		options[i+1] = runCycle(m, ray{[2]int{j, cols}, LF})
 | 
			
		||||
		i+=2
 | 
			
		||||
		i += 2
 | 
			
		||||
	}
 | 
			
		||||
	for j:=0; j<=cols-1; j++ {
 | 
			
		||||
	for j := 0; j <= cols-1; j++ {
 | 
			
		||||
		options[i+0] = runCycle(m, ray{[2]int{-1, j}, DN})
 | 
			
		||||
		options[i+1] = runCycle(m, ray{[2]int{rows, j}, UP})
 | 
			
		||||
		i+=2
 | 
			
		||||
		i += 2
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// fmt.Println(options)
 | 
			
		||||
@ -96,7 +96,6 @@ func (m *Map) Get(p [2]int) rune {
 | 
			
		||||
	return (*m)[p[0]][p[1]]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
func runCycle(m Map, r ray) int {
 | 
			
		||||
	current := r
 | 
			
		||||
 | 
			
		||||
@ -186,4 +185,4 @@ func runCycle(m Map, r ray) int {
 | 
			
		||||
	// }
 | 
			
		||||
 | 
			
		||||
	return len(energized)
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -47,4 +47,4 @@ func TestStack(t *testing.T) {
 | 
			
		||||
	s := stack[int]{}
 | 
			
		||||
	s.Push(5)
 | 
			
		||||
	is.Equal(s.Pop(), 5)
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								day17/example.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								day17/example.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,13 @@
 | 
			
		||||
2413432311323
 | 
			
		||||
3215453535623
 | 
			
		||||
3255245654254
 | 
			
		||||
3446585845452
 | 
			
		||||
4546657867536
 | 
			
		||||
1438598798454
 | 
			
		||||
4457876987766
 | 
			
		||||
3637877979653
 | 
			
		||||
4654967986887
 | 
			
		||||
4564679986453
 | 
			
		||||
1224686865563
 | 
			
		||||
2546548887735
 | 
			
		||||
4322674655533
 | 
			
		||||
							
								
								
									
										141
									
								
								day17/input.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								day17/input.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,141 @@
 | 
			
		||||
222343122415245553243251316124223234134666332224124211645376775672443247264263475261513546522316162532215534453661231232515522214351143451211
 | 
			
		||||
422125443253354142511545636246664666565355152246453231651172747635424163415626462753445445312334225221624336126244661514234445544425223533122
 | 
			
		||||
131212112421423414125516356342555542626661163526211536677376523712262371162153644117776261645533664544366146314432523222515425314231311544521
 | 
			
		||||
131334344235153415214541223454455223563154114267331524774136127715554416125273543276346471735741663351266324144422511534542234341513351345352
 | 
			
		||||
314541545523112111131565114333211153312641614321771374726154434476767125613311254537363422511721275135434164664442151263234241114111121141334
 | 
			
		||||
435153335153513534132112326653656626231351436457153446433363235565156156723233715473535244413451723176561153261562445512312413413513135513241
 | 
			
		||||
235243535523134543445216214455445352435554624255171271225755313626173154112144673146273747537614771377613244145436355342536323123434425211113
 | 
			
		||||
132552152551514515631323412533333446136243376366556365574745474652757277632216317677316551253673465513776336664225626313216456312542531241352
 | 
			
		||||
311415311541314143614162642634556464574541744355655753776632763662153656721435137347422375344242225276244673434333351454464536453212424421425
 | 
			
		||||
453351344131342126143165264626543453632747531417235617257564537542611276314542732241535726557435722271523761452243145343543365433423153132344
 | 
			
		||||
424354321333252642533513531241416236636427325176724425161362563217173773414665312244155777552374513335344162564462411154332652126231133233331
 | 
			
		||||
433224533551436134314641523151361154615353522622137441214134673454347752343853221756746664765556521762762464233333523123643145626644231443435
 | 
			
		||||
243311313556533564523443331214721572253144611715156456321767676655457736255732864573164467712433421256325731135656541255561161224441152415141
 | 
			
		||||
511211214252345356344156642436611545463224342452742717585325436325574336455336582448256836717741726221177352616311422112513255165441212221131
 | 
			
		||||
244253443163544142511413446172632624762126756145146775348573476557644782564438437852836725866452746165474553473737534665123425113435563332453
 | 
			
		||||
232155346345514313654314235557517112176174776332136456448427547478426265844263882743533766568854547675464477171376662424251312612162632514355
 | 
			
		||||
424114441642564135264345176163444365144163124128832285838626688224834432458556377773645427653638562736676174576737574642156232566466636441124
 | 
			
		||||
543244331213246512421551417132132647763461226245235583478358556478588445828784366325778587856624776125647332126411416416253326543252561355453
 | 
			
		||||
513411632124243263566153173255453461117356682265475822242236525286334354628536868726586284535383867467645552277715213631624352612331534144225
 | 
			
		||||
234513324414264131211345613416736552211115685767773523645885727834464346536233245827443237753783724626566246761647646475456131431415434413214
 | 
			
		||||
132312323255146664114745115275443572754326543474673247542856435836784453584863735676475556838547655484787272216413226712176641452341133361621
 | 
			
		||||
324445311115236332563161165371142354332783687877726543524347444677384655338335874866474624655543543466338566764524432633543363631622335214314
 | 
			
		||||
452146561262254136627644671525514257523265444635773245326674352228844844533536247443486645863647324742823822411266212747246263222143515531123
 | 
			
		||||
323443456261326564347757145611113632534754323645837762327643383533554795688333775647234446628482555868382485343642524356327477353226234131236
 | 
			
		||||
323566623463524644662155345214734554448367587534458465333783778836737748873896436675564776876254472473382773351746477537426351164321556552155
 | 
			
		||||
411624314463555226413151162214157826642348553426375774773937688356445778864665387877397647688288645648488526683635462551221145364643422311353
 | 
			
		||||
632541423444624336526576464457777686224586376437338832948677343497666833369685846994446858346385546773453274862246234173462724342631561154224
 | 
			
		||||
353552612514333121215745416727247272652423544685753368594647394695658845883548858535734584333432476287445274435882257755366724515216151451335
 | 
			
		||||
532166314441574113623175262414284358754786632434337878589943898388748395969493754638344944356356855723827482463322173565111471477266643531656
 | 
			
		||||
116644351623354144151425116542234543365536844644456554366885339853375594997998864974865377578863643354482658652565456654732562467462642222633
 | 
			
		||||
425265565534525427323521564886284475834357765873953575557676864375449896735695696945686539933897587748627756658646775714547636543542445454453
 | 
			
		||||
535223341313647443711526456446656284686644344893747447894898636684595668686646634379736944587367734766868686525582828566224141647377452234555
 | 
			
		||||
363661154543263115262561162483434662346246798873478436638737549697754638834495375733735333645433574877375276735684662372751455123234415466135
 | 
			
		||||
233425541263155564422777566657463284532222644739657858356574964435535676435594635788954898867344838753677578547362236357265747553176223645334
 | 
			
		||||
516113313346251471245336736766463235445577574763999559496983357388779634999695985559489635746544658453383775634426265623615715313624324613363
 | 
			
		||||
325162436525537742416463226466422582452664444569687695737766869564846698477563438574369658749388443473974527623665566388541124766765465414216
 | 
			
		||||
246532424466452274271137247462733834328375758733755764656833968984956876697799766884997394499744585594587876625677723447244217267426213343664
 | 
			
		||||
164356325132241765153442235356485242287535595375398869579646888545895757975449659944533834737579865398575662388572336243423321763313272155166
 | 
			
		||||
563615555622724634724833866443433524894838958833799835363644977657658578544664475868679458747866349983337933858733558557637772576116524351364
 | 
			
		||||
415635136113175137578553536586564768643559866697595733497557879468449998976698759797676436636689587877974934738258785642847435574452213713115
 | 
			
		||||
611145153512463742256332755487858466583796497738685664885658748948569545664445888744947857868589779795933867483673776857358564657524755764663
 | 
			
		||||
235565633417713142257732254688636564985938796475899556649457697557496557466787887559566976984578789695478656638728764846466352277661663613361
 | 
			
		||||
621414363456434251274757622526573747939964946885796964745598945469487687577499977988878866574434454755956575894225366755752223145132155653231
 | 
			
		||||
345131227736331632753528624737877993467633874573544566489488585879587798745544677645759486797999989373758553748378762622865225676664655255241
 | 
			
		||||
211147374365347566347683538644229836375367399779966469889799674657475784657559849567645885568589949973844765649576234674566626355732735375222
 | 
			
		||||
123377577423217135757464227844458664877347575684876765589445958984848645558957589999985649678755757487567997496322362828232445742466637677526
 | 
			
		||||
664165716524474573468574845478963396633746335989586478477469677874488696466969855457589699479795777786993453995866655558838835473455711456363
 | 
			
		||||
645354217411347423778226725287476938984748595969986859957845897656645797969945967774756979786597495489759753559534884668577746471267563715146
 | 
			
		||||
641123731653617153523878786635997676839634584755798896844786989789997886975976877949768456676679545757849946967975863276534664727276625714772
 | 
			
		||||
115172313432542554343534322666684547383747359496846665858866986576677885977798965677465955688547658777937483437698822255673227856674321437423
 | 
			
		||||
412316124234335666538374784464654983653484498444688865778477997658875656978599866558669858496479969969883747883595375635748886535531163731666
 | 
			
		||||
126215534552633672772444476653659865338587448788645985679486758768567978966789759768556688875958549895757653789978826784367383554244325537527
 | 
			
		||||
252471722164728674273366346869733763887789597776444684764998985757556667899857586887855996664484555498483585754587755247628423684671244526734
 | 
			
		||||
616643241174113524686752733973994433637977478579974486858559967566675596878985789668957757945476696698659695977366876442282382768473657366141
 | 
			
		||||
433715625621658365787576378559966694694594565764577974766866977599956779776859687775695787565694987685963787977966448785772368444344613132341
 | 
			
		||||
542654365337336826434765643879738646353964647955974749776876686976656857777555965796959755779797949695874357763646457888473355582731254116326
 | 
			
		||||
461216754736354442526774233456439439344649448885449769679668978899596596779679669865776767595846454969558697477357393642534444663773547743151
 | 
			
		||||
242515737157657333842228548349875463457585648494866999577597668698587656558567788999587689857767876885764484449548964773473277753231345166735
 | 
			
		||||
654521345226446835568566235799768737539786475876888887965595966585598966967969975867759665599758868667576445864433979732538253832712175534524
 | 
			
		||||
115512724255847238822523769738898864344596868468594857859588665686578579798878998656799555798598889485694534558457599364226342568753677472213
 | 
			
		||||
111524524557584843753648338688446565566879945758747566968678858898688798787995576956865896565768766698768659698554344826255288878683415552615
 | 
			
		||||
775523534424885336584535598468769386864885649976596679699998877966986778776767559667869889767766556949956568378399476985828735885425764761532
 | 
			
		||||
617234235723887272453554398456849533986998847969886896697596899979688786876777696866697569685659688446949473894494359678374775655237573674227
 | 
			
		||||
731315731775542663287374348536374735499748575465485866966768699899697997797776666566989778755777686999847946948853933693544267753841326646546
 | 
			
		||||
722426246522232587267567746363433367778759685487558796666966958776698867986668698666876866775886659846776955633755765593638285378256357434712
 | 
			
		||||
174725351666826552875547497865663863549888789874668876958895676696978768897788786788566955869997548858768874638777786742243328886625132571731
 | 
			
		||||
611354237262464432722652894576534365759676599966965877965957687768769888968769696957679665987557457444944459839769348686383583662783465636276
 | 
			
		||||
435775645554577458385385799454458446877466964957585556758766679978876698869886969697899756896864788684659949467367797467452464686586746747527
 | 
			
		||||
326715157438852348356648795697795987947557758498877979757678677886679987996677668886868888557795864545877549896579885386328386465786533157726
 | 
			
		||||
453273273424255488663856445483976736667859995777897779896656697978997888787987898778776958957796758748894869487957534497554376546868722122324
 | 
			
		||||
224573216435873475783673336556553645879964994546857977556976898696968678989979687688777875655579994576659674597887987885384834758677414425113
 | 
			
		||||
356241135726344637684746374354974769468887978766569659956588999669799779786678667886579699675678884889486587434679643859352582448655434457222
 | 
			
		||||
466565323122567376356874397989745956794895966548765989989778688799697678896789997978696969665976575677558444868875986457762338452225134143337
 | 
			
		||||
362264215456463347238855743779549969969487765646768855768895876877976886666866799968989767688568764586578687569679978449782326532643416155546
 | 
			
		||||
671362724447463788282378857469553747694544454845755975585656699878677799678797776968799697957896898878765444867363549353272748888443452166364
 | 
			
		||||
632542654733754847425787585687488755596748847964799999775985798869786789699666867675565568797969676665954954838875438688564548862244145146171
 | 
			
		||||
333723417316447367476286584684499973896998895898557855668598997699996977697796768788767776689759949696664864687338847464274357245662617625121
 | 
			
		||||
732722335132788573566373398994377893654688989578766978658865988697879899789898877758688978567997675756877983739477395738266566365866553224517
 | 
			
		||||
147177514747474242267782783587784747967985778647866665897959877679967669667689876857669669767556998597597497483549887695587764775634662343617
 | 
			
		||||
152744472376652374322667687839455953897495766449899756875956679668789688868676978978876787578985556849965685833354883453248267842384616432657
 | 
			
		||||
217227543612352346346455856939488455758985798868598588765697888677977868879697796686766696678556576857569777547694747435272652536672167123712
 | 
			
		||||
744625215616674868776537785459394998859647888485449778786556769796876987889777989756758976977758496584958578978633843394583557326773745211217
 | 
			
		||||
353354332722486863626455784779737558677796677557648786868756998567779997999757769989968679778794444858495938377534839655447657354377534537617
 | 
			
		||||
351162251452745473452566496983484689397949849568679798775655588857855767769795678968695766898846549555848585493436735966444566758545364773274
 | 
			
		||||
546334341147183722785558798496869978864895677895756565879578585766957665575757696669676677769768545948765446463585354842584745473612425647573
 | 
			
		||||
235615763364478535767825263879546994497978874484569465769576969857869669765659777668868977865946966479776587987999955433355672374557554754214
 | 
			
		||||
162177325222163583735436483646438894396659587698644456886655596959879587966867768858997789444759867989565846639353845278562446263633245724416
 | 
			
		||||
324535255452483383635664425784958857579867676497445879975595969977679879855779697798889657664476857564676937793853344868547244368834643131142
 | 
			
		||||
121347276513238722442368557665693779499584456766988769868757758795788956896585869778678687556788794995887699638544336543625582864246234111541
 | 
			
		||||
357771157266317334828437783465549356369747964978875778866775965679685977988796799568586768676664767564576835757749675276226376757244531177246
 | 
			
		||||
336664616327762746632336856333359783983467896468668468658857596888666655696975568657694759566847599666396674475446532283582787232143364371132
 | 
			
		||||
644533212754142233635788744897443835653636699755644785889878558985567878858696858779788657475547995487649399794638387758824355331366214575725
 | 
			
		||||
222217676717612667687783367437478679946969645869469768494864887557985785659965856994457654994548995554598868743539788752855264561637271324324
 | 
			
		||||
356452154463414577848785374339498366535638544946846765677495769785557579699659788879447959897745467466459849543743454246822537753427335371562
 | 
			
		||||
343351256333451586862433643627656985753774749546555768998795848687576559887698545798748988498774696693748665338953758884323743215516455337651
 | 
			
		||||
511156433162323673647444877388393898578477588665844949845684789786485757669794987664595874795599974455755347864958728824643583546532455523751
 | 
			
		||||
156124537652656126446766564883685565845949468648655489495444579455874554846945778967786444756587898964737436487344256846452377111452125151424
 | 
			
		||||
515264356113762652852852632686537484556764597765774578755556886965448899978985694964457598494775673883444869546887836668355228143455736361562
 | 
			
		||||
263512646525146141226625365446528679473694599878945468469659775468694555669548954648468546665655847884688365888823562232347546127534712221733
 | 
			
		||||
631415241711525626678448673422265459959576695493999586674865475767744965494946497644686744965594334353963643655244478563353652375272512755651
 | 
			
		||||
233341711151632262167275682837682337594668593834657957999678754665457846558698875995554875885564465558544593484682334467458266753354353656363
 | 
			
		||||
222614621174264456548568855775763264556684446457483755666594465554896878549965797747587445795345639937745754468637877328233727712145444373316
 | 
			
		||||
551136576466563613374865837744634548656596546959875864946578986489646467467887584454698786369755639588797883757583882864432762672266561742114
 | 
			
		||||
311433545766254471655428367633528758869667674337353886355568568977559794557448545869856978986385835684993879575657778365536445625371464633155
 | 
			
		||||
223612464456771261577683747465843843667648368983574634838577897765496687876598844667977633334687854753563787465237347324763236171472235426346
 | 
			
		||||
411245121677351625555347323585443444334598696449339998397379788744556985684748696646376458494657966586849537253887746577841254462522431254352
 | 
			
		||||
344346233632636772414765673728476885836598589955558748979779588656646877576889768598337348786569379345443684386546372358847445714773517622512
 | 
			
		||||
155323536362462251246768675874228887274856495665585569666835536867574987794867838438565638693854398377677783434776265675564455312663443423541
 | 
			
		||||
331566446775752674417132753235465665833378447847639386878845593445734945386694688999635777683567968539426228468486664337643254264256612362121
 | 
			
		||||
243564654224225645722672382353864676463257496747548887493585987546678658735985743376384577953533946647357564447863573451724364472125432653566
 | 
			
		||||
342315614225414552353574355435638346877654437484463854837898965395385547754648364866393337683989446882326338262227448314144441743477561422165
 | 
			
		||||
513316635431624236671443348277886572254832458877847668477593794644585888563857755634797589885668862754772785358487877315135613177367144545513
 | 
			
		||||
463143244643262172563515774358878556748352525757567987986693359853994963575439443448643467386743366524235883462535432614464455735443452664134
 | 
			
		||||
365641135114444646623465131227245648484522527682468766639838853356859443957586854538395483886846572325432336737857272623363152162131551135414
 | 
			
		||||
416313341334271754356764361744638674522648825426627539586358437534848469663986377869797354638474474353788632454247175546246417444136416435644
 | 
			
		||||
224353155431264253763746646441542886447853826453463553364576374757797585985553484899859547773742768633328427884282476754133441524461616242643
 | 
			
		||||
141663652631255115673535171111246265842334873322667887864398959494389595436394448689564435578232373254536888873517235136312276614212451451513
 | 
			
		||||
124131511566566612435515461237554545678463532355284383577958338477334574565899548354995646534573786226335788675417311262514713363312364535154
 | 
			
		||||
423124641651141434731445642547213258886735546328578275442562699767675575457466479427885838355373878586875834224154546773247146645646322335264
 | 
			
		||||
412644326632526437735316412561445417468882886666655743427476665574794946797787288666754744722668682487625266217525212752446411411125122652443
 | 
			
		||||
533453646465125514654252753512273714342227373732733663723654553522224855828427587263828376724486786422622551345652174733731235533661345526462
 | 
			
		||||
431416626556561415256423726364711356216462533453778624228776264745488556248346558664685886255267664468734267241413666377354236365315112133322
 | 
			
		||||
115242144546551242654657115464153653733572255453735867582743877872748475375858445224247557346684865447435434415136572343667245436453541641214
 | 
			
		||||
211445545143351463615353774344215444543156828652686467572385233427763332873666832447256386848435536242337137777716372765516254142315334335233
 | 
			
		||||
345124663224645321264314114673647256557756426376735374628552375257437773764536467386624358238642865332573246663566211211655655563524242452555
 | 
			
		||||
314351264524343426135362454521352527263736457447533445374485277766767738682474542365754582457568722614424111744153725635141565436222616112315
 | 
			
		||||
525142531331665442641251651451342365334554162254374267466577736465886625773232626738363773743786773241666727445735231415436342625513255235151
 | 
			
		||||
543245142256442454155334231734217734761146755176638778856523266374354672783363252424683478557527343237227211135754547531342136551132351221533
 | 
			
		||||
241355115114515145351235241342577311663523713245571552423844478483444456674576776374774635321762611146175633416417526461446534624524525232351
 | 
			
		||||
413212231435125464562416642131514721163172662635774761555772466528432746222877628357558463622434577676277711461224526611415645224221334321153
 | 
			
		||||
424114552242412235261232556412366663124614547557116436567672766285253724382874567666431356536715216512355113511563132462412461555112225422135
 | 
			
		||||
322324544333135432235125224253374616723165212337472223432464246434784434268261665524555163346167575177573432151165141342526636661664333152245
 | 
			
		||||
533322454514225135644666511564116113743567665217446774461763723457213436114546254524754413534661176555531123216654634336153535555615455221351
 | 
			
		||||
345114245113253556125335351622625171466165175642167753751336711273734343723253343654164414153211641676412352766561245653215262351455523141451
 | 
			
		||||
142421541514212154334545211465656444644552463442357616615277117635256363621723512341776351424463622726131565431516465664346151153212233245553
 | 
			
		||||
444314343434312135211364665242441535527647475416223551347736416724264751235567161762631557147415445546211321423221136662344161541525343455425
 | 
			
		||||
513343214231252255165411335621632642146147645756642561211667322537371252122672641421372561555336143123644446534414131135624333443543522413531
 | 
			
		||||
151133414553422411155141354122545416221132657162133367556711163132611352466177573117122527412137673543111622364234433423115531533515415532534
 | 
			
		||||
344341433553215433332561124312211661162315615567541645475225431414323527474442612165214546553775576346352241352363416414626442233143123431324
 | 
			
		||||
312334123334252355135521123323245125516132154636463653576675247514555746177477533534522123547665145656414436131454466514531422525141331441324
 | 
			
		||||
221234522113214232242154165523542235561622643243233434644217742623556626525264626677654256257462621433131425222466152534235213545112335523443
 | 
			
		||||
							
								
								
									
										137
									
								
								day17/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								day17/main.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,137 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	_ "embed"
 | 
			
		||||
	"fmt"
 | 
			
		||||
 | 
			
		||||
	aoc "go.sour.is/advent-of-code"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// var log = aoc.Log
 | 
			
		||||
 | 
			
		||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
			
		||||
 | 
			
		||||
type result struct {
 | 
			
		||||
	valuePT1 int
 | 
			
		||||
	valuePT2 int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
			
		||||
 | 
			
		||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
			
		||||
	var m aoc.Map[rune]
 | 
			
		||||
 | 
			
		||||
	for scan.Scan() {
 | 
			
		||||
		text := scan.Text()
 | 
			
		||||
		m = append(m, []rune(text))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	result := result{}
 | 
			
		||||
	result.valuePT1 = search(m, 1, 3)
 | 
			
		||||
	result.valuePT2 = search(m, 4, 10)
 | 
			
		||||
 | 
			
		||||
	return &result, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func search(m aoc.Map[rune], minSteps, maxSteps int) int {
 | 
			
		||||
	type direction int8
 | 
			
		||||
	type rotate int8
 | 
			
		||||
 | 
			
		||||
	const (
 | 
			
		||||
		CW  rotate = 1
 | 
			
		||||
		CCW rotate = -1
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	var (
 | 
			
		||||
		U = aoc.Point{-1, 0}
 | 
			
		||||
		R = aoc.Point{0, 1}
 | 
			
		||||
		D = aoc.Point{1, 0}
 | 
			
		||||
		L = aoc.Point{0, -1}
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	var Direction = []aoc.Point{U, R, D, L}
 | 
			
		||||
 | 
			
		||||
	var Directions = make(map[aoc.Point]direction, len(Direction))
 | 
			
		||||
	for k, v := range Direction {
 | 
			
		||||
		Directions[v] = direction(k)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	rows, cols := m.Size()
 | 
			
		||||
	target := aoc.Point{rows - 1, cols - 1}
 | 
			
		||||
 | 
			
		||||
	type position struct {
 | 
			
		||||
		loc       aoc.Point
 | 
			
		||||
		direction aoc.Point
 | 
			
		||||
		steps     int
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	step := func(p position) position {
 | 
			
		||||
		return position{p.loc.Add(p.direction), p.direction, p.steps + 1}
 | 
			
		||||
	}
 | 
			
		||||
	rotateAndStep := func(p position, towards rotate) position {
 | 
			
		||||
		d := Direction[(int8(Directions[p.direction])+int8(towards)+4)%4]
 | 
			
		||||
		// fmt.Println(towards, Directions[p.direction], "->", Directions[d])
 | 
			
		||||
		return position{p.loc.Add(d), d, 1}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	type memo struct {
 | 
			
		||||
		cost int
 | 
			
		||||
		position
 | 
			
		||||
	}
 | 
			
		||||
	less := func(a, b memo) bool {
 | 
			
		||||
		if a.cost != b.cost {
 | 
			
		||||
			return a.cost < b.cost
 | 
			
		||||
		}
 | 
			
		||||
		if a.position.loc != b.position.loc {
 | 
			
		||||
			return b.position.loc.Less(a.position.loc)
 | 
			
		||||
		}
 | 
			
		||||
		if a.position.direction != b.position.direction {
 | 
			
		||||
			return b.position.direction.Less(a.position.direction)
 | 
			
		||||
		}
 | 
			
		||||
		return a.steps < b.steps
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pq := aoc.PriorityQueue(less)
 | 
			
		||||
	pq.Enqueue(memo{position: position{direction: D}})
 | 
			
		||||
	pq.Enqueue(memo{position: position{direction: R}})
 | 
			
		||||
	visited := aoc.Set[position]()
 | 
			
		||||
 | 
			
		||||
	for !pq.IsEmpty() {
 | 
			
		||||
		current, _ := pq.Dequeue()
 | 
			
		||||
 | 
			
		||||
		if current.loc == target && current.steps >= minSteps {
 | 
			
		||||
			return current.cost
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		seen := position{loc: current.loc, direction: current.direction, steps: current.steps}
 | 
			
		||||
 | 
			
		||||
		if visited.Has(seen) {
 | 
			
		||||
			// fmt.Println("visited", seen)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		visited.Add(seen)
 | 
			
		||||
 | 
			
		||||
		// fmt.Print("\033[2J\033[H")
 | 
			
		||||
		// fmt.Println("step ", current.steps, " dir ", Directions[current.direction], " steps ",  " score ", current.cost, current.loc)
 | 
			
		||||
 | 
			
		||||
		if left := rotateAndStep(current.position, CCW); current.steps >= minSteps && m.Valid(left.loc) {
 | 
			
		||||
			_, cost, _ := m.Get(left.loc)
 | 
			
		||||
			// fmt.Println("turn left", current, left)
 | 
			
		||||
			pq.Enqueue(memo{cost: current.cost + int(cost-'0'), position: left})
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if right := rotateAndStep(current.position, CW); current.steps >= minSteps && m.Valid(right.loc) {
 | 
			
		||||
			_, cost, _ := m.Get(right.loc)
 | 
			
		||||
			// fmt.Println("turn right", current, right)
 | 
			
		||||
			pq.Enqueue(memo{cost: current.cost + int(cost-'0'), position: right})
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if forward := step(current.position); current.steps < maxSteps && m.Valid(forward.loc) {
 | 
			
		||||
			_, cost, _ := m.Get(forward.loc)
 | 
			
		||||
			// fmt.Println("go forward", current, forward)
 | 
			
		||||
			pq.Enqueue(memo{cost: current.cost + int(cost-'0'), position: forward})
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return -1
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										41
									
								
								day17/main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								day17/main_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,41 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	_ "embed"
 | 
			
		||||
 | 
			
		||||
	"github.com/matryer/is"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:embed example.txt
 | 
			
		||||
var example []byte
 | 
			
		||||
 | 
			
		||||
//go:embed input.txt
 | 
			
		||||
var input []byte
 | 
			
		||||
 | 
			
		||||
func TestExample(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
			
		||||
 | 
			
		||||
	result, err := run(scan)
 | 
			
		||||
	is.NoErr(err)
 | 
			
		||||
 | 
			
		||||
	t.Log(result)
 | 
			
		||||
	is.Equal(result.valuePT1, 102)
 | 
			
		||||
	is.Equal(result.valuePT2, 94)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// func TestSolution(t *testing.T) {
 | 
			
		||||
// 	is := is.New(t)
 | 
			
		||||
// 	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
			
		||||
 | 
			
		||||
// 	result, err := run(scan)
 | 
			
		||||
// 	is.NoErr(err)
 | 
			
		||||
 | 
			
		||||
// 	t.Log(result)
 | 
			
		||||
// 	is.Equal(result.valuePT1, 843)
 | 
			
		||||
// 	is.Equal(result.valuePT2, 1017)
 | 
			
		||||
// }
 | 
			
		||||
							
								
								
									
										14
									
								
								day18/example.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								day18/example.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,14 @@
 | 
			
		||||
R 6 (#70c710)
 | 
			
		||||
D 5 (#0dc571)
 | 
			
		||||
L 2 (#5713f0)
 | 
			
		||||
D 2 (#d2c081)
 | 
			
		||||
R 2 (#59c680)
 | 
			
		||||
D 2 (#411b91)
 | 
			
		||||
L 5 (#8ceee2)
 | 
			
		||||
U 2 (#caa173)
 | 
			
		||||
L 1 (#1b58a2)
 | 
			
		||||
U 2 (#caa171)
 | 
			
		||||
R 2 (#7807d2)
 | 
			
		||||
U 3 (#a77fa3)
 | 
			
		||||
L 2 (#015232)
 | 
			
		||||
U 2 (#7a21e3)
 | 
			
		||||
							
								
								
									
										766
									
								
								day18/input.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										766
									
								
								day18/input.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,766 @@
 | 
			
		||||
R 4 (#0a7a60)
 | 
			
		||||
U 8 (#4453b3)
 | 
			
		||||
R 6 (#8e4f70)
 | 
			
		||||
U 2 (#4453b1)
 | 
			
		||||
R 4 (#0feb00)
 | 
			
		||||
U 4 (#355591)
 | 
			
		||||
R 8 (#2a09c0)
 | 
			
		||||
U 4 (#544c71)
 | 
			
		||||
R 4 (#472930)
 | 
			
		||||
U 2 (#199e33)
 | 
			
		||||
R 3 (#3d8df0)
 | 
			
		||||
U 5 (#199e31)
 | 
			
		||||
R 7 (#45de50)
 | 
			
		||||
U 4 (#57a941)
 | 
			
		||||
L 7 (#671c70)
 | 
			
		||||
U 5 (#5e5e81)
 | 
			
		||||
R 4 (#2e9b60)
 | 
			
		||||
U 8 (#490881)
 | 
			
		||||
L 7 (#1846f0)
 | 
			
		||||
U 3 (#304101)
 | 
			
		||||
L 4 (#1846f2)
 | 
			
		||||
D 2 (#58f3f1)
 | 
			
		||||
L 9 (#2e9b62)
 | 
			
		||||
D 2 (#56dcd1)
 | 
			
		||||
L 2 (#671c72)
 | 
			
		||||
D 9 (#275fd1)
 | 
			
		||||
L 4 (#76b7b2)
 | 
			
		||||
U 9 (#5b9641)
 | 
			
		||||
L 4 (#1d3212)
 | 
			
		||||
U 10 (#3d1841)
 | 
			
		||||
L 3 (#5ad5e2)
 | 
			
		||||
D 6 (#010211)
 | 
			
		||||
L 5 (#13ec52)
 | 
			
		||||
D 8 (#166471)
 | 
			
		||||
L 3 (#53ebc0)
 | 
			
		||||
D 5 (#0fdba1)
 | 
			
		||||
L 4 (#54e450)
 | 
			
		||||
D 9 (#440a21)
 | 
			
		||||
L 3 (#49b242)
 | 
			
		||||
D 5 (#2f0171)
 | 
			
		||||
L 6 (#447332)
 | 
			
		||||
D 4 (#182561)
 | 
			
		||||
L 8 (#1aaaa2)
 | 
			
		||||
D 6 (#0996a1)
 | 
			
		||||
L 4 (#1c1212)
 | 
			
		||||
D 6 (#5780d1)
 | 
			
		||||
L 7 (#0fc1d2)
 | 
			
		||||
D 7 (#36cb41)
 | 
			
		||||
L 3 (#505552)
 | 
			
		||||
D 7 (#8d8b81)
 | 
			
		||||
R 4 (#2bf742)
 | 
			
		||||
D 7 (#152791)
 | 
			
		||||
R 5 (#760492)
 | 
			
		||||
D 3 (#11a991)
 | 
			
		||||
R 3 (#5debc0)
 | 
			
		||||
D 10 (#59f211)
 | 
			
		||||
L 4 (#66d342)
 | 
			
		||||
D 8 (#1fc6b1)
 | 
			
		||||
R 4 (#66d340)
 | 
			
		||||
D 6 (#72dff1)
 | 
			
		||||
L 2 (#3f1b10)
 | 
			
		||||
D 4 (#2fca13)
 | 
			
		||||
L 10 (#2d0162)
 | 
			
		||||
D 5 (#8b5e53)
 | 
			
		||||
L 6 (#2d0160)
 | 
			
		||||
U 2 (#317053)
 | 
			
		||||
L 2 (#650c20)
 | 
			
		||||
U 7 (#2bed01)
 | 
			
		||||
R 10 (#409ed0)
 | 
			
		||||
U 2 (#166713)
 | 
			
		||||
L 10 (#939350)
 | 
			
		||||
U 6 (#166711)
 | 
			
		||||
L 4 (#38a180)
 | 
			
		||||
D 3 (#1d95f1)
 | 
			
		||||
L 6 (#11ea60)
 | 
			
		||||
D 5 (#931dc1)
 | 
			
		||||
R 6 (#11bf70)
 | 
			
		||||
D 7 (#536051)
 | 
			
		||||
L 3 (#995b60)
 | 
			
		||||
D 2 (#254e91)
 | 
			
		||||
L 3 (#332fd2)
 | 
			
		||||
U 6 (#7669f1)
 | 
			
		||||
L 3 (#574642)
 | 
			
		||||
U 6 (#1778a1)
 | 
			
		||||
L 3 (#1a00c2)
 | 
			
		||||
U 5 (#2eaa81)
 | 
			
		||||
L 3 (#1cf8e2)
 | 
			
		||||
U 6 (#0c71a1)
 | 
			
		||||
L 6 (#868472)
 | 
			
		||||
U 3 (#0a9fd1)
 | 
			
		||||
R 9 (#104c02)
 | 
			
		||||
U 4 (#082451)
 | 
			
		||||
L 7 (#850d02)
 | 
			
		||||
U 6 (#082453)
 | 
			
		||||
L 7 (#322552)
 | 
			
		||||
U 3 (#1339d1)
 | 
			
		||||
L 6 (#8e11d2)
 | 
			
		||||
U 4 (#6c5691)
 | 
			
		||||
R 6 (#1dda10)
 | 
			
		||||
U 3 (#25e5c3)
 | 
			
		||||
R 7 (#370670)
 | 
			
		||||
U 4 (#9324f1)
 | 
			
		||||
L 3 (#451030)
 | 
			
		||||
U 7 (#1f1021)
 | 
			
		||||
L 7 (#0ba3c0)
 | 
			
		||||
U 5 (#8a10a3)
 | 
			
		||||
L 8 (#67db30)
 | 
			
		||||
U 5 (#282473)
 | 
			
		||||
L 4 (#0cd350)
 | 
			
		||||
U 4 (#25e5c1)
 | 
			
		||||
R 3 (#6b4ee0)
 | 
			
		||||
U 4 (#333cf1)
 | 
			
		||||
R 5 (#02b610)
 | 
			
		||||
D 4 (#4e7cc1)
 | 
			
		||||
R 3 (#92abb0)
 | 
			
		||||
U 5 (#2f6ff1)
 | 
			
		||||
R 5 (#483360)
 | 
			
		||||
U 5 (#7b1cd1)
 | 
			
		||||
L 8 (#3a5d50)
 | 
			
		||||
U 3 (#1d2461)
 | 
			
		||||
R 8 (#3b2fd0)
 | 
			
		||||
U 5 (#630763)
 | 
			
		||||
R 6 (#5033c0)
 | 
			
		||||
U 3 (#252523)
 | 
			
		||||
R 7 (#08eeb0)
 | 
			
		||||
U 8 (#516633)
 | 
			
		||||
L 7 (#156240)
 | 
			
		||||
U 4 (#2db063)
 | 
			
		||||
L 3 (#791070)
 | 
			
		||||
D 5 (#2920a3)
 | 
			
		||||
L 3 (#0dafe0)
 | 
			
		||||
U 5 (#4185b3)
 | 
			
		||||
L 5 (#7ac0e0)
 | 
			
		||||
U 2 (#5a6cd3)
 | 
			
		||||
L 2 (#3ca790)
 | 
			
		||||
U 7 (#755403)
 | 
			
		||||
L 4 (#3b0740)
 | 
			
		||||
U 5 (#2004a3)
 | 
			
		||||
L 3 (#2db4f0)
 | 
			
		||||
U 6 (#602a23)
 | 
			
		||||
R 5 (#32c1c0)
 | 
			
		||||
D 2 (#000f53)
 | 
			
		||||
R 5 (#388360)
 | 
			
		||||
D 7 (#24d9e3)
 | 
			
		||||
R 4 (#4703a0)
 | 
			
		||||
D 3 (#2f1133)
 | 
			
		||||
R 3 (#4703a2)
 | 
			
		||||
U 11 (#52e853)
 | 
			
		||||
R 5 (#278132)
 | 
			
		||||
D 11 (#0665e3)
 | 
			
		||||
R 3 (#239112)
 | 
			
		||||
U 6 (#8f0ad1)
 | 
			
		||||
R 5 (#447de2)
 | 
			
		||||
U 6 (#8f0ad3)
 | 
			
		||||
R 6 (#636122)
 | 
			
		||||
U 2 (#187283)
 | 
			
		||||
R 3 (#5aae62)
 | 
			
		||||
U 10 (#1d8833)
 | 
			
		||||
L 5 (#476db0)
 | 
			
		||||
U 5 (#136393)
 | 
			
		||||
L 7 (#29e6b0)
 | 
			
		||||
U 5 (#136391)
 | 
			
		||||
R 7 (#3ba060)
 | 
			
		||||
U 3 (#635e23)
 | 
			
		||||
L 5 (#2042f0)
 | 
			
		||||
U 3 (#181643)
 | 
			
		||||
L 6 (#5af952)
 | 
			
		||||
U 8 (#28d0b1)
 | 
			
		||||
L 2 (#4a98f2)
 | 
			
		||||
U 9 (#28d0b3)
 | 
			
		||||
L 6 (#27a572)
 | 
			
		||||
D 3 (#3d7213)
 | 
			
		||||
L 4 (#516842)
 | 
			
		||||
D 11 (#21ef63)
 | 
			
		||||
L 5 (#38e342)
 | 
			
		||||
D 2 (#1118b3)
 | 
			
		||||
L 3 (#560502)
 | 
			
		||||
D 9 (#1118b1)
 | 
			
		||||
R 2 (#1c39a2)
 | 
			
		||||
D 2 (#303ab3)
 | 
			
		||||
R 6 (#716ba0)
 | 
			
		||||
D 6 (#780a93)
 | 
			
		||||
L 8 (#77ec30)
 | 
			
		||||
U 2 (#780a91)
 | 
			
		||||
L 3 (#271100)
 | 
			
		||||
U 10 (#5882f3)
 | 
			
		||||
L 4 (#2050c2)
 | 
			
		||||
D 3 (#434843)
 | 
			
		||||
L 3 (#7d9572)
 | 
			
		||||
D 2 (#3129b3)
 | 
			
		||||
L 5 (#21fb12)
 | 
			
		||||
D 5 (#8c2c33)
 | 
			
		||||
L 4 (#57bf92)
 | 
			
		||||
D 6 (#2730b3)
 | 
			
		||||
L 4 (#6a3902)
 | 
			
		||||
D 8 (#4656a3)
 | 
			
		||||
L 5 (#60ac80)
 | 
			
		||||
D 4 (#43b863)
 | 
			
		||||
R 9 (#3d69a0)
 | 
			
		||||
D 8 (#3ca913)
 | 
			
		||||
L 2 (#411d80)
 | 
			
		||||
D 3 (#725383)
 | 
			
		||||
L 8 (#4a98d0)
 | 
			
		||||
D 9 (#274553)
 | 
			
		||||
L 5 (#580d60)
 | 
			
		||||
U 5 (#568223)
 | 
			
		||||
L 6 (#473af0)
 | 
			
		||||
U 5 (#827593)
 | 
			
		||||
L 7 (#251dc2)
 | 
			
		||||
U 5 (#0fcea3)
 | 
			
		||||
L 8 (#5ae3d2)
 | 
			
		||||
U 3 (#4efa11)
 | 
			
		||||
R 9 (#389852)
 | 
			
		||||
U 2 (#7f7f91)
 | 
			
		||||
R 6 (#618342)
 | 
			
		||||
U 3 (#441143)
 | 
			
		||||
L 7 (#886df2)
 | 
			
		||||
U 3 (#26a093)
 | 
			
		||||
L 8 (#886df0)
 | 
			
		||||
U 4 (#63c7d3)
 | 
			
		||||
L 3 (#04f842)
 | 
			
		||||
D 10 (#0fcea1)
 | 
			
		||||
L 6 (#388e62)
 | 
			
		||||
U 10 (#3ae7f3)
 | 
			
		||||
L 3 (#2a6880)
 | 
			
		||||
U 6 (#3bfd53)
 | 
			
		||||
L 6 (#73a0c0)
 | 
			
		||||
U 5 (#3bfd51)
 | 
			
		||||
L 4 (#0d18a0)
 | 
			
		||||
U 2 (#19da93)
 | 
			
		||||
L 6 (#120600)
 | 
			
		||||
U 8 (#233b53)
 | 
			
		||||
L 6 (#2e1050)
 | 
			
		||||
U 3 (#4b2aa3)
 | 
			
		||||
L 4 (#5f9930)
 | 
			
		||||
U 10 (#6e65f1)
 | 
			
		||||
R 6 (#1eefa0)
 | 
			
		||||
U 9 (#50b9d3)
 | 
			
		||||
R 2 (#548ed0)
 | 
			
		||||
U 9 (#50b9d1)
 | 
			
		||||
R 7 (#8bd9f0)
 | 
			
		||||
U 4 (#5ae473)
 | 
			
		||||
R 6 (#0b0490)
 | 
			
		||||
U 10 (#186891)
 | 
			
		||||
R 4 (#764830)
 | 
			
		||||
U 7 (#33b0e1)
 | 
			
		||||
R 5 (#363c90)
 | 
			
		||||
U 8 (#7bd631)
 | 
			
		||||
R 7 (#031e30)
 | 
			
		||||
U 7 (#095881)
 | 
			
		||||
R 3 (#640e50)
 | 
			
		||||
D 5 (#02e7f3)
 | 
			
		||||
R 7 (#0922f0)
 | 
			
		||||
D 7 (#6b7af3)
 | 
			
		||||
R 9 (#0922f2)
 | 
			
		||||
D 3 (#62e543)
 | 
			
		||||
R 3 (#21e320)
 | 
			
		||||
U 9 (#5ead81)
 | 
			
		||||
R 7 (#01fd70)
 | 
			
		||||
D 9 (#3b0cf1)
 | 
			
		||||
R 2 (#2758a0)
 | 
			
		||||
D 5 (#7279b1)
 | 
			
		||||
R 8 (#5c7dc0)
 | 
			
		||||
D 7 (#3c8db1)
 | 
			
		||||
R 4 (#3c3740)
 | 
			
		||||
U 2 (#26b151)
 | 
			
		||||
R 6 (#11eb12)
 | 
			
		||||
U 4 (#587921)
 | 
			
		||||
R 6 (#11eb10)
 | 
			
		||||
U 4 (#320051)
 | 
			
		||||
R 4 (#038630)
 | 
			
		||||
U 3 (#6a2e61)
 | 
			
		||||
R 2 (#4ff680)
 | 
			
		||||
U 5 (#3c57f1)
 | 
			
		||||
R 9 (#0b2440)
 | 
			
		||||
U 8 (#497533)
 | 
			
		||||
L 6 (#704680)
 | 
			
		||||
U 11 (#549113)
 | 
			
		||||
R 6 (#23b470)
 | 
			
		||||
U 4 (#9e0641)
 | 
			
		||||
R 7 (#1aeec0)
 | 
			
		||||
D 7 (#4a6331)
 | 
			
		||||
R 2 (#547d80)
 | 
			
		||||
D 5 (#457a71)
 | 
			
		||||
R 9 (#7daa90)
 | 
			
		||||
D 4 (#16d7b1)
 | 
			
		||||
L 6 (#266810)
 | 
			
		||||
D 3 (#363561)
 | 
			
		||||
L 5 (#5312b2)
 | 
			
		||||
D 4 (#42c301)
 | 
			
		||||
R 5 (#9a0952)
 | 
			
		||||
D 7 (#42c303)
 | 
			
		||||
R 7 (#7d1df2)
 | 
			
		||||
D 4 (#51e321)
 | 
			
		||||
R 5 (#609422)
 | 
			
		||||
D 4 (#3b8f01)
 | 
			
		||||
R 6 (#644792)
 | 
			
		||||
U 4 (#2d8b11)
 | 
			
		||||
R 7 (#22bbc2)
 | 
			
		||||
D 7 (#6b39b1)
 | 
			
		||||
R 5 (#680e72)
 | 
			
		||||
U 2 (#7f9f31)
 | 
			
		||||
R 3 (#0e9b52)
 | 
			
		||||
U 3 (#3086c1)
 | 
			
		||||
R 3 (#5a60c0)
 | 
			
		||||
U 6 (#53b6e3)
 | 
			
		||||
R 7 (#8117d0)
 | 
			
		||||
U 7 (#53b6e1)
 | 
			
		||||
R 3 (#2cb930)
 | 
			
		||||
U 3 (#1bffd1)
 | 
			
		||||
R 6 (#4539f0)
 | 
			
		||||
U 8 (#680411)
 | 
			
		||||
R 4 (#6032c0)
 | 
			
		||||
U 6 (#255061)
 | 
			
		||||
R 3 (#5562a0)
 | 
			
		||||
U 6 (#088071)
 | 
			
		||||
R 3 (#3bf2f0)
 | 
			
		||||
U 5 (#52bdb1)
 | 
			
		||||
L 6 (#070500)
 | 
			
		||||
U 5 (#69e001)
 | 
			
		||||
R 6 (#070502)
 | 
			
		||||
U 3 (#071051)
 | 
			
		||||
R 2 (#036000)
 | 
			
		||||
U 4 (#0ea8a1)
 | 
			
		||||
R 5 (#05e4d0)
 | 
			
		||||
U 3 (#674de1)
 | 
			
		||||
R 3 (#804250)
 | 
			
		||||
D 6 (#3ffca1)
 | 
			
		||||
R 4 (#23dcb2)
 | 
			
		||||
D 6 (#9f9841)
 | 
			
		||||
L 5 (#45f210)
 | 
			
		||||
D 9 (#15efc1)
 | 
			
		||||
R 5 (#45f212)
 | 
			
		||||
D 4 (#969551)
 | 
			
		||||
L 9 (#23dcb0)
 | 
			
		||||
D 2 (#41bea1)
 | 
			
		||||
L 4 (#2f2a32)
 | 
			
		||||
D 4 (#71ffd1)
 | 
			
		||||
R 3 (#5c0bb2)
 | 
			
		||||
D 7 (#6f3501)
 | 
			
		||||
R 4 (#2b0a72)
 | 
			
		||||
D 4 (#7b3571)
 | 
			
		||||
R 3 (#1c67d2)
 | 
			
		||||
U 11 (#42f011)
 | 
			
		||||
R 3 (#51ae62)
 | 
			
		||||
D 3 (#75fcf1)
 | 
			
		||||
R 3 (#1f4742)
 | 
			
		||||
D 4 (#2813f1)
 | 
			
		||||
R 4 (#3d1812)
 | 
			
		||||
D 2 (#2b1d01)
 | 
			
		||||
R 11 (#1eb302)
 | 
			
		||||
U 3 (#27b0a1)
 | 
			
		||||
R 4 (#227b20)
 | 
			
		||||
U 5 (#34b7e1)
 | 
			
		||||
R 10 (#201220)
 | 
			
		||||
U 7 (#0502f3)
 | 
			
		||||
R 4 (#5ab7f0)
 | 
			
		||||
U 4 (#0502f1)
 | 
			
		||||
R 4 (#5d09b0)
 | 
			
		||||
U 7 (#504a81)
 | 
			
		||||
R 7 (#1e8250)
 | 
			
		||||
U 3 (#715aa1)
 | 
			
		||||
R 6 (#26d290)
 | 
			
		||||
U 6 (#9a12f1)
 | 
			
		||||
L 3 (#18be90)
 | 
			
		||||
U 8 (#037d11)
 | 
			
		||||
L 5 (#647600)
 | 
			
		||||
U 3 (#40b983)
 | 
			
		||||
L 5 (#04e450)
 | 
			
		||||
U 3 (#9a9a43)
 | 
			
		||||
L 8 (#04e452)
 | 
			
		||||
U 6 (#8af153)
 | 
			
		||||
R 8 (#6cbc90)
 | 
			
		||||
U 4 (#04d121)
 | 
			
		||||
L 4 (#285292)
 | 
			
		||||
U 3 (#688d51)
 | 
			
		||||
L 6 (#176332)
 | 
			
		||||
U 4 (#400a91)
 | 
			
		||||
L 5 (#176330)
 | 
			
		||||
U 5 (#43def1)
 | 
			
		||||
R 2 (#285290)
 | 
			
		||||
U 2 (#3e0711)
 | 
			
		||||
R 3 (#7eb9c0)
 | 
			
		||||
U 7 (#36f611)
 | 
			
		||||
R 7 (#666af0)
 | 
			
		||||
D 7 (#381b31)
 | 
			
		||||
R 3 (#298922)
 | 
			
		||||
U 3 (#475671)
 | 
			
		||||
R 6 (#977c12)
 | 
			
		||||
D 4 (#602d01)
 | 
			
		||||
R 6 (#25b0c2)
 | 
			
		||||
D 6 (#7ede81)
 | 
			
		||||
R 3 (#1d58c2)
 | 
			
		||||
D 8 (#873523)
 | 
			
		||||
L 9 (#265ae2)
 | 
			
		||||
D 3 (#57d663)
 | 
			
		||||
R 7 (#1565c2)
 | 
			
		||||
D 8 (#06ed11)
 | 
			
		||||
R 4 (#a348c2)
 | 
			
		||||
D 2 (#06ed13)
 | 
			
		||||
R 8 (#12d052)
 | 
			
		||||
D 4 (#2d3741)
 | 
			
		||||
L 7 (#0ccfd2)
 | 
			
		||||
D 3 (#1fcd61)
 | 
			
		||||
R 4 (#39a4c2)
 | 
			
		||||
D 3 (#44f7f1)
 | 
			
		||||
R 6 (#5c3202)
 | 
			
		||||
D 8 (#2625c1)
 | 
			
		||||
L 8 (#2b08c2)
 | 
			
		||||
D 2 (#20d7e1)
 | 
			
		||||
L 2 (#67b892)
 | 
			
		||||
D 10 (#546471)
 | 
			
		||||
R 7 (#484ef2)
 | 
			
		||||
D 7 (#49bc91)
 | 
			
		||||
R 4 (#91aa72)
 | 
			
		||||
U 11 (#499591)
 | 
			
		||||
R 3 (#0048b2)
 | 
			
		||||
U 7 (#34a7a1)
 | 
			
		||||
R 7 (#514600)
 | 
			
		||||
U 8 (#1cdc43)
 | 
			
		||||
L 7 (#471470)
 | 
			
		||||
U 3 (#8c8393)
 | 
			
		||||
R 3 (#18a780)
 | 
			
		||||
U 5 (#8c8391)
 | 
			
		||||
R 3 (#4e6f80)
 | 
			
		||||
U 3 (#1cdc41)
 | 
			
		||||
R 8 (#428930)
 | 
			
		||||
U 5 (#5dcb51)
 | 
			
		||||
R 3 (#4b21e2)
 | 
			
		||||
U 4 (#0464b1)
 | 
			
		||||
R 9 (#850552)
 | 
			
		||||
D 8 (#464881)
 | 
			
		||||
R 7 (#543852)
 | 
			
		||||
D 3 (#2d3a11)
 | 
			
		||||
R 3 (#081b22)
 | 
			
		||||
D 5 (#0cc731)
 | 
			
		||||
R 7 (#6990e0)
 | 
			
		||||
D 3 (#79d7b1)
 | 
			
		||||
R 3 (#509520)
 | 
			
		||||
D 5 (#438571)
 | 
			
		||||
R 3 (#27d510)
 | 
			
		||||
D 3 (#30d2d3)
 | 
			
		||||
L 8 (#1b7a00)
 | 
			
		||||
D 5 (#8a0da3)
 | 
			
		||||
L 8 (#1b7a02)
 | 
			
		||||
U 5 (#027cb3)
 | 
			
		||||
L 7 (#350130)
 | 
			
		||||
D 8 (#2ff771)
 | 
			
		||||
R 7 (#16dc02)
 | 
			
		||||
D 2 (#68f1c1)
 | 
			
		||||
R 5 (#02f782)
 | 
			
		||||
D 6 (#4e2a41)
 | 
			
		||||
R 11 (#448e32)
 | 
			
		||||
D 5 (#2cfac1)
 | 
			
		||||
L 11 (#417502)
 | 
			
		||||
D 5 (#2cfac3)
 | 
			
		||||
L 4 (#22f022)
 | 
			
		||||
U 9 (#1e9f01)
 | 
			
		||||
L 5 (#543572)
 | 
			
		||||
U 3 (#076e31)
 | 
			
		||||
L 6 (#081b20)
 | 
			
		||||
U 5 (#1ae851)
 | 
			
		||||
L 3 (#823132)
 | 
			
		||||
U 9 (#2d7993)
 | 
			
		||||
L 4 (#5738f2)
 | 
			
		||||
D 8 (#79e273)
 | 
			
		||||
L 4 (#5c9ad2)
 | 
			
		||||
D 8 (#4ed1b3)
 | 
			
		||||
L 3 (#311722)
 | 
			
		||||
D 4 (#0d5493)
 | 
			
		||||
L 6 (#5d63e0)
 | 
			
		||||
D 6 (#178cf3)
 | 
			
		||||
L 5 (#75b1b0)
 | 
			
		||||
D 5 (#178cf1)
 | 
			
		||||
L 6 (#11d550)
 | 
			
		||||
D 6 (#44ed03)
 | 
			
		||||
L 3 (#76a842)
 | 
			
		||||
U 6 (#3b6993)
 | 
			
		||||
L 5 (#184892)
 | 
			
		||||
D 4 (#5c8163)
 | 
			
		||||
L 3 (#14d872)
 | 
			
		||||
U 2 (#261a01)
 | 
			
		||||
L 5 (#2d01e2)
 | 
			
		||||
U 9 (#326ca3)
 | 
			
		||||
L 4 (#59ad32)
 | 
			
		||||
U 8 (#326ca1)
 | 
			
		||||
R 4 (#389ab2)
 | 
			
		||||
U 9 (#261a03)
 | 
			
		||||
L 4 (#50cb42)
 | 
			
		||||
D 4 (#2f8263)
 | 
			
		||||
L 5 (#9f3752)
 | 
			
		||||
D 6 (#4bb383)
 | 
			
		||||
L 4 (#2693f2)
 | 
			
		||||
D 4 (#19dca3)
 | 
			
		||||
R 4 (#475bc2)
 | 
			
		||||
D 6 (#960e13)
 | 
			
		||||
L 7 (#0c90a2)
 | 
			
		||||
D 8 (#3463d3)
 | 
			
		||||
L 6 (#5a82e2)
 | 
			
		||||
D 3 (#5a5c43)
 | 
			
		||||
R 7 (#120bf2)
 | 
			
		||||
D 3 (#5069e3)
 | 
			
		||||
R 3 (#4b47a2)
 | 
			
		||||
D 6 (#635b63)
 | 
			
		||||
R 4 (#66ca10)
 | 
			
		||||
U 4 (#1418f1)
 | 
			
		||||
R 7 (#1d5470)
 | 
			
		||||
D 4 (#1418f3)
 | 
			
		||||
R 8 (#66d4f0)
 | 
			
		||||
D 5 (#3c5533)
 | 
			
		||||
R 4 (#2f6e02)
 | 
			
		||||
D 3 (#2cf5e3)
 | 
			
		||||
R 4 (#633ec2)
 | 
			
		||||
D 7 (#2cf5e1)
 | 
			
		||||
R 7 (#5846b2)
 | 
			
		||||
D 3 (#4f9d63)
 | 
			
		||||
R 4 (#533380)
 | 
			
		||||
D 11 (#13c7e3)
 | 
			
		||||
R 2 (#222b62)
 | 
			
		||||
D 3 (#928ab3)
 | 
			
		||||
R 5 (#222b60)
 | 
			
		||||
U 5 (#0a4793)
 | 
			
		||||
R 5 (#15d3b0)
 | 
			
		||||
U 8 (#363fe1)
 | 
			
		||||
R 4 (#2feb30)
 | 
			
		||||
U 5 (#05d8b1)
 | 
			
		||||
R 3 (#39e030)
 | 
			
		||||
U 3 (#05d8b3)
 | 
			
		||||
R 2 (#3cd780)
 | 
			
		||||
U 8 (#02c781)
 | 
			
		||||
R 5 (#186452)
 | 
			
		||||
D 3 (#37bba1)
 | 
			
		||||
R 5 (#9e1232)
 | 
			
		||||
D 5 (#58e6f1)
 | 
			
		||||
R 5 (#182c30)
 | 
			
		||||
D 5 (#072db1)
 | 
			
		||||
R 5 (#85e600)
 | 
			
		||||
D 4 (#607651)
 | 
			
		||||
R 5 (#186450)
 | 
			
		||||
D 3 (#0aca91)
 | 
			
		||||
L 5 (#0ceb10)
 | 
			
		||||
D 5 (#860001)
 | 
			
		||||
L 6 (#54c8b0)
 | 
			
		||||
U 5 (#393971)
 | 
			
		||||
L 4 (#37c390)
 | 
			
		||||
D 3 (#1f1433)
 | 
			
		||||
L 5 (#3d8790)
 | 
			
		||||
D 6 (#353623)
 | 
			
		||||
R 4 (#78c830)
 | 
			
		||||
D 4 (#6fafa3)
 | 
			
		||||
R 6 (#2b0612)
 | 
			
		||||
D 5 (#31fff3)
 | 
			
		||||
R 7 (#8b49b2)
 | 
			
		||||
D 9 (#6f0ee3)
 | 
			
		||||
R 5 (#4212e0)
 | 
			
		||||
D 6 (#5d11f3)
 | 
			
		||||
R 6 (#648340)
 | 
			
		||||
D 8 (#393743)
 | 
			
		||||
R 6 (#34ddd0)
 | 
			
		||||
U 8 (#346fb3)
 | 
			
		||||
R 5 (#34fc22)
 | 
			
		||||
D 4 (#71c453)
 | 
			
		||||
R 6 (#5048f2)
 | 
			
		||||
D 4 (#0bb993)
 | 
			
		||||
R 4 (#42b9f0)
 | 
			
		||||
D 9 (#5cdf83)
 | 
			
		||||
R 5 (#42b9f2)
 | 
			
		||||
D 3 (#6f3f93)
 | 
			
		||||
R 3 (#3dbae2)
 | 
			
		||||
D 8 (#495363)
 | 
			
		||||
R 9 (#328ba2)
 | 
			
		||||
D 3 (#77afa1)
 | 
			
		||||
R 5 (#575710)
 | 
			
		||||
D 2 (#10d861)
 | 
			
		||||
R 4 (#257822)
 | 
			
		||||
D 4 (#6efe61)
 | 
			
		||||
R 9 (#257820)
 | 
			
		||||
D 5 (#521d01)
 | 
			
		||||
R 5 (#575712)
 | 
			
		||||
D 6 (#494cf1)
 | 
			
		||||
L 5 (#683ab2)
 | 
			
		||||
D 4 (#5e79c3)
 | 
			
		||||
L 3 (#4242a2)
 | 
			
		||||
D 4 (#5e79c1)
 | 
			
		||||
L 7 (#2c3442)
 | 
			
		||||
D 8 (#2fbd23)
 | 
			
		||||
L 5 (#636fb2)
 | 
			
		||||
D 5 (#63bd53)
 | 
			
		||||
L 2 (#299960)
 | 
			
		||||
D 6 (#31ea33)
 | 
			
		||||
R 3 (#51dfb0)
 | 
			
		||||
D 7 (#4e4ec3)
 | 
			
		||||
R 4 (#7b7912)
 | 
			
		||||
D 5 (#4b4bf3)
 | 
			
		||||
R 4 (#54e882)
 | 
			
		||||
D 5 (#7d2193)
 | 
			
		||||
R 3 (#3b77d2)
 | 
			
		||||
D 3 (#826973)
 | 
			
		||||
R 8 (#646ec2)
 | 
			
		||||
D 4 (#076c63)
 | 
			
		||||
L 10 (#674052)
 | 
			
		||||
D 6 (#3676b1)
 | 
			
		||||
L 9 (#3bd890)
 | 
			
		||||
D 4 (#7feb71)
 | 
			
		||||
L 3 (#3bd892)
 | 
			
		||||
D 3 (#27fc21)
 | 
			
		||||
R 8 (#66bba2)
 | 
			
		||||
D 8 (#645c73)
 | 
			
		||||
R 5 (#43e132)
 | 
			
		||||
D 5 (#51d9e3)
 | 
			
		||||
R 8 (#43e130)
 | 
			
		||||
D 6 (#2827f3)
 | 
			
		||||
R 4 (#412c92)
 | 
			
		||||
D 5 (#7e7f63)
 | 
			
		||||
L 4 (#218122)
 | 
			
		||||
D 4 (#546e83)
 | 
			
		||||
L 9 (#82f672)
 | 
			
		||||
D 8 (#6ed383)
 | 
			
		||||
L 3 (#701412)
 | 
			
		||||
D 7 (#47de23)
 | 
			
		||||
L 5 (#46f912)
 | 
			
		||||
D 7 (#0d9ec3)
 | 
			
		||||
L 4 (#515142)
 | 
			
		||||
D 3 (#4699e3)
 | 
			
		||||
L 9 (#2ed562)
 | 
			
		||||
U 6 (#00a273)
 | 
			
		||||
L 9 (#8d7d12)
 | 
			
		||||
U 2 (#6c3a83)
 | 
			
		||||
L 7 (#318fa2)
 | 
			
		||||
U 7 (#0bd473)
 | 
			
		||||
L 2 (#6d5050)
 | 
			
		||||
U 10 (#415673)
 | 
			
		||||
R 3 (#9e8420)
 | 
			
		||||
U 6 (#1ff213)
 | 
			
		||||
R 5 (#0c8bf0)
 | 
			
		||||
U 2 (#479a11)
 | 
			
		||||
R 6 (#977360)
 | 
			
		||||
U 5 (#479a13)
 | 
			
		||||
L 8 (#250680)
 | 
			
		||||
U 2 (#1ff211)
 | 
			
		||||
L 3 (#216630)
 | 
			
		||||
U 3 (#22d143)
 | 
			
		||||
L 3 (#3b4342)
 | 
			
		||||
U 7 (#9d4ff3)
 | 
			
		||||
L 5 (#43aca2)
 | 
			
		||||
U 6 (#29efd3)
 | 
			
		||||
L 3 (#5c6a12)
 | 
			
		||||
D 11 (#134a73)
 | 
			
		||||
L 6 (#2a0982)
 | 
			
		||||
U 11 (#444723)
 | 
			
		||||
L 4 (#47e2e2)
 | 
			
		||||
U 4 (#6855c3)
 | 
			
		||||
L 4 (#06a382)
 | 
			
		||||
U 4 (#2222e3)
 | 
			
		||||
R 3 (#4edc62)
 | 
			
		||||
U 6 (#9a2683)
 | 
			
		||||
R 6 (#131872)
 | 
			
		||||
U 10 (#4f5a23)
 | 
			
		||||
R 4 (#858f70)
 | 
			
		||||
U 5 (#4d4823)
 | 
			
		||||
L 9 (#3f73f0)
 | 
			
		||||
U 3 (#46f5a3)
 | 
			
		||||
L 4 (#935370)
 | 
			
		||||
U 4 (#46f5a1)
 | 
			
		||||
L 5 (#3ca140)
 | 
			
		||||
U 6 (#07b1e3)
 | 
			
		||||
L 5 (#61ecd0)
 | 
			
		||||
U 5 (#654743)
 | 
			
		||||
L 5 (#3cec42)
 | 
			
		||||
U 6 (#30bb83)
 | 
			
		||||
R 3 (#920782)
 | 
			
		||||
U 6 (#1f9323)
 | 
			
		||||
R 8 (#3d8aa2)
 | 
			
		||||
U 8 (#7492c3)
 | 
			
		||||
R 3 (#301cd2)
 | 
			
		||||
U 3 (#32e2f1)
 | 
			
		||||
R 4 (#6936f2)
 | 
			
		||||
U 6 (#32e2f3)
 | 
			
		||||
R 6 (#5112c2)
 | 
			
		||||
U 7 (#535b53)
 | 
			
		||||
L 10 (#61f4d0)
 | 
			
		||||
U 3 (#915863)
 | 
			
		||||
L 2 (#51d540)
 | 
			
		||||
U 5 (#32dee1)
 | 
			
		||||
L 10 (#4ec320)
 | 
			
		||||
U 5 (#406bc1)
 | 
			
		||||
L 2 (#1b3890)
 | 
			
		||||
U 3 (#681181)
 | 
			
		||||
L 6 (#35ed60)
 | 
			
		||||
D 9 (#153fd3)
 | 
			
		||||
L 5 (#323e30)
 | 
			
		||||
U 5 (#381ad3)
 | 
			
		||||
L 3 (#69a550)
 | 
			
		||||
U 3 (#310f63)
 | 
			
		||||
L 4 (#2cbb80)
 | 
			
		||||
U 5 (#3448a3)
 | 
			
		||||
R 6 (#206282)
 | 
			
		||||
U 5 (#202ab1)
 | 
			
		||||
L 6 (#83af82)
 | 
			
		||||
U 4 (#202ab3)
 | 
			
		||||
L 4 (#248d02)
 | 
			
		||||
D 9 (#28a983)
 | 
			
		||||
L 4 (#32cf10)
 | 
			
		||||
D 7 (#249d73)
 | 
			
		||||
R 4 (#2f5c70)
 | 
			
		||||
D 6 (#021c93)
 | 
			
		||||
L 7 (#957782)
 | 
			
		||||
D 6 (#550e53)
 | 
			
		||||
R 5 (#957780)
 | 
			
		||||
D 6 (#50bb13)
 | 
			
		||||
R 9 (#49b7f2)
 | 
			
		||||
U 6 (#096e93)
 | 
			
		||||
R 4 (#769452)
 | 
			
		||||
D 3 (#6dc543)
 | 
			
		||||
R 5 (#2ad352)
 | 
			
		||||
D 7 (#167963)
 | 
			
		||||
L 10 (#673682)
 | 
			
		||||
D 5 (#152883)
 | 
			
		||||
L 10 (#13f332)
 | 
			
		||||
D 3 (#996721)
 | 
			
		||||
L 4 (#4be2a2)
 | 
			
		||||
D 4 (#9c2443)
 | 
			
		||||
L 4 (#2b83b0)
 | 
			
		||||
D 3 (#5d63b3)
 | 
			
		||||
L 9 (#9cfd40)
 | 
			
		||||
D 7 (#49e793)
 | 
			
		||||
L 7 (#0b5422)
 | 
			
		||||
D 8 (#5c51b3)
 | 
			
		||||
L 2 (#6db152)
 | 
			
		||||
D 4 (#215b53)
 | 
			
		||||
L 3 (#38dc12)
 | 
			
		||||
D 8 (#7dad01)
 | 
			
		||||
L 6 (#559e22)
 | 
			
		||||
D 3 (#929d23)
 | 
			
		||||
L 2 (#0f7560)
 | 
			
		||||
D 6 (#448d13)
 | 
			
		||||
L 7 (#73a972)
 | 
			
		||||
D 2 (#2221c3)
 | 
			
		||||
L 3 (#73a970)
 | 
			
		||||
D 5 (#53b553)
 | 
			
		||||
R 10 (#513590)
 | 
			
		||||
D 3 (#293c83)
 | 
			
		||||
L 10 (#58e2e0)
 | 
			
		||||
D 4 (#54dd21)
 | 
			
		||||
L 5 (#1bcdf2)
 | 
			
		||||
D 5 (#4b0b71)
 | 
			
		||||
L 5 (#1bcdf0)
 | 
			
		||||
U 6 (#43b811)
 | 
			
		||||
L 5 (#4df1d0)
 | 
			
		||||
U 6 (#36d6a3)
 | 
			
		||||
R 5 (#3bfb20)
 | 
			
		||||
U 5 (#75de61)
 | 
			
		||||
L 5 (#1e0ec2)
 | 
			
		||||
U 4 (#30b571)
 | 
			
		||||
L 7 (#2dfd20)
 | 
			
		||||
D 5 (#49ad61)
 | 
			
		||||
L 2 (#2dfd22)
 | 
			
		||||
D 11 (#715d41)
 | 
			
		||||
L 3 (#1e0ec0)
 | 
			
		||||
U 4 (#0f2091)
 | 
			
		||||
L 4 (#9d29c0)
 | 
			
		||||
U 9 (#475a73)
 | 
			
		||||
L 2 (#108610)
 | 
			
		||||
U 3 (#1e5423)
 | 
			
		||||
L 8 (#394192)
 | 
			
		||||
U 3 (#0274b3)
 | 
			
		||||
							
								
								
									
										89
									
								
								day18/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								day18/main.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	_ "embed"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
 | 
			
		||||
	aoc "go.sour.is/advent-of-code"
 | 
			
		||||
	"golang.org/x/exp/maps"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// var log = aoc.Log
 | 
			
		||||
 | 
			
		||||
func main() { aoc.MustResult(aoc.Runner(run)) }
 | 
			
		||||
 | 
			
		||||
type result struct {
 | 
			
		||||
	valuePT1 int
 | 
			
		||||
	valuePT2 int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (r result) String() string { return fmt.Sprintf("%#v", r) }
 | 
			
		||||
 | 
			
		||||
func run(scan *bufio.Scanner) (*result, error) {
 | 
			
		||||
 | 
			
		||||
	var vecsPT1 []aoc.Vector
 | 
			
		||||
	var vecsPT2 []aoc.Vector
 | 
			
		||||
 | 
			
		||||
	for scan.Scan() {
 | 
			
		||||
		text := scan.Text()
 | 
			
		||||
 | 
			
		||||
		if len(text) == 0 {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		v, color := fromLine(text)
 | 
			
		||||
 | 
			
		||||
		vecsPT1 = append(vecsPT1, v)
 | 
			
		||||
		vecsPT2 = append(vecsPT2, fromColor(color))
 | 
			
		||||
	}
 | 
			
		||||
	return &result{
 | 
			
		||||
		valuePT1: findArea(vecsPT1),
 | 
			
		||||
		valuePT2: findArea(vecsPT2),
 | 
			
		||||
	}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var OFFSET = map[string]aoc.Point{
 | 
			
		||||
	"R": {0, 1},
 | 
			
		||||
	"D": {1, 0},
 | 
			
		||||
	"L": {0, -1},
 | 
			
		||||
	"U": {-1, 0},
 | 
			
		||||
}
 | 
			
		||||
var OFFSET_INDEXES = maps.Values(OFFSET)
 | 
			
		||||
 | 
			
		||||
func fromLine(text string) (aoc.Vector, string) {
 | 
			
		||||
	v := aoc.Vector{}
 | 
			
		||||
	s, text, _ := strings.Cut(text, " ")
 | 
			
		||||
	v.Offset = OFFSET[s]
 | 
			
		||||
 | 
			
		||||
	s, text, _ = strings.Cut(text, " ")
 | 
			
		||||
	v.Scale = aoc.Atoi(s)
 | 
			
		||||
 | 
			
		||||
	_, text, _ = strings.Cut(text, "(#")
 | 
			
		||||
	s, _, _ = strings.Cut(text, ")")
 | 
			
		||||
	return v, s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fromColor(c string) aoc.Vector {
 | 
			
		||||
	scale, _ := strconv.ParseInt(c[:5], 16, 64)
 | 
			
		||||
	offset := OFFSET_INDEXES[c[5]-'0']
 | 
			
		||||
 | 
			
		||||
	return aoc.Vector{
 | 
			
		||||
		Offset: offset,
 | 
			
		||||
		Scale:  int(scale),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func findArea(vecs []aoc.Vector) int {
 | 
			
		||||
	shoelace := []aoc.Point{{0, 0}}
 | 
			
		||||
	borderLength := 0
 | 
			
		||||
 | 
			
		||||
	for _, vec := range vecs {
 | 
			
		||||
		shoelace = append(shoelace, shoelace[len(shoelace)-1].Add(vec.Point()))
 | 
			
		||||
		borderLength += vec.Scale
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return aoc.NumPoints(shoelace, borderLength)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								day18/main_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								day18/main_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,42 @@
 | 
			
		||||
package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	_ "embed"
 | 
			
		||||
 | 
			
		||||
	"github.com/matryer/is"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
//go:embed example.txt
 | 
			
		||||
var example []byte
 | 
			
		||||
 | 
			
		||||
//go:embed input.txt
 | 
			
		||||
var input []byte
 | 
			
		||||
 | 
			
		||||
func TestExample(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
	scan := bufio.NewScanner(bytes.NewReader(example))
 | 
			
		||||
 | 
			
		||||
	result, err := run(scan)
 | 
			
		||||
	is.NoErr(err)
 | 
			
		||||
 | 
			
		||||
	t.Log(result)
 | 
			
		||||
	is.Equal(result.valuePT1, 62)
 | 
			
		||||
	is.Equal(result.valuePT2, 952408144115)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSolution(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
	scan := bufio.NewScanner(bytes.NewReader(input))
 | 
			
		||||
 | 
			
		||||
	result, err := run(scan)
 | 
			
		||||
	is.NoErr(err)
 | 
			
		||||
 | 
			
		||||
	t.Log(result)
 | 
			
		||||
	is.True(result.valuePT1 < 68834) // first attempt too high.
 | 
			
		||||
	is.Equal(result.valuePT1, 46334)
 | 
			
		||||
	is.Equal(result.valuePT2, 102000662718092)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										78
									
								
								grids.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								grids.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
type Vector struct {
 | 
			
		||||
	Offset Point
 | 
			
		||||
	Scale  int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (v Vector) Point() Point {
 | 
			
		||||
	return v.Offset.Scale(v.Scale)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Point [2]int
 | 
			
		||||
 | 
			
		||||
func (p Point) Add(a Point) Point {
 | 
			
		||||
	return Point{p[0] + a[0], p[1] + a[1]}
 | 
			
		||||
}
 | 
			
		||||
func (p Point) Scale(m int) Point {
 | 
			
		||||
	return Point{p[0] * m, p[1] * m}
 | 
			
		||||
}
 | 
			
		||||
func (p Point) Less(b Point) bool {
 | 
			
		||||
	if p[0] != b[0] {
 | 
			
		||||
		return p[0] < b[0]
 | 
			
		||||
	}
 | 
			
		||||
	return p[1] < b[1]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Transpose[T any](matrix [][]T) [][]T {
 | 
			
		||||
	rows, cols := len(matrix), len(matrix[0])
 | 
			
		||||
 | 
			
		||||
	m := make([][]T, cols)
 | 
			
		||||
	for i := range m {
 | 
			
		||||
		m[i] = make([]T, rows)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < cols; i++ {
 | 
			
		||||
		for j := 0; j < rows; j++ {
 | 
			
		||||
			m[i][j] = matrix[j][i]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// NumPoints the number of the points inside an outline plus the number of points in the outline
 | 
			
		||||
func NumPoints(outline []Point, borderLength int) int {
 | 
			
		||||
	// shoelace - find the float area in a shape
 | 
			
		||||
	sum := 0
 | 
			
		||||
	for _, p := range Pairwise(outline) {
 | 
			
		||||
		row1, col1 := p[0][0], p[0][1]
 | 
			
		||||
		row2, col2 := p[1][0], p[1][1]
 | 
			
		||||
 | 
			
		||||
		sum += row1*col2 - row2*col1
 | 
			
		||||
	}
 | 
			
		||||
	area := sum / 2
 | 
			
		||||
 | 
			
		||||
	// pick's theorem - find the number of points in a shape given its area
 | 
			
		||||
	return (ABS(area) - borderLength/2 + 1) + borderLength
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Map[T any] [][]T
 | 
			
		||||
 | 
			
		||||
func (m *Map[T]) Get(p Point) (Point, T, bool) {
 | 
			
		||||
	var zero T
 | 
			
		||||
	if !m.Valid(p) {
 | 
			
		||||
		return [2]int{0, 0}, zero, false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return p, (*m)[p[0]][p[1]], true
 | 
			
		||||
}
 | 
			
		||||
func (m *Map[T]) Size() (int, int) {
 | 
			
		||||
	if m == nil || len(*m) == 0 {
 | 
			
		||||
		return 0, 0
 | 
			
		||||
	}
 | 
			
		||||
	return len(*m), len((*m)[0])
 | 
			
		||||
}
 | 
			
		||||
func (m *Map[T]) Valid(p Point) bool {
 | 
			
		||||
	rows, cols := m.Size()
 | 
			
		||||
	return p[0] >= 0 && p[0] < rows && p[1] >= 0 && p[1] < cols
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										56
									
								
								itertools.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								itertools.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"strconv"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Atoi(s string) int {
 | 
			
		||||
	i, _ := strconv.Atoi(s)
 | 
			
		||||
	return i
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Repeat[T any](s T, i int) []T {
 | 
			
		||||
	lis := make([]T, i)
 | 
			
		||||
	for i := range lis {
 | 
			
		||||
		lis[i] = s
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Reduce[T, U any](fn func(int, T, U) U, u U, list ...T) U {
 | 
			
		||||
	for i, t := range list {
 | 
			
		||||
		u = fn(i, t, u)
 | 
			
		||||
	}
 | 
			
		||||
	return u
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Reverse[T any](arr []T) []T {
 | 
			
		||||
	for i := 0; i < len(arr)/2; i++ {
 | 
			
		||||
		arr[i], arr[len(arr)-i-1] = arr[len(arr)-i-1], arr[i]
 | 
			
		||||
	}
 | 
			
		||||
	return arr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SliceMap[T, U any](fn func(T) U, in ...T) []U {
 | 
			
		||||
	lis := make([]U, len(in))
 | 
			
		||||
	for i := range lis {
 | 
			
		||||
		lis[i] = fn(in[i])
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
func SliceIMap[T, U any](fn func(int, T) U, in ...T) []U {
 | 
			
		||||
	lis := make([]U, len(in))
 | 
			
		||||
	for i := range lis {
 | 
			
		||||
		lis[i] = fn(i, in[i])
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Pairwise iterates over a list pairing i, i+1
 | 
			
		||||
func Pairwise[T any](arr []T) [][2]T {
 | 
			
		||||
	var pairs [][2]T
 | 
			
		||||
	for i := range arr[:len(arr)-1] {
 | 
			
		||||
		pairs = append(pairs, [2]T{arr[i], arr[i+1]})
 | 
			
		||||
	}
 | 
			
		||||
	return pairs
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										100
									
								
								lists.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								lists.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,100 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
import "fmt"
 | 
			
		||||
 | 
			
		||||
type Node[T any] struct {
 | 
			
		||||
	value T
 | 
			
		||||
	pos   int
 | 
			
		||||
	left  *Node[T]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) add(a *Node[T]) *Node[T] {
 | 
			
		||||
	if a == nil {
 | 
			
		||||
		return n
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return a
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n.left = a
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) Value() (value T, ok bool) {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return n.value, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) Position() int {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	return n.pos
 | 
			
		||||
}
 | 
			
		||||
func (n *Node[T]) SetPosition(i int) {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	n.pos = i
 | 
			
		||||
}
 | 
			
		||||
func (n *Node[T]) Next() *Node[T] {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return n.left
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) String() string {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return "EOL"
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("node %v", n.value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type List[T any] struct {
 | 
			
		||||
	head *Node[T]
 | 
			
		||||
	n    *Node[T]
 | 
			
		||||
	p    map[int]*Node[T]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewList[T any](a *Node[T]) *List[T] {
 | 
			
		||||
	lis := &List[T]{
 | 
			
		||||
		head: a,
 | 
			
		||||
		n:    a,
 | 
			
		||||
		p:    make(map[int]*Node[T]),
 | 
			
		||||
	}
 | 
			
		||||
	lis.add(a)
 | 
			
		||||
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) Add(value T, pos int) {
 | 
			
		||||
	a := &Node[T]{value: value, pos: pos}
 | 
			
		||||
	l.add(a)
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) add(a *Node[T]) {
 | 
			
		||||
	if l.head == nil {
 | 
			
		||||
		l.head = a
 | 
			
		||||
	}
 | 
			
		||||
	if a == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	l.n = l.n.add(a)
 | 
			
		||||
	l.p[a.pos] = a
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) Get(pos int) *Node[T] {
 | 
			
		||||
	return l.p[pos]
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) GetN(pos ...int) []*Node[T] {
 | 
			
		||||
	lis := make([]*Node[T], len(pos))
 | 
			
		||||
	for i, p := range pos {
 | 
			
		||||
		lis[i] = l.p[p]
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) Head() *Node[T] {
 | 
			
		||||
	return l.head
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										96
									
								
								math.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								math.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,96 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
import "cmp"
 | 
			
		||||
 | 
			
		||||
type uinteger interface {
 | 
			
		||||
	uint | uint8 | uint16 | uint32 | uint64
 | 
			
		||||
}
 | 
			
		||||
type sinteger interface {
 | 
			
		||||
	int | int8 | int16 | int32 | int64
 | 
			
		||||
}
 | 
			
		||||
type integer interface {
 | 
			
		||||
	sinteger | uinteger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// type float interface {
 | 
			
		||||
// 	complex64 | complex128 | float32 | float64
 | 
			
		||||
// }
 | 
			
		||||
// type number interface{ integer | float }
 | 
			
		||||
 | 
			
		||||
// greatest common divisor (GCD) via Euclidean algorithm
 | 
			
		||||
func GCD[T integer](a, b T) T {
 | 
			
		||||
	for b != 0 {
 | 
			
		||||
		t := b
 | 
			
		||||
		b = a % b
 | 
			
		||||
		a = t
 | 
			
		||||
	}
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// find Least Common Multiple (LCM) via GCD
 | 
			
		||||
func LCM[T integer](integers ...T) T {
 | 
			
		||||
	if len(integers) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if len(integers) == 1 {
 | 
			
		||||
		return integers[0]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a, b := integers[0], integers[1]
 | 
			
		||||
	result := a * b / GCD(a, b)
 | 
			
		||||
 | 
			
		||||
	for _, c := range integers[2:] {
 | 
			
		||||
		result = LCM(result, c)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Sum[T integer](arr ...T) T {
 | 
			
		||||
	var acc T
 | 
			
		||||
	for _, a := range arr {
 | 
			
		||||
		acc += a
 | 
			
		||||
	}
 | 
			
		||||
	return acc
 | 
			
		||||
}
 | 
			
		||||
func SumFunc[T any, U integer](fn func(T) U, input ...T) U {
 | 
			
		||||
	return Sum(SliceMap(fn, input...)...)
 | 
			
		||||
}
 | 
			
		||||
func SumIFunc[T any, U integer](fn func(int, T) U, input ...T) U {
 | 
			
		||||
	return Sum(SliceIMap(fn, input...)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Power2(n int) int {
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
	p := 2
 | 
			
		||||
	for ; n > 1; n-- {
 | 
			
		||||
		p *= 2
 | 
			
		||||
	}
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ABS(i int) int {
 | 
			
		||||
	if i < 0 {
 | 
			
		||||
		return -i
 | 
			
		||||
	}
 | 
			
		||||
	return i
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Max[T cmp.Ordered](a T, v ...T) T {
 | 
			
		||||
	for _, b := range v {
 | 
			
		||||
		if b > a {
 | 
			
		||||
			a = b
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
func Min[T cmp.Ordered](a T, v ...T) T {
 | 
			
		||||
	for _, b := range v {
 | 
			
		||||
		if b < a {
 | 
			
		||||
			a = b
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								runner.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								runner.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,46 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Runner[R any, F func(*bufio.Scanner) (R, error)](run F) (R, error) {
 | 
			
		||||
	if len(os.Args) != 2 {
 | 
			
		||||
		Log("Usage:", filepath.Base(os.Args[0]), "FILE")
 | 
			
		||||
		os.Exit(22)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	input, err := os.Open(os.Args[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		Log(err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scan := bufio.NewScanner(input)
 | 
			
		||||
	return run(scan)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func MustResult[T any](result T, err error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println("ERR", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log("result", result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Log(v ...any) { fmt.Fprintln(os.Stderr, v...) }
 | 
			
		||||
func Logf(format string, v ...any) {
 | 
			
		||||
	if !strings.HasSuffix(format, "\n") {
 | 
			
		||||
		format += "\n"
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintf(os.Stderr, format, v...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReadStringToInts(fields []string) []int {
 | 
			
		||||
	return SliceMap(Atoi, fields...)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										35
									
								
								search.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								search.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,35 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"sort"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type priorityQueue[T any, U []T] struct {
 | 
			
		||||
	elems U
 | 
			
		||||
	less  func(a, b T) bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func PriorityQueue[T any, U []T](less func(a, b T) bool) *priorityQueue[T, U] {
 | 
			
		||||
	return &priorityQueue[T, U]{less: less}
 | 
			
		||||
}
 | 
			
		||||
func (pq *priorityQueue[T, U]) Enqueue(elem T) {
 | 
			
		||||
	pq.elems = append(pq.elems, elem)
 | 
			
		||||
	sort.Slice(pq.elems, func(i, j int) bool { return pq.less(pq.elems[j], pq.elems[i]) })
 | 
			
		||||
}
 | 
			
		||||
func (pq *priorityQueue[T, I]) IsEmpty() bool {
 | 
			
		||||
	return len(pq.elems) == 0
 | 
			
		||||
}
 | 
			
		||||
func (pq *priorityQueue[T, I]) Dequeue() (T, bool) {
 | 
			
		||||
	var elem T
 | 
			
		||||
	if pq.IsEmpty() {
 | 
			
		||||
		return elem, false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pq.elems, elem = pq.elems[:len(pq.elems)-1], pq.elems[len(pq.elems)-1]
 | 
			
		||||
	return elem, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type DS[T comparable] struct {
 | 
			
		||||
	*priorityQueue[T, []T]
 | 
			
		||||
	*set[T]
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										59
									
								
								set.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								set.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,59 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
import "golang.org/x/exp/maps"
 | 
			
		||||
 | 
			
		||||
type set[T comparable] map[T]struct{}
 | 
			
		||||
 | 
			
		||||
func Set[T comparable](arr ...T) set[T] {
 | 
			
		||||
	m := make(set[T], len(arr))
 | 
			
		||||
	for _, a := range arr {
 | 
			
		||||
		m[a] = struct{}{}
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
func (m *set[T]) Add(a T) {
 | 
			
		||||
	(*m)[a] = struct{}{}
 | 
			
		||||
}
 | 
			
		||||
func (m *set[T]) Items() []T {
 | 
			
		||||
	return maps.Keys(*m)
 | 
			
		||||
}
 | 
			
		||||
func (m *set[T]) Has(a T) bool {
 | 
			
		||||
	var ok bool
 | 
			
		||||
	_, ok = (*m)[a]
 | 
			
		||||
	return ok
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type defaultMap[K comparable, V any] struct {
 | 
			
		||||
	m map[K]V
 | 
			
		||||
	d V
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func DefaultMap[K comparable, V any](d V) *defaultMap[K, V] {
 | 
			
		||||
	return &defaultMap[K, V]{
 | 
			
		||||
		make(map[K]V),
 | 
			
		||||
		d,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *defaultMap[K, V]) Set(k K, v V) {
 | 
			
		||||
	m.m[k] = v
 | 
			
		||||
}
 | 
			
		||||
func (m *defaultMap[K, V]) Get(k K) (V, bool) {
 | 
			
		||||
	if v, ok := m.m[k]; ok {
 | 
			
		||||
		return v, true
 | 
			
		||||
	}
 | 
			
		||||
	return m.d, false
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type pair[K, V any] struct {
 | 
			
		||||
	K K
 | 
			
		||||
	V V
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *defaultMap[K, V]) Items() []pair[K, V] {
 | 
			
		||||
	var items = make([]pair[K, V], 0, len(m.m))
 | 
			
		||||
	for k, v := range m.m {
 | 
			
		||||
		items = append(items, pair[K, V]{k, v})
 | 
			
		||||
	}
 | 
			
		||||
	return items
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										395
									
								
								tools.go
									
									
									
									
									
								
							
							
						
						
									
										395
									
								
								tools.go
									
									
									
									
									
								
							@ -1,395 +0,0 @@
 | 
			
		||||
package aoc
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bufio"
 | 
			
		||||
	"cmp"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func Runner[R any, F func(*bufio.Scanner) (R, error)](run F) (R, error) {
 | 
			
		||||
	if len(os.Args) != 2 {
 | 
			
		||||
		Log("Usage:", filepath.Base(os.Args[0]), "FILE")
 | 
			
		||||
		os.Exit(22)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	input, err := os.Open(os.Args[1])
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		Log(err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	scan := bufio.NewScanner(input)
 | 
			
		||||
	return run(scan)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func MustResult[T any](result T, err error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		fmt.Println("ERR", err)
 | 
			
		||||
		os.Exit(1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	Log("result", result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Log(v ...any) { fmt.Fprintln(os.Stderr, v...) }
 | 
			
		||||
func Logf(format string, v ...any) {
 | 
			
		||||
	if !strings.HasSuffix(format, "\n") {
 | 
			
		||||
		format += "\n"
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Fprintf(os.Stderr, format, v...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Reverse[T any](arr []T) []T {
 | 
			
		||||
	for i := 0; i < len(arr)/2; i++ {
 | 
			
		||||
		arr[i], arr[len(arr)-i-1] = arr[len(arr)-i-1], arr[i]
 | 
			
		||||
	}
 | 
			
		||||
	return arr
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type uinteger interface {
 | 
			
		||||
	uint | uint8 | uint16 | uint32 | uint64
 | 
			
		||||
}
 | 
			
		||||
type sinteger interface {
 | 
			
		||||
	int | int8 | int16 | int32 | int64
 | 
			
		||||
}
 | 
			
		||||
type integer interface {
 | 
			
		||||
	sinteger | uinteger
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// type float interface {
 | 
			
		||||
// 	complex64 | complex128 | float32 | float64
 | 
			
		||||
// }
 | 
			
		||||
// type number interface{ integer | float }
 | 
			
		||||
 | 
			
		||||
// greatest common divisor (GCD) via Euclidean algorithm
 | 
			
		||||
func GCD[T integer](a, b T) T {
 | 
			
		||||
	for b != 0 {
 | 
			
		||||
		t := b
 | 
			
		||||
		b = a % b
 | 
			
		||||
		a = t
 | 
			
		||||
	}
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// find Least Common Multiple (LCM) via GCD
 | 
			
		||||
func LCM[T integer](integers ...T) T {
 | 
			
		||||
	if len(integers) == 0 {
 | 
			
		||||
		return 0
 | 
			
		||||
	}
 | 
			
		||||
	if len(integers) == 1 {
 | 
			
		||||
		return integers[0]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	a, b := integers[0], integers[1]
 | 
			
		||||
	result := a * b / GCD(a, b)
 | 
			
		||||
 | 
			
		||||
	for _, c := range integers[2:] {
 | 
			
		||||
		result = LCM(result, c)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ReadStringToInts(fields []string) []int {
 | 
			
		||||
	return SliceMap(Atoi, fields...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Node[T any] struct {
 | 
			
		||||
	value T
 | 
			
		||||
	pos   int
 | 
			
		||||
	left  *Node[T]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) add(a *Node[T]) *Node[T] {
 | 
			
		||||
	if a == nil {
 | 
			
		||||
		return n
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return a
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	n.left = a
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) Value() (value T, ok bool) {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	return n.value, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) Position() int {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return -1
 | 
			
		||||
	}
 | 
			
		||||
	return n.pos
 | 
			
		||||
}
 | 
			
		||||
func (n *Node[T]) SetPosition(i int) {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	n.pos = i
 | 
			
		||||
}
 | 
			
		||||
func (n *Node[T]) Next() *Node[T] {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	return n.left
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *Node[T]) String() string {
 | 
			
		||||
	if n == nil {
 | 
			
		||||
		return "EOL"
 | 
			
		||||
	}
 | 
			
		||||
	return fmt.Sprintf("node %v", n.value)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type List[T any] struct {
 | 
			
		||||
	head *Node[T]
 | 
			
		||||
	n    *Node[T]
 | 
			
		||||
	p    map[int]*Node[T]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewList[T any](a *Node[T]) *List[T] {
 | 
			
		||||
	lis := &List[T]{
 | 
			
		||||
		head: a,
 | 
			
		||||
		n:    a,
 | 
			
		||||
		p:    make(map[int]*Node[T]),
 | 
			
		||||
	}
 | 
			
		||||
	lis.add(a)
 | 
			
		||||
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) Add(value T, pos int) {
 | 
			
		||||
	a := &Node[T]{value: value, pos: pos}
 | 
			
		||||
	l.add(a)
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) add(a *Node[T]) {
 | 
			
		||||
	if l.head == nil {
 | 
			
		||||
		l.head = a
 | 
			
		||||
	}
 | 
			
		||||
	if a == nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	l.n = l.n.add(a)
 | 
			
		||||
	l.p[a.pos] = a
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) Get(pos int) *Node[T] {
 | 
			
		||||
	return l.p[pos]
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) GetN(pos ...int) []*Node[T] {
 | 
			
		||||
	lis := make([]*Node[T], len(pos))
 | 
			
		||||
	for i, p := range pos {
 | 
			
		||||
		lis[i] = l.p[p]
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
func (l *List[T]) Head() *Node[T] {
 | 
			
		||||
	return l.head
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func SliceMap[T, U any](fn func(T) U, in ...T) []U {
 | 
			
		||||
	lis := make([]U, len(in))
 | 
			
		||||
	for i := range lis {
 | 
			
		||||
		lis[i] = fn(in[i])
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
func SliceIMap[T, U any](fn func(int, T) U, in ...T) []U {
 | 
			
		||||
	lis := make([]U, len(in))
 | 
			
		||||
	for i := range lis {
 | 
			
		||||
		lis[i] = fn(i, in[i])
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Atoi(s string) int {
 | 
			
		||||
	i, _ := strconv.Atoi(s)
 | 
			
		||||
	return i
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Repeat[T any](s T, i int) []T {
 | 
			
		||||
	lis := make([]T, i)
 | 
			
		||||
	for i := range lis {
 | 
			
		||||
		lis[i] = s
 | 
			
		||||
	}
 | 
			
		||||
	return lis
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Sum[T integer](arr ...T) T {
 | 
			
		||||
	var acc T
 | 
			
		||||
	for _, a := range arr {
 | 
			
		||||
		acc += a
 | 
			
		||||
	}
 | 
			
		||||
	return acc
 | 
			
		||||
}
 | 
			
		||||
func SumFunc[T any, U integer](fn func(T) U, input ...T) U {
 | 
			
		||||
	return Sum(SliceMap(fn, input...)...)
 | 
			
		||||
}
 | 
			
		||||
func SumIFunc[T any, U integer](fn func(int, T) U, input ...T) U {
 | 
			
		||||
	return Sum(SliceIMap(fn, input...)...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Power2(n int) int {
 | 
			
		||||
	if n == 0 {
 | 
			
		||||
		return 1
 | 
			
		||||
	}
 | 
			
		||||
	p := 2
 | 
			
		||||
	for ; n > 1; n-- {
 | 
			
		||||
		p *= 2
 | 
			
		||||
	}
 | 
			
		||||
	return p
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func ABS(i int) int {
 | 
			
		||||
	if i < 0 {
 | 
			
		||||
		return -i
 | 
			
		||||
	}
 | 
			
		||||
	return i
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Transpose[T any](matrix [][]T) [][]T {
 | 
			
		||||
	rows, cols := len(matrix), len(matrix[0])
 | 
			
		||||
 | 
			
		||||
	m := make([][]T, cols)
 | 
			
		||||
	for i := range m {
 | 
			
		||||
		m[i] = make([]T, rows)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for i := 0; i < cols; i++ {
 | 
			
		||||
		for j := 0; j < rows; j++ {
 | 
			
		||||
			m[i][j] = matrix[j][i]
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return m
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Reduce[T, U any](fn func(int, T, U) U, u U, list ...T) U {
 | 
			
		||||
	for i, t := range list {
 | 
			
		||||
		u = fn(i, t, u)
 | 
			
		||||
	}
 | 
			
		||||
	return u
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Max[T cmp.Ordered](a T, v ...T) T {
 | 
			
		||||
	for _, b := range v {
 | 
			
		||||
		if b > a {
 | 
			
		||||
			a = b
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
func Min[T cmp.Ordered](a T, v ...T) T {
 | 
			
		||||
	for _, b := range v {
 | 
			
		||||
		if b < a {
 | 
			
		||||
			a = b
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return a
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type PQElem[T any, I integer] struct {
 | 
			
		||||
	Value    T
 | 
			
		||||
	Priority I
 | 
			
		||||
}
 | 
			
		||||
type PQList[T any, I integer] []PQElem[T, I]
 | 
			
		||||
 | 
			
		||||
func (pq PQList[T, I]) Len() int {
 | 
			
		||||
	return len(pq)
 | 
			
		||||
}
 | 
			
		||||
func (pq PQList[T, I]) Less(i int, j int) bool {
 | 
			
		||||
	return pq[i].Priority < pq[j].Priority
 | 
			
		||||
}
 | 
			
		||||
func (pq PQList[T, I]) Swap(i int, j int) {
 | 
			
		||||
	pq[i], pq[j] = pq[j], pq[i]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ sort.Interface = (*PQList[rune, int])(nil)
 | 
			
		||||
 | 
			
		||||
type PriorityQueue[T any, I integer] struct {
 | 
			
		||||
	elem PQList[T, I]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (pq *PriorityQueue[T, I]) Enqueue(elem T, priority I) {
 | 
			
		||||
	pq.elem = append(pq.elem, PQElem[T, I]{elem, priority})
 | 
			
		||||
	sort.Sort(pq.elem)
 | 
			
		||||
}
 | 
			
		||||
func (pq *PriorityQueue[T, I]) IsEmpty() bool {
 | 
			
		||||
	return len(pq.elem) == 0
 | 
			
		||||
}
 | 
			
		||||
func (pq *PriorityQueue[T, I]) Dequeue() (T, bool) {
 | 
			
		||||
	var elem T
 | 
			
		||||
	if pq.IsEmpty() {
 | 
			
		||||
		return elem, false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	elem, pq.elem = pq.elem[0].Value, pq.elem[1:]
 | 
			
		||||
	return elem, true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Vertex[V comparable, I integer] struct {
 | 
			
		||||
	to    V
 | 
			
		||||
	score I
 | 
			
		||||
}
 | 
			
		||||
type graph[V comparable, I uinteger] struct {
 | 
			
		||||
	adj map[V][]Vertex[V, I]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func Graph[V comparable, I uinteger](size int) *graph[V, I] {
 | 
			
		||||
	return &graph[V, I]{
 | 
			
		||||
		adj: make(map[V][]Vertex[V, I], size),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
func (g *graph[V, I]) AddEdge(u, v V, w I) {
 | 
			
		||||
	g.adj[u] = append(g.adj[u], Vertex[V, I]{to: v, score: w})
 | 
			
		||||
	g.adj[v] = append(g.adj[v], Vertex[V, I]{to: u, score: w})
 | 
			
		||||
}
 | 
			
		||||
func (g *graph[V, I]) Dijkstra(m interface{Get()}, src V) map[V]I {
 | 
			
		||||
	pq := PriorityQueue[V, I]{}
 | 
			
		||||
	dist := make(map[V]I, len(g.adj))
 | 
			
		||||
	visited := make(map[V]bool, len(g.adj))
 | 
			
		||||
	var INF I
 | 
			
		||||
	INF = ^INF
 | 
			
		||||
 | 
			
		||||
	pq.Enqueue(src, 0)
 | 
			
		||||
	dist[src] = 0
 | 
			
		||||
 | 
			
		||||
	for !pq.IsEmpty() {
 | 
			
		||||
		u, _ := pq.Dequeue()
 | 
			
		||||
 | 
			
		||||
		if _, ok := visited[u]; ok {
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		visited[u] = true
 | 
			
		||||
 | 
			
		||||
		for _, v := range g.adj[u] {
 | 
			
		||||
			_, ok := visited[v.to]
 | 
			
		||||
			var du, dv I
 | 
			
		||||
			if d, inf := dist[u]; !inf {
 | 
			
		||||
				du = INF
 | 
			
		||||
			} else {
 | 
			
		||||
				du = d
 | 
			
		||||
			}
 | 
			
		||||
			if d, inf := dist[v.to]; !inf {
 | 
			
		||||
				dv = INF
 | 
			
		||||
			} else {
 | 
			
		||||
				dv = d
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if !ok && du+v.score < dv {
 | 
			
		||||
				dist[v.to] = du + v.score
 | 
			
		||||
				pq.Enqueue(v.to, du+v.score)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return dist
 | 
			
		||||
}
 | 
			
		||||
@ -1,93 +0,0 @@
 | 
			
		||||
package aoc_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"testing"
 | 
			
		||||
 | 
			
		||||
	"github.com/matryer/is"
 | 
			
		||||
	aoc "go.sour.is/advent-of-code"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func TestReverse(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.Reverse([]int{1, 2, 3, 4}), []int{4, 3, 2, 1})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestLCM(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.LCM([]int{}...), 0)
 | 
			
		||||
	is.Equal(aoc.LCM(5), 5)
 | 
			
		||||
	is.Equal(aoc.LCM(5, 3), 15)
 | 
			
		||||
	is.Equal(aoc.LCM(5, 3, 2), 30)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestReadStringToInts(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.ReadStringToInts([]string{"1", "2", "3"}), []int{1, 2, 3})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestRepeat(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.Repeat(5, 3), []int{5, 5, 5})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestPower2(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.Power2(0), 1)
 | 
			
		||||
	is.Equal(aoc.Power2(1), 2)
 | 
			
		||||
	is.Equal(aoc.Power2(2), 4)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestABS(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(aoc.ABS(1), 1)
 | 
			
		||||
	is.Equal(aoc.ABS(0), 0)
 | 
			
		||||
	is.Equal(aoc.ABS(-1), 1)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestTranspose(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	is.Equal(
 | 
			
		||||
		aoc.Transpose(
 | 
			
		||||
			[][]int{
 | 
			
		||||
				{1, 1},
 | 
			
		||||
				{0, 0},
 | 
			
		||||
				{1, 1},
 | 
			
		||||
			},
 | 
			
		||||
		),
 | 
			
		||||
		[][]int{
 | 
			
		||||
			{1, 0, 1},
 | 
			
		||||
			{1, 0, 1},
 | 
			
		||||
		},
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestList(t *testing.T) {
 | 
			
		||||
	is := is.New(t)
 | 
			
		||||
 | 
			
		||||
	lis := aoc.NewList[int](nil)
 | 
			
		||||
	lis.Add(5, 0)
 | 
			
		||||
 | 
			
		||||
	a, _ := lis.Head().Value()
 | 
			
		||||
 | 
			
		||||
	is.Equal(a, 5)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestGraph(t *testing.T) {
 | 
			
		||||
	g := aoc.Graph[int, uint](7)
 | 
			
		||||
	g.AddEdge(0, 1, 2)
 | 
			
		||||
	g.AddEdge(0, 2, 6)
 | 
			
		||||
	g.AddEdge(1, 3, 5)
 | 
			
		||||
	g.AddEdge(2, 3, 8)
 | 
			
		||||
	g.AddEdge(3, 4, 10)
 | 
			
		||||
	g.AddEdge(3, 5, 15)
 | 
			
		||||
	g.AddEdge(4, 6, 2)
 | 
			
		||||
	g.AddEdge(5, 6, 6)
 | 
			
		||||
	// g.Dijkstra(0)
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user