diff options
| author | Mohammad Sajid Anwar <mohammad.anwar@yahoo.com> | 2025-11-10 00:42:51 +0000 |
|---|---|---|
| committer | Mohammad Sajid Anwar <mohammad.anwar@yahoo.com> | 2025-11-10 00:42:51 +0000 |
| commit | b07a0019e07bb4697ee1f3527e440e8a9f5120b8 (patch) | |
| tree | a090ecb3dddf0607044cc8445673c95e3260c791 /challenge-346 | |
| parent | 221ad5c01245d61163a1eb34f8d756f8eabab479 (diff) | |
| download | perlweeklychallenge-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.md | 2 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/elixir/ch-1.exs | 68 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/elixir/ch-2.exs | 66 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/perl/ch-1.pl | 48 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/perl/ch-2.pl | 58 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/python/ch-1.py | 42 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/python/ch-2.py | 52 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/raku/ch-1.raku | 48 | ||||
| -rw-r--r-- | challenge-346/packy-anderson/raku/ch-2.raku | 56 |
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); |
