From 4a4bec6384f4ebabb33c70fd43f40b3894ce1bad Mon Sep 17 00:00:00 2001 From: Jan Krňávek Date: Sun, 10 Mar 2024 22:48:35 +0100 Subject: solutions week 259 --- challenge-259/wambash/raku/ch-1.raku | 20 ++++++++++ challenge-259/wambash/raku/ch-2.raku | 72 ++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 challenge-259/wambash/raku/ch-1.raku create mode 100644 challenge-259/wambash/raku/ch-2.raku diff --git a/challenge-259/wambash/raku/ch-1.raku b/challenge-259/wambash/raku/ch-1.raku new file mode 100644 index 0000000000..8daddb66b0 --- /dev/null +++ b/challenge-259/wambash/raku/ch-1.raku @@ -0,0 +1,20 @@ +#!/usr/bin/env raku + +sub banking-day-offset (Date() $start-day,+bank-holidays,:$offset) { + $start-day, *.later(:1day) ... * + andthen .grep: *.day-of-week != 6|7 + andthen .grep: { $_ ∉ bank-holidays }\ + andthen .skip: $offset + andthen .head +} + +multi MAIN (Bool :test($)!) { + use Test; + is banking-day-offset('2018-06-28'.Date, <2018-07-03>».Date):3offset, '2018-07-04'.Date; + is banking-day-offset('2018-06-28'.Date, ):3offset, '2018-07-03'.Date; + done-testing; +} + +multi MAIN ($start-day,+bank-holidays,:$offset) { + say banking-day-offset $start-day, bank-holidays».Date,:$offset +} diff --git a/challenge-259/wambash/raku/ch-2.raku b/challenge-259/wambash/raku/ch-2.raku new file mode 100644 index 0000000000..42b4d64930 --- /dev/null +++ b/challenge-259/wambash/raku/ch-2.raku @@ -0,0 +1,72 @@ +#!/usr/bin/env raku + +grammar LineParser { + rule TOP { <.ws> [ {} )>]? } + + rule tag { '{%' ~ '%}' [ *] } + + token id { \w+ } + rule field { '=' } + token name { \w+ } + token value { \d+ | '"' ~ '"' } #" + token value-string { [<-["]> | '\"' | '\\']* } + + token lines { [.]* } + rule endtag($id) { '{%' ~ '%}' ['end'$id] } +} + +class LineAction { + method TOP ($/) { make %(|$.made, |$.made ) } + method tag ($/) { make %( name => ~$, fields => %( $».made ) ) } + method field ($/) { make ~$ => $.made } + method value ($/) { make $.made // +$/ } + method value-string ($/) { make ~$/ } + method lines ($/) { make (text => ~$/.trim) } +} + +sub line-parser ($string) { + LineParser.parse( $string, actions => LineAction.new) + andthen .made +} + +multi MAIN (Bool :test($)!) { + use Test; + + is LineParser.parse( 'field1 = "value1"', :rule)., 'field1'; + is LineParser.parse( 'field1="value1"', :rule)., 'value1'; + is LineParser.parse( 'field1 = 12', :rule)., 12; + is LineParser.parse('\"quoted\"', :rule ), '\"quoted\"'; + is LineParser.parse('Title \"quoted\" done', :rule ).so, True; + is LineParser.parse('abab {a', :rule ).so, True; + is LineParser.parse('abab {%', :rule ).so, False; + is LineParser.parse('{% endid %}',:rule,:args('id',) ).so, True; + is LineParser.parse('{% id %} Text {% endid %}', )., 'Text '; + is LineParser.parse('{% tag %} Text {% endtag %}', )., 'tag'; + is LineParser.parse('{% id field1="value1" field2="value2" field3=42 %}')», + ; + is LineParser.parse('{% youtube title="Title \"quoted\" done" %}'), 'youtube'; + + is-deeply LineParser.parse( 'field1 = "value1"', :rule, actions => LineAction.new).made, (field1 => 'value1'); + is-deeply LineParser.parse( 'field1 = 12', :rule, actions => LineAction.new).made, (field1 => 12); + + my %parsed := %( + name => 'id', + fields => { + field1 => 'value1', + field2 => 'value2', + field3 => 42, + }, + text => 'LINES' + ); + is-deeply line-parser('{% id t=1 tit="a" %} Text {% endid %}'), %(:fields(%(:t(1), :tit("a"))), :name("id"), :text("Text")); + is-deeply line-parser(' + {% id field1="value1" field2="value2" field3=42 %} + LINES + {% endid %} + '), %parsed; + done-testing; +} + +multi MAIN ($string) { + say line-parser $string +} -- cgit