diff options
| author | Packy Anderson <packy@cpan.org> | 2025-11-20 00:01:42 -0500 |
|---|---|---|
| committer | Packy Anderson <packy@cpan.org> | 2025-11-20 00:01:42 -0500 |
| commit | 23e5825c28794bb33711cf01294d0e06f2994045 (patch) | |
| tree | 30e33a15d177773468eeb89390a00083b4bbadb8 | |
| parent | 25572447da12014ff4f20d22dcc3260e8a906f99 (diff) | |
| download | perlweeklychallenge-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.md | 3 | ||||
| -rw-r--r-- | challenge-348/packy-anderson/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/elixir/ch-1.exs | 47 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/elixir/ch-2.exs | 62 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/perl/ch-1.pl | 45 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/perl/ch-2.pl | 52 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/python/ch-1.py | 42 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/python/ch-2.py | 45 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/raku/ch-1.raku | 45 | ||||
| -rwxr-xr-x | challenge-348/packy-anderson/raku/ch-2.raku | 46 |
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"); |
