aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo Custodio <pauloscustodio@gmail.com>2021-02-16 22:34:26 +0000
committerPaulo Custodio <pauloscustodio@gmail.com>2021-02-16 22:34:26 +0000
commitf8fb226e2de2fcbed5da6ac21eb54baa76ca935f (patch)
treee9f38143435080162da2a64a77334ab90c393701
parent81d0e649a1806722ae856cbb612716a50824b8f6 (diff)
downloadperlweeklychallenge-club-f8fb226e2de2fcbed5da6ac21eb54baa76ca935f.tar.gz
perlweeklychallenge-club-f8fb226e2de2fcbed5da6ac21eb54baa76ca935f.tar.bz2
perlweeklychallenge-club-f8fb226e2de2fcbed5da6ac21eb54baa76ca935f.zip
Add Forth solution to challenge 100
-rw-r--r--challenge-100/paulo-custodio/forth/ch-1.fs75
-rw-r--r--challenge-100/paulo-custodio/forth/ch-2.fs105
-rw-r--r--challenge-100/paulo-custodio/perl/ch-2.pl7
3 files changed, 184 insertions, 3 deletions
diff --git a/challenge-100/paulo-custodio/forth/ch-1.fs b/challenge-100/paulo-custodio/forth/ch-1.fs
new file mode 100644
index 0000000000..192b0dc2a5
--- /dev/null
+++ b/challenge-100/paulo-custodio/forth/ch-1.fs
@@ -0,0 +1,75 @@
+#! /usr/bin/env gforth
+
+\ TASK #1 > Fun Time
+\ Submitted by: Mohammad S Anwar
+\ You are given a time (12 hour / 24 hour).
+\
+\ Write a script to convert the given time from 12 hour format to 24 hour format and vice versa.
+\
+\ Ideally we expect a one-liner.
+\
+\ Example 1:
+\ Input: 05:15 pm or 05:15pm
+\ Output: 17:15
+\ Example 2:
+\ Input: 19:15
+\ Output: 07:15 pm or 07:15pm
+
+\ skip blanks
+: skip-blanks ( str len -- str len )
+ BEGIN
+ DUP 0= IF EXIT THEN \ string empty
+ OVER C@ BL <> IF EXIT THEN \ not space
+ 1 /STRING
+ AGAIN
+;
+
+\ parse a time string, return number of minutes since midnight
+\ and true if it was in AM/PM format
+: parse-time { str len -- hours minutes f-am-pm }
+ 0 0 { hours minutes }
+ 0 0 str len >NUMBER TO len TO str DROP TO hours \ convert hours
+ str C@ ':' <> IF 1 THROW THEN
+ str len 1 /STRING TO len TO str \ skip ':'
+ 0 0 str len >NUMBER TO len TO str DROP TO minutes \ convert minutes
+ str len skip-blanks TO len TO str \ spaces
+ len 0= IF
+ hours minutes FALSE
+ ELSE str C@ DUP 'a' = SWAP 'A' = OR IF \ AM
+ hours 12 = IF 0 TO hours THEN
+ hours minutes TRUE
+ ELSE str C@ DUP 'p' = SWAP 'P' = OR IF \ PM
+ hours 12 <> IF hours 12 + TO hours THEN
+ hours minutes TRUE
+ THEN THEN THEN
+;
+
+\ output in 24-hour format
+: print24 ( hours minutes -- )
+ SWAP 100 * + 0 \ convert to hhmm in decimal, double
+ <# # # ':' HOLD # # #> TYPE
+;
+
+\ output in 12-hour format
+: print12 { hours minutes -- }
+ FALSE { pm } \ assume AM
+
+ hours DUP 12 > IF
+ DROP hours 12 - TO hours TRUE TO pm ELSE
+ DUP 12 = IF
+ DROP TRUE TO pm ELSE
+ DUP 0= IF
+ DROP 12 TO HOURS
+ ELSE DROP THEN THEN THEN
+
+ hours minutes print24
+ pm IF ." pm" ELSE ." am" THEN
+;
+
+\ convert time
+: convert-time ( str len -- )
+ parse-time IF print24 ELSE print12 THEN
+;
+
+\ main
+NEXT-ARG convert-time CR BYE
diff --git a/challenge-100/paulo-custodio/forth/ch-2.fs b/challenge-100/paulo-custodio/forth/ch-2.fs
new file mode 100644
index 0000000000..35156151a7
--- /dev/null
+++ b/challenge-100/paulo-custodio/forth/ch-2.fs
@@ -0,0 +1,105 @@
+#! /usr/bin/env gforth
+
+\ TASK #2 > Triangle Sum
+\ Submitted by: Mohammad S Anwar
+\ You are given triangle array.
+\
+\ Write a script to find the minimum path sum from top to bottom.
+\
+\ When you are on index i on the current row then you may move to either
+\ index i or index i + 1 on the next row.
+\
+\ Example 1:
+\ Input: Triangle = [ [1], [2,4], [6,4,9], [5,1,7,2] ]
+\ Output: 8
+\
+\ Explanation: The given triangle
+\
+\ 1
+\ 2 4
+\ 6 4 9
+\ 5 1 7 2
+\
+\ The minimum path sum from top to bottom: 1 + 2 + 4 + 1 = 8
+\
+\ [1]
+\ [2] 4
+\ 6 [4] 9
+\ 5 [1] 7 2
+\ Example 2:
+\ Input: Triangle = [ [3], [3,1], [5,2,3], [4,3,1,3] ]
+\ Output: 7
+\
+\ Explanation: The given triangle
+\
+\ 3
+\ 3 1
+\ 5 2 3
+\ 4 3 1 3
+\
+\ The minimum path sum from top to bottom: 3 + 1 + 2 + 1 = 7
+\
+\ [3]
+\ 3 [1]
+\ 5 [2] 3
+\ 4 3 [1] 3
+
+\ create a square to store the triangle
+20 CONSTANT max-height \ maximum height of triangle
+CREATE triangle max-height DUP * CELLS ALLOT
+
+\ get address of value at row,col, 0-based
+: triangle[] ( row col -- addr )
+ SWAP max-height * + CELLS triangle +
+;
+
+\ skip non-digits
+: skip-non-digits ( str len -- str len )
+ BEGIN
+ DUP 0= IF EXIT THEN \ string empty
+ OVER C@ DUP '0' >= SWAP '9' <= AND IF EXIT THEN \ digit
+ 1 /STRING
+ AGAIN
+;
+
+\ store last filled row of triangle
+-1 VALUE last-row
+
+\ parse a list of values from string, store at last-row
+: parse-line ( str len -- )
+ last-row 1+ TO last-row
+ last-row 1+ 0 ?DO
+ skip-non-digits
+ 0 0 2SWAP >NUMBER 2SWAP DROP \ convert one number
+ last-row I triangle[] !
+ LOOP
+ 2DROP
+;
+
+\ parse and store triangle
+: parse-triangle ( -- )
+ -1 TO last-row
+ BEGIN NEXT-ARG DUP 0> WHILE
+ parse-line
+ REPEAT 2DROP
+ last-row 0< THROW
+;
+
+\ compute the minimum sum of a sub-triangle
+: min-sum-1 { sum row col -- min-sum }
+ row col triangle[] @ sum + TO sum
+ row last-row = IF
+ sum
+ ELSE
+ sum row 1+ col RECURSE \ compute left sum
+ sum row 1+ col 1+ RECURSE \ comppute right sum
+ MIN
+ THEN
+;
+
+: min-sum ( -- min-sum )
+ 0 0 0 min-sum-1
+;
+
+\ main
+parse-triangle min-sum . CR BYE
diff --git a/challenge-100/paulo-custodio/perl/ch-2.pl b/challenge-100/paulo-custodio/perl/ch-2.pl
index 03ca506736..a75afbffc8 100644
--- a/challenge-100/paulo-custodio/perl/ch-2.pl
+++ b/challenge-100/paulo-custodio/perl/ch-2.pl
@@ -6,7 +6,8 @@
#
# Write a script to find the minimum path sum from top to bottom.
#
-# When you are on index i on the current row then you may move to either index i or index i + 1 on the next row.
+# When you are on index i on the current row then you may move to either
+# index i or index i + 1 on the next row.
#
# Example 1:
# Input: Triangle = [ [1], [2,4], [6,4,9], [5,1,7,2] ]
@@ -71,11 +72,11 @@ sub min_sum {
sub min_sum_1 {
my($sum, $r, $c, $triangle) = @_;
+ $sum += $triangle->[$r][$c];
if ($r == $#$triangle) { # bottom row
- return $sum + $triangle->[$r][$c];
+ return $sum;
}
else {
- $sum += $triangle->[$r][$c];
my $sum1 = min_sum_1($sum, $r+1, $c, $triangle);
my $sum2 = min_sum_1($sum, $r+1, $c+1, $triangle);
return $sum1<$sum2 ? $sum1 : $sum2;