aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-336/packy-anderson/README.md2
-rw-r--r--challenge-336/packy-anderson/blog.txt1
-rwxr-xr-xchallenge-336/packy-anderson/elixir/ch-1.exs97
-rwxr-xr-xchallenge-336/packy-anderson/elixir/ch-2.exs74
-rwxr-xr-xchallenge-336/packy-anderson/perl/ch-1.pl89
-rwxr-xr-xchallenge-336/packy-anderson/perl/ch-2.pl52
-rwxr-xr-xchallenge-336/packy-anderson/python/ch-1.py75
-rwxr-xr-xchallenge-336/packy-anderson/python/ch-2.py53
-rwxr-xr-xchallenge-336/packy-anderson/raku/ch-1.raku77
-rwxr-xr-xchallenge-336/packy-anderson/raku/ch-2.raku49
10 files changed, 568 insertions, 1 deletions
diff --git a/challenge-336/packy-anderson/README.md b/challenge-336/packy-anderson/README.md
index 83462935ff..64c1d65b5e 100644
--- a/challenge-336/packy-anderson/README.md
+++ b/challenge-336/packy-anderson/README.md
@@ -23,4 +23,4 @@
## Blog Post
-[Perl Weekly Challenge: Fanfare for the Common Character](https://packy.dardan.com/b/_V)
+[Perl Weekly Challenge: The Score for Group Therapy](https://packy.dardan.com/b/a9)
diff --git a/challenge-336/packy-anderson/blog.txt b/challenge-336/packy-anderson/blog.txt
new file mode 100644
index 0000000000..ed45643d4a
--- /dev/null
+++ b/challenge-336/packy-anderson/blog.txt
@@ -0,0 +1 @@
+https://packy.dardan.com/b/a9 \ No newline at end of file
diff --git a/challenge-336/packy-anderson/elixir/ch-1.exs b/challenge-336/packy-anderson/elixir/ch-1.exs
new file mode 100755
index 0000000000..00cffe4844
--- /dev/null
+++ b/challenge-336/packy-anderson/elixir/ch-1.exs
@@ -0,0 +1,97 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ def divides_unevenly(smallest, bag) do
+ bag
+ |> Map.values
+ |> Enum.filter(fn v -> rem(v, smallest) != 0 end)
+ |> length != 0
+ end
+
+ def find_smallest(smallest, _) when smallest <= 2,
+ do: 2
+
+ def find_smallest(smallest, bag) when smallest > 2 do
+ # can we divide the list evenly into multiples
+ # of the smallest group?
+ if divides_unevenly(smallest, bag) do
+ # no, let's divide it by 2 and try again
+ find_smallest(trunc(smallest/2), bag)
+ else
+ smallest
+ end
+ end
+
+ def render_groups(stream) do
+ stream
+ |> Enum.to_list
+ |> Enum.map(fn l -> "(" <> Enum.join(l,",") <> ")" end)
+ |> Enum.join(" ")
+ end
+
+ def equal_group(ints, bag) do
+ # find the smallest number of instances of
+ # an int in the list
+ smallest = Map.values(bag) |> Enum.min |> find_smallest(bag)
+
+ # make the groups and return the result
+ if divides_unevenly(smallest, bag) do
+ # we can't evenly divide by smallest, just
+ # make a single group for each unique int
+ {
+ "false",
+ ints |> Stream.chunk_by(&(&1)) |> render_groups
+ }
+ else
+ # make groups of smallest
+ {
+ "true",
+ ints |> Stream.chunk_every(smallest) |> render_groups
+ }
+ end
+ end
+
+ def equal_group(ints) do
+ bag = Enum.frequencies(ints) # one line bag!
+ if Enum.any?(Map.values(bag), fn v -> v < 2 end) do
+ # if we don't have more than 2 instances of
+ # a particular int, we can't make groups
+ {"false", ""}
+ else
+ equal_group(ints, bag)
+ end
+ end
+
+ def solution(ints) do
+ IO.puts("Input: @ints = (" <> Enum.join(ints, ",") <> ")")
+ {result, groups} = equal_group(ints)
+ IO.puts("Output: #{result}")
+ if groups != "" do
+ IO.puts("\nGroups: #{groups}")
+ end
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution([1,1,2,2,2,2])
+
+IO.puts("\nExample 2:")
+PWC.solution([1,1,1,2,2,2,3,3])
+
+IO.puts("\nExample 3:")
+PWC.solution([5,5,5,5,5,5,7,7,7,7,7,7])
+
+IO.puts("\nExample 4:")
+PWC.solution([1,2,3,4])
+
+IO.puts("\nExample 5:")
+PWC.solution([8,8,9,9,10,10,11,11])
+
+IO.puts("\nExample 6 (2a):")
+PWC.solution([1,1,1,1,2,2,2,2,3,3])
+
+IO.puts("\nExample 7 (2b):")
+PWC.solution([1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3])
+
+IO.puts("\nExample 8 (3a):")
+PWC.solution([5,5,5,5,5,7,7,7,7,7,7])
diff --git a/challenge-336/packy-anderson/elixir/ch-2.exs b/challenge-336/packy-anderson/elixir/ch-2.exs
new file mode 100755
index 0000000000..1dfd9b181b
--- /dev/null
+++ b/challenge-336/packy-anderson/elixir/ch-2.exs
@@ -0,0 +1,74 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ defp pad(num) do
+ String.pad_leading(to_string(num), 2)
+ end
+
+ defp wrap(num) do
+ if num < 0 do
+ "(#{num})"
+ else
+ "#{num}"
+ end
+ end
+
+ def final_score([], stack, rounds, _) do
+ total = Enum.sum(stack)
+ { total, rounds <> "\nTotal Scores: #{total}" }
+ end
+
+ def final_score([action | scores], stack, rounds, count) do
+ previous = List.last(stack)
+ stack = case action do
+ "+" ->
+ {a, b} = {Enum.at(stack, -1), Enum.at(stack, -2)}
+ List.insert_at(stack, -1, a + b)
+ "C" ->
+ List.delete_at(stack, -1)
+ "D" ->
+ List.insert_at(stack, -1, Enum.at(stack, -1) * 2)
+ _ ->
+ List.insert_at(stack, -1, String.to_integer(action) )
+ end
+ rounds = rounds
+ <> "Round #{pad(count)}: "
+ <> Enum.join(Enum.map(stack, &wrap/1), " + ")
+ <> case action do
+ "+" -> " (sum of previous two scores)"
+ "C" -> " (invalidate the previous score #{previous})"
+ "D" -> " (double the previous score #{previous})"
+ _ -> ""
+ end
+ <> "\n"
+ final_score(scores, stack, rounds, count+1)
+ end
+
+ def final_score(scores) do
+ final_score(scores, [], "", 1)
+ end
+
+ def solution(scores) do
+ score_list = scores
+ |> Enum.map(fn n -> "\"#{n}\"" end)
+ |> Enum.join(", ")
+ IO.puts("Input: @ints = (#{score_list})")
+ {output, rounds} = final_score(scores)
+ IO.puts("Output: #{output}\n\n#{rounds}")
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution(["5","2","C","D","+"])
+
+IO.puts("\nExample 2:")
+PWC.solution(["5","-2","4","C","D","9","+","+"])
+
+IO.puts("\nExample 3:")
+PWC.solution(["7","D","D","C","+","3"])
+
+IO.puts("\nExample 4:")
+PWC.solution(["-5","-10","+","D","C","+"])
+
+IO.puts("\nExample 5:")
+PWC.solution(["3","6","+","D","C","8","+","D","-2","C","+"])
diff --git a/challenge-336/packy-anderson/perl/ch-1.pl b/challenge-336/packy-anderson/perl/ch-1.pl
new file mode 100755
index 0000000000..2f044a1bf7
--- /dev/null
+++ b/challenge-336/packy-anderson/perl/ch-1.pl
@@ -0,0 +1,89 @@
+#!/usr/bin/env perl
+use v5.40;
+
+use List::AllUtils qw( any min );
+use Set::Bag;
+
+# for some reason, Set::Bag doesn't have a method that
+# will return a list of ALL the values. if $bag->grab()
+# is called with a list of keys, it returns the values
+# for those keys, but if it's called with no keys, it
+# returns a hash of keys => values. so I rolled my own
+# method to return a list of all the values...
+sub bag_values($bag) { $bag->grab($bag->elements) }
+
+sub dividesUnevenly($smallest, $bag) {
+ any { $_ % $smallest != 0 } values(%$bag)
+}
+
+sub equalGroup(@ints) {
+ my $bag = Set::Bag->new( map { $_ => 1 } @ints );
+ # if we don't have more than 2 instances of
+ # a particular int, we can't make groups
+ return ("false", q{}) if any { $_ < 2 } values(%$bag);
+
+ # find the smallest number of instances of
+ # an int in the list
+ my $smallest = min values(%$bag);
+
+ # can we divide the list evenly into multiples
+ # of the smallest group?
+ while (dividesUnevenly($smallest, $bag) && $smallest > 2) {
+ # no, let's divide it by 2 and try again
+ $smallest = int($smallest / 2);
+ }
+
+ # make the groups and return the result
+ my $groups;
+ if (dividesUnevenly($smallest, $bag)) {
+ # we can't evenly divide by $smallest, just
+ # make a single group for each unique int
+ foreach my $k ( $bag->elements ) {
+ my $count = $bag->grab($k);
+ $groups .= '(' . join(',', (($k) x $count)) . ') ';
+ }
+ return ("false", $groups);
+ }
+ else {
+ # make groups of $smallest
+ foreach my $k ( $bag->elements ) {
+ my $count = $bag->grab($k);
+ while ($count) {
+ $groups .= '(' . join(',', (($k) x $smallest)) . ') ';
+ $count -= $smallest;
+ }
+ }
+ return ("true", $groups);
+ }
+}
+
+sub solution($ints) {
+ say 'Input: @ints = (' . join(',',@$ints) . ')';
+ my ($result, $groups) = equalGroup(@$ints);
+ say "Output: $result";
+ say "\nGroups: $groups" if $groups;
+}
+
+say "Example 1:";
+solution([1,1,2,2,2,2]);
+
+say "\nExample 2:";
+solution([1,1,1,2,2,2,3,3]);
+
+say "\nExample 3:";
+solution([5,5,5,5,5,5,7,7,7,7,7,7]);
+
+say "\nExample 4:";
+solution([1,2,3,4]);
+
+say "\nExample 5:";
+solution([8,8,9,9,10,10,11,11]);
+
+say "\nExample 6 (2a):";
+solution([1,1,1,1,2,2,2,2,3,3]);
+
+say "\nExample 7 (2b):";
+solution([1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3]);
+
+say "\nExample 8 (3a):";
+solution([5,5,5,5,5,7,7,7,7,7,7]);
diff --git a/challenge-336/packy-anderson/perl/ch-2.pl b/challenge-336/packy-anderson/perl/ch-2.pl
new file mode 100755
index 0000000000..20fdba67f9
--- /dev/null
+++ b/challenge-336/packy-anderson/perl/ch-2.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/env perl
+use v5.40;
+
+use List::AllUtils qw( sum );
+
+sub finalScore(@scores) {
+ my (@stack, $rounds, $count);
+ foreach my $action ( @scores ) {
+ my $previous = $stack[-1];
+ foreach ($action) {
+ /\+/ && do { push @stack, $stack[-1] + $stack[-2]; last };
+ /C/ && do { pop @stack; last; };
+ /D/ && do { push @stack, $stack[-1] * 2; last; };
+ push @stack, $action;
+ }
+ $rounds .= sprintf "Round %2d: ", ++$count;
+ $rounds .= join(" + ", map {$_ < 0 ? "($_)" : $_} @stack);
+ $rounds .= " (sum of previous two scores)"
+ if $action eq "+";
+ $rounds .= " (double the previous score $previous)"
+ if $action eq "D";
+ $rounds .= " (invalidate the previous score $previous)"
+ if $action eq "C";
+ $rounds .= "\n";
+ }
+ my $sum = sum(@stack);
+ $rounds .= "\nTotal Scores: $sum";
+ return ($sum, $rounds);
+}
+
+sub solution($scores) {
+ my $list = join(', ', map { qq{"$_"} } @$scores);
+ say "Input: \@scores = ($list)";
+ my ($output, $rounds) = finalScore(@$scores);
+ say "Output: $output\n\n$rounds";
+}
+
+say "Example 1:";
+solution(["5","2","C","D","+"]);
+
+say "\nExample 2:";
+solution(["5","-2","4","C","D","9","+","+"]);
+
+say "\nExample 3:";
+solution(["7","D","D","C","+","3"]);
+
+say "\nExample 4:";
+solution(["-5","-10","+","D","C","+"]);
+
+say "\nExample 5:";
+solution(["3","6","+","D","C","8","+","D","-2","C","+"]);
+
diff --git a/challenge-336/packy-anderson/python/ch-1.py b/challenge-336/packy-anderson/python/ch-1.py
new file mode 100755
index 0000000000..e8f3514075
--- /dev/null
+++ b/challenge-336/packy-anderson/python/ch-1.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+from collections import Counter
+
+def int_join(joiner, arr):
+ return joiner.join(map(lambda i: str(i), arr))
+
+def divides_unevenly(smallest, bag):
+ return [ n for n in bag.values() if n % smallest != 0 ]
+
+def equal_group(ints):
+ bag = Counter(ints)
+
+ # if we don't have more than 2 instances of
+ # a particular int, we can't make groups
+ if [ n for n in bag.values() if n < 2 ]:
+ return False, ""
+
+ # find the smallest number of instances of
+ # an int in the list
+ smallest = min(bag.values())
+
+ # can we divide the list evenly into multiples
+ # of the smallest group?
+ while divides_unevenly(smallest, bag) and smallest > 2:
+ smallest = int(smallest / 2)
+
+ # make the groups and return the result
+ groups = ""
+ if divides_unevenly(smallest, bag):
+ for k in bag.keys():
+ group = []
+ for i in range(bag[k]): group.append(k)
+ groups += "(" + int_join(",",group) + ") "
+ return False, groups
+ else:
+ for k in bag.keys():
+ count = bag[k]
+ while count > 0:
+ group = []
+ for i in range(smallest): group.append(k)
+ groups += "(" + int_join(",",group) + ") "
+ count -= smallest
+ return True, groups
+
+def solution(ints):
+ print(f'Input: @ints = ({int_join(",", ints)})')
+ result, groups = equal_group(ints)
+ print(f'Output: {result}')
+ if groups != "":
+ print(f'\nGroups: {groups}')
+
+print('Example 1:')
+solution([1,1,2,2,2,2])
+
+print('\nExample 2:')
+solution([1,1,1,2,2,2,3,3])
+
+print('\nExample 3:')
+solution([5,5,5,5,5,5,7,7,7,7,7,7])
+
+print('\nExample 4:')
+solution([1,2,3,4])
+
+print('\nExample 5:')
+solution([8,8,9,9,10,10,11,11])
+
+print('\nExample 6 (2a):')
+solution([1,1,1,1,2,2,2,2,3,3])
+
+print('\nExample 7 (2b):')
+solution([1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3])
+
+print('\nExample 8 (3a):')
+solution([5,5,5,5,5,7,7,7,7,7,7]) \ No newline at end of file
diff --git a/challenge-336/packy-anderson/python/ch-2.py b/challenge-336/packy-anderson/python/ch-2.py
new file mode 100755
index 0000000000..4d43d4745b
--- /dev/null
+++ b/challenge-336/packy-anderson/python/ch-2.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+def final_score(scores):
+ stack = []
+ rounds = ""
+ count = 0
+ for action in scores:
+ if stack: previous = stack[-1]
+ match action:
+ case '+':
+ stack.append( stack[-1] + stack[-2] )
+ case 'C':
+ stack.pop()
+ case 'D':
+ stack.append( stack[-1] * 2 )
+ case _:
+ stack.append( int(action) )
+ count += 1
+ rounds += "Round {:2d}: ".format(count)
+ rounds += " + ".join([
+ f'({n})' if n < 0 else f'{n}' for n in stack
+ ])
+ if action == "+":
+ rounds += " (sum of previous two scores)"
+ if action == "D":
+ rounds += f" (double the previous score {previous})"
+ if action == "C":
+ rounds += f" (invalidate the previous score {previous})"
+ rounds += "\n"
+ total = sum(stack)
+ rounds += f"\nTotal Scores: {total}"
+ return (total, rounds)
+
+def solution(scores):
+ score_list = ', '.join([ f'"{s}"' for s in scores ])
+ print(f'Input: @scores = ({score_list})')
+ output, rounds = final_score(scores)
+ print(f'Output: {output}\n\n{rounds}')
+
+print('Example 1:')
+solution(["5","2","C","D","+"])
+
+print('\nExample 2:')
+solution(["5","-2","4","C","D","9","+","+"])
+
+print('\nExample 3:')
+solution(["7","D","D","C","+","3"])
+
+print('\nExample 4:')
+solution(["-5","-10","+","D","C","+"])
+
+print('\nExample 5:')
+solution(["3","6","+","D","C","8","+","D","-2","C","+"])
diff --git a/challenge-336/packy-anderson/raku/ch-1.raku b/challenge-336/packy-anderson/raku/ch-1.raku
new file mode 100755
index 0000000000..4b73cbd5dd
--- /dev/null
+++ b/challenge-336/packy-anderson/raku/ch-1.raku
@@ -0,0 +1,77 @@
+#!/usr/bin/env raku
+use v6;
+
+sub dividesUnevenly($smallest, $bag) {
+ $bag.values.grep({ $_ mod $smallest != 0 })
+}
+
+sub equalGroup(@ints) {
+ my $bag = @ints.Bag;
+ # if we don't have more than 2 instances of
+ # a particular int, we can't make groups
+ return (False, q{}) if $bag.values.any < 2;
+
+ # find the smallest number of instances of
+ # an int in the list
+ my $smallest = $bag.values.min;
+
+ # can we divide the list evenly into multiples
+ # of the smallest group?
+ while (dividesUnevenly($smallest, $bag) && $smallest > 2) {
+ # no, let's divide it by 2 and try again
+ $smallest = ($smallest / 2).Int;
+ }
+
+ # make the groups and return the result
+ my $groups;
+ if (dividesUnevenly($smallest, $bag)) {
+ # we can't evenly divide by $smallest, just
+ # make a single group for each unique int
+ for $bag.keys.sort -> $k {
+ $groups ~= '(' ~ $bag.kxxv.grep($k).join(',') ~ ') ';
+ }
+ return (False, $groups);
+ }
+ else {
+ # make groups of $smallest
+ for $bag.keys.sort -> $k {
+ my $count = $bag{$k};
+ while ($count) {
+ $groups ~= '(' ~ (($k) xx $smallest).join(',') ~ ') ';
+ $count -= $smallest;
+ }
+ }
+ return (True, $groups);
+ }
+}
+
+sub solution(@ints) {
+ say 'Input: @ints = (' ~ @ints.join(',') ~ ')';
+ my ($result, $groups) = equalGroup(@ints);
+ say "Output: $result";
+ say "\nGroups: $groups" if $groups;
+}
+
+say "Example 1:";
+solution([1,1,2,2,2,2]);
+
+say "\nExample 2:";
+solution([1,1,1,2,2,2,3,3]);
+
+say "\nExample 3:";
+solution([5,5,5,5,5,5,7,7,7,7,7,7]);
+
+say "\nExample 4:";
+solution([1,2,3,4]);
+
+say "\nExample 5:";
+solution([8,8,9,9,10,10,11,11]);
+
+say "\nExample 6 (2a):";
+solution([1,1,1,1,2,2,2,2,3,3]);
+
+say "\nExample 7 (2b):";
+solution([1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3,3,3]);
+
+say "\nExample 8 (3a):";
+solution([5,5,5,5,5,7,7,7,7,7,7]);
diff --git a/challenge-336/packy-anderson/raku/ch-2.raku b/challenge-336/packy-anderson/raku/ch-2.raku
new file mode 100755
index 0000000000..d15323f498
--- /dev/null
+++ b/challenge-336/packy-anderson/raku/ch-2.raku
@@ -0,0 +1,49 @@
+#!/usr/bin/env raku
+use v6;
+
+sub finalScore(@scores) {
+ my (@stack, $rounds, $count);
+ for @scores -> $action {
+ my $previous = @stack[*-1];
+ given $action {
+ when "+" { @stack.push( @stack[*-1] + @stack[*-2] ) }
+ when "C" { @stack.pop() }
+ when "D" { @stack.push( @stack[*-1] * 2 ) }
+ default { @stack.push($action) }
+ }
+ $rounds ~= sprintf "Round %2d: ", ++$count;
+ $rounds ~= @stack.map({$_ < 0 ?? "($_)" !! $_}).join(" + ");
+ $rounds ~= " (sum of previous two scores)"
+ if $action eq "+";
+ $rounds ~= " (double the previous score $previous)"
+ if $action eq "D";
+ $rounds ~= " (invalidate the previous score $previous)"
+ if $action eq "C";
+ $rounds ~= "\n";
+ }
+ my $sum = sum(@stack);
+ $rounds ~= "\nTotal Scores: $sum";
+ return ($sum, $rounds);
+}
+
+sub solution(@scores) {
+ my $list = @scores.map({ qq{"$_"} }).join(', ');
+ say "Input: \@scores = ($list)";
+ my ($output, $rounds) = finalScore(@scores);
+ say "Output: $output\n\n$rounds";
+}
+
+say "Example 1:";
+solution(["5","2","C","D","+"]);
+
+say "\nExample 2:";
+solution(["5","-2","4","C","D","9","+","+"]);
+
+say "\nExample 3:";
+solution(["7","D","D","C","+","3"]);
+
+say "\nExample 4:";
+solution(["-5","-10","+","D","C","+"]);
+
+say "\nExample 5:";
+solution(["3","6","+","D","C","8","+","D","-2","C","+"]);