aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPacky Anderson <packy@cpan.org>2025-11-20 00:01:42 -0500
committerPacky Anderson <packy@cpan.org>2025-11-20 00:01:42 -0500
commit23e5825c28794bb33711cf01294d0e06f2994045 (patch)
tree30e33a15d177773468eeb89390a00083b4bbadb8
parent25572447da12014ff4f20d22dcc3260e8a906f99 (diff)
downloadperlweeklychallenge-club-23e5825c28794bb33711cf01294d0e06f2994045.tar.gz
perlweeklychallenge-club-23e5825c28794bb33711cf01294d0e06f2994045.tar.bz2
perlweeklychallenge-club-23e5825c28794bb33711cf01294d0e06f2994045.zip
Challenge 348 solutions by Packy Anderson
* Raku that is finally Raku-ish * Perl * Python that kinda looks like Raku * Elixir that is starting to look like Elixir 1 blog post
-rw-r--r--challenge-348/packy-anderson/README.md3
-rw-r--r--challenge-348/packy-anderson/blog.txt1
-rwxr-xr-xchallenge-348/packy-anderson/elixir/ch-1.exs47
-rwxr-xr-xchallenge-348/packy-anderson/elixir/ch-2.exs62
-rwxr-xr-xchallenge-348/packy-anderson/perl/ch-1.pl45
-rwxr-xr-xchallenge-348/packy-anderson/perl/ch-2.pl52
-rwxr-xr-xchallenge-348/packy-anderson/python/ch-1.py42
-rwxr-xr-xchallenge-348/packy-anderson/python/ch-2.py45
-rwxr-xr-xchallenge-348/packy-anderson/raku/ch-1.raku45
-rwxr-xr-xchallenge-348/packy-anderson/raku/ch-2.raku46
10 files changed, 386 insertions, 2 deletions
diff --git a/challenge-348/packy-anderson/README.md b/challenge-348/packy-anderson/README.md
index b54c5bd3b8..c1bb4c0bec 100644
--- a/challenge-348/packy-anderson/README.md
+++ b/challenge-348/packy-anderson/README.md
@@ -22,5 +22,4 @@
## Blog Post
-
-[Perl Weekly Challenge: Oh, oh, formatted strings, give me some thing...](https://packy.dardan.com/b/dp)
+[Perl Weekly Challenge: Ticking away the moments that make up a challenge...](https://packy.dardan.com/b/eC)
diff --git a/challenge-348/packy-anderson/blog.txt b/challenge-348/packy-anderson/blog.txt
new file mode 100644
index 0000000000..3457a0bca4
--- /dev/null
+++ b/challenge-348/packy-anderson/blog.txt
@@ -0,0 +1 @@
+https://packy.dardan.com/b/eC \ No newline at end of file
diff --git a/challenge-348/packy-anderson/elixir/ch-1.exs b/challenge-348/packy-anderson/elixir/ch-1.exs
new file mode 100755
index 0000000000..241efd4137
--- /dev/null
+++ b/challenge-348/packy-anderson/elixir/ch-1.exs
@@ -0,0 +1,47 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ def count_vowels(str) do
+ str = str |> String.replace(~r/[^aeiou]/i, "")
+ count = String.length(str)
+ vowels = if count == 1, do: "vowel", else: "vowels"
+ { count, vowels }
+ end
+
+ def string_alike(str) do
+ # split the string
+ half_len = Integer.floor_div(String.length(str), 2)
+ first = String.slice(str, 0, half_len)
+ second = String.slice(str, half_len, half_len)
+ # count the vowels
+ {count1, vowel1} = count_vowels(first)
+ explain = "1st half: \"#{first}\" (#{count1} #{vowel1})\n"
+ {count2, vowel2} = count_vowels(second)
+ explain = explain
+ <> "2nd half: \"#{second}\" (#{count2} #{vowel2})"
+ # return the result
+ bool = if count1 == count2 and count1 > 0, do: "True",
+ else: "False"
+ "#{bool}\n\n#{explain}"
+ end
+
+ def solution(str) do
+ IO.puts("Input: $str = \"#{str}\"")
+ IO.puts("Output: " <> string_alike(str))
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution("textbook")
+
+IO.puts("\nExample 2:")
+PWC.solution("book")
+
+IO.puts("\nExample 3:")
+PWC.solution("AbCdEfGh")
+
+IO.puts("\nExample 4:")
+PWC.solution("rhythmmyth")
+
+IO.puts("\nExample 5:")
+PWC.solution("UmpireeAudio")
diff --git a/challenge-348/packy-anderson/elixir/ch-2.exs b/challenge-348/packy-anderson/elixir/ch-2.exs
new file mode 100755
index 0000000000..7b7cfee27c
--- /dev/null
+++ b/challenge-348/packy-anderson/elixir/ch-2.exs
@@ -0,0 +1,62 @@
+#!/usr/bin/env elixir
+
+defmodule PWC do
+ def mytime(t) do
+ {_, dt, _} = DateTime.from_iso8601("2000-01-01T#{t}:00Z")
+ dt
+ end
+
+ def convert_time([], _, ops), do: ops
+ def convert_time(_, diff, ops) when diff == 0, do: ops
+
+ def convert_time([op | rest], diff, ops) do
+ n = Integer.floor_div(diff, op)
+ {diff, ops} = cond do
+ n > 0 ->
+ minutes = if op == 1, do: "minute", else: "minutes"
+ {
+ diff - n * op,
+ ops ++ Enum.map(
+ Range.to_list(1..n),
+ fn _ -> "Add #{op} #{minutes}" end
+ )
+ }
+ true -> {diff, ops}
+ end
+ convert_time(rest, diff, ops)
+ end
+
+ def convert_time(source, target) do
+ s = mytime(source)
+ t = mytime(target)
+ t = if t < s, # it must be a time in the next day
+ do: DateTime.add(t, 1, :day), else: t
+ diff = DateTime.diff(t, s, :minute)
+ ops = convert_time([60, 15, 5, 1], diff, [])
+ count = length(ops)
+ operations = if count == 1, do: "Operation",
+ else: "Operations"
+ "#{count}\n\n#{operations}:\n + " <> Enum.join(ops, "\n + ")
+ end
+
+ def solution(source, target) do
+ IO.puts("Input: $source = \"#{source}\"")
+ IO.puts(" $target = \"#{target}\"")
+ IO.puts("Output: " <> convert_time(source, target))
+ end
+end
+
+IO.puts("Example 1:")
+PWC.solution("02:30", "02:45")
+
+IO.puts("\nExample 2:")
+PWC.solution("11:55", "12:15")
+
+IO.puts("\nExample 3:")
+PWC.solution("09:00", "13:00")
+
+IO.puts("\nExample 4:")
+PWC.solution("23:45", "00:30")
+
+IO.puts("\nExample 5:")
+PWC.solution("14:20", "15:25")
diff --git a/challenge-348/packy-anderson/perl/ch-1.pl b/challenge-348/packy-anderson/perl/ch-1.pl
new file mode 100755
index 0000000000..12c63bb949
--- /dev/null
+++ b/challenge-348/packy-anderson/perl/ch-1.pl
@@ -0,0 +1,45 @@
+#!/usr/bin/env perl
+use v5.40;
+
+sub countVowels($str) {
+ (my $vowels = $str) =~ s/[^aeiou]//ig;
+ my $count = length($vowels);
+ my $vowel = 'vowel' . ($count == 1 ? '' : 's');
+ return ($count, $vowel);
+}
+
+sub stringAlike($str) {
+ my $explain;
+ # split the string
+ my $halfLen = length($str) / 2;
+ my $first = substr($str, 0, $halfLen);
+ my $second = substr($str, $halfLen);
+ # count the vowels
+ my ($count1, $vowel1) = countVowels($first);
+ $explain = qq{1st half: "$first" ($count1 $vowel1)\n};
+ my ($count2, $vowel2) = countVowels($second);
+ $explain .= qq{2nd half: "$second" ($count2 $vowel2)};
+ # return the result
+ my $bool = $count1 == $count2 && $count1 > 0 ? 'True' : 'False';
+ return "$bool\n\n$explain";
+}
+
+sub solution($str) {
+ say qq/Input: \$str = "$str"/;
+ say qq/Output: @{[stringAlike($str)]}/;
+}
+
+say "Example 1:";
+solution("textbook");
+
+say "\nExample 2:";
+solution("book");
+
+say "\nExample 3:";
+solution("AbCdEfGh");
+
+say "\nExample 4:";
+solution("rhythmmyth");
+
+say "\nExample 5:";
+solution("UmpireeAudio");
diff --git a/challenge-348/packy-anderson/perl/ch-2.pl b/challenge-348/packy-anderson/perl/ch-2.pl
new file mode 100755
index 0000000000..04ec83620d
--- /dev/null
+++ b/challenge-348/packy-anderson/perl/ch-2.pl
@@ -0,0 +1,52 @@
+#!/usr/bin/env perl
+use v5.40;
+use Time::Piece;
+use Time::Seconds qw( ONE_DAY );
+
+sub mytime($str) {
+ Time::Piece->strptime("2000-01-01T$str", "%Y-%m-%dT%H:%M");
+}
+
+sub convertTime($source, $target) {
+ # find difference between $source and $target
+ my $s = mytime($source);
+ my $t = mytime($target);
+ if ($t < $s) { # it must be a time in the next day
+ $t += ONE_DAY;
+ }
+ my $diff = ($t - $s) / 60; # (t-s) is in seconds
+ # find how many operations needed
+ my @ops;
+ foreach my $op (60, 15, 5, 1) {
+ if (my $n = int($diff / $op)) {
+ my $min = $op == 1 ? "minute" : "minutes";
+ push @ops, "Add $op $min" for 1..$n;
+ $diff -= $n * $op;
+ last unless $diff > 0;
+ }
+ }
+ my $count = scalar(@ops);
+ my $operations = $count == 1 ? "Operation" : "Operations";
+ return "$count\n\n$operations:\n + @{[join(qq/\n + /, @ops)]}";
+}
+
+sub solution($source, $target) {
+ say qq/Input: \$source = "$source"/;
+ say qq/ \$target = "$target"/;
+ say 'Output: ' . convertTime($source, $target);
+}
+
+say "Example 1:";
+solution("02:30", "02:45");
+
+say "\nExample 2:";
+solution("11:55", "12:15");
+
+say "\nExample 3:";
+solution("09:00", "13:00");
+
+say "\nExample 4:";
+solution("23:45", "00:30");
+
+say "\nExample 5:";
+solution("14:20", "15:25");
diff --git a/challenge-348/packy-anderson/python/ch-1.py b/challenge-348/packy-anderson/python/ch-1.py
new file mode 100755
index 0000000000..bf13afe7a0
--- /dev/null
+++ b/challenge-348/packy-anderson/python/ch-1.py
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+
+import re
+
+def countVowels(text):
+ text = re.sub(r'[^aeiou]', '', text, flags=re.IGNORECASE)
+ count = len(text)
+ vowel = "vowel" if count == 1 else "vowels"
+ return count, vowel
+
+def string_alike(text):
+ # split the string
+ half_len = int(len(text) / 2)
+ first = text[0:half_len]
+ second = text[half_len:]
+ # count the vowels
+ count1, vowel1 = countVowels(first)
+ explain = f'1st half: "{first}" ({count1} {vowel1})\n'
+ count2, vowel2 = countVowels(second)
+ explain += f'2nd half: "{second}" ({count2} {vowel2})'
+ # return the result
+ bool = "True" if count1 == count2 and count1 > 0 else "False"
+ return f'{bool}\n\n{explain}'
+
+def solution(text):
+ print(f'Input: $str = "{text}"')
+ print(f'Output: {string_alike(text)}')
+
+print('Example 1:')
+solution("textbook")
+
+print('\nExample 2:')
+solution("book")
+
+print('\nExample 3:')
+solution("AbCdEfGh")
+
+print('\nExample 4:')
+solution("rhythmmyth")
+
+print('\nExample 5:')
+solution("UmpireeAudio")
diff --git a/challenge-348/packy-anderson/python/ch-2.py b/challenge-348/packy-anderson/python/ch-2.py
new file mode 100755
index 0000000000..25dac8a6c2
--- /dev/null
+++ b/challenge-348/packy-anderson/python/ch-2.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+
+from datetime import datetime, timedelta
+
+def mytime(t):
+ return datetime.strptime(f'2000-01-01T{t}', '%Y-%m-%dT%H:%M')
+
+def convert_time(source, target):
+ s = mytime(source)
+ t = mytime(target)
+ if t < s: # it must be a time in the next day
+ t += timedelta(days = 1) # add 1 day
+ diff = int((t - s).seconds / 60)
+ ops = []
+ for op in [60, 15, 5, 1]:
+ n = diff // op
+ if n:
+ minutes = "minute" if op == 1 else "minutes"
+ for i in range(n): ops.append(f'Add {op} {minutes}')
+ diff -= n * op
+ if diff == 0: break
+ count = len(ops)
+ operations = "Operation" if count == 1 else "Operations"
+ return f'{count}\n\n{operations}:\n + {"\n + ".join(ops)}'
+
+def solution(source, target):
+ print(f'Input: $source = "{source}"')
+ print(f' $target = "{target}"')
+ print(f'Output: {convert_time(source, target)}')
+
+
+print('Example 1:')
+solution("02:30", "02:45")
+
+print('\nExample 2:')
+solution("11:55", "12:15")
+
+print('\nExample 3:')
+solution("09:00", "13:00")
+
+print('\nExample 4:')
+solution("23:45", "00:30")
+
+print('\nExample 5:')
+solution("14:20", "15:25")
diff --git a/challenge-348/packy-anderson/raku/ch-1.raku b/challenge-348/packy-anderson/raku/ch-1.raku
new file mode 100755
index 0000000000..570d17b881
--- /dev/null
+++ b/challenge-348/packy-anderson/raku/ch-1.raku
@@ -0,0 +1,45 @@
+#!/usr/bin/env raku
+use v6;
+
+sub countVowels($str) {
+ my @vowels = $str.lc.comb(/<[aeiou]>/);
+ my $count = @vowels.elems;
+ my $vowel = 'vowel' ~ ($count == 1 ?? '' !! 's');
+ return ($count, $vowel);
+}
+
+sub stringAlike($str) {
+ my $explain;
+ # split the string
+ my $halfLen = $str.chars / 2;
+ my $first = $str.substr(0..($halfLen-1));
+ my $second = $str.substr($halfLen);
+ # count the vowels
+ my ($count1, $vowel1) = countVowels($first);
+ $explain = qq{1st half: "$first" ($count1 $vowel1)\n};
+ my ($count2, $vowel2) = countVowels($second);
+ $explain ~= qq{2nd half: "$second" ($count2 $vowel2)};
+ # return the result
+ my $bool = $count1 == $count2 && $count1 > 0;
+ return "$bool\n\n$explain";
+}
+
+sub solution($str) {
+ say qq/Input: \$str = "$str"/;
+ say qq/Output: {stringAlike($str)}/;
+}
+
+say "Example 1:";
+solution("textbook");
+
+say "\nExample 2:";
+solution("book");
+
+say "\nExample 3:";
+solution("AbCdEfGh");
+
+say "\nExample 4:";
+solution("rhythmmyth");
+
+say "\nExample 5:";
+solution("UmpireeAudio");
diff --git a/challenge-348/packy-anderson/raku/ch-2.raku b/challenge-348/packy-anderson/raku/ch-2.raku
new file mode 100755
index 0000000000..cc8c66b57e
--- /dev/null
+++ b/challenge-348/packy-anderson/raku/ch-2.raku
@@ -0,0 +1,46 @@
+#!/usr/bin/env raku
+use v6;
+
+sub convertTime($source, $target) {
+ # find difference between $source and $target
+ my $s = DateTime.new("2000-01-01T$source:00");
+ my $t = DateTime.new("2000-01-01T$target:00");
+ if ($t < $s) { # it must be a time in the next day
+ $t = $t.later(days => 1);
+ }
+ my $diff = ($t - $s) / 60; # (t-s) is in seconds
+ # find how many operations needed
+ my @ops;
+ for [60, 15, 5, 1] -> $op {
+ if (my $n = $diff div $op) {
+ my $min = $op == 1 ?? "minute" !! "minutes";
+ @ops.push("Add $op $min") for 1..$n;
+ $diff -= $n * $op;
+ last unless $diff > 0;
+ }
+ }
+ my $count = @ops.elems;
+ my $operations = $count == 1 ?? "Operation" !! "Operations";
+ return "$count\n\n$operations:\n + {@ops.join(qq/\n + /)}";
+}
+
+sub solution($source, $target) {
+ say qq/Input: \$source = "$source"/;
+ say qq/ \$target = "$target"/;
+ say 'Output: ' ~ convertTime($source, $target);
+}
+
+say "Example 1:";
+solution("02:30", "02:45");
+
+say "\nExample 2:";
+solution("11:55", "12:15");
+
+say "\nExample 3:";
+solution("09:00", "13:00");
+
+say "\nExample 4:";
+solution("23:45", "00:30");
+
+say "\nExample 5:";
+solution("14:20", "15:25");