Tapping out on Day 19

This commit is contained in:
2021-12-19 21:12:48 +00:00
parent 34c3b2da7e
commit 0c7c723b40
7 changed files with 464 additions and 0 deletions

View File

@@ -191,3 +191,23 @@ The solution for "eighteen" is:
The magnitude of the final sum is 4202
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
```

View File

@@ -13,6 +13,7 @@ import (
"unsupervised.ca/aoc2021/four"
"unsupervised.ca/aoc2021/fourteen"
"unsupervised.ca/aoc2021/nine"
"unsupervised.ca/aoc2021/nineteen"
"unsupervised.ca/aoc2021/one"
"unsupervised.ca/aoc2021/seven"
"unsupervised.ca/aoc2021/seventeen"
@@ -76,6 +77,8 @@ func main() {
day = seventeen.Init("seventeen/input.txt")
case "eighteen":
day = eighteen.Init("eighteen/input.txt")
case "nineteen":
day = nineteen.Init("nineteen/input.txt")
default:
fmt.Printf("%q does not have a solution.\n", flagParts[1])
help()

0
nineteen/input.txt Normal file
View File

23
nineteen/main.go Normal file
View 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
View 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
View 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
View 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