diff options
| -rwxr-xr-x | challenge-281/packy-anderson/elixir/ch-2.exs | 124 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/perl/ch-2.pl | 2 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/python/ch-2.py | 2 | ||||
| -rwxr-xr-x | challenge-281/packy-anderson/raku/ch-2.raku | 2 |
4 files changed, 119 insertions, 11 deletions
diff --git a/challenge-281/packy-anderson/elixir/ch-2.exs b/challenge-281/packy-anderson/elixir/ch-2.exs index 04b5c8529b..1009526549 100755 --- a/challenge-281/packy-anderson/elixir/ch-2.exs +++ b/challenge-281/packy-anderson/elixir/ch-2.exs @@ -1,20 +1,128 @@ #!/usr/bin/env elixir defmodule PWC do + defp letterAdd(letter, add) do + <<val::utf8>> = letter + List.to_string([val + add]) + end + + def onBoard(c,r) do + "a" <= c and c <= "h" and 1 <= r and r <= 8 + end + + defp knightMoveList(), do: [ + {-2, -1}, {-2, +1}, {-1, -2}, {-1, +2}, + {+2, -1}, {+2, +1}, {+1, -2}, {+1, +2}, + ] + + def knightMoves([], _, _, endpoints), do: endpoints + + def knightMoves([next | rest], letter, num, endpoints) do + {col, row} = next + newcol = letterAdd(letter, col) + newrow = num + row + endpoints = if onBoard(newcol,newrow) do + # add to list being returned + endpoints ++ [ newcol <> to_string(newrow) ] + else + endpoints + end + knightMoves(rest, letter, num, endpoints) + end + + def knightMoves(coordinates) do + letter = String.first(coordinates) + {num, _} = Integer.parse(String.last(coordinates)) + knightMoves(knightMoveList(), letter, num, []) + end + + def processEndpoints( + next, params = %{ + moves_to: moves_to, + path_to: path_to, + startPos: startPos, + endPos: endPos, + queue: queue + } + ) do + # update the move count map + moves_to = Map.put(moves_to, next, moves_to[startPos] + 1) + + # update the path to current space map + path_to = Map.put(path_to, next, + "#{path_to[startPos]} -> #{next}" + ) + + if next == endPos do + # we found the shortest path, update the return + # values which will stop the loop + %{ moves: moves_to[next], path: path_to[next] } + else + # update params for next iteration + params |> Map.put(:moves_to, moves_to) + |> Map.put(:path_to, path_to) + |> Map.put(:queue, queue ++ [ next ]) + end + end + + def processEndpoints(_, params = %{moves: moves}) + when not is_nil(moves), do: params + + # we've exhausted the queue + # (only possible when the chessboard is an odd size) + def processQueue([], _), do: %{ + moves: -1, path: "no path found" + } + + def processQueue(_, params = %{moves: moves}) + when not is_nil(moves), do: params + + def processQueue([startPos | queue], params = %{ + path_to: path_to + }) do + # put the current starting position and the current queue + # into the params + params = params |> Map.put(:queue, queue) + |> Map.put(:startPos, startPos) + + # figure out the valid moves that we haven't been to yet + endpoints = knightMoves(startPos) + |> Enum.filter(fn m -> !Map.has_key?(path_to, m) end) + + # call processEndpoints/2 for each of the endpoints + params = Enum.reduce(endpoints, params, &processEndpoints/2) + + # recursively call to process the rest of the queue + processQueue(params[:queue], params) + end + + # trivial case: we're already at the end point + def leastMoves(startPos, endPos) when startPos == endPos, do: + { 0, endPos } + + def leastMoves(startPos, endPos) do + params = processQueue([ startPos ], %{ + endPos: endPos, + moves_to: %{ startPos => 0 }, + path_to: %{ startPos => startPos }, + moves: nil, + path: nil + }) + { params[:moves], params[:path] } + end - def solution(ints) do - IO.puts("Input: @ints = (" <> Enum.join(ints, ", ") <> ")") - {sign, explain} = PWC.productSign(ints) - IO.puts("Output: " <> to_string(sign) ) - IO.puts("\n" <> explain) + def solution(startPos, endPos) do + IO.puts("Input: $start = '#{startPos}', $end = '#{endPos}'") + {count, moves} = leastMoves(startPos, endPos) + IO.puts("Output: #{to_string(count)}\n\n#{moves}" ) end end IO.puts("Example 1:") -PWC.solution() +PWC.solution("g2", "a8") IO.puts("\nExample 2:") -PWC.solution() +PWC.solution("g2", "h2") IO.puts("\nExample 3:") -PWC.solution() +PWC.solution("a1", "h8") diff --git a/challenge-281/packy-anderson/perl/ch-2.pl b/challenge-281/packy-anderson/perl/ch-2.pl index 92eeb1cbd4..3992136a60 100755 --- a/challenge-281/packy-anderson/perl/ch-2.pl +++ b/challenge-281/packy-anderson/perl/ch-2.pl @@ -68,7 +68,7 @@ sub solution($start, $end) { say qq/Input: \$start = '$start', \$end = '$end'/; my ($count, $moves) = leastMoves($start, $end); say 'Output: ' . $count; - say "\n$moves\n"; + say "\n$moves"; } say "Example 1:"; diff --git a/challenge-281/packy-anderson/python/ch-2.py b/challenge-281/packy-anderson/python/ch-2.py index f1b8803a71..72f51c823f 100755 --- a/challenge-281/packy-anderson/python/ch-2.py +++ b/challenge-281/packy-anderson/python/ch-2.py @@ -65,7 +65,7 @@ def leastMoves(start, end): def solution(start, end): print(f'Input: $start = \'{start}\', $end = \'{end}\'') count, moves = leastMoves(start, end) - print(f'Output: {count}\n\n{moves}\n') + print(f'Output: {count}\n\n{moves}') print('Example 1:') solution('g2', 'a8') diff --git a/challenge-281/packy-anderson/raku/ch-2.raku b/challenge-281/packy-anderson/raku/ch-2.raku index 4ab5b7f4b1..ed29559b0a 100755 --- a/challenge-281/packy-anderson/raku/ch-2.raku +++ b/challenge-281/packy-anderson/raku/ch-2.raku @@ -68,7 +68,7 @@ sub solution($start, $end) { say qq/Input: \$start = '$start', \$end = '$end'/; my ($count, $moves) = leastMoves($start, $end); say 'Output: ' ~ $count; - say "\n$moves\n"; + say "\n$moves"; } say "Example 1:"; |
