diff options
| author | arnesom <arne@bbop.org> | 2022-05-22 22:21:58 +0200 |
|---|---|---|
| committer | arnesom <arne@bbop.org> | 2022-05-22 22:21:58 +0200 |
| commit | a6eb1d94efeaae67661fe89dcbcdeb01b2d200ba (patch) | |
| tree | a8bd1523e6231120d1aff7a1d1d2691063dc6895 /challenge-165 | |
| parent | d9bb08876458314b070fa4679fa1ffc7a68b82a6 (diff) | |
| download | perlweeklychallenge-club-a6eb1d94efeaae67661fe89dcbcdeb01b2d200ba.tar.gz perlweeklychallenge-club-a6eb1d94efeaae67661fe89dcbcdeb01b2d200ba.tar.bz2 perlweeklychallenge-club-a6eb1d94efeaae67661fe89dcbcdeb01b2d200ba.zip | |
Arne Sommer
Diffstat (limited to 'challenge-165')
| -rw-r--r-- | challenge-165/arne-sommer/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/czech_rep.txt | 3 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/example-lsm.txt | 5 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/example-lsm2.txt | 1 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/example1.txt | 3 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/example2.txt | 6 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/japan.txt | 2 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/norway.txt | 3 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/ukraine.txt | 2 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/union_jack.txt | 10 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/usa-ascii.txt | 12 | ||||
| -rw-r--r-- | challenge-165/arne-sommer/misc/usa.txt | 12 | ||||
| -rwxr-xr-x | challenge-165/arne-sommer/raku/ch-1.raku | 95 | ||||
| -rwxr-xr-x | challenge-165/arne-sommer/raku/ch-2.raku | 95 | ||||
| -rwxr-xr-x | challenge-165/arne-sommer/raku/mksvg-turbo | 165 | ||||
| -rwxr-xr-x | challenge-165/arne-sommer/raku/mksvg1 | 63 | ||||
| -rwxr-xr-x | challenge-165/arne-sommer/raku/mksvg2 | 63 | ||||
| -rwxr-xr-x | challenge-165/arne-sommer/raku/mksvg3 | 95 |
18 files changed, 636 insertions, 0 deletions
diff --git a/challenge-165/arne-sommer/blog.txt b/challenge-165/arne-sommer/blog.txt new file mode 100644 index 0000000000..a6a759d6b2 --- /dev/null +++ b/challenge-165/arne-sommer/blog.txt @@ -0,0 +1 @@ +https://raku-musings.com/doubly-scalable.html diff --git a/challenge-165/arne-sommer/misc/czech_rep.txt b/challenge-165/arne-sommer/misc/czech_rep.txt new file mode 100644 index 0000000000..d525845135 --- /dev/null +++ b/challenge-165/arne-sommer/misc/czech_rep.txt @@ -0,0 +1,3 @@ +:fc:#FFFFFF r,0,0,6,2 +:fc:#d7141a r,0,2,6,2 +:fc:#11457e p,0,0,3,2,0,4 diff --git a/challenge-165/arne-sommer/misc/example-lsm.txt b/challenge-165/arne-sommer/misc/example-lsm.txt new file mode 100644 index 0000000000..fd1494f1af --- /dev/null +++ b/challenge-165/arne-sommer/misc/example-lsm.txt @@ -0,0 +1,5 @@ +2,4 +3,5 +5,7 +7,10 +9,15 diff --git a/challenge-165/arne-sommer/misc/example-lsm2.txt b/challenge-165/arne-sommer/misc/example-lsm2.txt new file mode 100644 index 0000000000..04ea5cd9b4 --- /dev/null +++ b/challenge-165/arne-sommer/misc/example-lsm2.txt @@ -0,0 +1 @@ +2,4 3,5 :r:3 5,7 7,10 :r:5 :f:#ff0000 9,15 diff --git a/challenge-165/arne-sommer/misc/example1.txt b/challenge-165/arne-sommer/misc/example1.txt new file mode 100644 index 0000000000..42acc2b70b --- /dev/null +++ b/challenge-165/arne-sommer/misc/example1.txt @@ -0,0 +1,3 @@ +53,10 +53,10,23,30 +23,30 diff --git a/challenge-165/arne-sommer/misc/example2.txt b/challenge-165/arne-sommer/misc/example2.txt new file mode 100644 index 0000000000..9e5ecc346a --- /dev/null +++ b/challenge-165/arne-sommer/misc/example2.txt @@ -0,0 +1,6 @@ +333,129 39,189 140,156 292,134 393,52 160,166 362,122 13,193 +341,104 320,113 109,177 203,152 343,100 225,110 23,186 282,102 +284,98 205,133 297,114 292,126 339,112 327,79 253,136 61,169 +128,176 346,72 316,103 124,162 65,181 159,137 212,116 337,86 +215,136 153,137 390,104 100,180 76,188 77,181 69,195 92,186 +275,96 250,147 34,174 213,134 186,129 189,154 361,82 363,89 diff --git a/challenge-165/arne-sommer/misc/japan.txt b/challenge-165/arne-sommer/misc/japan.txt new file mode 100644 index 0000000000..6fd1009bfc --- /dev/null +++ b/challenge-165/arne-sommer/misc/japan.txt @@ -0,0 +1,2 @@ +:fc:#FFFFFF r,0,0,30,20 +:cr:6 :cc:#bc002d 15,10 diff --git a/challenge-165/arne-sommer/misc/norway.txt b/challenge-165/arne-sommer/misc/norway.txt new file mode 100644 index 0000000000..e216138e36 --- /dev/null +++ b/challenge-165/arne-sommer/misc/norway.txt @@ -0,0 +1,3 @@ +:fc:#BA0C2F r,0,0,22,16 +:fc:#ffffff r,6,0,4,16 r,0,6,22,4 +:fc:#00205B r,7,0,2,16 r,0,7,22,2 diff --git a/challenge-165/arne-sommer/misc/ukraine.txt b/challenge-165/arne-sommer/misc/ukraine.txt new file mode 100644 index 0000000000..9f0d32273c --- /dev/null +++ b/challenge-165/arne-sommer/misc/ukraine.txt @@ -0,0 +1,2 @@ +:fc:#0057b7 r,0,0,3,1 +:fc:#ffd700 r,0,1,3,1 diff --git a/challenge-165/arne-sommer/misc/union_jack.txt b/challenge-165/arne-sommer/misc/union_jack.txt new file mode 100644 index 0000000000..b235d29621 --- /dev/null +++ b/challenge-165/arne-sommer/misc/union_jack.txt @@ -0,0 +1,10 @@ +:w:60 :h:30 + +:fc:#012169 r,0,0,60,30 + +:lw:6 :lc:#ffffff 0,0,60,30 0,30,60,0 +:lw:2 :lc:#C8102E -1.5,0,30,16 32.5,16,61.5,30 + -1,31,29.5,16 30.5,14,61,-1 + +:fc:#ffffff r,0,10,60,10 r,25,0,10,30 +:fc:#C8102E r,0,12,60,6 r,27,0,6,30 diff --git a/challenge-165/arne-sommer/misc/usa-ascii.txt b/challenge-165/arne-sommer/misc/usa-ascii.txt new file mode 100644 index 0000000000..da091642f3 --- /dev/null +++ b/challenge-165/arne-sommer/misc/usa-ascii.txt @@ -0,0 +1,12 @@ +:fc:#B31942 r,0,0,250,10 r,0,20,250,10 r,0,40,250,10 r,0,60,250,10 r,0,80,250,10 r,0,100,250,10 r,0,120,250,10 +:fc:#FFFFFF r,0,10,250,10 r,0,30,250,10 r,0,50,250,10 r,0,70,250,10 r,0,90,250,10 r,0,110,250,10 +:fc:#0A3161 r,0,0,100,70 +:tc:#FFFFFF :th:15 :ls:5pt +t,3,18,****** +t,11,27,***** +t,3,36,****** +t,11,46,***** +t,3,55,****** +t,11,64,***** +t,3,73,****** + diff --git a/challenge-165/arne-sommer/misc/usa.txt b/challenge-165/arne-sommer/misc/usa.txt new file mode 100644 index 0000000000..88a07e5bfd --- /dev/null +++ b/challenge-165/arne-sommer/misc/usa.txt @@ -0,0 +1,12 @@ +:fc:#B31942 r,0,0,250,10 r,0,20,250,10 r,0,40,250,10 r,0,60,250,10 r,0,80,250,10 r,0,100,250,10 r,0,120,250,10 +:fc:#FFFFFF r,0,10,250,10 r,0,30,250,10 r,0,50,250,10 r,0,70,250,10 r,0,90,250,10 r,0,110,250,10 +:fc:#0A3161 r,0,0,100,70 +:tc:#FFFFFF :th:9 :ls:4pt +t,3,12,★★★★★★ +t,11,21,★★★★★ +t,3,30,★★★★★★ +t,11,39,★★★★★ +t,3,48,★★★★★★ +t,11,57,★★★★★ +t,3,66,★★★★★★ + diff --git a/challenge-165/arne-sommer/raku/ch-1.raku b/challenge-165/arne-sommer/raku/ch-1.raku new file mode 100755 index 0000000000..e37805ae44 --- /dev/null +++ b/challenge-165/arne-sommer/raku/ch-1.raku @@ -0,0 +1,95 @@ +#! /usr/bin/env raku + +unit sub MAIN ($file where $file.IO.f && $file.IO.r, :l(:$lsm)); + +my @lines; +my @points; +my $height = 0; +my $width = 0; + +for $file.IO.lines.words -> $element +{ + my (@elems) = $element.split(","); + + if (@elems.elems == 4) + { + @lines.push: @elems; + + $height = max($height, @elems[1], @elems[3].Numeric); + $width = max($width, @elems[0], @elems[2].Numeric); + } + elsif (@elems.elems == 2) + { + @points.push: @elems; + + $height = max($height, @elems[1].Numeric); + $width = max($width, @elems[0].Numeric); + } + else + { + die "Wrong number of values; use 2 or 4 only"; + } +} + +if $lsm +{ + die "'Line of Best Fit' cannot be used with a dataset with lines" if @lines.elems; + + my $x = 0; + my $y = 0; + my $xx = 0; + my $xy = 0; + + my $N = @points.elems; + + my $min-x = Inf; + my $max-x = 0; + + for @points -> @point + { + my ($X, $Y) = @point; + + $min-x = min($min-x, $X.Numeric); + $max-x = max($max-x, $X.Numeric); + + $x += $X; + $y += $Y; + $xx += $X ** 2; + $xy += $X * $Y; + } + + my $m = ($N * $xy - $x * $y) / ($N * $xx - $x ** 2); + my $b = ($y - $m * $x) / $N; + + @lines.push(($min-x, ($m * $min-x) + $b, $max-x, ($m * $max-x) + $b)); +} + +say '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="' ~ $height +3 ~ '" width="' ~ $width +3 ~'" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'; + +if @points +{ + say '<g fill="#f73" id="points">'; + + for @points -> @point + { + say ' <circle cx="' ~ @point[0] ~ '" cy="' ~ @point[1] ~ '" r="3" />'; + } + + say '</g>'; +} + +if @lines +{ + say '<g id="lines" stroke="#369" stroke-width="4">'; + + for @lines -> @line + { + say ' <line x1="' ~ @line[0] ~ '" x2="' ~ @line[2] ~ '" y1="' ~ @line[1] ~ '" y2="' ~ @line[3] ~ '" />' + } + + say '</g>'; +} + +say '</svg>'; diff --git a/challenge-165/arne-sommer/raku/ch-2.raku b/challenge-165/arne-sommer/raku/ch-2.raku new file mode 100755 index 0000000000..e37805ae44 --- /dev/null +++ b/challenge-165/arne-sommer/raku/ch-2.raku @@ -0,0 +1,95 @@ +#! /usr/bin/env raku + +unit sub MAIN ($file where $file.IO.f && $file.IO.r, :l(:$lsm)); + +my @lines; +my @points; +my $height = 0; +my $width = 0; + +for $file.IO.lines.words -> $element +{ + my (@elems) = $element.split(","); + + if (@elems.elems == 4) + { + @lines.push: @elems; + + $height = max($height, @elems[1], @elems[3].Numeric); + $width = max($width, @elems[0], @elems[2].Numeric); + } + elsif (@elems.elems == 2) + { + @points.push: @elems; + + $height = max($height, @elems[1].Numeric); + $width = max($width, @elems[0].Numeric); + } + else + { + die "Wrong number of values; use 2 or 4 only"; + } +} + +if $lsm +{ + die "'Line of Best Fit' cannot be used with a dataset with lines" if @lines.elems; + + my $x = 0; + my $y = 0; + my $xx = 0; + my $xy = 0; + + my $N = @points.elems; + + my $min-x = Inf; + my $max-x = 0; + + for @points -> @point + { + my ($X, $Y) = @point; + + $min-x = min($min-x, $X.Numeric); + $max-x = max($max-x, $X.Numeric); + + $x += $X; + $y += $Y; + $xx += $X ** 2; + $xy += $X * $Y; + } + + my $m = ($N * $xy - $x * $y) / ($N * $xx - $x ** 2); + my $b = ($y - $m * $x) / $N; + + @lines.push(($min-x, ($m * $min-x) + $b, $max-x, ($m * $max-x) + $b)); +} + +say '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="' ~ $height +3 ~ '" width="' ~ $width +3 ~'" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'; + +if @points +{ + say '<g fill="#f73" id="points">'; + + for @points -> @point + { + say ' <circle cx="' ~ @point[0] ~ '" cy="' ~ @point[1] ~ '" r="3" />'; + } + + say '</g>'; +} + +if @lines +{ + say '<g id="lines" stroke="#369" stroke-width="4">'; + + for @lines -> @line + { + say ' <line x1="' ~ @line[0] ~ '" x2="' ~ @line[2] ~ '" y1="' ~ @line[1] ~ '" y2="' ~ @line[3] ~ '" />' + } + + say '</g>'; +} + +say '</svg>'; diff --git a/challenge-165/arne-sommer/raku/mksvg-turbo b/challenge-165/arne-sommer/raku/mksvg-turbo new file mode 100755 index 0000000000..88a0db172a --- /dev/null +++ b/challenge-165/arne-sommer/raku/mksvg-turbo @@ -0,0 +1,165 @@ +#! /usr/bin/env raku + +unit sub MAIN ($file where $file.IO.f && $file.IO.r, :l(:$lsm)); + +my $height = 0; +my $width = 0; +my $padding = 0; +my $line-width = 4; +my $line-colour = "#336699"; +my $circle-radius = 3; +my $circle-colour = "#FF7733"; +my $fill-colour = "#000000"; +my $text-height = 8; +my $text-font = "sans-serif"; +my $text-colour = "#ffffff"; +my $letter-spacing = 'normal'; +my $fixed-height = False; +my $fixed-width = False; +my @svg; +my @points; + +for $file.IO.lines.words -> $element +{ + my (@elems) = $element.split(","); + + if (@elems.elems == 1) + { + if @elems[0] ~~ /^\:h\:(\d+)$/ + { + $height = $0.Numeric; $fixed-height = True; + } + elsif @elems[0] ~~ /^\:w\:(\d+)$/ + { + $width = $0.Numeric; $fixed-width = True; + } + elsif @elems[0] ~~ /^\:p\:(\d+)$/ + { + $padding = $0.Numeric; + } + elsif @elems[0] ~~ /^\:cr\:(\d+)$/ + { + $circle-radius = $0.Numeric; + } + elsif @elems[0] ~~ /^\:lw\:(\d+)$/ + { + $line-width = $0.Numeric; + } + elsif @elems[0] ~~ /^\:lc\:(\#......)$/ + { + $line-colour = $0.Str; + } + elsif @elems[0] ~~ /^\:fc\:(\#......)$/ + { + $fill-colour = $0.Str; + } + elsif @elems[0] ~~ /^\:cc\:(\#......)$/ + { + $circle-colour = $0.Str; + } + elsif @elems[0] ~~ /^\:tc\:(\#......)$/ + { + $text-colour = $0.Str; + } + elsif @elems[0] ~~ /^\:tf\:(.+)$/ + { + $text-font = $0.Str; + } + elsif @elems[0] ~~ /^\:th\:(\d+)$/ + { + $text-height = $0.Numeric; + } + elsif @elems[0] ~~ /^\:ls\:(.+)$/ + { + $letter-spacing = $0.Str; + } + else { + die "Illegal: @elems[0]"; + } + } + + elsif (@elems.elems == 2) + { + @svg.push: '<circle cx="' ~ @elems[0] ~ '" cy="' ~ @elems[1] ~ '" r="' ~ $circle-radius ~ '" fill="' ~ $circle-colour ~ '"/>'; + + @points.push: @elems if $lsm; + + $height = max($height, @elems[1].Numeric) unless $fixed-height; + $width = max($width, @elems[0].Numeric) unless $fixed-width; + } + elsif (@elems[0] eq "p") + { + my $svg = '<polygon points="'; + + my @points = @elems[1 .. Inf]; + while (@points.elems >= 2) + { + $svg ~= @points.shift ~ "," ~ @points.shift ~ " "; + } + $svg ~= '" style="fill: ' ~ $fill-colour ~ ';"/>'; + @svg.push: $svg; + } + elsif (@elems.elems == 4 && @elems[0] eq "t") + { + @svg.push: '<text x="' ~ @elems[1] ~ '" y="' ~ @elems[2] ~ '" style="font-family: ' ~ $text-font ~ '; font-size: ' + ~ $text-height ~ 'pt; stroke: none; fill:' ~ $text-colour ~ '; letter-spacing: ' ~ $letter-spacing ~ ';">' ~ @elems[3] ~ '</text>'; + } + elsif (@elems.elems == 4) + { + @svg.push: '<line x1="' ~ @elems[0] ~ '" x2="' ~ @elems[2] ~ '" y1="' ~ @elems[1] ~ '" y2="' ~ @elems[3] ~ '" stroke-width="' ~ $line-width ~ '" stroke="' ~ $line-colour ~ '"/>'; + + $height = max($height, @elems[1], @elems[3].Numeric) unless $fixed-height; + $width = max($width, @elems[0], @elems[2].Numeric) unless $fixed-width; + } + elsif (@elems.elems == 5 && @elems[0] eq "r") + { + @svg.push: '<rect x="' ~ @elems[1] ~ '" y="' ~ @elems[2] ~ '" width="' ~ @elems[3] ~ '" height="' ~ @elems[4] ~ '" fill="' ~ $fill-colour ~ '"/>'; + + $height = max($height, @elems[2] + @elems[4]) unless $fixed-height; + $width = max($width, @elems[1] + @elems[3]) unless $fixed-width; + } + + + else + { + die "Wrong number of values; use 2 or 4 only"; + } +} + +if $lsm +{ + my $x = 0; + my $y = 0; + my $xx = 0; + my $xy = 0; + + my $N = @points.elems; + + my $min-x = Inf; + my $max-x = 0; + + for @points -> @point + { + my ($X, $Y) = @point; + + $min-x = min($min-x, $X.Numeric); + $max-x = max($max-x, $X.Numeric); + + $x += $X; + $y += $Y; + $xx += $X ** 2; + $xy += $X * $Y; + } + + my $m = ($N * $xy - $x * $y) / ($N * $xx - $x ** 2); + my $b = ($y - $m * $x) / $N; + + @svg.push: ' <line x1="' ~ $min-x ~ '" y1="' ~ ($m * $min-x) + $b ~ '" x2="' ~ $max-x ~ '" y2="' ~ ($m * $max-x) + $b ~ '" stroke-width="' ~ $line-width ~ '" stroke="' ~ $line-colour ~ '"/>'; +} + +say '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="' ~ $height + $padding ~ '" width="' ~ $width + $padding ~'" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'; + +say @svg.join("\n"); +say '</svg>'; diff --git a/challenge-165/arne-sommer/raku/mksvg1 b/challenge-165/arne-sommer/raku/mksvg1 new file mode 100755 index 0000000000..8ec47d096c --- /dev/null +++ b/challenge-165/arne-sommer/raku/mksvg1 @@ -0,0 +1,63 @@ +#! /usr/bin/env raku + +unit sub MAIN ($file where $file.IO.f && $file.IO.r); + +my @lines; +my @points; +my $height = 0; +my $width = 0; + +for $file.IO.lines -> $row +{ + my (@elems) = $row.split(","); + + if (@elems.elems == 4) + { + @lines.push: @elems; + + $height = max($height, @elems[1], @elems[3].Numeric); + $width = max($width, @elems[0], @elems[2].Numeric); + } + elsif (@elems.elems == 2) + { + @points.push: @elems; + + $height = max($height, @elems[1].Numeric); + $width = max($width, @elems[0].Numeric); + } + else + { + die "Wrong number of values; use 2 or 4 only"; + } +} + +say '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="' ~ $height ~ '" width="' ~ $width ~'" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'; + +if @lines +{ + say '<g id="lines" stroke="#369" stroke-width="4">'; + + for @lines -> @line + { + say ' <line x1="' ~ @line[0] ~ '" x2="' ~ @line[2] ~ '" y1="' ~ @line[1] ~ '" y2="' ~ @line[3] ~ '" />' + } + + say '</g>'; +} + +if @points +{ + say '<g fill="#f73" id="points">'; + + for @points -> @point + { + say ' <circle cx="' ~ @point[0] ~ '" cy="' ~ @point[1] ~ '" r="3" />'; + } + + say '</g>'; +} + +say '</svg>'; + diff --git a/challenge-165/arne-sommer/raku/mksvg2 b/challenge-165/arne-sommer/raku/mksvg2 new file mode 100755 index 0000000000..1800f5b90b --- /dev/null +++ b/challenge-165/arne-sommer/raku/mksvg2 @@ -0,0 +1,63 @@ +#! /usr/bin/env raku + +unit sub MAIN ($file where $file.IO.f && $file.IO.r); + +my @lines; +my @points; +my $height = 0; +my $width = 0; + +for $file.IO.lines -> $element +{ + my (@elems) = $element.split(","); + + if (@elems.elems == 4) + { + @lines.push: @elems; + + $height = max($height, @elems[1], @elems[3].Numeric); + $width = max($width, @elems[0], @elems[2].Numeric); + } + elsif (@elems.elems == 2) + { + @points.push: @elems; + + $height = max($height, @elems[1].Numeric); + $width = max($width, @elems[0].Numeric); + } + else + { + die "Wrong number of values; use 2 or 4 only"; + } +} + +say '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="' ~ $height +3 ~ '" width="' ~ $width +3 ~'" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'; + +if @lines +{ + say '<g id="lines" stroke="#369" stroke-width="4">'; + + for @lines -> @line + { + say ' <line x1="' ~ @line[0] ~ '" x2="' ~ @line[2] ~ '" y1="' ~ @line[1] ~ '" y2="' ~ @line[3] ~ '" />' + } + + say '</g>'; +} + +if @points +{ + say '<g fill="#f73" id="points">'; + + for @points -> @point + { + say ' <circle cx="' ~ @point[0] ~ '" cy="' ~ @point[1] ~ '" r="3" />'; + } + + say '</g>'; +} + +say '</svg>'; + diff --git a/challenge-165/arne-sommer/raku/mksvg3 b/challenge-165/arne-sommer/raku/mksvg3 new file mode 100755 index 0000000000..e37805ae44 --- /dev/null +++ b/challenge-165/arne-sommer/raku/mksvg3 @@ -0,0 +1,95 @@ +#! /usr/bin/env raku + +unit sub MAIN ($file where $file.IO.f && $file.IO.r, :l(:$lsm)); + +my @lines; +my @points; +my $height = 0; +my $width = 0; + +for $file.IO.lines.words -> $element +{ + my (@elems) = $element.split(","); + + if (@elems.elems == 4) + { + @lines.push: @elems; + + $height = max($height, @elems[1], @elems[3].Numeric); + $width = max($width, @elems[0], @elems[2].Numeric); + } + elsif (@elems.elems == 2) + { + @points.push: @elems; + + $height = max($height, @elems[1].Numeric); + $width = max($width, @elems[0].Numeric); + } + else + { + die "Wrong number of values; use 2 or 4 only"; + } +} + +if $lsm +{ + die "'Line of Best Fit' cannot be used with a dataset with lines" if @lines.elems; + + my $x = 0; + my $y = 0; + my $xx = 0; + my $xy = 0; + + my $N = @points.elems; + + my $min-x = Inf; + my $max-x = 0; + + for @points -> @point + { + my ($X, $Y) = @point; + + $min-x = min($min-x, $X.Numeric); + $max-x = max($max-x, $X.Numeric); + + $x += $X; + $y += $Y; + $xx += $X ** 2; + $xy += $X * $Y; + } + + my $m = ($N * $xy - $x * $y) / ($N * $xx - $x ** 2); + my $b = ($y - $m * $x) / $N; + + @lines.push(($min-x, ($m * $min-x) + $b, $max-x, ($m * $max-x) + $b)); +} + +say '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg height="' ~ $height +3 ~ '" width="' ~ $width +3 ~'" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'; + +if @points +{ + say '<g fill="#f73" id="points">'; + + for @points -> @point + { + say ' <circle cx="' ~ @point[0] ~ '" cy="' ~ @point[1] ~ '" r="3" />'; + } + + say '</g>'; +} + +if @lines +{ + say '<g id="lines" stroke="#369" stroke-width="4">'; + + for @lines -> @line + { + say ' <line x1="' ~ @line[0] ~ '" x2="' ~ @line[2] ~ '" y1="' ~ @line[1] ~ '" y2="' ~ @line[3] ~ '" />' + } + + say '</g>'; +} + +say '</svg>'; |
