aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad Sajid Anwar <Mohammad.Anwar@yahoo.com>2024-03-05 12:11:48 +0000
committerGitHub <noreply@github.com>2024-03-05 12:11:48 +0000
commit152e8a0cc895f66aed5db82c00e89ed7b2272038 (patch)
treedda6f6d86bb02dd3cd28c4dd48d84407d266874d
parent5135ca89f43ed6d20f4414d28507a68980de1a82 (diff)
parente921f528bf55574f74fcf6e4ded3419bdb5ddd22 (diff)
downloadperlweeklychallenge-club-152e8a0cc895f66aed5db82c00e89ed7b2272038.tar.gz
perlweeklychallenge-club-152e8a0cc895f66aed5db82c00e89ed7b2272038.tar.bz2
perlweeklychallenge-club-152e8a0cc895f66aed5db82c00e89ed7b2272038.zip
Merge pull request #9698 from Firedrake/rogerbw-challenge-259
RogerBW solutions for challenge no. 259
-rwxr-xr-xchallenge-259/roger-bell-west/javascript/ch-1.js30
-rw-r--r--challenge-259/roger-bell-west/kotlin/ch-1.kt32
-rwxr-xr-xchallenge-259/roger-bell-west/perl/ch-1.pl30
-rw-r--r--challenge-259/roger-bell-west/postscript/ch-1.ps200
-rwxr-xr-xchallenge-259/roger-bell-west/python/ch-1.py25
-rwxr-xr-xchallenge-259/roger-bell-west/raku/ch-1.p625
-rwxr-xr-xchallenge-259/roger-bell-west/ruby/ch-1.rb34
-rwxr-xr-xchallenge-259/roger-bell-west/rust/ch-1.rs41
-rwxr-xr-xchallenge-259/roger-bell-west/rust/ch-2.rs123
-rw-r--r--challenge-259/roger-bell-west/scala/ch-1.scala32
-rw-r--r--challenge-259/roger-bell-west/tests.yaml15
11 files changed, 587 insertions, 0 deletions
diff --git a/challenge-259/roger-bell-west/javascript/ch-1.js b/challenge-259/roger-bell-west/javascript/ch-1.js
new file mode 100755
index 0000000000..903fd4e349
--- /dev/null
+++ b/challenge-259/roger-bell-west/javascript/ch-1.js
@@ -0,0 +1,30 @@
+#! /usr/bin/node
+
+"use strict"
+
+function bankingdayoffset(start, offset, bankholidays) {
+ let bh = new Set(bankholidays.map(x => new Date(Date.parse(x)).toString()));
+ let d = new Date(Date.parse(start));
+ for (let i = 1; i <= offset; i++) {
+ d.setDate(d.getDate() + 1);
+ while (bh.has(d.toString()) || d.getDay() == 0 || d.getDay() == 6) {
+ d.setDate(d.getDate() + 1);
+ }
+ }
+ return d.getFullYear().toString().padStart(4, "0") + "-" +
+ (d.getMonth()+1).toString().padStart(2, "0") + "-" +
+ d.getDate().toString().padStart(2, "0");
+}
+
+if (bankingdayoffset('2018-06-28', 3, ['2018-07-03']) == '2018-07-04') {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write(" ");
+if (bankingdayoffset('2018-06-28', 3, []) == '2018-07-03') {
+ process.stdout.write("Pass");
+} else {
+ process.stdout.write("FAIL");
+}
+process.stdout.write("\n");
diff --git a/challenge-259/roger-bell-west/kotlin/ch-1.kt b/challenge-259/roger-bell-west/kotlin/ch-1.kt
new file mode 100644
index 0000000000..9b7cfb52aa
--- /dev/null
+++ b/challenge-259/roger-bell-west/kotlin/ch-1.kt
@@ -0,0 +1,32 @@
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+fun bankingdayoffset(start: String, offset: Int, bankholidays: List<String>): String {
+ val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
+ val bh = bankholidays.map {LocalDate.parse(it, formatter)}.toSet()
+ var current = LocalDate.parse(start, formatter)
+ for (i in 1 .. offset) {
+ current = current.plusDays(1)
+ while (bh.contains(current) || current.getDayOfWeek().getValue() > 5) {
+ current = current.plusDays(1)
+ }
+ }
+ return current.format(formatter)
+}
+
+fun main() {
+
+ if (bankingdayoffset("2018-06-28", 3, listOf("2018-07-03")) == "2018-07-04") {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (bankingdayoffset("2018-06-28", 3, emptyList<String>()) == "2018-07-03") {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+}
diff --git a/challenge-259/roger-bell-west/perl/ch-1.pl b/challenge-259/roger-bell-west/perl/ch-1.pl
new file mode 100755
index 0000000000..ccaf86c903
--- /dev/null
+++ b/challenge-259/roger-bell-west/perl/ch-1.pl
@@ -0,0 +1,30 @@
+#! /usr/bin/perl
+
+use strict;
+use warnings;
+use experimental 'signatures';
+
+use Test::More tests => 2;
+
+is(bankingdayoffset('2018-06-28', 3, ['2018-07-03']), '2018-07-04', 'example 1');
+is(bankingdayoffset('2018-06-28', 3, []), '2018-07-03', 'example 2');
+
+use DateTime;
+use DateTime::Format::Strptime;
+
+sub bankingdayoffset($start, $offset, $bankholidays) {
+ my $strp = DateTime::Format::Strptime->new(
+ pattern => '%Y-%m-%d',
+ strict => 1,
+ time_zone => 'GMT',
+ );
+ my %bh = map {$strp->parse_datetime($_) => 1} @{$bankholidays};
+ my $current = $strp->parse_datetime($start);
+ foreach (1 .. $offset) {
+ $current = $current->add(days => 1);
+ while (exists $bh{$current} || $current->day_of_week > 5) {
+ $current = $current->add(days => 1);
+ }
+ }
+ return $current->strftime('%Y-%m-%d');
+}
diff --git a/challenge-259/roger-bell-west/postscript/ch-1.ps b/challenge-259/roger-bell-west/postscript/ch-1.ps
new file mode 100644
index 0000000000..6e2e31189f
--- /dev/null
+++ b/challenge-259/roger-bell-west/postscript/ch-1.ps
@@ -0,0 +1,200 @@
+%!PS
+
+% begin included library code
+% see https://codeberg.org/Firedrake/postscript-libraries/
+/test {
+ /test.count test.count 1 add def
+ {
+ /test.pass test.pass 1 add def
+ } {
+ ( ) print
+ test.count (....) cvs print
+ (-fail) print
+ } ifelse
+} bind def
+
+/jd2ymd {
+ 15 dict begin
+ /y 4716 def
+ /v 3 def
+ /j 1401 def
+ /u 5 def
+ /m 2 def
+ /s 153 def
+ /n 12 def
+ /w 2 def
+ /r 4 def
+ /B 274277 def
+ /p 1461 def
+ /C -38 def
+ dup
+ 4 mul B add 146097 idiv 3 mul 4 idiv C add j add add /f exch def
+ r f mul v add /e exch def
+ e p mod r idiv u mul w add /h exch def
+ /day h s mod u idiv 1 add def
+ /month h s idiv m add n mod 1 add def
+ /year e p idiv y sub n m add month sub n idiv add def
+ [ year month day ]
+ end
+} bind def
+
+/map { % array proc -> array
+ 2 dict begin
+ /p exch def
+ [ exch
+ {
+ p
+ } forall
+ ]
+ end
+} bind def
+
+/toset { % array -> dict of (value, true)
+ << exch
+ {
+ true
+ } forall
+ >>
+} bind def
+
+/test.end {
+ ( ) print
+ test.count 0 gt {
+ (Passed ) print
+ test.pass (...) cvs print
+ (/) print
+ test.count (...) cvs print
+ ( \() print
+ test.pass 100 mul test.count idiv (...) cvs print
+ (%\)) print
+ (\r\n) print
+ } if
+} bind def
+
+/strjoin % [(a) (b) (c)] (j) -> (ajbjc)
+{
+ 3 dict begin
+ /j exch def
+ dup 0 get /out exch def
+ /first true def
+ {
+ first {
+ pop
+ /first false def
+ } {
+ out j strconcat
+ exch strconcat
+ /out exch def
+ } ifelse
+ } forall
+ out
+ end
+} bind def
+
+/a2s {
+ 2 dict begin
+ /i exch def
+ i length dup string /o exch def
+ 1 sub 0 exch 1 exch {
+ dup i 3 -1 roll get o 3 1 roll put
+ } for
+ o
+ end
+} bind def
+
+
+/test.start {
+ print (:) print
+ /test.pass 0 def
+ /test.count 0 def
+} bind def
+
+/s2a {
+ [ exch { } forall ]
+} bind def
+
+/ymd2jd {
+ 4 dict begin
+ aload pop
+ /d exch def
+ /m exch def
+ /y exch def
+ /mn m 14 sub 12 idiv def
+ y 4800 add mn add 1461 mul 4 idiv
+ mn 12 mul neg 2 sub m add 367 mul 12 idiv add
+ y 4900 add mn add 100 idiv 3 mul 4 idiv sub
+ d add
+ 32075 sub
+ end
+} bind def
+
+/jd2dow {
+ 1 add 7 mod
+} bind def
+
+/strconcat % (a) (b) -> (ab)
+{
+ [
+ 3 -1 roll
+ s2a aload length
+ 2 add -1 roll
+ s2a aload pop
+ ] a2s
+} bind def
+
+
+% end included library code
+
+/s2jd {
+ 0 dict begin
+ /s exch def
+ [ exch
+ s 0 4 getinterval cvi
+ s 5 2 getinterval cvi
+ s 8 2 getinterval cvi
+ ] ymd2jd
+ end
+} bind def
+
+/flz {
+ 0 dict begin
+ /width exch def
+ /value exch def
+ value type /stringtype ne {
+ /value value width string cvs def
+ } if
+ /out [ width { 48 } repeat ] a2s def
+ out width value length sub value putinterval
+ out
+ end
+} bind def
+
+/bankingdayoffset {
+ 0 dict begin
+ /bh exch { s2jd } map toset def
+ /offset exch def
+ /d exch s2jd def
+ offset {
+ /d d 1 add def
+ {
+ d jd2dow dup
+ 0 gt exch 6 lt and
+ bh d known not and {
+ exit
+ } if
+ /d d 1 add def
+ } loop
+ } repeat
+ [
+ d jd2ymd aload pop
+ 2 flz 3 1 roll
+ 2 flz 3 1 roll
+ 4 flz 3 1 roll
+ ] (-) strjoin
+ end
+} bind def
+
+(bankingdayoffset) test.start
+(2018-06-28) 3 [(2018-07-03)] bankingdayoffset (2018-07-04) eq test
+(2018-06-28) 3 [] bankingdayoffset (2018-07-03) eq test
+test.end
diff --git a/challenge-259/roger-bell-west/python/ch-1.py b/challenge-259/roger-bell-west/python/ch-1.py
new file mode 100755
index 0000000000..fef13ed084
--- /dev/null
+++ b/challenge-259/roger-bell-west/python/ch-1.py
@@ -0,0 +1,25 @@
+#! /usr/bin/python3
+
+from datetime import date, timedelta
+
+def bankingdayoffset(start, offset, bankholidays):
+ bh = set(date.fromisoformat(i) for i in bankholidays)
+ d = date.fromisoformat(start)
+ day = timedelta(days = 1)
+ for _ in range(offset):
+ d += day
+ while d in bh or d.weekday() > 4:
+ d += day
+ return d.strftime("%Y-%m-%d")
+
+import unittest
+
+class TestBankingdayoffset(unittest.TestCase):
+
+ def test_ex1(self):
+ self.assertEqual(bankingdayoffset("2018-06-28", 3, ["2018-07-03"]), "2018-07-04", 'example 1')
+
+ def test_ex2(self):
+ self.assertEqual(bankingdayoffset("2018-06-28", 3, []), "2018-07-03", 'example 2')
+
+unittest.main()
diff --git a/challenge-259/roger-bell-west/raku/ch-1.p6 b/challenge-259/roger-bell-west/raku/ch-1.p6
new file mode 100755
index 0000000000..f95a7cd92c
--- /dev/null
+++ b/challenge-259/roger-bell-west/raku/ch-1.p6
@@ -0,0 +1,25 @@
+#! /usr/bin/raku
+
+use Test;
+
+plan 2;
+
+is(bankingdayoffset('2018-06-28', 3, ['2018-07-03']), '2018-07-04', 'example 1');
+is(bankingdayoffset('2018-06-28', 3, []), '2018-07-03', 'example 2');
+
+sub parsedate($s) {
+ $s ~~ /(<[0..9]>+)\D(<[0..9]>+)\D(<[0..9]>+)/;
+ return Date.new($0, $1, $2);
+}
+
+sub bankingdayoffset($start, $offset, @bankholidays) {
+ my $bh = Set(@bankholidays.map({parsedate($_)}));
+ my $current = parsedate($start);
+ for (1 .. $offset) {
+ $current = $current.later(days => 1);
+ while ($bh{$current}:exists || $current.day-of-week > 5) {
+ $current = $current.later(days => 1);
+ }
+ }
+ return $current.yyyy-mm-dd;
+}
diff --git a/challenge-259/roger-bell-west/ruby/ch-1.rb b/challenge-259/roger-bell-west/ruby/ch-1.rb
new file mode 100755
index 0000000000..4ea9277f76
--- /dev/null
+++ b/challenge-259/roger-bell-west/ruby/ch-1.rb
@@ -0,0 +1,34 @@
+#! /usr/bin/ruby
+
+require 'set'
+require 'time'
+
+def parsedate(s)
+ return Time.strptime(s + " 12:00 +0000", '%Y-%m-%d %H:%M %z')
+end
+
+def bankingdayoffset(start, offset, bankholidays)
+ bh = Set.new(bankholidays.map {|d| parsedate(d)})
+ s = parsedate(start)
+ 1.upto(offset) do
+ s += 86400
+ while bh.include?(s) || s.wday == 0 || s.wday == 6 do
+ s += 86400
+ end
+ end
+ return s.strftime('%Y-%m-%d')
+end
+
+require 'test/unit'
+
+class TestBankingdayoffset < Test::Unit::TestCase
+
+ def test_ex1
+ assert_equal('2018-07-04', bankingdayoffset('2018-06-28', 3, ['2018-07-03']))
+ end
+
+ def test_ex2
+ assert_equal('2018-07-03', bankingdayoffset('2018-06-28', 3, []))
+ end
+
+end
diff --git a/challenge-259/roger-bell-west/rust/ch-1.rs b/challenge-259/roger-bell-west/rust/ch-1.rs
new file mode 100755
index 0000000000..38598b9589
--- /dev/null
+++ b/challenge-259/roger-bell-west/rust/ch-1.rs
@@ -0,0 +1,41 @@
+// [dependencies]
+// chrono = "0.4.34"
+
+use chrono::{Datelike, NaiveDate};
+use std::collections::HashSet;
+
+#[test]
+fn test_ex1() {
+ assert_eq!(
+ bankingdayoffset("2018-06-28", 3, vec!["2018-07-03"]),
+ "2018-07-04"
+ );
+}
+
+#[test]
+fn test_ex2() {
+ assert_eq!(
+ bankingdayoffset("2018-06-28", 3, Vec::<&str>::new()),
+ "2018-07-03"
+ );
+}
+
+fn parsedate(s: &str) -> NaiveDate {
+ NaiveDate::parse_from_str(s, "%Y-%m-%d").unwrap()
+}
+
+fn bankingdayoffset(
+ start: &str,
+ offset: u32,
+ bankholidays: Vec<&str>,
+) -> String {
+ let bh = bankholidays.iter().map(|i| parsedate(i)).collect::<HashSet<_>>();
+ let mut d = parsedate(start);
+ for _ in 0..offset {
+ d = d.succ_opt().unwrap();
+ while bh.contains(&d) || d.weekday().num_days_from_monday() > 4 {
+ d = d.succ_opt().unwrap();
+ }
+ }
+ d.format("%Y-%m-%d").to_string()
+}
diff --git a/challenge-259/roger-bell-west/rust/ch-2.rs b/challenge-259/roger-bell-west/rust/ch-2.rs
new file mode 100755
index 0000000000..70a0124249
--- /dev/null
+++ b/challenge-259/roger-bell-west/rust/ch-2.rs
@@ -0,0 +1,123 @@
+#! /bin/sh
+//usr/bin/env rustc --test $0 -o ${0}x && ./${0}x --nocapture; rm -f ${0}x ; exit
+
+use std::collections::{HashMap, VecDeque};
+
+#[derive(PartialEq, Debug)]
+pub struct Lump {
+ id: String,
+ fields: HashMap<String, String>,
+}
+
+#[test]
+fn test_ex1() {
+ assert_eq!(
+ lineparser(
+ "{% id field1=\"value1\" field2=\"value2\" field3=42 %}"
+ ),
+ Lump {
+ id: "id".to_string(),
+ fields: HashMap::from([
+ ("field3".to_string(), "42".to_string()),
+ ("field2".to_string(), "value2".to_string()),
+ ("field1".to_string(), "value1".to_string())
+ ])
+ }
+ );
+}
+
+#[test]
+fn test_ex2() {
+ assert_eq!(
+ lineparser("{% youtube title=\"Title \\\"quoted\\\" done\" %}"),
+ Lump {
+ id: "youtube".to_string(),
+ fields: HashMap::from([(
+ "title".to_string(),
+ "Title \"quoted\" done".to_string()
+ )])
+ }
+ );
+}
+
+#[test]
+fn test_ex3() {
+ assert_eq!(
+ lineparser(
+ "{% youtube title=\"Title with escaped backslash \\\\\" %}"
+ ),
+ Lump {
+ id: "youtube".to_string(),
+ fields: HashMap::from([(
+ "title".to_string(),
+ "Title with escaped backslash \\".to_string()
+ )])
+ }
+ );
+}
+
+#[derive(PartialEq, Debug)]
+enum State {
+ Outside,
+ PreID,
+ InID,
+ InterField,
+ FieldName,
+ FieldValue,
+ FieldValueQuoted,
+}
+
+fn lineparser(line: &str) -> Lump {
+ let mut l = line.chars().collect::<VecDeque<_>>();
+ let mut state = State::Outside;
+ let mut trail: Vec<char> = Vec::new();
+ let mut fieldname = "".to_string();
+ let mut out = Lump { id: "".to_string(), fields: HashMap::new() };
+ while l.len() > 0 {
+ let mut c = l.pop_front().unwrap();
+ if state == State::Outside && c == '{' {
+ c = l.pop_front().unwrap();
+ if c == '%' {
+ state = State::PreID;
+ }
+ } else if (state == State::PreID || state == State::InID) && c != ' ' {
+ trail.push(c);
+ state = State::InID;
+ } else if state == State::InID && c == ' ' {
+ out.id = trail.into_iter().collect();
+ trail = Vec::new();
+ state = State::InterField;
+ } else if (state == State::InterField || state == State::FieldName)
+ && c != ' '
+ && c != '='
+ && c != '%'
+ {
+ trail.push(c);
+ state = State::FieldName;
+ } else if state == State::FieldName && c == '=' {
+ fieldname = trail.into_iter().collect();
+ trail = Vec::new();
+ state = State::FieldValue;
+ } else if state == State::FieldValue && trail.len() == 0 && c == '"' {
+ state = State::FieldValueQuoted;
+ } else if state == State::FieldValue || state == State::FieldValueQuoted
+ {
+ let mut literal = false;
+ if c == '\\' {
+ c = l.pop_front().unwrap();
+ literal = true;
+ }
+ if (c == ' ' && state == State::FieldValue)
+ || (c == '"' && state == State::FieldValueQuoted && !literal)
+ {
+ out.fields
+ .insert(fieldname.clone(), trail.into_iter().collect());
+ trail = Vec::new();
+ state = State::InterField;
+ } else {
+ trail.push(c);
+ }
+ }
+ }
+ out
+}
diff --git a/challenge-259/roger-bell-west/scala/ch-1.scala b/challenge-259/roger-bell-west/scala/ch-1.scala
new file mode 100644
index 0000000000..6e5b2e3f52
--- /dev/null
+++ b/challenge-259/roger-bell-west/scala/ch-1.scala
@@ -0,0 +1,32 @@
+import java.time.LocalDate
+import java.time.format.DateTimeFormatter
+
+object Bankingdayoffset {
+ def bankingdayoffset(start: String, offset: Int, bankholidays: List[String]): String = {
+ val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
+ val bh = bankholidays.map(d => LocalDate.parse(d, formatter)).toSet
+ var current = LocalDate.parse(start, formatter)
+ for (i <- 1 to offset) {
+ current = current.plusDays(1)
+ while (bh.contains(current) || current.getDayOfWeek().getValue() > 5) {
+ current = current.plusDays(1)
+ }
+ }
+ return current.format(formatter)
+ }
+ def main(args: Array[String]) {
+ if (bankingdayoffset("2018-06-28", 3, List("2018-07-03")) == "2018-07-04") {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ print(" ")
+ if (bankingdayoffset("2018-06-28", 3, List()) == "2018-07-03") {
+ print("Pass")
+ } else {
+ print("Fail")
+ }
+ println("")
+
+ }
+}
diff --git a/challenge-259/roger-bell-west/tests.yaml b/challenge-259/roger-bell-west/tests.yaml
new file mode 100644
index 0000000000..3bc7c11499
--- /dev/null
+++ b/challenge-259/roger-bell-west/tests.yaml
@@ -0,0 +1,15 @@
+---
+ch-1:
+ - function: bankingdayoffset
+ multiarg: true
+ arguments:
+ - 2018-06-28
+ - 3
+ - - 2018-07-03
+ result: 2018-07-04
+ - multiarg: true
+ arguments:
+ - 2018-06-28
+ - 3
+ - []
+ result: 2018-07-03