Tapping out on Day 19
This commit is contained in:
20
README.md
20
README.md
@@ -191,3 +191,23 @@ The solution for "eighteen" is:
|
|||||||
The magnitude of the final sum is 4202
|
The magnitude of the final sum is 4202
|
||||||
The largest magnitude of any two snail numbers is 4779
|
The largest magnitude of any two snail numbers is 4779
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Day nineteen
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ./aoc2021 --nineteen
|
||||||
|
The solution for "nineteen" is:
|
||||||
|
nineteen part 1 answer for map
|
||||||
|
nineteen part 2 answer for map
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
### Day nineteen
|
||||||
|
|
||||||
|
```sh
|
||||||
|
$ ./aoc2021 --nineteen
|
||||||
|
The solution for "nineteen" is:
|
||||||
|
nineteen part 1 answer for mapping
|
||||||
|
nineteen part 2 answer for mapping
|
||||||
|
```
|
||||||
|
|
||||||
|
3
main.go
3
main.go
@@ -13,6 +13,7 @@ import (
|
|||||||
"unsupervised.ca/aoc2021/four"
|
"unsupervised.ca/aoc2021/four"
|
||||||
"unsupervised.ca/aoc2021/fourteen"
|
"unsupervised.ca/aoc2021/fourteen"
|
||||||
"unsupervised.ca/aoc2021/nine"
|
"unsupervised.ca/aoc2021/nine"
|
||||||
|
"unsupervised.ca/aoc2021/nineteen"
|
||||||
"unsupervised.ca/aoc2021/one"
|
"unsupervised.ca/aoc2021/one"
|
||||||
"unsupervised.ca/aoc2021/seven"
|
"unsupervised.ca/aoc2021/seven"
|
||||||
"unsupervised.ca/aoc2021/seventeen"
|
"unsupervised.ca/aoc2021/seventeen"
|
||||||
@@ -76,6 +77,8 @@ func main() {
|
|||||||
day = seventeen.Init("seventeen/input.txt")
|
day = seventeen.Init("seventeen/input.txt")
|
||||||
case "eighteen":
|
case "eighteen":
|
||||||
day = eighteen.Init("eighteen/input.txt")
|
day = eighteen.Init("eighteen/input.txt")
|
||||||
|
case "nineteen":
|
||||||
|
day = nineteen.Init("nineteen/input.txt")
|
||||||
default:
|
default:
|
||||||
fmt.Printf("%q does not have a solution.\n", flagParts[1])
|
fmt.Printf("%q does not have a solution.\n", flagParts[1])
|
||||||
help()
|
help()
|
||||||
|
0
nineteen/input.txt
Normal file
0
nineteen/input.txt
Normal file
23
nineteen/main.go
Normal file
23
nineteen/main.go
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package nineteen
|
||||||
|
|
||||||
|
type Nineteen struct {
|
||||||
|
mapping mapping
|
||||||
|
}
|
||||||
|
|
||||||
|
func Init(filepath string) *Nineteen {
|
||||||
|
nineteen := &Nineteen{
|
||||||
|
mapping: mapping{},
|
||||||
|
}
|
||||||
|
|
||||||
|
nineteen.mapping.load(filepath)
|
||||||
|
return nineteen
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Nineteen) Answer() string {
|
||||||
|
return "nineteen part 1 answer for mapping"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Nineteen) FollowUp() string {
|
||||||
|
return "nineteen part 2 answer for mapping"
|
||||||
|
}
|
||||||
|
|
227
nineteen/mapping.go
Normal file
227
nineteen/mapping.go
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
package nineteen
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type offset struct {
|
||||||
|
label string
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
z int
|
||||||
|
}
|
||||||
|
|
||||||
|
type point struct {
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
z int
|
||||||
|
}
|
||||||
|
|
||||||
|
type distance struct {
|
||||||
|
first string
|
||||||
|
second string
|
||||||
|
magnitude float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type pair struct {
|
||||||
|
aIndex int
|
||||||
|
a distance
|
||||||
|
|
||||||
|
bIndex int
|
||||||
|
b distance
|
||||||
|
}
|
||||||
|
|
||||||
|
type beacon struct {
|
||||||
|
references map[int]string
|
||||||
|
}
|
||||||
|
|
||||||
|
type scanner struct {
|
||||||
|
id int
|
||||||
|
location point
|
||||||
|
distances []distance
|
||||||
|
beacons []offset
|
||||||
|
}
|
||||||
|
|
||||||
|
type mapping struct {
|
||||||
|
scanners []*scanner
|
||||||
|
beacons []beacon
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mapping) load(filename string) error {
|
||||||
|
file, err := os.Open(filename)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
s := bufio.NewScanner(file)
|
||||||
|
|
||||||
|
m.scanners = []*scanner{}
|
||||||
|
newScanner := true
|
||||||
|
var scan *scanner
|
||||||
|
|
||||||
|
for s.Scan() {
|
||||||
|
if s.Text() == "" {
|
||||||
|
newScanner = true
|
||||||
|
m.scanners = append(m.scanners, scan)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if newScanner {
|
||||||
|
scan = &scanner{}
|
||||||
|
header := strings.Split(s.Text(), " ")
|
||||||
|
newScannerID, _ := strconv.Atoi(header[2])
|
||||||
|
scan.id = newScannerID
|
||||||
|
newScanner = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
coords := strings.Split(s.Text(), ",")
|
||||||
|
xVal, _ := strconv.Atoi(coords[0])
|
||||||
|
yVal, _ := strconv.Atoi(coords[1])
|
||||||
|
zVal, _ := strconv.Atoi(coords[2])
|
||||||
|
scan.beacons = append(scan.beacons, offset{
|
||||||
|
label: s.Text(),
|
||||||
|
x: xVal,
|
||||||
|
y: yVal,
|
||||||
|
z: zVal,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
m.scanners = append(m.scanners, scan)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mapping) initialize() {
|
||||||
|
// For each scanner initialize the distances between points
|
||||||
|
for _, s := range m.scanners {
|
||||||
|
// For each beacon in the scanner find its distance to all others
|
||||||
|
for i := 0; i < len(s.beacons)-1; i++ {
|
||||||
|
// We don't need to check i == j ever and don't need to do a full double loop
|
||||||
|
for j := i + 1; j < len(s.beacons); j++ {
|
||||||
|
s.distances = append(s.distances, distance{
|
||||||
|
first: s.beacons[i].label,
|
||||||
|
second: s.beacons[j].label,
|
||||||
|
magnitude: distanceMagnitude(s.beacons[i], s.beacons[j]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check each scanner for overlap
|
||||||
|
for i := 0; i < len(m.scanners)-1; i++ {
|
||||||
|
for j := i + 1; j < len(m.scanners); j++ {
|
||||||
|
overlapMagnitudes := []pair{}
|
||||||
|
for _, iDist := range m.scanners[i].distances {
|
||||||
|
for _, jDist := range m.scanners[j].distances {
|
||||||
|
if iDist.magnitude == jDist.magnitude {
|
||||||
|
overlapMagnitudes = append(overlapMagnitudes, pair{
|
||||||
|
aIndex: i,
|
||||||
|
a: iDist,
|
||||||
|
bIndex: j,
|
||||||
|
b: jDist,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(overlapMagnitudes) >= 6 {
|
||||||
|
fmt.Println("Overlap between scanners", i, "and", j)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(overlapMagnitudes) >= 6 {
|
||||||
|
for _, p := range overlapMagnitudes {
|
||||||
|
// Check if we have seen this on another scanner
|
||||||
|
found := false
|
||||||
|
var newBeacon *beacon
|
||||||
|
for _, b := range m.beacons {
|
||||||
|
if b.references[p.aIndex] == p.a.first {
|
||||||
|
b.references[p.bIndex] = p.b.first
|
||||||
|
newBeacon = &beacon{
|
||||||
|
references: map[int]string{
|
||||||
|
p.aIndex: p.a.second,
|
||||||
|
p.bIndex: p.b.second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
} else if b.references[p.aIndex] == p.a.second {
|
||||||
|
b.references[p.bIndex] = p.b.second
|
||||||
|
newBeacon = &beacon{
|
||||||
|
references: map[int]string{
|
||||||
|
p.aIndex: p.a.first,
|
||||||
|
p.bIndex: p.b.first,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.references[p.bIndex] == p.b.first {
|
||||||
|
b.references[p.aIndex] = p.a.first
|
||||||
|
|
||||||
|
if found {
|
||||||
|
newBeacon = nil
|
||||||
|
} else {
|
||||||
|
newBeacon = &beacon{
|
||||||
|
references: map[int]string{
|
||||||
|
p.aIndex: p.a.second,
|
||||||
|
p.bIndex: p.b.second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
found = true
|
||||||
|
} else if b.references[p.bIndex] == p.b.second {
|
||||||
|
b.references[p.bIndex] = p.b.second
|
||||||
|
if found {
|
||||||
|
newBeacon = nil
|
||||||
|
} else {
|
||||||
|
newBeacon = &beacon{
|
||||||
|
references: map[int]string{
|
||||||
|
p.aIndex: p.a.first,
|
||||||
|
p.bIndex: p.b.first,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
if found {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if found {
|
||||||
|
if newBeacon != nil {
|
||||||
|
m.beacons = append(m.beacons, *newBeacon)
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
b1 := beacon{
|
||||||
|
references: map[int]string{
|
||||||
|
p.aIndex: p.a.first,
|
||||||
|
p.bIndex: p.b.first,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
b2 := beacon{
|
||||||
|
references: map[int]string{
|
||||||
|
p.aIndex: p.a.second,
|
||||||
|
p.bIndex: p.b.second,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
m.beacons = append(m.beacons, b1, b2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func distanceMagnitude(a offset, b offset) float64 {
|
||||||
|
return math.Sqrt(float64(((b.x - a.x) * (b.x - a.x)) + ((b.y - a.y) * (b.y - a.y)) + ((b.z - a.z) * (b.z - a.z))))
|
||||||
|
}
|
55
nineteen/mapping_test.go
Normal file
55
nineteen/mapping_test.go
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package nineteen
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func Test_read(t *testing.T) {
|
||||||
|
m := mapping{}
|
||||||
|
if err := m.load("test_input.txt"); err != nil {
|
||||||
|
t.Log(err)
|
||||||
|
t.FailNow()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.scanners) != 5 {
|
||||||
|
t.Logf("Expected 5 scanners, found %d", len(m.scanners))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.scanners[0].beacons) != 25 {
|
||||||
|
t.Logf("Expected 25 beacons on scanner %d, found %d", m.scanners[0].id, len(m.scanners[0].beacons))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.scanners[1].beacons) != 25 {
|
||||||
|
t.Logf("Expected 25 beacons on scanner %d, found %d", m.scanners[1].id, len(m.scanners[1].beacons))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.scanners[2].beacons) != 26 {
|
||||||
|
t.Logf("Expected 26 beacons on scanner %d, found %d", m.scanners[2].id, len(m.scanners[2].beacons))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.scanners[3].beacons) != 25 {
|
||||||
|
t.Logf("Expected 25 beacons on scanner %d, found %d", m.scanners[3].id, len(m.scanners[3].beacons))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(m.scanners[4].beacons) != 26 {
|
||||||
|
t.Logf("Expected 26 beacons on scanner %d, found %d", m.scanners[4].id, len(m.scanners[4].beacons))
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_initialize(t *testing.T) {
|
||||||
|
m := mapping{}
|
||||||
|
m.load("test_input.txt")
|
||||||
|
|
||||||
|
m.initialize()
|
||||||
|
|
||||||
|
beaconCount := len(m.beacons)
|
||||||
|
|
||||||
|
if beaconCount != 79 {
|
||||||
|
t.Logf("Expected 79 beacons, found %d", beaconCount)
|
||||||
|
t.Fail()
|
||||||
|
}
|
||||||
|
}
|
136
nineteen/test_input.txt
Normal file
136
nineteen/test_input.txt
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
--- scanner 0 ---
|
||||||
|
404,-588,-901
|
||||||
|
528,-643,409
|
||||||
|
-838,591,734
|
||||||
|
390,-675,-793
|
||||||
|
-537,-823,-458
|
||||||
|
-485,-357,347
|
||||||
|
-345,-311,381
|
||||||
|
-661,-816,-575
|
||||||
|
-876,649,763
|
||||||
|
-618,-824,-621
|
||||||
|
553,345,-567
|
||||||
|
474,580,667
|
||||||
|
-447,-329,318
|
||||||
|
-584,868,-557
|
||||||
|
544,-627,-890
|
||||||
|
564,392,-477
|
||||||
|
455,729,728
|
||||||
|
-892,524,684
|
||||||
|
-689,845,-530
|
||||||
|
423,-701,434
|
||||||
|
7,-33,-71
|
||||||
|
630,319,-379
|
||||||
|
443,580,662
|
||||||
|
-789,900,-551
|
||||||
|
459,-707,401
|
||||||
|
|
||||||
|
--- scanner 1 ---
|
||||||
|
686,422,578
|
||||||
|
605,423,415
|
||||||
|
515,917,-361
|
||||||
|
-336,658,858
|
||||||
|
95,138,22
|
||||||
|
-476,619,847
|
||||||
|
-340,-569,-846
|
||||||
|
567,-361,727
|
||||||
|
-460,603,-452
|
||||||
|
669,-402,600
|
||||||
|
729,430,532
|
||||||
|
-500,-761,534
|
||||||
|
-322,571,750
|
||||||
|
-466,-666,-811
|
||||||
|
-429,-592,574
|
||||||
|
-355,545,-477
|
||||||
|
703,-491,-529
|
||||||
|
-328,-685,520
|
||||||
|
413,935,-424
|
||||||
|
-391,539,-444
|
||||||
|
586,-435,557
|
||||||
|
-364,-763,-893
|
||||||
|
807,-499,-711
|
||||||
|
755,-354,-619
|
||||||
|
553,889,-390
|
||||||
|
|
||||||
|
--- scanner 2 ---
|
||||||
|
649,640,665
|
||||||
|
682,-795,504
|
||||||
|
-784,533,-524
|
||||||
|
-644,584,-595
|
||||||
|
-588,-843,648
|
||||||
|
-30,6,44
|
||||||
|
-674,560,763
|
||||||
|
500,723,-460
|
||||||
|
609,671,-379
|
||||||
|
-555,-800,653
|
||||||
|
-675,-892,-343
|
||||||
|
697,-426,-610
|
||||||
|
578,704,681
|
||||||
|
493,664,-388
|
||||||
|
-671,-858,530
|
||||||
|
-667,343,800
|
||||||
|
571,-461,-707
|
||||||
|
-138,-166,112
|
||||||
|
-889,563,-600
|
||||||
|
646,-828,498
|
||||||
|
640,759,510
|
||||||
|
-630,509,768
|
||||||
|
-681,-892,-333
|
||||||
|
673,-379,-804
|
||||||
|
-742,-814,-386
|
||||||
|
577,-820,562
|
||||||
|
|
||||||
|
--- scanner 3 ---
|
||||||
|
-589,542,597
|
||||||
|
605,-692,669
|
||||||
|
-500,565,-823
|
||||||
|
-660,373,557
|
||||||
|
-458,-679,-417
|
||||||
|
-488,449,543
|
||||||
|
-626,468,-788
|
||||||
|
338,-750,-386
|
||||||
|
528,-832,-391
|
||||||
|
562,-778,733
|
||||||
|
-938,-730,414
|
||||||
|
543,643,-506
|
||||||
|
-524,371,-870
|
||||||
|
407,773,750
|
||||||
|
-104,29,83
|
||||||
|
378,-903,-323
|
||||||
|
-778,-728,485
|
||||||
|
426,699,580
|
||||||
|
-438,-605,-362
|
||||||
|
-469,-447,-387
|
||||||
|
509,732,623
|
||||||
|
647,635,-688
|
||||||
|
-868,-804,481
|
||||||
|
614,-800,639
|
||||||
|
595,780,-596
|
||||||
|
|
||||||
|
--- scanner 4 ---
|
||||||
|
727,592,562
|
||||||
|
-293,-554,779
|
||||||
|
441,611,-461
|
||||||
|
-714,465,-776
|
||||||
|
-743,427,-804
|
||||||
|
-660,-479,-426
|
||||||
|
832,-632,460
|
||||||
|
927,-485,-438
|
||||||
|
408,393,-506
|
||||||
|
466,436,-512
|
||||||
|
110,16,151
|
||||||
|
-258,-428,682
|
||||||
|
-393,719,612
|
||||||
|
-211,-452,876
|
||||||
|
808,-476,-593
|
||||||
|
-575,615,604
|
||||||
|
-485,667,467
|
||||||
|
-680,325,-822
|
||||||
|
-627,-443,-432
|
||||||
|
872,-547,-609
|
||||||
|
833,512,582
|
||||||
|
807,604,487
|
||||||
|
839,-516,451
|
||||||
|
891,-625,532
|
||||||
|
-652,-548,-490
|
||||||
|
30,-46,-14
|
Reference in New Issue
Block a user