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