aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-347/packy-anderson/README.md2
-rw-r--r--challenge-347/packy-anderson/blog.txt1
-rwxr-xr-xchallenge-347/packy-anderson/elixir/ch-1.exs77
-rwxr-xr-xchallenge-347/packy-anderson/elixir/ch-2.exs41
-rwxr-xr-xchallenge-347/packy-anderson/perl/ch-1.pl73
-rwxr-xr-xchallenge-347/packy-anderson/perl/ch-2.pl37
-rwxr-xr-xchallenge-347/packy-anderson/python/ch-1.py75
-rwxr-xr-xchallenge-347/packy-anderson/python/ch-2.py41
-rwxr-xr-xchallenge-347/packy-anderson/raku/ch-1.raku66
-rwxr-xr-xchallenge-347/packy-anderson/raku/ch-2.raku36
10 files changed, 367 insertions, 82 deletions
diff --git a/challenge-347/packy-anderson/README.md b/challenge-347/packy-anderson/README.md
index 4b575063b3..b54c5bd3b8 100644
--- a/challenge-347/packy-anderson/README.md
+++ b/challenge-347/packy-anderson/README.md
@@ -23,4 +23,4 @@
## Blog Post
-[Perl Weekly Challenge: Whoa-oh-oh! Sing about parens!](https://packy.dardan.com/b/dX)
+[Perl Weekly Challenge: Oh, oh, formatted strings, give me some thing...](https://packy.dardan.com/b/dp)
diff --git a/challenge-347/packy-anderson/blog.txt b/challenge-347/packy-anderson/blog.txt
index e69de29bb2..f7505b9a52 100644
--- a/challenge-347/packy-anderson/blog.txt
+++ b/challenge-347/packy-anderson/blog.txt
@@ -0,0 +1 @@
+https://packy.dardan.com/b/dp \ No newline at end of file
diff --git a/challenge-347/packy-anderson/elixir/ch-1.exs b/challenge-347/packy-anderson/elixir/ch-1.exs
index 45a0ed2251..5e9fe3b639 100755
--- a/challenge-347/packy-anderson/elixir/ch-1.exs
+++ b/challenge-347/packy-anderson/elixir/ch-1.exs
@@ -1,26 +1,83 @@
#!/usr/bin/env elixir
defmodule PWC do
+ def format_date(_, _, _, year) when year < 1900,
+ do: "Year must be between 1900-2100"
- def solution(ints) do
- IO.puts("Input: @ints = (" <> Enum.join(ints, ", ") <> ")")
- {sign, explain} = PWC.productSign(ints)
- IO.puts("Output: " <> to_string(sign) )
- IO.puts("\n" <> explain)
+ def format_date(_, _, _, year) when year > 2100,
+ do: "Year must be between 1900-2100"
+
+ def format_date(_, month, mnum, _) when is_nil(mnum),
+ do: "Unknown month '#{month}'"
+
+ def format_date(dnum, _, mnum, year) do
+ with {:ok, date} <- Date.new(year, mnum, dnum) do
+ "\"#{date |> Date.to_iso8601}\""
+ else
+ {:error, :invalid_date} -> "Invalid date"
+ end
+ end
+
+ def format_date(str) do
+ [day, month, year] = String.split(str)
+
+ m = Regex.named_captures(~r'(?<dnum>\d+)(?<dord>\D+)', day)
+ dnum = m["dnum"] |> String.to_integer # make sure it's an int
+
+ if not (
+ ((dnum == 1 or dnum == 21 or dnum == 31) and
+ m["dord"] == "st")
+ or
+ ((dnum == 2 or dnum == 22) and m["dord"] == "nd")
+ or
+ ((dnum == 3 or dnum == 23) and m["dord"] == "rd")
+ or
+ m["dord"] == "th"
+ ) do
+ "#{day} has the incorrect ordinal"
+ else
+ year = year |> String.to_integer # make sure it's an int
+ mnum = Map.get(%{
+ "Jan" => 1, "Feb" => 2, "Mar" => 3, "Apr" => 4,
+ "May" => 5, "Jun" => 6, "Jul" => 7, "Aug" => 8,
+ "Sep" => 9, "Oct" => 10, "Nov" => 11, "Dec" => 12
+ }, month)
+ format_date(dnum, month, mnum, year)
+ end
+ end
+
+ def solution(str) do
+ IO.puts("Input: $str = \"#{str}\"")
+ IO.puts("Output: " <> format_date(str))
end
end
IO.puts("Example 1:")
-PWC.solution()
+PWC.solution("1st Jan 2025")
IO.puts("\nExample 2:")
-PWC.solution()
+PWC.solution("22nd Feb 2025")
IO.puts("\nExample 3:")
-PWC.solution()
+PWC.solution("15th Apr 2025")
IO.puts("\nExample 4:")
-PWC.solution()
+PWC.solution("23rd Oct 2025")
IO.puts("\nExample 5:")
-PWC.solution()
+PWC.solution("31st Dec 2025")
+
+IO.puts("\nExample Year Too Big:")
+PWC.solution("31st Dec 2525")
+
+IO.puts("\nExample Year Too Small:")
+PWC.solution("31st Dec 1825")
+
+IO.puts("\nExample Bad Ordinal:")
+PWC.solution("31nd Dec 2025")
+
+IO.puts("\nExample Bad Month:")
+PWC.solution("30th Avril 2025")
+
+IO.puts("\nExample Bad Date:")
+PWC.solution("31st Feb 2025")
diff --git a/challenge-347/packy-anderson/elixir/ch-2.exs b/challenge-347/packy-anderson/elixir/ch-2.exs
index 45a0ed2251..6bd182cf1f 100755
--- a/challenge-347/packy-anderson/elixir/ch-2.exs
+++ b/challenge-347/packy-anderson/elixir/ch-2.exs
@@ -1,26 +1,47 @@
#!/usr/bin/env elixir
defmodule PWC do
+ def format_phone(list, formatted) when length(list) < 4 do
+ formatted <> Enum.join(list)
+ end
+
+ def format_phone(list, formatted) when length(list) == 4 do
+ {a, list} = {hd(list), tl(list)}
+ {b, list} = {hd(list), tl(list)}
+ formatted <> "#{a}#{b}-" <> Enum.join(list)
+ end
+
+ def format_phone(list, formatted) when length(list) > 4 do
+ {a, list} = {hd(list), tl(list)}
+ {b, list} = {hd(list), tl(list)}
+ {c, list} = {hd(list), tl(list)}
+ format_phone(list, formatted <> "#{a}#{b}#{c}-")
+ end
+
+ def format_phone(phone) do
+ phone
+ |> String.replace(~r/\D/, "")
+ |> String.graphemes
+ |> format_phone("")
+ end
- def solution(ints) do
- IO.puts("Input: @ints = (" <> Enum.join(ints, ", ") <> ")")
- {sign, explain} = PWC.productSign(ints)
- IO.puts("Output: " <> to_string(sign) )
- IO.puts("\n" <> explain)
+ def solution(phone) do
+ IO.puts("Input: $phone = \"#{phone}\"")
+ IO.puts("Output: \"#{format_phone(phone)}\"")
end
end
IO.puts("Example 1:")
-PWC.solution()
+PWC.solution("1-23-45-6")
IO.puts("\nExample 2:")
-PWC.solution()
+PWC.solution("1234")
IO.puts("\nExample 3:")
-PWC.solution()
+PWC.solution("12 345-6789")
IO.puts("\nExample 4:")
-PWC.solution()
+PWC.solution("123 4567")
IO.puts("\nExample 5:")
-PWC.solution()
+PWC.solution("123 456-78")
diff --git a/challenge-347/packy-anderson/perl/ch-1.pl b/challenge-347/packy-anderson/perl/ch-1.pl
index 98a155f02b..eb813f7671 100755
--- a/challenge-347/packy-anderson/perl/ch-1.pl
+++ b/challenge-347/packy-anderson/perl/ch-1.pl
@@ -1,22 +1,79 @@
#!/usr/bin/env perl
use v5.40;
-sub solution(@arr) {
- say 'Input: @arr = (' . join(', ', @arr) . ')';
- say 'Output: (' . join(', ', @arr) . ')';
+use Time::Local;
+use Time::Piece;
+
+my %months = (
+ Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
+ Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12
+);
+
+sub formatDate($str) {
+ my ($day, $month, $year) = split / /, $str;
+
+ my ($dnum, $dord) = $day =~ /(\d+)(\D+)/;
+ return "$day has the incorrect ordinal"
+ unless
+ (($dnum == 1 || $dnum == 21 || $dnum == 31) && $dord eq "st")
+ ||
+ (($dnum == 2 || $dnum == 22) && $dord eq "nd")
+ ||
+ (($dnum == 3 || $dnum == 23) && $dord eq "rd")
+ ||
+ $dord eq "th";
+ $day = $dnum; # grab just the numeric portion
+
+ return "Unknown month '$month'"
+ unless exists $months{$month};
+ $month = $months{$month}; # convert to numeric
+
+ return "Year must be between 1900-2100"
+ unless 1900 <= $year && $year <= 2100;
+
+ my $date;
+ eval {
+ my $epoch = timelocal(0, 0, 0, $day, $month-1, $year);
+ $date = Time::Piece->new($epoch);
+ };
+ if (my $err = $@) { # get rid of line info in the error
+ $err =~ s{at .+ line \d+.\n}{};
+ return $err;
+ }
+ return qq/"@{[ $date->date ]}"/;
+}
+
+sub solution($str) {
+ say qq/Input: \$str = "$str"/;
+ say qq/Output: / . formatDate($str);
}
say "Example 1:";
-solution();
+solution("1st Jan 2025");
say "\nExample 2:";
-solution();
+solution("22nd Feb 2025");
say "\nExample 3:";
-solution();
+solution("15th Apr 2025");
say "\nExample 4:";
-solution();
+solution("23rd Oct 2025");
say "\nExample 5:";
-solution();
+solution("31st Dec 2025");
+
+say "\nExample Year Too Big:";
+solution("31st Dec 2525");
+
+say "\nExample Year Too Small:";
+solution("31st Dec 1825");
+
+say "\nExample Bad Ordinal:";
+solution("31nd Dec 2025");
+
+say "\nExample Bad Month:";
+solution("30th Avril 2025");
+
+say "\nExample Bad Date:";
+solution("31st Feb 2025");
diff --git a/challenge-347/packy-anderson/perl/ch-2.pl b/challenge-347/packy-anderson/perl/ch-2.pl
index 98a155f02b..4226e87493 100755
--- a/challenge-347/packy-anderson/perl/ch-2.pl
+++ b/challenge-347/packy-anderson/perl/ch-2.pl
@@ -1,22 +1,43 @@
#!/usr/bin/env perl
use v5.40;
-sub solution(@arr) {
- say 'Input: @arr = (' . join(', ', @arr) . ')';
- say 'Output: (' . join(', ', @arr) . ')';
+sub formatPhone2($phone, $formatted) {
+ if (length($phone) < 4) {
+ $formatted . $phone;
+ }
+ elsif (length($phone) == 4) {
+ $formatted . substr($phone, 0,2) . "-" . substr($phone, 2,2);
+ }
+ else {
+ formatPhone2(
+ substr($phone, 3),
+ $formatted . substr($phone, 0, 3) . "-"
+ );
+ }
+}
+
+sub formatPhone($phone) {
+ $phone =~ s/\D+//g;
+ formatPhone2($phone, "");
+}
+
+sub solution($phone) {
+ say qq/Input: \$phone = "$phone"/;
+ say qq/Output: "@{[formatPhone($phone)]}"/;
}
say "Example 1:";
-solution();
+solution("1-23-45-6");
say "\nExample 2:";
-solution();
+solution("1234");
say "\nExample 3:";
-solution();
+solution("12 345-6789");
say "\nExample 4:";
-solution();
+solution("123 4567");
say "\nExample 5:";
-solution();
+solution("123 456-78");
+
diff --git a/challenge-347/packy-anderson/python/ch-1.py b/challenge-347/packy-anderson/python/ch-1.py
index d669a661ec..4e6c939861 100755
--- a/challenge-347/packy-anderson/python/ch-1.py
+++ b/challenge-347/packy-anderson/python/ch-1.py
@@ -1,28 +1,77 @@
#!/usr/bin/env python
-def distinctAverages(nums):
- pass
+from datetime import date
+import re
-def int_join(joiner, arr):
- return joiner.join(map(str, arr))
+months = {
+ 'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4, 'May': 5, 'Jun': 6,
+ 'Jul': 7, 'Aug': 8, 'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
+}
-def solution(nums):
- print(f'Input: @nums = ({int_join(", ", nums)})')
- count, explain = distinctAverages(nums)
- print(f'Output: {count}\n\n{explain}')
+def format_date(dstr):
+ day, month, year = dstr.split()
+ m = re.match(r'(\d+)(\D+)', day)
+ dnum = int(m.group(1)) # make sure it's an int
+ dord = m.group(2)
+ if not (
+ ((dnum == 1 or dnum == 21 or dnum == 31) and dord == "st")
+ or
+ ((dnum == 2 or dnum == 22) and dord == "nd")
+ or
+ ((dnum == 3 or dnum == 23) and dord == "rd")
+ or
+ dord == "th"
+ ):
+ return f"{day} has the incorrect ordinal"
+ day = dnum # grab just the numeric portion
+
+ if not month in months:
+ return f"Unknown month '{month}'"
+
+ month = months[month] # convert to numeric
+
+ year = int(year) # make sure it's an int
+ if not (1900 <= year <= 2100):
+ return "Year must be between 1900-2100"
+
+ try:
+ dateobj = date(year, month, day)
+ except ValueError as err:
+ return err
+
+ return f'"#{dateobj.strftime("%Y-%m-%d")}"'
+
+def solution(dstr):
+ print(f'Input: $str = "{dstr}"')
+ print(f'Output: {format_date(dstr)}')
print('Example 1:')
-solution()
+solution("1st Jan 2025")
print('\nExample 2:')
-solution()
+solution("22nd Feb 2025")
print('\nExample 3:')
-solution()
+solution("15th Apr 2025")
print('\nExample 4:')
-solution()
+solution("23rd Oct 2025")
print('\nExample 5:')
-solution()
+solution("31st Dec 2025")
+
+print('\nExample Year Too Big:')
+solution("31st Dec 2525")
+
+print('\nExample Year Too Small:')
+solution("31st Dec 1825")
+
+print('\nExample Bad Ordinal:')
+solution("31nd Dec 2025")
+
+print('\nExample Bad Month:')
+solution("30th Avril 2025")
+
+print('\nExample Bad Date:')
+solution("31st Feb 2025")
diff --git a/challenge-347/packy-anderson/python/ch-2.py b/challenge-347/packy-anderson/python/ch-2.py
index d669a661ec..b835c0f190 100755
--- a/challenge-347/packy-anderson/python/ch-2.py
+++ b/challenge-347/packy-anderson/python/ch-2.py
@@ -1,28 +1,37 @@
#!/usr/bin/env python
-def distinctAverages(nums):
- pass
-
-def int_join(joiner, arr):
- return joiner.join(map(str, arr))
-
-def solution(nums):
- print(f'Input: @nums = ({int_join(", ", nums)})')
- count, explain = distinctAverages(nums)
- print(f'Output: {count}\n\n{explain}')
-
+import re
+
+def format_phone2(phone, formatted):
+ if len(phone) < 4:
+ return formatted + phone
+ elif len(phone) == 4:
+ return formatted + phone[0:2] + "-" + phone[2:4]
+ else:
+ return format_phone2(
+ phone[3:],
+ formatted + phone[0:3] + "-"
+ )
+
+def format_phone(phone):
+ phone = re.sub(r'\D', '', phone)
+ return format_phone2(phone, "")
+
+def solution(phone):
+ print(f'Input: $phone = "{phone}"')
+ print(f'Output: "{format_phone(phone)}"')
print('Example 1:')
-solution()
+solution("1-23-45-6")
print('\nExample 2:')
-solution()
+solution("1234")
print('\nExample 3:')
-solution()
+solution("12 345-6789")
print('\nExample 4:')
-solution()
+solution("123 4567")
print('\nExample 5:')
-solution()
+solution("123 456-78")
diff --git a/challenge-347/packy-anderson/raku/ch-1.raku b/challenge-347/packy-anderson/raku/ch-1.raku
index 53bd47e1a7..76de0214fb 100755
--- a/challenge-347/packy-anderson/raku/ch-1.raku
+++ b/challenge-347/packy-anderson/raku/ch-1.raku
@@ -1,22 +1,72 @@
#!/usr/bin/env raku
use v6;
-sub solution(@arr) {
- say 'Input: @arr = (' ~ @arr.join(', ') ~ ')';
- say 'Output: (' ~ @arr.join(', ') ~ ')';
+my %months = (
+ Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
+ Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12
+);
+
+sub formatDate($str) {
+ my ($day, $month, $year) = $str.split(" ");
+
+ my $m = $day ~~ /(\d+)(\D+)/;
+ return "$day has the incorrect ordinal"
+ unless
+ (($m[0] == 1 || $m[0] == 21 || $m[0] == 31) && $m[1] eq "st")
+ ||
+ (($m[0] == 2 || $m[0] == 22) && $m[1] eq "nd")
+ ||
+ (($m[0] == 3 || $m[0] == 23) && $m[1] eq "rd")
+ ||
+ $m[1] eq "th";
+ $day = $m[0]; # grab just the numeric portion
+
+ return "Unknown month '$month'"
+ unless %months{$month}:exists;
+ $month = %months{$month}; # convert to numeric
+
+ return "Year must be between 1900-2100"
+ unless 1900 <= $year <= 2100;
+
+ my $date;
+ try {
+ $date = Date.new($year, $month, $day);
+ }
+ return $! if $!;
+ return qq/"$date"/;
+}
+
+sub solution($str) {
+ say qq/Input: \$str = "$str"/;
+ say qq/Output: / ~ formatDate($str);
}
say "Example 1:";
-solution();
+solution("1st Jan 2025");
say "\nExample 2:";
-solution();
+solution("22nd Feb 2025");
say "\nExample 3:";
-solution();
+solution("15th Apr 2025");
say "\nExample 4:";
-solution();
+solution("23rd Oct 2025");
say "\nExample 5:";
-solution();
+solution("31st Dec 2025");
+
+say "\nExample Year Too Big:";
+solution("31st Dec 2525");
+
+say "\nExample Year Too Small:";
+solution("31st Dec 1825");
+
+say "\nExample Bad Ordinal:";
+solution("31nd Dec 2025");
+
+say "\nExample Bad Month:";
+solution("30th Avril 2025");
+
+say "\nExample Bad Date:";
+solution("31st Feb 2025");
diff --git a/challenge-347/packy-anderson/raku/ch-2.raku b/challenge-347/packy-anderson/raku/ch-2.raku
index 53bd47e1a7..581d2f97e2 100755
--- a/challenge-347/packy-anderson/raku/ch-2.raku
+++ b/challenge-347/packy-anderson/raku/ch-2.raku
@@ -1,22 +1,42 @@
#!/usr/bin/env raku
use v6;
-sub solution(@arr) {
- say 'Input: @arr = (' ~ @arr.join(', ') ~ ')';
- say 'Output: (' ~ @arr.join(', ') ~ ')';
+multi formatPhone($phone where $phone.chars < 4, $formatted) {
+ $formatted ~ $phone;
+}
+
+multi formatPhone($phone where $phone.chars == 4, $formatted) {
+ $formatted ~ $phone.substr(0..1) ~ "-" ~ $phone.substr(2..3);
+}
+
+multi formatPhone($phone, $formatted) {
+ formatPhone(
+ $phone.substr(3),
+ $formatted ~ $phone.substr(0..2) ~ "-"
+ );
+}
+
+multi formatPhone(Str $phone is copy) {
+ $phone ~~ s:global/\D+//;
+ formatPhone($phone, "");
+}
+
+sub solution($phone) {
+ say qq/Input: \$phone = "$phone"/;
+ say qq/Output: "{formatPhone($phone)}"/;
}
say "Example 1:";
-solution();
+solution("1-23-45-6");
say "\nExample 2:";
-solution();
+solution("1234");
say "\nExample 3:";
-solution();
+solution("12 345-6789");
say "\nExample 4:";
-solution();
+solution("123 4567");
say "\nExample 5:";
-solution();
+solution("123 456-78");