Skip to content

Instantly share code, notes, and snippets.

@Wilczeek
Last active December 16, 2021 01:05
Advent of Code - Day 15 - Part 2 Powershell
$rawinput = Get-Content -Path "\D15\input.txt"
$unvisited_nodes = [ordered]@{}
$unvisited_nodes_big = [ordered]@{}
$unvisited_nodes_heap = [ordered]@{}
[System.Collections.ArrayList]$visited_nodes = @()
for($y=0; $y -lt $rawinput.Length; $y++){
for($x=0; $x -lt $rawinput[$y].Length; $x++){
$ob = [ordered]@{
Cords = "x$($x)y$($y)"
x = $x
y = $y
Risk = ([int]"$($rawinput[$y][$x])")
Visited = $false
TentativeDist = [double]::PositiveInfinity
}
[void]$unvisited_nodes.Add("$($ob.Cords)", $ob)
}
}
$z= 0
for($z=0; $z -lt 5; $z++) {
$unvisited_nodes.GetEnumerator() | ForEach-Object {
$nx = $_.Value.x# + (10*$z)
$ny = $_.Value.y + (100*$z)
$nr = $_.Value.Risk + (1*$z)
if($nr -ge 10) { $nr = $nr%9 }
$obj = [ordered] @{
Cords = "x$($nx)y$($ny)"
x = $nx
y = $ny
Risk = ([int]$nr)
Visited = $false
TentativeDist = [double]::PositiveInfinity
}
[void]$unvisited_nodes_big.Add("$($obj.Cords)", $obj)
}
}
$unvisited_nodes = [ordered]@{}
for($z=0; $z -lt 5; $z++) {
$unvisited_nodes_big.GetEnumerator() | ForEach-Object {
$nx = $_.Value.x + (100*$z)
$ny = $_.Value.y# + (10*$z)
$nr = $_.Value.Risk + (1*$z)
if($nr -ge 10) { $nr = $nr%9 }
$obj = [ordered] @{
Cords = "x$($nx)y$($ny)"
x = $nx
y = $ny
Risk = ([int]$nr)
Visited = $false
TentativeDist = [double]::PositiveInfinity
}
[void]$unvisited_nodes.Add("$($obj.Cords)", $obj)
}
}
$str = "x$($rawinput[0].Length*5-1)y$($rawinput.Length*5-1)"
$start_node = $unvisited_nodes."x0y0"
$end_node = $unvisited_nodes.$str
$bFinished = $false
$currentNode = $start_node
$currentNode.TentativeDist = 0
$i = 0
do {
if($i%1000 -eq 0) { write-host $i }
if($currentNode.Visited) {
$currentNode = $nextNode
}
[System.Collections.ArrayList]$neighbors = @(
@{
Name = "Left"
x = $currentNode.x-1
y = $currentNode.y
},
@{
Name = "Right"
x = $currentNode.x+1
y = $currentNode.y
},
@{
Name = "Top"
x = $currentNode.x
y = $currentNode.y-1
},
@{
Name = "Bottom"
x = $currentNode.x
y = $currentNode.y+1
}
)
foreach($neighbor in $neighbors){
# out of Left/Top - Right/Bottom array bounds
if(($neighbor.x -lt 0 -or $neighbor.y -lt 0) -or ($neighbor.x -ge $rawinput[0].Length*5 -or $neighbor.y -ge $rawinput.Length*5)) {
#Write-Host "Wrong neighbor: X: $($neighbor.x) - Y: $($neighbor.y)"
continue
}
$str = "x$($neighbor.x)y$($neighbor.y)"
$heap_Node = $unvisited_nodes_heap.$str
if($heap_Node) {
$distance = $currentNode.TentativeDist + $heap_Node.Risk
if($heap_Node.TentativeDist -gt $distance){
$heap_Node.TentativeDist = $distance
}
}
else {
$ob = $unvisited_nodes.$str
if($ob) {
$distance = $currentNode.TentativeDist + $ob.Risk
if($ob.TentativeDist -gt $distance){
$ob.TentativeDist = $distance
}
[void]$unvisited_nodes_heap.Add("$($ob.Cords)", $ob)
$unvisited_nodes.Remove($ob.Cords)
}
}
}
$currentNode.Visited = $true
if($unvisited_nodes_heap.Count -eq 0 -and $unvisited_nodes.Count -le 1) {
$bFinished = $true
} else {
#[void]$visited_nodes.Add($currentNode)
$unvisited_nodes.Remove($currentNode.Cords)
$unvisited_nodes_heap.Remove($currentNode.Cords)
$str = ($unvisited_nodes_heap.GetEnumerator() | Sort {$_.Value.TentativeDist} | Select-Object -First 1).Name
if($str){
$nextNode = $unvisited_nodes_heap.$str
} else {
$str = ($unvisited_nodes.GetEnumerator() | Sort {$_.Value.TentativeDist} | Select-Object -First 1).Name
$nextNode = $unvisited_nodes.$str
}
$i++
}
} while (!($bFinished))
$end_node
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment