You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
2.8 KiB
PowerShell
103 lines
2.8 KiB
PowerShell
param (
|
|
[Parameter(position = 0)]
|
|
[array]
|
|
$Wires = @('R8,U5,L5,D3','U7,R6,D4,L4')
|
|
)
|
|
|
|
function Trace-Wire {
|
|
param (
|
|
[Parameter(Mandatory,
|
|
position = 0)]
|
|
[array]
|
|
$Steps
|
|
)
|
|
|
|
$path = New-Object -TypeName System.Collections.ArrayList
|
|
|
|
#start position is 0,0
|
|
$position = @{
|
|
x = 0
|
|
y = 0
|
|
distance = $null
|
|
}
|
|
|
|
foreach($step in $Steps) {
|
|
$direction = $step.Substring(0, 1)
|
|
$count = $step.Substring(1)
|
|
|
|
for($i = 1; $i -le $count; $i++) {
|
|
switch($direction) {
|
|
'U' {$position.y += 1}
|
|
'D' {$position.y -= 1}
|
|
'R' {$position.x += 1}
|
|
'L' {$position.x -= 1}
|
|
Default {Write-Error ('Unkown $direction: {0}' -f $direction)}
|
|
}
|
|
$path.Add($position) | Out-Null
|
|
|
|
#copy position to prevent adjustment of objects already added to $path
|
|
$position = $position.Clone()
|
|
}
|
|
}
|
|
|
|
return $path
|
|
}
|
|
function Compare-Paths {
|
|
param (
|
|
[Parameter(Mandatory,
|
|
position = 0)]
|
|
[System.Collections.ArrayList]
|
|
$PathOne,
|
|
|
|
[Parameter(Mandatory,
|
|
position = 1)]
|
|
[System.Collections.ArrayList]
|
|
$PathTwo
|
|
)
|
|
|
|
$intersections = New-Object -TypeName System.Collections.ArrayList
|
|
|
|
foreach($position_one in $path_one) {
|
|
foreach($position_two in $path_two) {
|
|
if($position_one.x -eq $position_two.x -and $position_one.y -eq $position_two.y) {
|
|
$intersections.Add($position_one) | Out-Null
|
|
}
|
|
}
|
|
}
|
|
|
|
return $intersections
|
|
}
|
|
function Get-ManhattenDistance {
|
|
param (
|
|
[Parameter(Mandatory = $false)]
|
|
[hashtable]
|
|
$Source = @{x = 0; y = 0},
|
|
|
|
[Parameter(Mandatory,
|
|
position = 0)]
|
|
[hashtable]
|
|
$Destination
|
|
)
|
|
|
|
$distance = [math]::Abs($Source.x) + [math]::Abs($Destination.x)
|
|
$distance += [math]::Abs($Source.y) + [math]::Abs($Destination.y)
|
|
|
|
return $distance
|
|
}
|
|
|
|
# use jobs to trace both wires in parallel
|
|
# (,$arr) prevents ArgumentList from splitting $arr
|
|
$path_one_job = Start-Job ${function:Trace-Wire} -ArgumentList (,$Wires[0].Split(','))
|
|
$path_two_job = Start-Job ${function:Trace-Wire} -ArgumentList (,$Wires[1].Split(','))
|
|
|
|
# wait for jobs to finish
|
|
$path_one = $path_one_job | Receive-Job -Wait -AutoRemoveJob
|
|
$path_two = $path_two_job | Receive-Job -Wait -AutoRemoveJob
|
|
|
|
$intersections = Compare-Paths $path_one $path_two
|
|
for($i = 0; $i -lt $intersections.Count; $i++) {
|
|
$distance = Get-ManhattenDistance -Destination $intersections[$i]
|
|
$intersections[$i].distance = $distance
|
|
}
|
|
|
|
($intersections | Sort-Object -Property distance | Select-Object -First 1).distance |