diff options
| -rw-r--r-- | challenge-334/packy-anderson/README.md | 2 | ||||
| -rw-r--r-- | challenge-334/packy-anderson/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/elixir/ch-1.exs | 28 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/elixir/ch-2.exs | 123 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/perl/ch-1.pl | 30 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/perl/ch-2.pl | 94 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/python/ch-1.py | 30 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/python/ch-2.py | 88 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/raku/ch-1.raku | 27 | ||||
| -rwxr-xr-x | challenge-334/packy-anderson/raku/ch-2.raku | 90 |
10 files changed, 512 insertions, 1 deletions
diff --git a/challenge-334/packy-anderson/README.md b/challenge-334/packy-anderson/README.md index b25fced0ab..4b48fc6b17 100644 --- a/challenge-334/packy-anderson/README.md +++ b/challenge-334/packy-anderson/README.md @@ -23,4 +23,4 @@ ## Blog Post -[Perl Weekly Challenge: Zero is Not the End of the Line](https://packy.dardan.com/b/Zd) +[Perl Weekly Challenge: SUMone tell me what makes a point VALID?](https://packy.dardan.com/b/_1) diff --git a/challenge-334/packy-anderson/blog.txt b/challenge-334/packy-anderson/blog.txt new file mode 100644 index 0000000000..f8c3c0daf0 --- /dev/null +++ b/challenge-334/packy-anderson/blog.txt @@ -0,0 +1 @@ +https://packy.dardan.com/b/_1
\ No newline at end of file diff --git a/challenge-334/packy-anderson/elixir/ch-1.exs b/challenge-334/packy-anderson/elixir/ch-1.exs new file mode 100755 index 0000000000..4e15793a75 --- /dev/null +++ b/challenge-334/packy-anderson/elixir/ch-1.exs @@ -0,0 +1,28 @@ +#!/usr/bin/env elixir + +defmodule PWC do + def range_sum(ints, x, y) do + Enum.slice(ints, x..y) |> Enum.sum + end + + def solution(ints, x, y) do + int_list = Enum.join(ints, ", ") + IO.puts("Input: @ints = (#{int_list}), $x = #{x}, $y = #{y}") + IO.puts("Output: #{range_sum(ints, x, y)}") + end +end + +IO.puts("Example 1:") +PWC.solution([-2, 0, 3, -5, 2, -1], 0, 2) + +IO.puts("\nExample 2:") +PWC.solution([1, -2, 3, -4, 5], 1, 3) + +IO.puts("\nExample 3:") +PWC.solution([1, 0, 2, -1, 3], 3, 4) + +IO.puts("\nExample 4:") +PWC.solution([-5, 4, -3, 2, -1, 0], 0, 3) + +IO.puts("\nExample 5:") +PWC.solution([-1, 0, 2, -3, -2, 1], 0, 2) diff --git a/challenge-334/packy-anderson/elixir/ch-2.exs b/challenge-334/packy-anderson/elixir/ch-2.exs new file mode 100755 index 0000000000..990fa9cf1a --- /dev/null +++ b/challenge-334/packy-anderson/elixir/ch-2.exs @@ -0,0 +1,123 @@ +#!/usr/bin/env elixir + +defmodule PWC do + def manhattan_distance(a, b) do + { + abs(Enum.at(a,0) - Enum.at(b,0)) + + abs(Enum.at(a,1) - Enum.at(b,1)), + "|#{Enum.at(a,0)} - #{Enum.at(b,0)}| + " <> + "|#{Enum.at(a,1)} - #{Enum.at(b,1)}|" + } + end + + def format_point(p) do + "[#{Enum.at(p, 0)}, #{Enum.at(p, 1)}]" + end + + def is_valid(x, y, p) do + Enum.at(p,0) == x or Enum.at(p,1) == y + end + + def range(points), do: 0..length(points)-1 + + def nvp(x, y, points, valid) do + explanation = cond do + map_size(valid) == length(points) -> + "Valid points: all of them" + true -> + vpoints = Map.keys(valid) + |> Enum.map(fn i -> Enum.at(points, i) end) + |> Enum.map(fn p -> format_point(p) end) + "Valid points: " <> Enum.join(vpoints, ", ") + end + + # now find the distances from the valid points to (x,y) + explanation = explanation <> "\n\nManhattan distances:\n" + {_, {dist, explanation}} = Enum.map_reduce( + range(points), {%{}, explanation}, + fn i, {dist, explanation} -> + {dist, explanation} = if Map.get(valid, i) do + {d, e} = manhattan_distance([x, y], Enum.at(points,i)) + explanation = explanation <> " " <> + format_point(Enum.at(points,i)) <> + " => #{e} => #{d}\n" + # add the index to a list for this distance + # get the existing list in d, default to empty list + dist = Map.put(dist, d, Map.get(dist, d, []) ++ [i]) + {dist, explanation} + else + {dist, explanation} + end + {i, {dist, explanation}} + end + ) + + # the minimum key in the dist map is the minimum distance + min_val = Enum.min(Map.keys(dist)) + + # label the minimum value list so its easier to use + min_list = Map.get(dist, min_val) + + # pick the lowest index from the min distance array + i = Enum.at(min_list, 0) + + explanation = explanation <> "\n" <> cond do + length(min_list) == 1 -> + point = format_point(Enum.at(points,i)) + "Closest valid point is #{point} at index #{i}." + length(min_list) < map_size(valid) -> + tie_list = Enum.join(min_list, " and ") + "Tie between index #{tie_list}, " <> + "pick the smaller index: #{i}." + true -> + "All tie, return the one with the lowest index: #{i}." + end + + {i, explanation} + end + + def nvp(x, y, points) do + # find the "valid" points + {_, valid} = Enum.map_reduce( + range(points), %{}, + fn i, valid -> + valid = if is_valid(x, y, Enum.at(points, i)) do + Map.put(valid, i, 1) + else + valid + end + {i, valid} + end + ) + + if map_size(valid) == 0 do + { -1, "No point shares x or y with (#{x}, #{y})." } + else + nvp(x, y, points, valid) + end + end + + def solution(x, y, points) do + str_list = Enum.map(points, fn p -> format_point(p) end) + |> Enum.join(", ") + IO.puts("Input: $x = #{x}, $y = #{y}, @points (#{str_list})") + {output, explain} = nvp(x, y, points) + IO.puts("Output: #{output}") + IO.puts("\n#{explain}") + end +end + +IO.puts("Example 1:") +PWC.solution(3, 4, [[1, 2], [3, 1], [2, 4], [2, 3]]) + +IO.puts("\nExample 2:") +PWC.solution(2, 5, [[3, 4], [2, 3], [1, 5], [2, 5]]) + +IO.puts("\nExample 3:") +PWC.solution(1, 1, [[2, 2], [3, 3], [4, 4]]) + +IO.puts("\nExample 4:") +PWC.solution(0, 0, [[0, 1], [1, 0], [0, 2], [2, 0]]) + +IO.puts("\nExample 5:") +PWC.solution(5, 5, [[5, 6], [6, 5], [5, 4], [4, 5]]) diff --git a/challenge-334/packy-anderson/perl/ch-1.pl b/challenge-334/packy-anderson/perl/ch-1.pl new file mode 100755 index 0000000000..5e59dc6070 --- /dev/null +++ b/challenge-334/packy-anderson/perl/ch-1.pl @@ -0,0 +1,30 @@ +#!/usr/bin/env perl +use v5.40; + +use List::AllUtils qw( sum ); + +sub rangeSum($x, $y, @ints) { + return sum @ints[$x..$y]; +} + +sub solution($ints, $x, $y) { + print 'Input: @ints = (' . join(', ', @$ints) . '), '; + say "\$x = $x, \$y = $y"; + say 'Output: ' . rangeSum($x, $y, @$ints); +} + +say "Example 1:"; +solution([-2, 0, 3, -5, 2, -1], 0, 2); + +say "\nExample 2:"; +solution([1, -2, 3, -4, 5], 1, 3); + +say "\nExample 3:"; +solution([1, 0, 2, -1, 3], 3, 4); + +say "\nExample 4:"; +solution([-5, 4, -3, 2, -1, 0], 0, 3); + +say "\nExample 5:"; +solution([-1, 0, 2, -3, -2, 1], 0, 2); + diff --git a/challenge-334/packy-anderson/perl/ch-2.pl b/challenge-334/packy-anderson/perl/ch-2.pl new file mode 100755 index 0000000000..b88ad7098d --- /dev/null +++ b/challenge-334/packy-anderson/perl/ch-2.pl @@ -0,0 +1,94 @@ +#!/usr/bin/env perl +use v5.40; + +use List::AllUtils qw( min ); + +sub manhattanDistance($a, $b) { + return ( + abs($$a[0] - $$b[0]) + abs($$a[1] - $$b[1]), + "|$$a[0] - $$b[0]| + |$$a[1] - $$b[1]|" + ); +} + +sub formatPoint($p) { + return "[$$p[0], $$p[1]]"; +} + +sub NVP($x, $y, @points) { + my $explanation; + + # find the "valid" points + my %valid; + for my $i (0 .. $#points) { + next unless $points[$i][0] == $x || $points[$i][1] == $y; + $valid{$i} = 1; + } + unless (%valid) { + return (-1, "No point shares x or y with ($x, $y)."); + } + if (scalar(%valid) == scalar(@points)) { + $explanation = 'Valid points: all of them'; + } + else { + $explanation = 'Valid points: ' . join(", ", + map { formatPoint($_) } @points[keys %valid] + ); + } + + # now find the distances from the valid points to (x,y) + $explanation .= "\n\nManhattan distances:\n"; + my %dist; + for my $i (0 .. $#points) { + next unless exists $valid{$i}; + my ($d, $e) = manhattanDistance([$x, $y], $points[$i]); + $explanation .= " " . formatPoint($points[$i]) + . " => $e => $d\n"; + # add the index to a list for this dist + push @{ $dist{ $d } }, $i; + } + + # the minimum key in the %dist hash is the minimum distance + my $min = min(keys %dist); + + # pick the lowest index from the min distance array + my $i = @{$dist{$min}}[0]; + + if (@{$dist{$min}} == 1) { # only one min distance + $explanation .= "\nClosest valid point is " + . formatPoint($points[$i]) . " at index $i."; + } + elsif (@{$dist{$min}} < scalar(keys %valid)) { + $explanation .= "\nTie between index " + . join(" and ", @{$dist{$min}}) + . ", pick the smaller index: $i."; + } + else { + $explanation .= "\nAll tie, return the one with " + . "the lowest index: $i."; + } + + return ($i, $explanation); +} + +sub solution($x, $y, $points) { + my $str_list = join(', ', map { formatPoint($_) } @$points); + say "Input: \$x = $x, \$y = $y, \@points ($str_list)"; + my ($output, $explanation) = NVP($x, $y, @$points); + say 'Output: ' . $output; + say "\n$explanation"; +} + +say "Example 1:"; +solution(3, 4, [[1, 2], [3, 1], [2, 4], [2, 3]]); + +say "\nExample 2:"; +solution(2, 5, [[3, 4], [2, 3], [1, 5], [2, 5]]); + +say "\nExample 3:"; +solution(1, 1, [[2, 2], [3, 3], [4, 4]]); + +say "\nExample 4:"; +solution(0, 0, [[0, 1], [1, 0], [0, 2], [2, 0]]); + +say "\nExample 5:"; +solution(5, 5, [[5, 6], [6, 5], [5, 4], [4, 5]]); diff --git a/challenge-334/packy-anderson/python/ch-1.py b/challenge-334/packy-anderson/python/ch-1.py new file mode 100755 index 0000000000..d97a879aff --- /dev/null +++ b/challenge-334/packy-anderson/python/ch-1.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python + +def range_sum(ints, x, y): + return sum(ints[x:y+1]) + +def int_join(joiner, arr): + return joiner.join(map(lambda i: str(i), arr)) + +def solution(ints, x, y): + print( + f'Input: @ints = ({int_join(", ", ints)}), ' + + f'$x = {x}, $y = {y}' + ) + print(f'Output: {range_sum(ints, x, y)}') + + +print('Example 1:') +solution([-2, 0, 3, -5, 2, -1], 0, 2) + +print('\nExample 2:') +solution([1, -2, 3, -4, 5], 1, 3) + +print('\nExample 3:') +solution([1, 0, 2, -1, 3], 3, 4) + +print('\nExample 4:') +solution([-5, 4, -3, 2, -1, 0], 0, 3) + +print('\nExample 5:') +solution([-1, 0, 2, -3, -2, 1], 0, 2) diff --git a/challenge-334/packy-anderson/python/ch-2.py b/challenge-334/packy-anderson/python/ch-2.py new file mode 100755 index 0000000000..3fe94e8a9b --- /dev/null +++ b/challenge-334/packy-anderson/python/ch-2.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python + +from collections import Counter + +def manhattan_distance(a, b): + return ( + abs(a[0] - b[0]) + abs(a[1] - b[1]), + f'|{a[0]} - {b[0]}| + |{a[1]} - {b[1]}|' + ) + +def format_point(p): + return f'[{p[0]}, {p[1]}]' + +def nvp(x, y, points): + explanation = '' + + # find the "valid" points + valid = Counter() + for i in range(len(points)): + if points[i][0] == x or points[i][1] == y: + valid[i] = 1 + if len(valid) == 0: + return (-1, f'No point shares x or y with ({x}, {y}).') + + if (len(valid) == len(points)): + explanation = 'Valid points: all of them' + else: + vpoints = [ format_point(points[i]) for i in valid.keys() ] + explanation = 'Valid points: ' + ', '.join(vpoints) + + # now find the distances from the valid points to (x,y) + explanation += '\n\nManhattan distances:\n' + dist = {} + for i in range(len(points)): + if valid[i]: + d, e = manhattan_distance([x, y], points[i]) + explanation += ( + " " + format_point(points[i]) + f' => {e} => {d}\n' + ) + # add the index to a list for this distance + # get the existing list in d, default to empty list + l = dist.setdefault(d, []) + l.append(i) + + # the minimum key in the dist dict is the minimum distance + min_val = min(dist.keys()) + + # pick the lowest index from the min distance array + i = dist[min_val][0] + + if len(dist[min_val]) == 1: # only one min distance + explanation += ( + '\nClosest valid point is ' + format_point(points[i]) + + f' at index {i}.' + ) + elif len(dist[min_val]) < len(valid): + tie_list = [ str(n) for n in dist[min_val] ] + explanation += ( + '\nTie between index ' + ' and '.join(tie_list) + + f', pick the smaller index: {i}.' + ) + else: + explanation += ( + f'\nAll tie, return the one with the lowest index: {i}.' + ) + + return (i, explanation) + +def solution(x, y, points): + str_list = ', '.join([format_point(p) for p in points]) + print(f'Input: $x = {x}, $y = {y}, @points ({str_list})') + output, explain = nvp(x, y, points) + print(f'Output: {output}\n\n{explain}') + +print('Example 1:') +solution(3, 4, [[1, 2], [3, 1], [2, 4], [2, 3]]) + +print('\nExample 2:') +solution(2, 5, [[3, 4], [2, 3], [1, 5], [2, 5]]) + +print('\nExample 3:') +solution(1, 1, [[2, 2], [3, 3], [4, 4]]) + +print('\nExample 4:') +solution(0, 0, [[0, 1], [1, 0], [0, 2], [2, 0]]) + +print('\nExample 5:') +solution(5, 5, [[5, 6], [6, 5], [5, 4], [4, 5]]) diff --git a/challenge-334/packy-anderson/raku/ch-1.raku b/challenge-334/packy-anderson/raku/ch-1.raku new file mode 100755 index 0000000000..bec52296ec --- /dev/null +++ b/challenge-334/packy-anderson/raku/ch-1.raku @@ -0,0 +1,27 @@ +#!/usr/bin/env raku +use v6; + +sub rangeSum(@ints, $x, $y) { + return @ints[$x..$y].sum; +} + +sub solution(@ints, $x, $y) { + print 'Input: @ints = (' ~ @ints.join(', ') ~ '), '; + say "\$x = $x, \$y = $y"; + say 'Output: ' ~ rangeSum(@ints, $x, $y); +} + +say "Example 1:"; +solution([-2, 0, 3, -5, 2, -1], 0, 2); + +say "\nExample 2:"; +solution([1, -2, 3, -4, 5], 1, 3); + +say "\nExample 3:"; +solution([1, 0, 2, -1, 3], 3, 4); + +say "\nExample 4:"; +solution([-5, 4, -3, 2, -1, 0], 0, 3); + +say "\nExample 5:"; +solution([-1, 0, 2, -3, -2, 1], 0, 2); diff --git a/challenge-334/packy-anderson/raku/ch-2.raku b/challenge-334/packy-anderson/raku/ch-2.raku new file mode 100755 index 0000000000..7596651784 --- /dev/null +++ b/challenge-334/packy-anderson/raku/ch-2.raku @@ -0,0 +1,90 @@ +#!/usr/bin/env raku +use v6; + +sub manhattanDistance(@a, @b) { + return ( + abs(@a[0] - @b[0]) + abs(@a[1] - @b[1]), + "|@a[0] - @b[0]| + |@a[1] - @b[1]|" + ); +} + +sub formatPoint(@p) { + return "[@p[0], @p[1]]"; +} + +sub NVP($x, $y, @points) { + my $explanation; + + # find the "valid" points + my %valid; + for 0 .. @points.end -> $i { + next unless @points[$i][0] == $x || @points[$i][1] == $y; + %valid{$i} = 1; + } + unless (%valid) { + return (-1, "No point shares x or y with ($x, $y)."); + } + if (%valid.elems == @points.elems) { + $explanation = 'Valid points: all of them'; + } + else { + $explanation = 'Valid points: ' ~ @points[%valid.keys] + .map({ formatPoint($_) }).join(", "); + } + + # now find the distances from the valid points to (x,y) + $explanation ~= "\n\nManhattan distances:\n"; + my %dist; + for 0 .. @points.end -> $i { + next unless %valid{$i}:exists; + my ($d, $e) = manhattanDistance([$x, $y], @points[$i]); + $explanation ~= " " ~ formatPoint(@points[$i]) + ~ " => $e => $d\n"; + %dist{ $d }.push($i); # add the index to a list for this dist + } + + # the minimum key in the %dist hash is the minimum distance + my $min = min(%dist.keys); + + # pick the lowest index from the min distance array + my $i = %dist{$min}[0]; + + if (%dist{$min}.elems == 1) { # only one min distance + $explanation ~= "\nClosest valid point is " + ~ formatPoint(@points[$i]) ~ " at index $i."; + } + elsif (%dist{$min}.elems < %valid.elems) { + $explanation ~= "\nTie between index " + ~ %dist{$min}.join(" and ") + ~ ", pick the smaller index: $i."; + } + else { + $explanation ~= "\nAll tie, return the one with " + ~ "the lowest index: $i."; + } + + return ($i, $explanation); +} + +sub solution($x, $y, @points) { + my $str_list = @points.map({ formatPoint($_) }).join(', '); + say "Input: \$x = $x, \$y = $y, \@points ($str_list)"; + my ($output, $explanation) = NVP($x, $y, @points); + say 'Output: ' ~ $output; + say "\n$explanation"; +} + +say "Example 1:"; +solution(3, 4, [[1, 2], [3, 1], [2, 4], [2, 3]]); + +say "\nExample 2:"; +solution(2, 5, [[3, 4], [2, 3], [1, 5], [2, 5]]); + +say "\nExample 3:"; +solution(1, 1, [[2, 2], [3, 3], [4, 4]]); + +say "\nExample 4:"; +solution(0, 0, [[0, 1], [1, 0], [0, 2], [2, 0]]); + +say "\nExample 5:"; +solution(5, 5, [[5, 6], [6, 5], [5, 4], [4, 5]]); |
