aboutsummaryrefslogtreecommitdiff
path: root/challenge-346
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <mohammad.anwar@yahoo.com>2025-11-10 00:42:51 +0000
committerMohammad Sajid Anwar <mohammad.anwar@yahoo.com>2025-11-10 00:42:51 +0000
commitb07a0019e07bb4697ee1f3527e440e8a9f5120b8 (patch)
treea090ecb3dddf0607044cc8445673c95e3260c791 /challenge-346
parent221ad5c01245d61163a1eb34f8d756f8eabab479 (diff)
downloadperlweeklychallenge-club-b07a0019e07bb4697ee1f3527e440e8a9f5120b8.tar.gz
perlweeklychallenge-club-b07a0019e07bb4697ee1f3527e440e8a9f5120b8.tar.bz2
perlweeklychallenge-club-b07a0019e07bb4697ee1f3527e440e8a9f5120b8.zip
- Added solutions by Packy Anderson.
Diffstat (limited to 'challenge-346')
-rw-r--r--challenge-346/packy-anderson/README.md2
-rw-r--r--challenge-346/packy-anderson/blog.txt1
-rw-r--r--challenge-346/packy-anderson/elixir/ch-1.exs68
-rw-r--r--challenge-346/packy-anderson/elixir/ch-2.exs66
-rw-r--r--challenge-346/packy-anderson/perl/ch-1.pl48
-rw-r--r--challenge-346/packy-anderson/perl/ch-2.pl58
-rw-r--r--challenge-346/packy-anderson/python/ch-1.py42
-rw-r--r--challenge-346/packy-anderson/python/ch-2.py52
-rw-r--r--challenge-346/packy-anderson/raku/ch-1.raku48
-rw-r--r--challenge-346/packy-anderson/raku/ch-2.raku56
10 files changed, 440 insertions, 1 deletions
diff --git a/challenge-346/packy-anderson/README.md b/challenge-346/packy-anderson/README.md
index b26414818b..4b575063b3 100644
--- a/challenge-346/packy-anderson/README.md
+++ b/challenge-346/packy-anderson/README.md
@@ -23,4 +23,4 @@
## Blog Post
-[Perl Weekly Challenge: Teach Them How To Say PWC...](https://packy.dardan.com/b/dD)
+[Perl Weekly Challenge: Whoa-oh-oh! Sing about parens!](https://packy.dardan.com/b/dX)
diff --git a/challenge-346/packy-anderson/blog.txt b/challenge-346/packy-anderson/blog.txt
new file mode 100644
index 0000000000..c95f449f6e
--- /dev/null
+++ b/challenge-346/packy-anderson/blog.txt
@@ -0,0 +1 @@
+https://packy.dardan.com/b/dX
diff --git a/challenge-346/packy-anderson/elixir/ch-1.exs b/challenge-346/packy-anderson/elixir/ch-1.exs
new file mode 100644
index 0000000000..b2071accc0
--- /dev/null
+++ b/challenge-346/packy-anderson/elixir/ch-1.exs
@@ -0,0 +1,68 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ # we're at the end of the outer loop
+ def longest_paren(_, len, found, start, stop, _)
+ when start == len and stop == len, do: found
+
+ # we're at the end of the inner loop, next outer loop iteration
+ def longest_paren(str, len, found, start, stop, _)
+ when start < len and stop == len, do:
+ longest_paren(str, len, found, start+1, start+1, 0)
+
+ def longest_paren(str, len, found, start, stop, count) do
+ c = String.slice(str, stop, 1)
+ substring = String.slice(str, start, stop-start+1)
+ count = cond do
+ c == "(" -> count + 1
+ c == ")" -> count - 1
+ end
+ cond do
+ # unbalanced left paren
+ count < 0 ->
+ longest_paren(str, len, found, start+1, start+1, 0)
+
+ # if we've reached the end of $str and we're at 0,
+ # any valid paren strings we find in subsequent outer loop
+ # iterations will be substrings
+ count == 0 and stop == len-1 ->
+ found ++ [substring]
+
+ # we have exactly as many right parens as we've seen left
+ count == 0 ->
+ longest_paren(str, len, found ++ [substring],
+ start, stop+1, count)
+
+ # process the next inner loop iteration
+ true ->
+ longest_paren(str, len, found, start, stop+1, count)
+ end
+ end
+
+ def longest_paren(str) do
+ longest_paren(str, String.length(str), [], 0, 0, 0)
+ |> Enum.sort(&(String.length(&1) >= String.length(&2)))
+ |> List.first
+ |> String.length
+ end
+
+ def solution(str) do
+ IO.puts("Input: $str = '#{str}'")
+ IO.puts("Output: #{longest_paren(str)}")
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution("(()())")
+
+IO.puts("\nExample 2:")
+PWC.solution(")()())")
+
+IO.puts("\nExample 3:")
+PWC.solution("((()))()(((()")
+
+IO.puts("\nExample 4:")
+PWC.solution("))))((()(")
+
+IO.puts("\nExample 5:")
+PWC.solution("()(()")
diff --git a/challenge-346/packy-anderson/elixir/ch-2.exs b/challenge-346/packy-anderson/elixir/ch-2.exs
new file mode 100644
index 0000000000..0c204fe647
--- /dev/null
+++ b/challenge-346/packy-anderson/elixir/ch-2.exs
@@ -0,0 +1,66 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ def eval(str) do
+ {result, _} = Code.eval_string(str)
+ result
+ end
+
+ def magic_expression(found, op, target, digits, ops, pos) do
+ ops = List.replace_at(ops, pos, op)
+ str = Enum.zip(digits, ops++[""])
+ |> Enum.flat_map(fn t -> Tuple.to_list(t) end)
+ |> Enum.join
+ found = cond do
+ !Regex.run(~r/\D0\d+/,str) && target == eval(str) ->
+ Map.put(found, str, 1)
+ true ->
+ found
+ end
+ magic_expression(target, digits, ops, pos+1, found)
+ end
+
+ def magic_expression(_, _, ops, pos, found)
+ when pos >= length(ops), do: found
+
+ def magic_expression(target, digits, ops, pos, found) do
+ magic_expression(found, "", target, digits, ops, pos)
+ |> magic_expression("+", target, digits, ops, pos)
+ |> magic_expression("-", target, digits, ops, pos)
+ |> magic_expression("*", target, digits, ops, pos)
+ end
+
+ def magic_expression(target, str) do
+ magic_expression(
+ target,
+ String.codepoints(str),
+ List.duplicate("", String.length(str)-1),
+ 0, # pos
+ %{} # found
+ )
+ |> Map.keys
+ end
+
+ def solution(str, target) do
+ IO.puts("Input: mystr = \"#{str}\", $target = #{target}")
+ output = magic_expression(target, str)
+ |> Enum.map(fn s -> "\"#{s}\"" end)
+ |> Enum.join(", ")
+ IO.puts("Output: (#{output})")
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution("123", 6)
+
+IO.puts("\nExample 2:")
+PWC.solution("105", 5)
+
+IO.puts("\nExample 3:")
+PWC.solution("232", 8)
+
+IO.puts("\nExample 4:")
+PWC.solution("1234", 10)
+
+IO.puts("\nExample 5:")
+PWC.solution("1001", 2)
diff --git a/challenge-346/packy-anderson/perl/ch-1.pl b/challenge-346/packy-anderson/perl/ch-1.pl
new file mode 100644
index 0000000000..b19c60a3a6
--- /dev/null
+++ b/challenge-346/packy-anderson/perl/ch-1.pl
@@ -0,0 +1,48 @@
+#!/usr/bin/env perl
+use v5.40;
+
+sub longestParen($str) {
+ my @found;
+ for my $start (0 .. length($str) - 2) {
+ my $count = 0;
+ for my $end ($start .. length($str) - 1) {
+ my $c = substr($str, $end, 1);
+ my $substring = substr($str, $start, $end-$start+1);
+ if ($c eq "(") {
+ $count++;
+ }
+ else {
+ $count--;
+ }
+ # unbalanced left paren
+ last if $count < 0;
+ # we have exactly as many right parens as we've seen left
+ push @found, $substring if $count == 0;
+ }
+ # if we've reached the end of $str and we're at 0,
+ # any valid paren strings we find in subsequent outer loop
+ # iterations will be substrings
+ last if $count == 0;
+ }
+ return length((sort { length($a) <=> length($b) } @found)[-1]);
+}
+
+sub solution($str) {
+ say "Input: \$str = '$str'";
+ say "Output: " . longestParen($str);
+}
+
+say "Example 1:";
+solution("(()())");
+
+say "\nExample 2:";
+solution(")()())");
+
+say "\nExample 3:";
+solution("((()))()(((()");
+
+say "\nExample 4:";
+solution("))))((()(");
+
+say "\nExample 5:";
+solution("()(()"); \ No newline at end of file
diff --git a/challenge-346/packy-anderson/perl/ch-2.pl b/challenge-346/packy-anderson/perl/ch-2.pl
new file mode 100644
index 0000000000..b825a334a2
--- /dev/null
+++ b/challenge-346/packy-anderson/perl/ch-2.pl
@@ -0,0 +1,58 @@
+#!/usr/bin/env perl
+use v5.40;
+
+use List::AllUtils qw( zip );
+
+sub targetMatch($target, $str) {
+ my $result;
+ eval "\$result = $str";
+ $result == $target;
+}
+
+sub magicExpression3($op, $target, $digits, $ops, $pos, $found) {
+ $ops->[$pos] = $op;
+ my $str = join("", zip(@$digits, @{[@$ops,""]}));
+
+ $found->{$str} = 1 if $str !~ /\D0\d+/
+ && targetMatch($target, $str);
+ magicExpression2($target, $digits, $ops, $pos+1, $found);
+}
+
+sub magicExpression2($target, $digits, $ops, $pos, $found) {
+ return if $pos >= @$ops; # terminate recusrion
+
+ magicExpression3("", $target, $digits, $ops, $pos, $found);
+ magicExpression3("+", $target, $digits, $ops, $pos, $found);
+ magicExpression3("-", $target, $digits, $ops, $pos, $found);
+ magicExpression3("*", $target, $digits, $ops, $pos, $found);
+}
+
+sub magicExpression($target, $str) {
+ my %found;
+ my $digits = [ split //, $str ];
+ my $ops = [ map { "" } 1 .. length($str)-1 ];
+ magicExpression2($target, $digits, $ops, 0, \%found);
+ return keys %found;
+}
+
+sub solution($str, $target) {
+ say qq{Input: \$str = "$str", \$target = $target};
+ say 'Output: (' .
+ join(', ', map { qq{"$_"} } magicExpression($target, $str)) .
+ ')';
+}
+
+say "Example 1:";
+solution("123", 6);
+
+say "\nExample 2:";
+solution("105", 5);
+
+say "\nExample 3:";
+solution("232", 8);
+
+say "\nExample 4:";
+solution("1234", 10);
+
+say "\nExample 5:";
+solution("1001", 2);
diff --git a/challenge-346/packy-anderson/python/ch-1.py b/challenge-346/packy-anderson/python/ch-1.py
new file mode 100644
index 0000000000..368da9f768
--- /dev/null
+++ b/challenge-346/packy-anderson/python/ch-1.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+
+def longest_paren(my_str):
+ found = []
+ for start in range(len(my_str)-1):
+ count = 0
+ for end in range(start, len(my_str)):
+ c = my_str[end:end+1]
+ substring = my_str[start:end+1]
+ if c == "(":
+ count += 1
+ else:
+ count -= 1
+ # unbalanced left paren
+ if count < 0: break
+ # we have exactly as many right parens as we've seen left
+ if count == 0: found.append(substring)
+ # if we've reached the end of $str and we're at 0,
+ # any valid paren strings we find in subsequent outer loop
+ # iterations will be substrings
+ if count == 0: break
+ found.sort(key=len)
+ return len(found[-1])
+
+def solution(my_str):
+ print(f"Input: $str = '{my_str}'")
+ print(f'Output: {longest_paren(my_str)}')
+
+print('Example 1:')
+solution("(()())")
+
+print('\nExample 2:')
+solution(")()())")
+
+print('\nExample 3:')
+solution("((()))()(((()")
+
+print('\nExample 4:')
+solution("))))((()(")
+
+print('\nExample 5:')
+solution("()(()")
diff --git a/challenge-346/packy-anderson/python/ch-2.py b/challenge-346/packy-anderson/python/ch-2.py
new file mode 100644
index 0000000000..c0a6b90780
--- /dev/null
+++ b/challenge-346/packy-anderson/python/ch-2.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+
+from itertools import chain
+import re
+
+has_leading_zero = re.compile("[^0-9]0[0-9]+")
+
+def to_str(digits, ops):
+ return "".join(
+ list( chain.from_iterable( zip(digits, ops+[""]) ) )
+ )
+
+def magic_expression3(op, target, digits, ops, pos, found):
+ ops[pos] = op
+ mystr = to_str(digits, ops)
+ if not has_leading_zero.search(mystr) and target == eval(mystr):
+ found[mystr] = 1
+ magic_expression2(target, digits, ops, pos+1, found)
+
+def magic_expression2(target, digits, ops, pos, found):
+ if pos >= len(ops): return # terminate recusrion
+ magic_expression3("", target, digits, ops, pos, found)
+ magic_expression3("+", target, digits, ops, pos, found)
+ magic_expression3("-", target, digits, ops, pos, found)
+ magic_expression3("*", target, digits, ops, pos, found)
+
+def magic_expression(target, mystr):
+ found = {}
+ digits = list(mystr)
+ ops = [ "" for x in range(len(mystr)-1)]
+ magic_expression2(target, digits, ops, 0, found)
+ return found.keys()
+
+def solution(mystr, target):
+ print(f'Input: mystr = "{mystr}", $target = {target}')
+ output = [ f'"{s}"' for s in magic_expression(target, mystr) ]
+ print(f'Output: ({", ".join(output)})')
+
+print('Example 1:')
+solution("123", 6)
+
+print('\nExample 2:')
+solution("105", 5)
+
+print('\nExample 3:')
+solution("232", 8)
+
+print('\nExample 4:')
+solution("1234", 10)
+
+print('\nExample 5:')
+solution("1001", 2)
diff --git a/challenge-346/packy-anderson/raku/ch-1.raku b/challenge-346/packy-anderson/raku/ch-1.raku
new file mode 100644
index 0000000000..c16e7d2b52
--- /dev/null
+++ b/challenge-346/packy-anderson/raku/ch-1.raku
@@ -0,0 +1,48 @@
+#!/usr/bin/env raku
+use v6;
+
+sub longestParen($str) {
+ my @found;
+ for 0..$str.chars-2 -> $start {
+ my $count = 0;
+ for $start..$str.chars-1 -> $end {
+ my $c = $str.substr($end, 1);
+ my $substring = $str.substr($start..$end);
+ if ($c eq "(") {
+ $count++;
+ }
+ else {
+ $count--;
+ }
+ # unbalanced left paren
+ last if $count < 0;
+ # we have exactly as many right parens as we've seen left
+ @found.push($substring) if $count == 0;
+ }
+ # if we've reached the end of $str and we're at 0,
+ # any valid paren strings we find in subsequent outer loop
+ # iterations will be substrings
+ last if $count == 0;
+ }
+ return (@found.sort: *.chars)[*-1].chars;
+}
+
+sub solution($str) {
+ say "Input: \$str = '$str'";
+ say "Output: " ~ longestParen($str);
+}
+
+say "Example 1:";
+solution("(()())");
+
+say "\nExample 2:";
+solution(")()())");
+
+say "\nExample 3:";
+solution("((()))()(((()");
+
+say "\nExample 4:";
+solution("))))((()(");
+
+say "\nExample 5:";
+solution("()(()");
diff --git a/challenge-346/packy-anderson/raku/ch-2.raku b/challenge-346/packy-anderson/raku/ch-2.raku
new file mode 100644
index 0000000000..85f6f0e8a2
--- /dev/null
+++ b/challenge-346/packy-anderson/raku/ch-2.raku
@@ -0,0 +1,56 @@
+#!/usr/bin/env raku
+use v6;
+
+sub targetMatch($target, $str) {
+ my $result;
+ use MONKEY-SEE-NO-EVAL;
+ EVAL "\$result = $str";
+ $result == $target;
+}
+
+multi magicExpression($op, $target, @digits, @ops is copy, $pos,
+ %found) {
+ @ops[$pos] = $op;
+ my $str = (@digits Z~ (@ops,"").flat).join("");
+ %found{$str} = 1 if $str !~~ /\D0\d+/
+ && targetMatch($target, $str);
+ magicExpression($target, @digits, @ops, $pos+1, %found);
+}
+
+multi magicExpression($target, @digits, @ops, $pos, %found) {
+ return if $pos > @ops.end; # terminate recusrion
+
+ magicExpression("", $target, @digits, @ops, $pos, %found);
+ magicExpression("+", $target, @digits, @ops, $pos, %found);
+ magicExpression("-", $target, @digits, @ops, $pos, %found);
+ magicExpression("*", $target, @digits, @ops, $pos, %found);
+}
+
+multi magicExpression($target, $str) {
+ my %found;
+ my @digits = $str.comb;
+ magicExpression($target, @digits, "" xx @digits.end, 0, %found);
+ return %found.keys;
+}
+
+sub solution($str, $target) {
+ say qq{Input: \$str = "$str", \$target = $target};
+ say 'Output: (' ~
+ magicExpression($target, $str).map({qq{"$_"}}).join(', ') ~
+ ')';
+}
+
+say "Example 1:";
+solution("123", 6);
+
+say "\nExample 2:";
+solution("105", 5);
+
+say "\nExample 3:";
+solution("232", 8);
+
+say "\nExample 4:";
+solution("1234", 10);
+
+say "\nExample 5:";
+solution("1001", 2);