aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--challenge-259/zapwai/c/259.txt8
-rw-r--r--challenge-259/zapwai/c/ch-1.c123
-rw-r--r--challenge-259/zapwai/c/ch-2.c140
-rw-r--r--challenge-259/zapwai/javascript/ch-1.js134
-rw-r--r--challenge-259/zapwai/javascript/ch-2.js100
-rw-r--r--challenge-259/zapwai/perl/ch-1.pl65
-rw-r--r--challenge-259/zapwai/perl/ch-2.pl67
-rw-r--r--challenge-259/zapwai/python/ch-1.py72
-rw-r--r--challenge-259/zapwai/python/ch-2.py38
-rw-r--r--challenge-259/zapwai/rust/259.txt8
-rw-r--r--challenge-259/zapwai/rust/ch-1.rs111
-rw-r--r--challenge-259/zapwai/rust/ch-2.rs106
12 files changed, 972 insertions, 0 deletions
diff --git a/challenge-259/zapwai/c/259.txt b/challenge-259/zapwai/c/259.txt
new file mode 100644
index 0000000000..76fdb9009f
--- /dev/null
+++ b/challenge-259/zapwai/c/259.txt
@@ -0,0 +1,8 @@
+{% id field1="value1" field2="value2" field3=42 %}
+{% youtube title="Title \"quoted\" done" foo="bar" baz=31 %}
+{% youtube title="Title with escaped backslash \\" %}
+{% id field="val1" field2="val2" %}
+{% test field1="value1" df=42 %}
+LINES
+More Lines
+{% endtest %}
diff --git a/challenge-259/zapwai/c/ch-1.c b/challenge-259/zapwai/c/ch-1.c
new file mode 100644
index 0000000000..3d48cfb348
--- /dev/null
+++ b/challenge-259/zapwai/c/ch-1.c
@@ -0,0 +1,123 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+int base_year = 2000;
+int days_in_month[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+char* days[7] = {"sat", "sun", "mon", "tue", "wed", "thu", "fri"};
+
+bool is_leap_year(int year) {
+ if (year % 400 == 0)
+ return true;
+ if (year % 100 == 0)
+ return false;
+ if (year % 4 == 0)
+ return true;
+ return false;
+}
+
+char* weekday(int year,int month,int day) {
+ int skip_days = year - base_year;
+ for (int yr = base_year; yr < year; yr++)
+ if (is_leap_year(yr))
+ skip_days++;
+ if (is_leap_year(year) && month > 2)
+ skip_days++;
+ for (int m = 1; m < 13; m++)
+ if (m < month)
+ skip_days += days_in_month[m-1];
+ skip_days += day - 1;
+ return days[skip_days % 7];
+}
+
+bool is_weekend(int year,int month,int day) {
+ char* today = weekday(year, month, day);
+ if ((0 == strcmp(today, "sat")) || (0 == strcmp(today, "sun")))
+ return true;
+ return false;
+}
+
+char* format_date(int year,int month,int day) {
+ char *buf = malloc(11*sizeof(char));
+ char m[3];
+ char d[3];
+ sprintf(m, "%02d", month);
+ sprintf(d, "%02d", day);
+ sprintf(buf, "%d-%s-%s", year, m, d);
+ return buf;
+}
+
+int* parse_date(char* date) {
+ char y[5];
+ char m[3];
+ char d[3];
+ for (int i = 0; i < 4; i++)
+ y[i] = date[i];
+ y[4] = '\0';
+ for (int i = 0; i < 2; i++)
+ m[i] = date[i+5];
+ m[2] = '\0';
+ for (int i = 0; i < 2; i++)
+ d[i] = date[i+8];
+ d[2] = '\0';
+
+ int year = atoi(y);
+ int month = atoi(m);
+ int day = atoi(d);
+ int* result = malloc(3*sizeof(int));
+ result[0] = year;
+ result[1] = month;
+ result[2] = day;
+ return result;
+}
+
+bool is_holiday(char* bank_holidays[], int bank_holidays_length, int year, int month, int day) {
+ char* date = format_date(year, month, day);
+ for (int i = 0; i < bank_holidays_length; i++)
+ if (strcmp(bank_holidays[i], date) == 0) {
+ free(date);
+ return true;
+ }
+ free(date);
+ return false;
+}
+
+void proc(char* start_date, int offset, char* bank_holidays[], int bank_holidays_length) {
+ int* result = parse_date(start_date);
+ int year = result[0];
+ int month = result[1];
+ int day = result[2];
+ free(result);
+ int new_year = year;
+ int new_month = month;
+ int new_day = day;
+ int steps = offset;
+ while (steps > 0) {
+ int leap = (is_leap_year(new_year) && new_month == 2) ? 1 : 0;
+ if (new_day + 1 > leap + days_in_month[new_month - 1]) {
+ if (new_month == 12)
+ new_year++;
+ new_month++;
+ if (new_month == 13)
+ new_month = 1;
+ new_day = 1;
+ } else
+ new_day++;
+ if ( (is_holiday(bank_holidays, bank_holidays_length, new_year, new_month, new_day) != 1) && (is_weekend(new_year, new_month, new_day) != 1)) steps--;
+ }
+
+ char* new_date = format_date(new_year, new_month, new_day);
+ printf("Input: start: %s, offset: %d, holidays: ", start_date, offset);
+ for (int i = 0; i < bank_holidays_length; i++)
+ printf("%s ", bank_holidays[i]);
+ printf("\nOutput: %s\n",new_date);
+}
+
+int main() {
+ char* start_date = "2018-06-28";
+ int offset = 3;
+ char* bank_holiday1 = "2018-07-03";
+ char* bank_holidays[] = {bank_holiday1};
+
+ proc(start_date, offset, bank_holidays, 1);
+}
diff --git a/challenge-259/zapwai/c/ch-2.c b/challenge-259/zapwai/c/ch-2.c
new file mode 100644
index 0000000000..ab45919788
--- /dev/null
+++ b/challenge-259/zapwai/c/ch-2.c
@@ -0,0 +1,140 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define max_length 200
+#define rows_in_file 500
+#define max_num_of_fields 12
+#define length_of_fieldname 30
+
+char** read_file(char* filename) {
+ FILE* fp = fopen(filename, "r");
+ if (fp == NULL) return NULL;
+ char** words = malloc(rows_in_file * sizeof(char*));
+ if (words == NULL) return NULL;
+ char buffer[max_length];
+ int i = 0;
+ while (fgets(buffer, max_length, fp) != NULL) {
+ words[i] = malloc(max_length * sizeof(char));
+ if (words[i] == NULL) return NULL;
+ strcpy(words[i], buffer);
+ i++;
+ }
+ fclose(fp);
+ return words;
+}
+
+int prev_space(int pos, char* line) {
+ int i = 0;
+ for (i = pos; line[i] != ' '; i--);
+ return i;
+}
+
+void proc(int line_num, char* line, char* field[rows_in_file][max_num_of_fields], char* value[rows_in_file][max_num_of_fields]) {
+ if (line[0] == '{') {
+ int equals_position[max_num_of_fields] = {0};
+ int j = 0;
+ for (int i = 2; i < strlen(line); i++) {
+ if (line[i] == '=') {
+ equals_position[j] = i;
+ j++;
+ }
+ }
+ int num_of_fields = j;
+ char id[length_of_fieldname] = {};
+ j = 0;
+ int id_flag = 1;
+ for (int i = 3; i < strlen(line); i++) {
+ if ((id_flag == 1) && (line[i] == ' '))
+ continue;
+ else if (id_flag == 1) {
+ id[j] = line[i];
+ j++;
+ id_flag = 0;
+ }
+ else {
+ if (line[i] == ' ')
+ break;
+ else {
+ id[j] = line[i];
+ j++;
+ }
+ }
+ }
+ id[j] = '\0';
+
+ char beg[4];
+ for (int i = 0; i < 3; i++) {
+ beg[i] = id[i];
+ }
+ beg[3] = '\0';
+ if (0 == strcmp(beg, "end"))
+ return;
+
+ printf("name => %s\n", id);
+
+ for (int i = 0; i < num_of_fields; i++) {
+ int eq = equals_position[i];
+ int sp = prev_space(eq, line);
+ char word[length_of_fieldname];
+ int j = 0;
+ for (int k = sp + 1; k < eq; k++) {
+ word[j] = line[k];
+ j++;
+ }
+ word[j] = '\0';
+ field[line_num][i] = malloc( sizeof(char) * length_of_fieldname );
+ strcpy(field[line_num][i], word);
+ }
+
+ for (int l = 0; l < num_of_fields - 1; l++) {
+ int eq = equals_position[l];
+ int eq_next = equals_position[l + 1];
+ int fieldlen = strlen(field[line_num][l + 1]);
+ char value_word[max_length];
+ int j = 0;
+ for (int k = eq + 1; k < eq_next - fieldlen; k++) {
+ value_word[j] = line[k];
+ j++;
+ }
+ value_word[j] = '\0';
+ value[line_num][l] = malloc( sizeof(char) * max_length );
+ strcpy(value[line_num][l], value_word);
+
+ }
+ int eq = equals_position[num_of_fields - 1];
+ char last_field[length_of_fieldname];
+ j = 0;
+ for (int i = eq + 1; i < strlen(line) - 3; i++) {
+ last_field[j] = line[i];
+ j++;
+ }
+ last_field[j] = '\0';
+ value[line_num][num_of_fields - 1] = malloc( sizeof(char) * max_length );
+ strcpy(value[line_num][num_of_fields - 1], last_field);
+
+ for (int l = 0; l < num_of_fields; l++)
+ printf("%s -> %s\n", field[line_num][l], value[line_num][l]);
+
+ printf("\n");
+
+ for (int l = 0; l < num_of_fields; l++) {
+ free(value[line_num][l]);
+ free(field[line_num][l]);
+ }
+ } else {
+ printf("Text => %s", line);
+ }
+
+}
+
+int main() {
+ char* field[rows_in_file][max_num_of_fields];
+ char* value[rows_in_file][max_num_of_fields];
+ char** row = read_file("259.txt");
+ for (int i = 0; row[i] != NULL; i++)
+ proc(i, row[i], field, value);
+ for (int i = 0; row[i] != NULL; i++)
+ free(row[i]);
+ free(row);
+}
diff --git a/challenge-259/zapwai/javascript/ch-1.js b/challenge-259/zapwai/javascript/ch-1.js
new file mode 100644
index 0000000000..662affe7cc
--- /dev/null
+++ b/challenge-259/zapwai/javascript/ch-1.js
@@ -0,0 +1,134 @@
+let base_year = 2000;
+let days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+let days = ["sat", "sun", "mon", "tue", "wed", "thu", "fri"];
+
+function is_leap_year(year) {
+ if (year % 400 == 0) {
+ return true;
+ }
+ if (year % 100 == 0) {
+ return false;
+ }
+ if (year % 4 == 0) {
+ return true;
+ }
+ return false;
+}
+
+function weekday(year, month, day) {
+ let skip_days = year - base_year;
+ for (let yr = base_year; yr < year; yr++) {
+ if (is_leap_year(yr)) {
+ skip_days++;
+ }
+ }
+ if (is_leap_year(year) && month > 2) {
+ skip_days++;
+ }
+ for (let m = 1; m < 13; m++) {
+ if (m < month) {
+ skip_days += days_in_month[m-1];
+ }
+ }
+ skip_days += day - 1;
+ return days[skip_days % 7];
+}
+
+function is_weekend(year, month, day) {
+ let today = weekday(year, month, day);
+ if (today == "sat" || today == "sun") {
+ return true;
+ }
+ return false;
+}
+
+function is_holiday(bank_holidays, year, month, day) {
+ let date = format_date(year, month, day);
+ for (let hol in bank_holidays) {
+ if (hol == date) {
+ return true;
+ }
+ }
+ return false;
+}
+
+function format_date(year, month, day) {
+ let yr = year.toString();
+ let mn = month.toString().padStart(2,'0');
+ let da = day.toString().padStart(2,'0');
+ return yr+"-"+mn+"-"+da;
+}
+
+function parse_date(date) {
+ let year = "";
+ let month = "";
+ let day = "";
+ for (let d of date) {
+ if (d == "-") {
+ continue;
+ }
+ if (year.length < 4) {
+ year += d;
+ } else if (month.length < 2) {
+ month += d;
+ } else if (day.length < 2) {
+ day += d;
+ }
+ }
+ yr = year;
+ mth = month;
+ da = day;
+ return [yr, mth, da];
+}
+
+function proc(start_date, offset, bank_holidays) {
+ let result = parse_date(start_date);
+ let year = result[0];
+ let month = result[1];
+ let day = result[2];
+ let new_year = year;
+ let new_month = month;
+ let new_day = day;
+ let steps = offset;
+ while (steps > 0) {
+ let leap = 0;
+ if (is_leap_year(new_year) && (new_month == 2)) {
+ leap = 1;
+ }
+ if (new_day + 1 > days_in_month[new_month - 1] + leap) {
+ if (new_month == 12) {
+ new_year++;
+ }
+ new_month++;
+ if (new_month == 13) {
+ new_month = 1;
+ }
+ new_day = 1;
+ } else {
+ new_day++;
+ }
+ if (!(is_holiday(bank_holidays, new_year, new_month, new_day)) && !(is_weekend(new_year,new_month,new_day))) {
+ steps--;
+ }
+ }
+ let new_date = format_date(new_year, new_month, new_day);
+ console.log("Input:", start_date, "offset:", offset);
+ if (bank_holidays.length > 0) {
+ for (let h of bank_holidays) {
+ console.log("\tHoliday:",h);
+ }
+ }
+ console.log("Output:", new_date);
+}
+
+function mn() {
+ let start_date = "2018-06-28";
+ let offset = 3;
+
+ let bank_holiday1 = "2018-07-03";
+ let bank_holidays = [bank_holiday1];
+
+ proc(start_date, offset, bank_holidays);
+}
+
+mn();
diff --git a/challenge-259/zapwai/javascript/ch-2.js b/challenge-259/zapwai/javascript/ch-2.js
new file mode 100644
index 0000000000..48dc540931
--- /dev/null
+++ b/challenge-259/zapwai/javascript/ch-2.js
@@ -0,0 +1,100 @@
+const l1 = '{% id field1="value1" field2="value2" field3=42 %}';
+const l2 = '{% youtube title="Title \"quoted\" done" foo="bar" baz=31 %}';
+const l3 = '{% youtube title="Title with escaped backslash \\" %}';
+const l4 = '{% id field="val1" field2="val2" %}';
+const l5 = '{% test field1="value1" df=42 %}';
+const l6 = 'LINES';
+const l7 = 'More Lines';
+const l8 = '{% endtest %}';
+
+function prev_space(pos, line) {
+ let i = pos;
+ while (line.charAt(i) != " ") {
+ i--;
+ }
+ return i;
+}
+
+function proc(line_num, line, field, value) {
+ if (line.charAt(0) == '{') {
+ let eq_pos = [];
+ for (let i = 2; i < line.length; i++) {
+ if (line.charAt(i) == '=') {
+ eq_pos.push(i);
+ }
+ }
+ let num_of_fields = eq_pos.length;
+ let id = "";
+ let id_flag = true;
+ for (let i = 3; i < line.length; i++) {
+ if (id_flag && (line[i] == ' ')) {
+ continue;
+ }
+ else if (id_flag) {
+ id += line.charAt(i);
+ id_flag = false;
+ }
+ else {
+ if (line.charAt(i) == ' ') {
+ break;
+ } else {
+ id += line.charAt(i);
+ }
+ }
+ }
+
+ if (id.substring(0,3) == "end") {
+ return;
+ }
+
+ console.log("Name =>", id);
+
+ field[line_num] = [];
+
+ for (let i = 0; i < num_of_fields; i++) {
+ let eq = eq_pos[i];
+ let sp = prev_space(eq, line);
+ let word = "";
+ for (let k = sp + 1; k < eq; k++) {
+ word += line.charAt(k);
+ }
+ field[line_num].push(word);
+ }
+
+ value[line_num] = [];
+ for (let l = 0; l < num_of_fields - 1; l++) {
+ let eq = eq_pos[l];
+ let eq_next = eq_pos[l + 1];
+ let fieldlen = field[line_num][l + 1].length;
+ let value_word = "";
+ for (let k = eq + 1; k < eq_next - fieldlen; k++) {
+ value_word += line.charAt(k);
+ }
+ value[line_num].push(value_word);
+ }
+ let eq = eq_pos[num_of_fields - 1];
+ let last_field = "";
+ for (let i = eq + 1; i < line.length - 3; i++) {
+ last_field += line.charAt(i);
+ }
+ value[line_num].push(last_field);
+ console.log("Fields => {");
+ for (let l = 0; l < num_of_fields; l++) {
+ console.log("\t",field[line_num][l], "->", value[line_num][l]);
+ }
+ console.log("}");
+ } else {
+ console.log("Text =>", line);
+ }
+}
+
+function main() {
+ let field = [], value = [];
+ let i = 0;
+ for (let l of [l1, l2, l3, l4, l5, l6, l7, l8]) {
+ proc(i, l, field, value);
+ i++;
+ }
+}
+
+main();
diff --git a/challenge-259/zapwai/perl/ch-1.pl b/challenge-259/zapwai/perl/ch-1.pl
new file mode 100644
index 0000000000..2ded625e93
--- /dev/null
+++ b/challenge-259/zapwai/perl/ch-1.pl
@@ -0,0 +1,65 @@
+use v5.38;
+my $first_year = 2000; # If you change this, change the first day in @day to match jan 1st
+my %days_in_month = qw( 01 31 02 28 03 31 04 30 05 31 06 30 07 31 08 31 09 30 10 31 11 30 12 31 );
+my @day = qw( sat sun mon tue wed thu fri );
+
+sub is_leap_year ($year) { return ($year % 400 == 0) ? 1 : ($year % 100 == 0) ? 0 : ($year % 4 == 0) ? 1 : 0; }
+
+# Every year adds one to day of the week (unless there's a leap day, then two)
+# The year 2000 started on a saturday -> 2001 starts on a monday.
+sub weekday($year, $month, $day) {
+ my $skip_days = $year - $first_year;
+ for my $yr ($first_year .. $year - 1) {
+ $skip_days++ if is_leap_year($yr);
+ }
+ $skip_days++ if (is_leap_year($year) and $month gt "02");
+ for my $m (qw (01 02 03 04 05 06 07 08 09 10 11 12)) {
+ $skip_days += $days_in_month{$m} if ($m lt $month);
+ }
+ $skip_days += $day - 1;
+ return $day[$skip_days % 7];
+}
+
+sub is_weekend ($year, $month, $day) {
+ my $weekday = weekday($year, $month, $day);
+ return ( $weekday eq "sat" or $weekday eq "sun" ) ? 1 : 0;
+}
+
+sub is_holiday ($bank_holidays, $year, $month, $day) {
+ for my $date (@$bank_holidays) {
+ my ($yr, $mn, $dy) = split "-", $date;
+ return 1 if (
+ ($yr eq $year) and
+ ($mn eq $month) and
+ ($dy eq $day) );
+ }
+ 0
+}
+
+sub proc ($start_date, $offset, $bank_holidays) {
+ my ($year, $month, $day) = split "-", $start_date;
+ my ($new_year, $new_month, $new_day) = ($year, $month, $day);
+ my $steps = $offset;
+ while ($steps > 0) {
+ my $leap = (is_leap_year($new_year) && ($new_month eq "02")) ? 1 : 0;
+ if ($new_day + 1 > $days_in_month{$new_month} + $leap) {
+ if ($new_month eq "12") {
+ $new_year++;
+ }
+ $new_month++;
+ $new_month = "01" if ($new_month eq "13");
+ $new_day = "01";
+ } else {
+ $new_day = sprintf("%02d", $new_day + 1);
+ }
+ $steps-- unless (is_holiday($bank_holidays, $new_year, $new_month, $new_day) or is_weekend($new_year, $new_month, $new_day));
+ }
+ say "Input: $start_date, offset: $offset, holidays: @{$bank_holidays}";
+ say "Output: $new_year-$new_month-$new_day";
+}
+
+my $start_date = '2018-06-28';
+my $offset = 3;
+my $bank_holidays = ['2018-07-03'];
+
+proc($start_date, $offset, $bank_holidays);
diff --git a/challenge-259/zapwai/perl/ch-2.pl b/challenge-259/zapwai/perl/ch-2.pl
new file mode 100644
index 0000000000..c1a3acb152
--- /dev/null
+++ b/challenge-259/zapwai/perl/ch-2.pl
@@ -0,0 +1,67 @@
+use v5.38;
+my $line1 = '{% id field1="value1" field2="value2" field3=42 %}';
+my $line2 = '{% youtube title="Title \"quoted\" done" foo="bar" baz=31 %}';
+my $line3 = '{% youtube title="Title with escaped backslash \\" %}';
+my $line4 = '{% id field="val1" field2="val2" %}';
+my $line5 = '{% test filed1="value1" df=42 %}';
+my $line6 = 'LINES';
+my $line7 = 'More Lines';
+my $line8 = '{% endtest %}';
+
+my %fv;
+my %text;
+my $current_id;
+
+my @lines = ($line1, $line2, $line3, $line4, $line5, $line6, $line7, $line8);
+proc($_) foreach (@lines);
+say $fv{$current_id} unless ($text{$current_id});
+
+sub proc ($line) {
+ if ($line =~ /^{%/) {
+ $line =~ /(\w+)/;
+ if ($1 =~ /^end/) {
+ say $fv{$current_id};
+ say $text{$current_id};
+ } else {
+ say $fv{$current_id} if ($current_id);
+ $current_id = $1;
+ process_line($line);
+ }
+ } else {
+ $text{$current_id} = "Text => " unless ($text{$current_id});
+ $text{$current_id} .= "$line\n";
+ }
+}
+
+sub process_line ($line) {
+ $line =~ /(\w+)/;
+ my $name = $1;
+
+ $line = substr $line, (index $line, $name) + length $name;
+ $line = substr $line, 0, -3;
+ $line =~ s/\s+/ /g;
+
+ my ($r, $s) = get_fv($line);
+ my @fields = @$r;
+ my @values = @$s;
+ my $output = "Name => $name\n";
+ $output .= "Fields => {\n";
+ $output .= "\t".$fields[$_]." => ".$values[$_]."\n" for (0 .. $#fields);
+ $output .= "}\n";
+ $fv{$current_id} = $output;
+}
+
+sub get_fv ($l) {
+ my @piece = split "=", $l;
+ my @field = ($piece[0]);
+ my @value;
+ for my $i (1 .. $#piece - 1) {
+ $piece[$i] =~ /(\w+)$/;
+ push @field, $1;
+ my $strip = substr $piece[$i], 0, -length($1);
+ push @value, $strip;
+ }
+ push @value, $piece[$#piece];
+ s/\s+//g for (@field);
+ return (\@field, \@value);
+}
diff --git a/challenge-259/zapwai/python/ch-1.py b/challenge-259/zapwai/python/ch-1.py
new file mode 100644
index 0000000000..502f126cbb
--- /dev/null
+++ b/challenge-259/zapwai/python/ch-1.py
@@ -0,0 +1,72 @@
+base_year = 2000
+days_in_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
+
+def is_leap_year(year):
+ if year % 400 == 0:
+ return True
+ if year % 100 == 0:
+ return False
+ if year % 4 == 0:
+ return True
+ return False
+
+def weekday(year, month, day):
+ year = int(year); month = int(month); day = int(day)
+ skip_days = year - base_year
+ for yr in range(base_year, year):
+ if is_leap_year(yr):
+ skip_days += 1
+ if is_leap_year(year) and month > 2:
+ skip_days += 1
+ for m in range(1, 13):
+ if m < month:
+ skip_days += days_in_month[m - 1]
+ skip_days += int(day) - 1
+ days = ["sat", "sun", "mon", "tue", "wed", "thu", "fri"]
+ return days[skip_days % 7]
+
+def is_weekend(year, month, day):
+ today = weekday(year, month, day)
+ if today == "sat" or today == "sun":
+ return True
+ else:
+ return False
+
+def is_holiday(bank_holidays, year, month, day):
+ for date in bank_holidays:
+ (hol_year, hol_month, hol_day) = date.split("-")
+ if year == hol_year and month == hol_month and day == hol_day:
+ return True
+ return False
+
+def proc(start_date, offset, bank_holidays):
+ (year, month, day) = start_date.split("-")
+ (new_year, new_month, new_day) = (year, month, day)
+ steps = offset
+ while steps > 0:
+ leap = 0
+ if is_leap_year(int(year)) and month == "02":
+ leap = 1
+ if int(new_day) + 1 > leap + days_in_month[int(new_month)-1]:
+ if new_month == "12":
+ new_year = str(int(new_year) + 1)
+ new_month = '{:02}'.format(int(new_month) + 1)
+ if new_month == "13":
+ new_month = "01"
+ new_day = "01"
+ else:
+ new_day = '{:02}'.format(int(new_day) + 1)
+ if not (is_holiday(bank_holidays, new_year, new_month, new_day) or is_weekend(new_year, new_month, new_day)):
+ steps -= 1
+ new_date = new_year + "-" + new_month + "-" + new_day
+ print("Input:", start_date, "Offset:", offset, "Holidays: ", end='')
+ for d in bank_holidays:
+ print(d,'', end='')
+ print("\nOutput:", new_date)
+
+start_date = '2018-06-28'
+offset = 3
+bank_holidays = ["2018-07-03"]
+
+proc(start_date, offset, bank_holidays)
+
diff --git a/challenge-259/zapwai/python/ch-2.py b/challenge-259/zapwai/python/ch-2.py
new file mode 100644
index 0000000000..663034efc7
--- /dev/null
+++ b/challenge-259/zapwai/python/ch-2.py
@@ -0,0 +1,38 @@
+def proc(line):
+ if line[0] == '{':
+ line = line[3:-3]
+ name = line.split("=")[0].split()[0]
+ if name[0:3] == "end":
+ return
+ line = line[len(name)+1:]
+ field = []
+ chunk = line.split("=")
+ for i in range(len(chunk) - 1):
+ field.append(chunk[i].split().pop())
+ value = []
+ for i in range(1, len(chunk) - 1):
+ s = chunk[i][:-len(field[i])]
+ value.append(s)
+ value.append(chunk[len(chunk)-1])
+ print("Name =>", name)
+ print("Fields =>")
+ for i in range(len(field)):
+ print("\t",field[i],"->",value[i])
+ print()
+ else:
+ print("Text =>", line)
+
+
+line1 = '{% id field1="value1" field2="value2" field3=42 %}'
+line2 = '{% youtube title="Title \"quoted\" done" foo="bar" baz=31 %}'
+line3 = '{% youtube title="Title with escaped backslash \\" %}'
+line4 = '{% id field="val1" field2="val2" %}'
+line5 = '{% test field1="value1" df=42 %}'
+line6 = 'LINES'
+line7 = 'More Lines'
+line8 = '{% endtest %}'
+
+lines = [line1, line2, line3, line4, line5, line6, line7, line8]
+
+for line in lines:
+ proc(line)
diff --git a/challenge-259/zapwai/rust/259.txt b/challenge-259/zapwai/rust/259.txt
new file mode 100644
index 0000000000..76fdb9009f
--- /dev/null
+++ b/challenge-259/zapwai/rust/259.txt
@@ -0,0 +1,8 @@
+{% id field1="value1" field2="value2" field3=42 %}
+{% youtube title="Title \"quoted\" done" foo="bar" baz=31 %}
+{% youtube title="Title with escaped backslash \\" %}
+{% id field="val1" field2="val2" %}
+{% test field1="value1" df=42 %}
+LINES
+More Lines
+{% endtest %}
diff --git a/challenge-259/zapwai/rust/ch-1.rs b/challenge-259/zapwai/rust/ch-1.rs
new file mode 100644
index 0000000000..c78e99d0f0
--- /dev/null
+++ b/challenge-259/zapwai/rust/ch-1.rs
@@ -0,0 +1,111 @@
+#![allow(non_upper_case_globals)]
+const base_year :i32 = 2000;
+const days : [&str; 7] = ["sat", "sun", "mon", "tue", "wed", "thu", "fri"];
+const days_in_month : [i32; 12] = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
+
+fn main() {
+ let start_date = "2018-06-28";
+ let offset = 3;
+ let bank_holiday1 = "2018-07-03";
+ let bank_holidays = [bank_holiday1];
+
+ proc(start_date, offset, &bank_holidays);
+}
+
+fn is_leap_year(year : i32) -> bool{
+ if year % 400 == 0 {
+ return true;
+ }
+ if year % 100 == 0 {
+ return false;
+ }
+ if year % 4 == 0 {
+ return true;
+ }
+ return false;
+}
+
+fn weekday(year : i32, month : i32, day : i32) -> String {
+ let mut skip_days : i32 = year - base_year;
+ for yr in base_year .. year {
+ if is_leap_year(yr) { skip_days += 1; }
+ }
+ if is_leap_year(year) && month > 2 { skip_days += 1; }
+ for m in 1 ..= 13 {
+ if m < month {
+ skip_days += days_in_month[(m-1) as usize];
+ }
+ }
+ skip_days += day - 1;
+ return String::from(days[(skip_days % 7) as usize]);
+}
+
+fn is_weekend(year : i32, month : i32, day : i32) -> bool {
+ let today = weekday(year, month, day);
+ if today == "sat" || today == "sun" {
+ return true;
+ }
+ return false;
+}
+
+fn is_holiday(bank_holidays :&[&str], year : i32, month : i32, day : i32) -> bool {
+ let date = format_date(year, month, day);
+ for s in bank_holidays {
+ if date == s.to_string() {
+ return true;
+ }
+ }
+ return false;
+}
+
+fn format_date(year : i32, month : i32, day : i32) -> String {
+ let s = format!("{}-{:02}-{:02}", year, month, day);
+ return String::from(s);
+}
+
+fn parse_date(date : &str ) -> [i32; 3] {
+ let s = String::from(date);
+ let yr = &s[0 .. 4];
+ let mn = &s[5 .. 7];
+ let da = &s[8 .. 10];
+ return [yr.parse::<i32>().unwrap(), mn.parse::<i32>().unwrap(), da.parse::<i32>().unwrap()];
+}
+
+fn proc(start_date : &str, offset : i32, bank_holidays : &[&str]) {
+ let result = parse_date(start_date);
+ let year = result[0];
+ let month = result[1];
+ let day = result[2];
+ let mut new_year = year;
+ let mut new_month = month;
+ let mut new_day = day;
+ let mut steps = offset;
+ while steps > 0 {
+ let mut leap = 0;
+ if is_leap_year(new_year) && new_month == 2 {
+ leap = 1;
+ }
+ if new_day + 1 > days_in_month[(new_month - 1) as usize] + leap {
+ if new_month == 12 {
+ new_year += 1;
+ }
+ new_month += 1;
+ if new_month == 13 {
+ new_month = 1;
+ }
+ new_day = 1;
+ } else {
+ new_day += 1;
+ }
+ if !is_holiday(bank_holidays, new_year, new_month, new_day) && !is_weekend(new_year, new_month, new_day) {
+ steps -= 1;
+ }
+ }
+
+ let new_date = format_date(new_year, new_month, new_day);
+ print!("Input: start: {start_date}, offset: {offset}, holidays: ");
+ for d in bank_holidays {
+ print!("{d} ");
+ }
+ println!("\nOutput: {new_date}");
+}
diff --git a/challenge-259/zapwai/rust/ch-2.rs b/challenge-259/zapwai/rust/ch-2.rs
new file mode 100644
index 0000000000..e48d808806
--- /dev/null
+++ b/challenge-259/zapwai/rust/ch-2.rs
@@ -0,0 +1,106 @@
+#![allow(unused)]
+
+const ROWS_IN_FILE :usize = 500;
+const MAX_NUM_OF_FIELDS :usize = 12;
+const LENGTH_OF_FIELDNAME :usize = 30;
+
+fn read_file(filename : &str) -> Vec<String> {
+ return std::fs::read_to_string(filename)
+ .expect("No file?")
+ .lines()
+ .map(|s| s.to_string())
+ .collect()
+}
+
+fn prev_space(pos :usize, line :&String) -> usize {
+ let mut i = pos;
+ while line.chars().nth(i).unwrap() != ' ' {
+ i -= 1;
+ }
+ return i;
+}
+
+fn proc(line_num : usize, line : &String, field : &mut Vec<Vec<String>>, value : &mut Vec<Vec<String>>) {
+ if line.chars().nth(0).unwrap() == '{' {
+ let mut eq_pos :[usize;MAX_NUM_OF_FIELDS] = [0; MAX_NUM_OF_FIELDS];
+ let mut j = 0;
+ for i in 2 .. line.len() {
+ if line.chars().nth(i).unwrap() == '=' {
+ eq_pos[j] = i;
+ j += 1;
+ }
+ }
+ let num_of_fields = j;
+ let mut id :Vec<char> = vec![];
+ let mut id_flag = true;
+ for i in 3 .. line.len() {
+ if id_flag && line.chars().nth(i).unwrap() == ' ' {
+ continue;
+ }
+ else if id_flag {
+ id.push(line.chars().nth(i).unwrap());
+ id_flag = false;
+ }
+ else {
+ if line.chars().nth(i).unwrap() == ' ' {
+ break;
+ }
+ else {
+ id.push(line.chars().nth(i).unwrap());
+ }
+ }
+ }
+ let name = id.iter().collect::<String>();
+ if name.len() > 2 && &name[0..3] == "end" {
+ return ();
+ }
+ println!("name => {name}");
+ if name.len() > 2 && "end" == &name[0..3] { return (); }
+ field.push(vec![]);
+ for i in 0 .. num_of_fields {
+ let eq = eq_pos[i];
+ let sp = prev_space(eq, line);
+ let mut word : Vec<char> = vec![];
+ for k in sp + 1 .. eq {
+ word.push(line.chars().nth(k).unwrap());
+ }
+ field[line_num].push(word.iter().collect::<String>());
+ }
+ value.push(vec![]);
+ for l in 0 .. num_of_fields - 1 {
+ let eq = eq_pos[l];
+ let eq_next = eq_pos[l+1];
+ let fieldlen :usize = field[line_num][l+1].len();
+ let mut value_word : Vec<char> = Vec::new();
+ for k in eq + 1 .. eq_next - fieldlen {
+ value_word.push(line.chars().nth(k).unwrap());
+ }
+ value[line_num].push(value_word.iter().collect::<String>());
+ }
+
+ let eq = eq_pos[num_of_fields - 1];
+ let mut last_field : Vec<char> = Vec::new();
+ for i in eq+1 .. line.len() - 3 {
+ last_field.push(line.chars().nth(i).unwrap());
+ }
+ value[line_num].push(last_field.iter().collect::<String>());
+ println!("Fields => ");
+ for i in 0 .. num_of_fields {
+ println!("\t{} -> {}", field[line_num][i], value[line_num][i]);
+ }
+ println!();
+ } else {
+ println!("Text => {}", line);
+ }
+}
+
+fn main() {
+ let filename = "259.txt";
+ let lines = read_file(filename);
+ let mut field : Vec<Vec<String>> = Vec::new();
+ let mut value : Vec<Vec<String>> = Vec::new();
+
+ for i in 0 .. lines.len() {
+ proc(i, &lines[i], &mut field, &mut value);
+ }
+}