aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-259/feng-chang/raku/ch-1.raku16
-rwxr-xr-xchallenge-259/feng-chang/raku/ch-2.raku62
-rwxr-xr-xchallenge-259/feng-chang/raku/test.raku20
3 files changed, 98 insertions, 0 deletions
diff --git a/challenge-259/feng-chang/raku/ch-1.raku b/challenge-259/feng-chang/raku/ch-1.raku
new file mode 100755
index 0000000000..4851785d14
--- /dev/null
+++ b/challenge-259/feng-chang/raku/ch-1.raku
@@ -0,0 +1,16 @@
+#!/bin/env raku
+
+subset DateStr of Str where *.Date;
+
+unit sub MAIN(DateStr:D $start, UInt:D $offset is copy, *@bank-holidays);
+
+my $day = $start.Date;
+
+while $offset {
+ ++$day;
+ next if $day.day-of-week == 6|7;
+ next if ~$day (elem) @bank-holidays;
+ --$offset;
+}
+
+put $day;
diff --git a/challenge-259/feng-chang/raku/ch-2.raku b/challenge-259/feng-chang/raku/ch-2.raku
new file mode 100755
index 0000000000..c8d7a15ee6
--- /dev/null
+++ b/challenge-259/feng-chang/raku/ch-2.raku
@@ -0,0 +1,62 @@
+#!/bin/env raku
+
+grammar Line {
+ rule TOP { '{%' <Name> <Field>* '%}' [<Text> '{%' 'endid' '%}']? }
+ token Name { \w+ }
+ rule Field { <Name> '=' <Value> }
+ rule Value { \d+ || '"' <Chars> '"' }
+ token Chars { ["\\\\" | '\"' | <-["]>]+ }
+ rule Text { .+? }
+}
+
+class LineActions {
+ method TOP($/) {
+ make (
+ :name($<Name>.made),
+ :fields(($<Field>ยป.made).Hash),
+ (:text($<Text>.made) with $<Text>)
+ ).Hash
+ }
+ method Name($/) { make ~$/ }
+ method Field($/) { make $<Name>.made => $<Value>.made }
+ method Value($/) {
+ with $<Chars> {
+ make $<Chars>.made
+ } else {
+ make +$/
+ }
+ }
+ method Chars($/) { make ~$/ }
+ method Text($/) { make (~$/).trim }
+}
+
+multi sub MAIN('test') {
+ use Test;
+
+ is Line.parse('abc', :rule<Chars>, :actions(LineActions)).made, 'abc', '"abc" parsed as Chars';
+ is Line.parse('ab c ', :rule<Chars>, :actions(LineActions)).made, 'ab c ', '"ab c " parsed as Chars';
+ is Line.parse('ab \"c ', :rule<Chars>, :actions(LineActions)).made, 'ab \"c ', '"ab \"c " parsed as Chars';
+
+ is-deeply Line.parse('{% id field1="value1" field2="value2" field3=42 %}', :actions(LineActions)).made,
+ (:name("id"), :fields((:field1("value1"), :field2("value2"), :field3(42)).Hash)).Hash,
+ q/{% id field1="value1" field2="value2" field3=42 %} => {name => id, fields => {field1 => value1, field2 => value2, field3 => 42}}/;
+
+ is-deeply Line.parse('{% youtube title="Title \"quoted\" done" %}', :actions(LineActions)).made,
+ (:name("youtube"), :fields((:title("Title \\\"quoted\\\" done")).Hash)).Hash,
+ q/{% youtube title="Title \"quoted\" done" %} => {name => youtube, fields => {title => Title \"quoted\" done}}/;
+
+ my $s = q:to/END/;
+ {% id field1="value1" field2="value2" %}
+ LINES
+ {% endid %}
+ END
+ is-deeply Line.parse($s, :actions(LineActions)).made,
+ (:name("id"), :fields((:field1("value1"), :field2("value2")).Hash), :text("LINES")).Hash,
+ "... => \{name => id, fields => \{field1 => value1, field2 => value2\}, text => LINES\}";
+
+ done-testing;
+}
+
+multi sub MAIN(Str:D $line) {
+ put Line.parse($line, :actions(LineActions)).made.gist;
+}
diff --git a/challenge-259/feng-chang/raku/test.raku b/challenge-259/feng-chang/raku/test.raku
new file mode 100755
index 0000000000..ca696e666e
--- /dev/null
+++ b/challenge-259/feng-chang/raku/test.raku
@@ -0,0 +1,20 @@
+#!/bin/env raku
+
+# The Weekly Challenge 259
+use Test;
+
+sub pwc-test(Str:D $script, Bool :$deeply? = False, *@input) {
+ my ($expect, $assertion) = @input.splice(*-2, 2);
+ my $p = run $script, |@input, :out;
+ if $deeply {
+ is-deeply $p.out.slurp(:close).chomp.words.Bag, $expect, $assertion;
+ } else {
+ is $p.out.slurp(:close).chomp, $expect, $assertion;
+ }
+}
+
+# Task 1, Banking Day Offset
+pwc-test './ch-1.raku', '2018-06-28', 3, <2018-07-03>, '2018-07-04',
+ 'Banking Day Offset: $start_date = "2018-06-28", $offset = 3, $bank_holidays = ["2018-07-03"] => "2018-07-04"';
+pwc-test './ch-1.raku', '2018-06-28', 3, '2018-07-03',
+ 'Banking Day Offset: $start_date = "2018-06-28", $offset = 3 => "2018-07-03"';