aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-219/jo-37/octave/ch-2.m109
-rwxr-xr-xchallenge-219/jo-37/perl/ch-1.pl56
2 files changed, 165 insertions, 0 deletions
diff --git a/challenge-219/jo-37/octave/ch-2.m b/challenge-219/jo-37/octave/ch-2.m
new file mode 100755
index 0000000000..772955db06
--- /dev/null
+++ b/challenge-219/jo-37/octave/ch-2.m
@@ -0,0 +1,109 @@
+#!/usr/bin/octave -qf
+
+#{
+ This task is very similar to task 2 from week 216. Again, it may
+ be regarded as an integer linear programming task.
+ Each travel day needs to be covered by at least one travel card.
+ Let N be the number of days, then we have 3 * N possible travel
+ cards: starting at each given day with a duration of 1, 7 or 30
+ days. This leads to N inequalities in 3 * N variables: The count
+ of cards that are valid at each day must be at least one. The
+ objective function as the sum of the prices of the selected cards
+ shall be minimized.
+
+ Usage:
+ ./ch-2.m P1 P7 P30 D...
+
+ P1 P7 P30
+ prices for a 1-, 7- or 30-day travel card
+
+ D...
+ travel days
+#}
+
+###
+
+function [xopt, fmin] = travel_cost (price, days, duration)
+ N = numel(days);
+ D = numel(duration);
+
+ # Indicator "matrix" for each travel card type on every travel day.
+ for i = 1:N
+ for k = 1:N
+ for t = 1:D
+ A(i, k, t) = ...
+ days(i) >= days(k) && days(i) < days(k) + duration(t);
+ endfor
+ endfor
+ endfor
+
+ # Vector describing the objective function.
+ c = reshape(repelem(price, N), 1, []);
+
+ # Inequalities' RHS.
+ b = ones(1, N);
+
+ # Relation ">=" for all inequalities.
+ ctype = repelem("L", N);
+
+ # Integer variables.
+ vartype = repelem("I", N * D);
+
+ # Join card type and start day dimensions and find a minimal
+ # solution.
+ [xopt, fmin] = glpk(c, reshape(A, N, []),
+ b, [], [], ctype, vartype, 1);
+endfunction
+
+###
+
+# Main
+
+# card durations:
+duration = [1, 7, 30]
+D = numel(duration);
+
+args = argv();
+price = transpose(cellfun("str2num", args(1:D)))
+days = transpose(cellfun("str2num", args(D+1:nargin)))
+N = numel(days);
+
+# find a minimum:
+[xopt, fmin] = travel_cost(price, days, duration);
+
+printf("minimum travel cost: %d\n", fmin);
+
+# Arrange solution by start day and card type.
+copt = reshape(xopt, N, []);
+for i = 1:N
+ for t = 1:D
+ if copt(i, t)
+ printf("On day %d, we buy a %d-day pass for %d.\n",
+ days(i), duration(t), price(t));
+ endif
+ endfor
+endfor
+
+###
+
+#{
+$ ./ch-2.m 2 7 25 1 2 3 5 7 10 11 12 14 20 30 31
+duration =
+
+ 1 7 30
+
+price =
+
+ 2 7 25
+
+days =
+
+ 1 2 3 5 7 10 11 12 14 20 30 31
+
+minimum travel cost: 20
+On day 1, we buy a 7-day pass for 7.
+On day 10, we buy a 7-day pass for 7.
+On day 20, we buy a 1-day pass for 2.
+On day 30, we buy a 1-day pass for 2.
+On day 31, we buy a 1-day pass for 2.
+#}
diff --git a/challenge-219/jo-37/perl/ch-1.pl b/challenge-219/jo-37/perl/ch-1.pl
new file mode 100755
index 0000000000..7f0fd3232d
--- /dev/null
+++ b/challenge-219/jo-37/perl/ch-1.pl
@@ -0,0 +1,56 @@
+#!/usr/bin/perl -s
+
+use v5.24;
+use Test2::V0;
+
+our ($tests, $examples);
+
+run_tests() if $tests || $examples; # does not return
+
+die <<EOS unless @ARGV;
+usage: $0 [-examples] [-tests] [--] [N...]
+
+-examples
+ run the examples from the challenge
+
+-tests
+ run some tests
+
+N...
+ list of numbers
+
+EOS
+
+
+### Input and Output
+
+say "@{[sorted_squares(@ARGV)]}";
+
+
+### Implementation
+
+sub sorted_squares {
+ sort {$a <=> $b} map $_ * $_, @_;
+}
+
+
+### Examples and tests
+
+sub run_tests {
+ SKIP: {
+ skip "examples" unless $examples;
+
+ is [sorted_squares(-2, -1, 0, 3, 4)],
+ [0, 1, 4, 9, 16], 'example 1';
+
+ is [sorted_squares(5, -4, -1, 3, 6)],
+ [1, 9, 16, 25, 36], 'example 2';
+ }
+
+ SKIP: {
+ skip "tests" unless $tests;
+ }
+
+ done_testing;
+ exit;
+}