Day 13 Complete
This commit is contained in:
parent
529cd54788
commit
f9fe534a3b
BIN
day13/day13
BIN
day13/day13
Binary file not shown.
399
day13/main.go
399
day13/main.go
@ -15,33 +15,35 @@ import (
|
|||||||
// Puzzle 1 Test Input: 10 7 4
|
// Puzzle 1 Test Input: 10 7 4
|
||||||
// Puzzle 2: 101 < x < 128 ?? 103
|
// Puzzle 2: 101 < x < 128 ?? 103
|
||||||
func main() {
|
func main() {
|
||||||
|
mode := "solve"
|
||||||
if len(os.Args) < 4 {
|
if len(os.Args) < 4 {
|
||||||
fmt.Println("Usage: day13 <seed> <dest-x> <dest-y>")
|
fmt.Println("Usage: day13 <seed> <dest-x> <dest-y>")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
seed := atoi(os.Args[1])
|
seed := atoi(os.Args[1])
|
||||||
destX, destY := atoi(os.Args[2]), atoi(os.Args[3])
|
destX, destY := atoi(os.Args[2]), atoi(os.Args[3])
|
||||||
|
if len(os.Args) >= 5 {
|
||||||
|
mode = os.Args[4]
|
||||||
|
}
|
||||||
f := CreateFloor(1, 1, destX, destY, seed)
|
f := CreateFloor(1, 1, destX, destY, seed)
|
||||||
|
|
||||||
//f.Print()
|
switch mode {
|
||||||
//SolveMaze(f)
|
case "solve":
|
||||||
fmt.Println("WalkFloor(50):", f.player.WalkFloor(50))
|
if f.Solve(f.start.x, f.start.y, 0, true) {
|
||||||
f.Print()
|
f.dispCoord = f.end
|
||||||
}
|
}
|
||||||
|
|
||||||
// SolveMaze finds a solution to the maze
|
|
||||||
func SolveMaze(f *Floor) {
|
|
||||||
for !f.player.FoundExit() {
|
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
ClearScreen()
|
ClearScreen()
|
||||||
f.player.MoveToExit()
|
|
||||||
f.Print()
|
f.Print()
|
||||||
|
fmt.Println("Shortest Path:", len(f.solvePath.coords))
|
||||||
|
case "walk":
|
||||||
|
dist := 50
|
||||||
|
f.Walk(f.start.x, f.start.y, 0, dist, true)
|
||||||
|
fmt.Println("Within", dist, "steps: ", len(f.testedPath.coords))
|
||||||
}
|
}
|
||||||
fmt.Println("Found the exit in", f.player.NumSteps(), "steps")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Coord struct {
|
type Coord struct {
|
||||||
x, y int
|
x, y, dist int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Coord) Is(x, y int) bool {
|
func (c *Coord) Is(x, y int) bool {
|
||||||
@ -53,169 +55,7 @@ func (c *Coord) Equals(t *Coord) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewCoord(x, y int) *Coord {
|
func NewCoord(x, y int) *Coord {
|
||||||
return &Coord{x, y}
|
return &Coord{x, y, -1}
|
||||||
}
|
|
||||||
|
|
||||||
type Player struct {
|
|
||||||
pos *Coord
|
|
||||||
currentFloor *Floor
|
|
||||||
visited []Coord
|
|
||||||
path Path
|
|
||||||
}
|
|
||||||
|
|
||||||
// WalkFloor determines how many places you can get to by taking
|
|
||||||
// <dist> steps
|
|
||||||
func (p *Player) WalkFloor(dist int) int {
|
|
||||||
if dist <= 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
fmt.Println("WalkFloor(", dist, ")")
|
|
||||||
var ret int
|
|
||||||
tryX, tryY := p.pos.x+1, p.pos.y
|
|
||||||
if !p.HasBeenAt(tryX, tryY) && !p.currentFloor.IsWall(tryX, tryY) {
|
|
||||||
ret++
|
|
||||||
p.WalkEast()
|
|
||||||
fmt.Println(" Walking East")
|
|
||||||
ret += p.WalkFloor(dist - 1)
|
|
||||||
p.WalkWest()
|
|
||||||
}
|
|
||||||
tryX, tryY = p.pos.x-1, p.pos.y
|
|
||||||
if !p.HasBeenAt(tryX, tryY) && !p.currentFloor.IsWall(tryX, tryY) {
|
|
||||||
ret++
|
|
||||||
p.WalkWest()
|
|
||||||
fmt.Println(" Walking West")
|
|
||||||
ret += p.WalkFloor(dist - 1)
|
|
||||||
p.WalkEast()
|
|
||||||
}
|
|
||||||
tryX, tryY = p.pos.x, p.pos.y+1
|
|
||||||
if !p.HasBeenAt(tryX, tryY) && !p.currentFloor.IsWall(tryX, tryY) {
|
|
||||||
ret++
|
|
||||||
p.WalkSouth()
|
|
||||||
fmt.Println(" Walking South")
|
|
||||||
ret += p.WalkFloor(dist - 1)
|
|
||||||
p.WalkNorth()
|
|
||||||
}
|
|
||||||
tryX, tryY = p.pos.x, p.pos.y-1
|
|
||||||
if !p.HasBeenAt(tryX, tryY) && !p.currentFloor.IsWall(tryX, tryY) {
|
|
||||||
ret++
|
|
||||||
p.WalkNorth()
|
|
||||||
fmt.Println(" Walking North")
|
|
||||||
ret += p.WalkFloor(dist - 1)
|
|
||||||
p.WalkSouth()
|
|
||||||
}
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) NumSteps() int {
|
|
||||||
return len(p.path.coords)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) MoveToExit() bool {
|
|
||||||
// First try to move closer to the goal
|
|
||||||
// Horizontally, then Vertically
|
|
||||||
if p.pos.x < p.currentFloor.end.x {
|
|
||||||
if !p.HasBeenAt(p.pos.x+1, p.pos.y) && p.WalkEast() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.pos.x > p.currentFloor.end.x {
|
|
||||||
if !p.HasBeenAt(p.pos.x-1, p.pos.y) && p.WalkWest() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.pos.y < p.currentFloor.end.y {
|
|
||||||
if !p.HasBeenAt(p.pos.x, p.pos.y+1) && p.WalkSouth() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if p.pos.y > p.currentFloor.end.y {
|
|
||||||
if !p.HasBeenAt(p.pos.x, p.pos.y-1) && p.WalkNorth() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Couldn't move towards it, can we move anywhere?
|
|
||||||
if !p.HasBeenAt(p.pos.x+1, p.pos.y) && p.WalkEast() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if !p.HasBeenAt(p.pos.x-1, p.pos.y) && p.WalkWest() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if !p.HasBeenAt(p.pos.x, p.pos.y+1) && p.WalkSouth() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if !p.HasBeenAt(p.pos.x, p.pos.y-1) && p.WalkNorth() {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Couldn't do any of those. Pop the path
|
|
||||||
if !p.Backtrack() {
|
|
||||||
// Couldn't backtrack! Game over man!
|
|
||||||
fmt.Println("Error! Couldn't find valid path!")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) Backtrack() bool {
|
|
||||||
if len(p.path.coords) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
p.path.Pop()
|
|
||||||
p.pos = &p.path.coords[len(p.path.coords)-1]
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) WalkEast() bool {
|
|
||||||
if !p.currentFloor.IsWall(p.pos.x+1, p.pos.y) {
|
|
||||||
p.pos.x++
|
|
||||||
p.path.Append(*p.pos)
|
|
||||||
p.visited = append(p.visited, *p.pos)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) WalkWest() bool {
|
|
||||||
if !p.currentFloor.IsWall(p.pos.x-1, p.pos.y) && p.pos.x > 0 {
|
|
||||||
p.pos.x--
|
|
||||||
p.path.Append(*p.pos)
|
|
||||||
p.visited = append(p.visited, *p.pos)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) WalkNorth() bool {
|
|
||||||
if !p.currentFloor.IsWall(p.pos.x, p.pos.y-1) && p.pos.y > 0 {
|
|
||||||
p.pos.y--
|
|
||||||
p.path.Append(*p.pos)
|
|
||||||
p.visited = append(p.visited, *p.pos)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) WalkSouth() bool {
|
|
||||||
if !p.currentFloor.IsWall(p.pos.x, p.pos.y+1) {
|
|
||||||
p.pos.y++
|
|
||||||
p.path.Append(*p.pos)
|
|
||||||
p.visited = append(p.visited, *p.pos)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) HasBeenAt(x, y int) bool {
|
|
||||||
for i := range p.visited {
|
|
||||||
if p.visited[i].Is(x, y) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Player) FoundExit() bool {
|
|
||||||
return p.pos.Equals(p.currentFloor.end)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Path struct {
|
type Path struct {
|
||||||
@ -228,7 +68,12 @@ func (p *Path) Append(c Coord) {
|
|||||||
|
|
||||||
func (p *Path) Pop() Coord {
|
func (p *Path) Pop() Coord {
|
||||||
var ret Coord
|
var ret Coord
|
||||||
|
prePop := len(p.coords)
|
||||||
ret, p.coords = p.coords[len(p.coords)-1], p.coords[:len(p.coords)-1]
|
ret, p.coords = p.coords[len(p.coords)-1], p.coords[:len(p.coords)-1]
|
||||||
|
if len(p.coords) != prePop-1 {
|
||||||
|
fmt.Println("Error, popping didn't result in one less size")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,12 +85,31 @@ func (p *Path) ContainsCoord(c *Coord) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
func (p *Path) ContainsCoordXY(x, y int) bool {
|
||||||
|
for i := range p.coords {
|
||||||
|
if p.coords[i].Is(x, y) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Path) GetCoordAt(x, y int) *Coord {
|
||||||
|
for i := range p.coords {
|
||||||
|
if p.coords[i].Is(x, y) {
|
||||||
|
return &p.coords[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type Floor struct {
|
type Floor struct {
|
||||||
player *Player
|
start *Coord
|
||||||
start *Coord
|
end *Coord
|
||||||
end *Coord
|
seed int
|
||||||
seed int
|
testedPath Path
|
||||||
|
solvePath Path
|
||||||
|
dispCoord *Coord
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateFloor(stX, stY, endX, endY, seed int) *Floor {
|
func CreateFloor(stX, stY, endX, endY, seed int) *Floor {
|
||||||
@ -254,11 +118,169 @@ func CreateFloor(stX, stY, endX, endY, seed int) *Floor {
|
|||||||
end: NewCoord(endX, endY),
|
end: NewCoord(endX, endY),
|
||||||
seed: seed,
|
seed: seed,
|
||||||
}
|
}
|
||||||
f.player = &Player{pos: f.start}
|
|
||||||
f.player.currentFloor = &f
|
|
||||||
return &f
|
return &f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (f *Floor) Walk(x, y, dist, maxDist int, print bool) {
|
||||||
|
wrkCoord := Coord{x, y, dist}
|
||||||
|
if f.IsWall(x, y) || f.testedPath.ContainsCoordXY(x, y) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if dist == maxDist {
|
||||||
|
f.testedPath.Append(wrkCoord)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if print {
|
||||||
|
f.dispCoord = &wrkCoord
|
||||||
|
ClearScreen()
|
||||||
|
f.Print()
|
||||||
|
fmt.Println("Tested Spots:", len(f.testedPath.coords))
|
||||||
|
time.Sleep(time.Millisecond * 70)
|
||||||
|
}
|
||||||
|
if !f.IsWall(x-1, y) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x-1, y); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !f.IsWall(x+1, y) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x+1, y); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !f.IsWall(x, y-1) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x, y-1); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !f.IsWall(x, y+1) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x, y+1); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.testedPath.Append(wrkCoord)
|
||||||
|
// Try intelligently first
|
||||||
|
// (Attempt to move towards the exit)
|
||||||
|
if x > 0 {
|
||||||
|
f.Walk(x-1, y, wrkCoord.dist+1, maxDist, print)
|
||||||
|
}
|
||||||
|
if y > 0 {
|
||||||
|
f.Walk(x, y-1, wrkCoord.dist+1, maxDist, print)
|
||||||
|
}
|
||||||
|
f.Walk(x+1, y, wrkCoord.dist+1, maxDist, print)
|
||||||
|
f.Walk(x, y+1, wrkCoord.dist+1, maxDist, print)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Floor) Solve(x, y, dist int, print bool) bool {
|
||||||
|
wrkCoord := Coord{x, y, dist}
|
||||||
|
if f.end.Is(x, y) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if f.IsWall(x, y) || f.testedPath.ContainsCoordXY(x, y) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// Test if there is a shorter path to this coordinate
|
||||||
|
if !f.IsWall(x-1, y) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x-1, y); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !f.IsWall(x+1, y) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x+1, y); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !f.IsWall(x, y-1) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x, y-1); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !f.IsWall(x, y+1) {
|
||||||
|
if t := f.testedPath.GetCoordAt(x, y+1); t != nil {
|
||||||
|
if t.dist+1 < wrkCoord.dist {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if print {
|
||||||
|
f.dispCoord = &wrkCoord
|
||||||
|
ClearScreen()
|
||||||
|
f.Print()
|
||||||
|
fmt.Println("Tested Spots:", len(f.testedPath.coords))
|
||||||
|
time.Sleep(time.Millisecond * 70)
|
||||||
|
}
|
||||||
|
f.testedPath.Append(wrkCoord)
|
||||||
|
// Try intelligently first
|
||||||
|
// (Attempt to move towards the exit)
|
||||||
|
if x > f.end.x && x > 0 {
|
||||||
|
if f.Solve(x-1, y, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if y > f.end.y && y > 0 {
|
||||||
|
if f.Solve(x, y-1, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if x < f.end.x {
|
||||||
|
if f.Solve(x+1, y, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if y < f.end.y {
|
||||||
|
if f.Solve(x, y+1, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Intelligence failed us... Just find a move
|
||||||
|
if x > 0 {
|
||||||
|
if f.Solve(x-1, y, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if y > 0 {
|
||||||
|
if f.Solve(x, y-1, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This is where it gets shaky...
|
||||||
|
// Since we have an infinite maze, this could run forever
|
||||||
|
// So we have a hard cutoff at:
|
||||||
|
var MaxInt = int(^uint(0) >> 1)
|
||||||
|
if len(f.testedPath.coords) >= MaxInt {
|
||||||
|
fmt.Println("Couldn't find a path.")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
if f.Solve(x+1, y, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if f.Solve(x, y+1, wrkCoord.dist+1, print) {
|
||||||
|
f.solvePath.Append(wrkCoord)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
func (f *Floor) IsWall(x, y int) bool {
|
func (f *Floor) IsWall(x, y int) bool {
|
||||||
sum := (x*x + 3*x + 2*x*y + y + y*y + f.seed)
|
sum := (x*x + 3*x + 2*x*y + y + y*y + f.seed)
|
||||||
s := fmt.Sprintf("%b", sum)
|
s := fmt.Sprintf("%b", sum)
|
||||||
@ -275,19 +297,14 @@ func (f *Floor) Print() {
|
|||||||
g.Add(color.Bold)
|
g.Add(color.Bold)
|
||||||
r := color.New(color.BgRed)
|
r := color.New(color.BgRed)
|
||||||
topY, topX := f.end.y+10, f.end.x+10
|
topY, topX := f.end.y+10, f.end.x+10
|
||||||
if f.player.pos.y > f.end.y {
|
|
||||||
topY = f.player.pos.y + 5
|
|
||||||
}
|
|
||||||
if f.player.pos.x > f.end.x {
|
|
||||||
topX = f.player.pos.x + 5
|
|
||||||
}
|
|
||||||
for y := 0; y < topY; y++ {
|
for y := 0; y < topY; y++ {
|
||||||
for x := 0; x < topX; x++ {
|
for x := 0; x < topX; x++ {
|
||||||
if f.player.pos.Is(x, y) {
|
if f.dispCoord != nil && f.dispCoord.Is(x, y) {
|
||||||
g.Print("O")
|
g.Print("O")
|
||||||
} else if f.player.path.ContainsCoord(&Coord{x, y}) {
|
} else if f.solvePath.ContainsCoordXY(x, y) {
|
||||||
g.Print(".")
|
g.Print(".")
|
||||||
} else if f.player.HasBeenAt(x, y) {
|
} else if f.testedPath.ContainsCoordXY(x, y) {
|
||||||
r.Print(" ")
|
r.Print(" ")
|
||||||
} else {
|
} else {
|
||||||
if f.end.Is(x, y) {
|
if f.end.Is(x, y) {
|
||||||
|
77
day13/problem
Normal file
77
day13/problem
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
Advent of Code
|
||||||
|
|
||||||
|
--- Day 13: A Maze of Twisty Little Cubicles ---
|
||||||
|
|
||||||
|
You arrive at the first floor of this new building to discover a much less welcoming environment than the shiny atrium of the
|
||||||
|
last one. Instead, you are in a maze of twisty little cubicles, all alike.
|
||||||
|
|
||||||
|
Every location in this area is addressed by a pair of non-negative integers (x,y). Each such coordinate is either a wall or an
|
||||||
|
open space. You can't move diagonally. The cube maze starts at 0,0 and seems to extend infinitely toward positive x and y;
|
||||||
|
negative values are invalid, as they represent a location outside the building. You are in a small waiting area at 1,1.
|
||||||
|
|
||||||
|
While it seems chaotic, a nearby morale-boosting poster explains, the layout is actually quite logical. You can determine
|
||||||
|
whether a given x,y coordinate will be a wall or an open space using a simple system:
|
||||||
|
|
||||||
|
• Find x*x + 3*x + 2*x*y + y + y*y.
|
||||||
|
• Add the office designer's favorite number (your puzzle input).
|
||||||
|
• Find the binary representation of that sum; count the number of bits that are 1.
|
||||||
|
|
||||||
|
• If the number of bits that are 1 is even, it's an open space.
|
||||||
|
• If the number of bits that are 1 is odd, it's a wall.
|
||||||
|
|
||||||
|
For example, if the office designer's favorite number were 10, drawing walls as # and open spaces as ., the corner of the
|
||||||
|
building containing 0,0 would look like this:
|
||||||
|
|
||||||
|
0123456789
|
||||||
|
0 .#.####.##
|
||||||
|
1 ..#..#...#
|
||||||
|
2 #....##...
|
||||||
|
3 ###.#.###.
|
||||||
|
4 .##..#..#.
|
||||||
|
5 ..##....#.
|
||||||
|
6 #...##.###
|
||||||
|
|
||||||
|
Now, suppose you wanted to reach 7,4. The shortest route you could take is marked as O:
|
||||||
|
|
||||||
|
0123456789
|
||||||
|
0 .#.####.##
|
||||||
|
1 .O#..#...#
|
||||||
|
2 #OOO.##...
|
||||||
|
3 ###O#.###.
|
||||||
|
4 .##OO#OO#.
|
||||||
|
5 ..##OOO.#.
|
||||||
|
6 #...##.###
|
||||||
|
|
||||||
|
Thus, reaching 7,4 would take a minimum of 11 steps (starting from your current location, 1,1).
|
||||||
|
|
||||||
|
What is the fewest number of steps required for you to reach 31,39?
|
||||||
|
|
||||||
|
Your puzzle answer was _____.
|
||||||
|
|
||||||
|
The first half of this puzzle is complete! It provides one gold star: *
|
||||||
|
|
||||||
|
--- Part Two ---
|
||||||
|
|
||||||
|
How many locations (distinct x,y coordinates, including your starting location) can you reach in at most 50 steps?
|
||||||
|
|
||||||
|
Your puzzle input is still 1364.
|
||||||
|
|
||||||
|
Answer: _____________________
|
||||||
|
|
||||||
|
References
|
||||||
|
|
||||||
|
Visible links
|
||||||
|
. http://adventofcode.com/
|
||||||
|
. http://adventofcode.com/2016/about
|
||||||
|
. http://adventofcode.com/2016/support
|
||||||
|
. http://adventofcode.com/2016/events
|
||||||
|
. http://adventofcode.com/2016/settings
|
||||||
|
. http://adventofcode.com/2016/auth/logout
|
||||||
|
. http://adventofcode.com/2016
|
||||||
|
. http://adventofcode.com/2016
|
||||||
|
. http://adventofcode.com/2016/leaderboard
|
||||||
|
. http://adventofcode.com/2016/stats
|
||||||
|
. http://adventofcode.com/2016/sponsors
|
||||||
|
. http://adventofcode.com/2016/sponsors
|
||||||
|
. https://en.wikipedia.org/wiki/Binary_number
|
||||||
|
. https://en.wikipedia.org/wiki/Bit
|
Loading…
Reference in New Issue
Block a user