-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
851363d
commit b70292f
Showing
4 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
func picoSecondsCheats() { | ||
// Read the input from the file | ||
file, err := os.Open("input.txt") | ||
if err != nil { | ||
fmt.Println("Error reading file:", err) | ||
return | ||
} | ||
defer file.Close() | ||
|
||
// Read all lines from the file into grid | ||
var grid []string | ||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
grid = append(grid, scanner.Text()) | ||
} | ||
|
||
if err := scanner.Err(); err != nil { | ||
fmt.Println("Error reading lines:", err) | ||
return | ||
} | ||
|
||
// Find start and end positions | ||
start := findPosition(grid, 'S') | ||
end := findPosition(grid, 'E') | ||
|
||
// Track visited positions and their step counts | ||
track := make(map[[2]int]int) | ||
track[start] = 0 | ||
cur := start | ||
curStep := 0 | ||
|
||
// Perform BFS-like traversal | ||
for cur != end { | ||
curStep++ | ||
i, j := cur[0], cur[1] | ||
found := false | ||
for _, dir := range [][2]int{{-1, 0}, {0, -1}, {0, 1}, {1, 0}} { | ||
newI, newJ := i+dir[0], j+dir[1] | ||
if isValid(newI, newJ, grid) && !isInTrack(track, [2]int{newI, newJ}) && isValidChar(grid[newI][newJ]) { | ||
cur = [2]int{newI, newJ} | ||
track[cur] = curStep | ||
found = true | ||
break | ||
} | ||
} | ||
if !found { | ||
break | ||
} | ||
} | ||
|
||
// Count pairs that satisfy the condition | ||
count := 0 | ||
for p1 := range track { | ||
for _, dir := range [][2]int{{-1, 0}, {0, -1}, {0, 1}, {1, 0}} { | ||
newI, newJ := p1[0]+dir[0], p1[1]+dir[1] | ||
if isInTrack(track, [2]int{newI, newJ}) { | ||
continue | ||
} | ||
otherPos := [2]int{newI + dir[0], newJ + dir[1]} | ||
if isInTrack(track, otherPos) && track[otherPos]-track[p1] >= 102 { | ||
count++ | ||
} | ||
} | ||
} | ||
|
||
fmt.Println(count) | ||
} | ||
|
||
// Helper function to find the position of a character in the grid | ||
func findPosition(grid []string, char rune) [2]int { | ||
for i, line := range grid { | ||
for j, cell := range line { | ||
if cell == char { | ||
return [2]int{i, j} | ||
} | ||
} | ||
} | ||
return [2]int{-1, -1} | ||
} | ||
|
||
// Check if the position is valid within the grid | ||
func isValid(i, j int, grid []string) bool { | ||
return i >= 0 && i < len(grid) && j >= 0 && j < len(grid[i]) | ||
} | ||
|
||
// Check if a character is 'S', 'E' or '.' | ||
func isValidChar(c byte) bool { | ||
return c == 'S' || c == 'E' || c == '.' | ||
} | ||
|
||
// Check if a position is already in the track map | ||
func isInTrack(track map[[2]int]int, pos [2]int) bool { | ||
_, exists := track[pos] | ||
return exists | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
package main | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"math" | ||
"os" | ||
) | ||
|
||
func saveHundredPicoSecondCheats() { | ||
// Read the input from the file | ||
file, err := os.Open("input.txt") | ||
if err != nil { | ||
fmt.Println("Error reading file:", err) | ||
return | ||
} | ||
defer file.Close() | ||
|
||
// Read the grid into a 2D slice | ||
var grid [][]rune | ||
scanner := bufio.NewScanner(file) | ||
for scanner.Scan() { | ||
grid = append(grid, []rune(scanner.Text())) | ||
} | ||
|
||
if err := scanner.Err(); err != nil { | ||
fmt.Println("Error reading lines:", err) | ||
return | ||
} | ||
|
||
// Find start and end positions | ||
start := reallyFindPosition(grid, 'S') | ||
end := reallyFindPosition(grid, 'E') | ||
|
||
// Track visited positions and their step counts | ||
track := make(map[[2]int]int) | ||
track[start] = 0 | ||
cur := start | ||
curStep := 0 | ||
|
||
// Perform BFS-like traversal | ||
for cur != end { | ||
curStep++ | ||
i, j := cur[0], cur[1] | ||
found := false | ||
for _, dir := range [][2]int{{-1, 0}, {0, -1}, {0, 1}, {1, 0}} { | ||
newI, newJ := i+dir[0], j+dir[1] | ||
if isReallyValid(newI, newJ, grid) && !isReallyInTrack(track, [2]int{newI, newJ}) && isReallyValidChar(grid[newI][newJ]) { | ||
cur = [2]int{newI, newJ} | ||
track[cur] = curStep | ||
found = true | ||
break | ||
} | ||
} | ||
if !found { | ||
break | ||
} | ||
} | ||
|
||
// Count valid pairs | ||
count := 0 | ||
for coords := range track { | ||
potentials := cheatEndpoints(coords, track) | ||
for otherCoords := range potentials { | ||
if track[otherCoords]-track[coords]-manhattanDistance(coords, otherCoords) >= 100 { | ||
count++ | ||
} | ||
} | ||
} | ||
|
||
fmt.Println(count) | ||
} | ||
|
||
// Helper function to find the position of a character in the grid | ||
func reallyFindPosition(grid [][]rune, char rune) [2]int { | ||
for i, line := range grid { | ||
for j, cell := range line { | ||
if cell == char { | ||
return [2]int{i, j} | ||
} | ||
} | ||
} | ||
return [2]int{-1, -1} | ||
} | ||
|
||
// Check if the position is valid within the grid | ||
func isReallyValid(i, j int, grid [][]rune) bool { | ||
return i >= 0 && i < len(grid) && j >= 0 && j < len(grid[i]) | ||
} | ||
|
||
// Check if a character is 'S', 'E' or '.' | ||
func isReallyValidChar(c rune) bool { | ||
return c == 'S' || c == 'E' || c == '.' | ||
} | ||
|
||
// Check if a position is already in the track map | ||
func isReallyInTrack(track map[[2]int]int, pos [2]int) bool { | ||
_, exists := track[pos] | ||
return exists | ||
} | ||
|
||
// Function to find possible endpoints in the neighborhood | ||
func cheatEndpoints(coords [2]int, track map[[2]int]int) map[[2]int]struct{} { | ||
i, j := coords[0], coords[1] | ||
output := make(map[[2]int]struct{}) | ||
for di := -20; di <= 20; di++ { | ||
djMax := 20 - int(math.Abs(float64(di))) | ||
for dj := -djMax; dj <= djMax; dj++ { | ||
newPos := [2]int{i + di, j + dj} | ||
if _, exists := track[newPos]; exists { | ||
output[newPos] = struct{}{} | ||
} | ||
} | ||
} | ||
return output | ||
} | ||
|
||
// Manhattan distance between two coordinates | ||
func manhattanDistance(coord1, coord2 [2]int) int { | ||
return int(math.Abs(float64(coord1[0]-coord2[0]))) + int(math.Abs(float64(coord1[1]-coord2[1]))) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from collections import deque | ||
from itertools import combinations | ||
|
||
|
||
def parseInput(): | ||
with open("input.txt", "r") as file: | ||
content = file.read() | ||
grid = [list(line) for line in content.strip().split("\n")] | ||
start, end = (0, 0), (0, 0) | ||
for r, row in enumerate(grid): | ||
for c, cell in enumerate(row): | ||
if cell == "S": | ||
start = (r, c) | ||
elif cell == "E": | ||
end = (r, c) | ||
return grid, start, end | ||
|
||
|
||
def bfs(grid, start, end): | ||
queue = deque([(start[0], start[1], 0)]) | ||
dists = {} | ||
while queue: | ||
r, c, n = queue.popleft() | ||
if (r, c) in dists: | ||
continue | ||
dists[(r, c)] = n | ||
if (r, c) == end: | ||
continue | ||
for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: | ||
rr, cc = r + dr, c + dc | ||
if 0 <= rr < len(grid) and 0 <= cc < len(grid[0]) and grid[rr][cc] != "#": | ||
queue.append((rr, cc, n + 1)) | ||
return dists | ||
|
||
|
||
# Part -1 | ||
def picoSecondsCheats() -> int: | ||
grid, start, end = parseInput() | ||
dists = bfs(grid, start, end) | ||
p1 = 0 | ||
for ((r1, c1), n1), ((r2, c2), n2) in combinations(dists.items(), 2): | ||
d = abs(r1 - r2) + abs(c1 - c2) | ||
if d <= 2 and abs(n2 - n1) >= d + 100: | ||
p1 += 1 | ||
print(p1) | ||
return p1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
from collections import deque | ||
from itertools import combinations | ||
|
||
|
||
|
||
def parseInput(): | ||
with open("input.txt", "r") as file: | ||
content = file.read() | ||
grid = [list(line) for line in content.strip().split("\n")] | ||
start, end = (0, 0), (0, 0) | ||
for r, row in enumerate(grid): | ||
for c, cell in enumerate(row): | ||
if cell == "S": | ||
start = (r, c) | ||
elif cell == "E": | ||
end = (r, c) | ||
return grid, start, end | ||
|
||
|
||
def bfs(grid, start, end): | ||
queue = deque([(start[0], start[1], 0)]) | ||
dists = {} | ||
while queue: | ||
r, c, n = queue.popleft() | ||
if (r, c) in dists: | ||
continue | ||
dists[(r, c)] = n | ||
if (r, c) == end: | ||
continue | ||
for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]: | ||
rr, cc = r + dr, c + dc | ||
if 0 <= rr < len(grid) and 0 <= cc < len(grid[0]) and grid[rr][cc] != "#": | ||
queue.append((rr, cc, n + 1)) | ||
return dists | ||
|
||
|
||
|
||
# Part -2 | ||
def saveHundredPicoSecondCheats() -> int: | ||
grid, start, end = parseInput() | ||
dists = bfs(grid, start, end) | ||
p2 = 0 | ||
for ((r1, c1), n1), ((r2, c2), n2) in combinations(dists.items(), 2): | ||
d = abs(r1 - r2) + abs(c1 - c2) | ||
if d <= 20 and abs(n2 - n1) >= d + 100: | ||
p2 += 1 | ||
print(p2) | ||
return p2 |