diff options
| author | drbaggy <js5@sanger.ac.uk> | 2022-05-23 10:18:47 +0100 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2022-05-23 10:18:47 +0100 |
| commit | c03c8411079c6277c7b1558f9c953d72ef439f4f (patch) | |
| tree | 48ff682540917d8777260a6787450cda2474218f /challenge-165 | |
| parent | 18e184b6eefa2d76f36b9ae51753f49396af65c5 (diff) | |
| parent | 3e7c636b7168fa0cae1191abab965af749e167de (diff) | |
| download | perlweeklychallenge-club-c03c8411079c6277c7b1558f9c953d72ef439f4f.tar.gz perlweeklychallenge-club-c03c8411079c6277c7b1558f9c953d72ef439f4f.tar.bz2 perlweeklychallenge-club-c03c8411079c6277c7b1558f9c953d72ef439f4f.zip | |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'challenge-165')
| -rwxr-xr-x | challenge-165/e-choroba/perl/ch-1.pl | 105 | ||||
| -rwxr-xr-x | challenge-165/e-choroba/perl/ch-2.pl | 60 | ||||
| -rw-r--r-- | challenge-165/wambash/raku/ch-1.raku | 75 | ||||
| -rw-r--r-- | challenge-165/wambash/raku/ch-2.raku | 31 |
4 files changed, 271 insertions, 0 deletions
diff --git a/challenge-165/e-choroba/perl/ch-1.pl b/challenge-165/e-choroba/perl/ch-1.pl new file mode 100755 index 0000000000..9a22702560 --- /dev/null +++ b/challenge-165/e-choroba/perl/ch-1.pl @@ -0,0 +1,105 @@ +#!/usr/bin/perl +use warnings; +use strict; + +use Template; + +my $HELP = << '__HELP__'; +Usage: $0 input_file [width height] + +Use - for input_file to read standard input. +Width and height default to 400x300. +__HELP__ + +my $TEMPLATE = << '__SVG__'; +<?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 -%] + <g id="lines" stroke="#369" stroke-width="4"> + [%- FOREACH line IN lines %] + <line x1="[% line.0 %]" x2="[% line.2 %]" y1="[% line.1 %]" y2="[% line.3 %]" /> + [%- END %] + </g> +[% END- %] +[%- IF points -%] + <g fill="#f73" id="points"> + [%- FOREACH point IN points %] + <circle cx="[% point.0 %]" cy="[% point.1 %]" r="3" /> + [%- END %] + </g> +[%- END %] +</svg> +__SVG__ + +my $file = shift; +if (! defined $file || $file =~ /^(?:-h|--help)$/) { + print $HELP; + exit ! defined $file +} + +my $width = shift || 400; +my $height = shift || 300; + +my ($min_x, $max_x, $min_y, $max_y); +my (@points, @lines); +my $FLOAT = qr/-?(?:[0-9]*(?:\.[0-9]+)?+)/; + +my $in; +if ('-' eq $file) { + $in = *STDIN; +} else { + open $in, '<', $file or die "$file: $!"; +} + +while (<$in>) { + if (/^($FLOAT),($FLOAT),($FLOAT),($FLOAT)$/) { + my ($x0, $y0, $x1, $y1) = ($1, $2, $3, $4); + push @lines, [$x0, $y0, $x1, $y1]; + for my $x ($x0, $x1) { + $min_x = $x if ! defined $min_x || $x < $min_x; + $max_x = $x if ! defined $max_x || $x > $max_x; + } + for my $y ($y0, $y1) { + $min_y = $y if ! defined $min_y || $y < $min_y; + $max_y = $y if ! defined $max_y || $y > $max_y; + } + + } elsif (/^($FLOAT),($FLOAT)$/) { + my ($x, $y) = ($1, $2); + push @points, [$x, $y]; + $min_x = $x if ! defined $min_x || $x < $min_x; + $max_x = $x if ! defined $max_x || $x > $max_x; + $min_y = $y if ! defined $min_y || $y < $min_y; + $max_y = $y if ! defined $max_y || $y > $max_y; + + } else { + warn "WARN: Ignoring: $_"; + } +} + +my $scale_x = ($max_x - $min_x) / $width; +my $scale_y = ($max_y - $min_y) / $height; +$_ ||= 1 for $scale_x, $scale_y; + +for my $point (@points) { + $point->[0] = ($point->[0] - $min_x) / $scale_x; + $point->[1] = ($point->[1] - $min_y) / $scale_y; +} +for my $line (@lines) { + $line->[$_] = ($line->[$_] - $min_x) / $scale_x for 0, 2; + $line->[$_] = ($line->[$_] - $min_y) / $scale_y for 1, 3; +} + +my $template = 'Template'->new; +$template->process(\$TEMPLATE, + {height => $height, + width => $width, + points => \@points, + lines => \@lines} +) or die $template->error; + +__DATA__ +53,10 +53,10,23,30 +23,30 diff --git a/challenge-165/e-choroba/perl/ch-2.pl b/challenge-165/e-choroba/perl/ch-2.pl new file mode 100755 index 0000000000..700420a82c --- /dev/null +++ b/challenge-165/e-choroba/perl/ch-2.pl @@ -0,0 +1,60 @@ +#!/usr/bin/perl +use warnings; +use strict; +use feature qw{ say }; + +use ARGV::OrDATA; +use List::Util qw{ sum }; + +=head1 Usage + +ch-2.pl input_file | ch-1.pl - > out.svg + +=cut + +my @points; +while (<>) { + push @points, map [split /,/], split; +} + +my ($min_x, $max_x, $min_y, $max_y) + = (($points[0][0]) x 2, ($points[0][1]) x 2); +for my $point (@points[1 .. $#points]) { + $min_x = $point->[0] if $point->[0] < $min_x; + $min_y = $point->[1] if $point->[1] < $min_y; + $max_x = $point->[0] if $point->[0] > $max_x; + $max_y = $point->[1] if $point->[1] > $max_y; +} + +my $sum_x = sum(map $_->[0], @points); +my $sum_y = sum(map $_->[1], @points); +my $sum_x_square = sum(map $_->[0] * $_->[0], @points); +my $sum_xy = sum(map $_->[0] * $_->[1], @points); + +my $divisor = @points * $sum_x_square - $sum_x * $sum_x; +my $slope = (@points * $sum_xy - $sum_x * $sum_y) + / ($divisor || 1); + +my $intercept = ($sum_y - $slope * $sum_x) / @points; + +my @line; +push @line, ($_, $intercept + $_ * $slope) for $min_x, $max_x; + +# Vertical. +if ($line[0] == $line[2] && $line[1] == $line[3]) { + $line[1] = $points[0][1]; + $line[3] = $points[1][1]; +} + +{ local $, = ','; + say @$_ for @points; + say @line; +} + +__DATA__ +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/wambash/raku/ch-1.raku b/challenge-165/wambash/raku/ch-1.raku new file mode 100644 index 0000000000..5d4409f1ce --- /dev/null +++ b/challenge-165/wambash/raku/ch-1.raku @@ -0,0 +1,75 @@ +#!/usr/bin/env raku + +role SVG { + method svg () { + '<' + ~ self.^name.gist.lc + ~ ' ' + ~ self.Capture.hash.sort.map( { .key ~ '=' ~ '"' ~ .value ~ '"' } ) + ~ ' ' + ~ '/>' + } +} + +class Circle does SVG { + has $.cx; + has $.cy; + has $.r = 2; + has $.fill = 'orange'; +} + +class Line does SVG { + has $.x1; + has $.y1; + has $.x2; + has $.y2; + has $.stroke= 'blue'; + has $.stroke-width = 1; +} + +sub svg ( +@svg, :$height = 400, :$width = 600 ) { + sprintf( q:to/END/ +<svg +version="1.1" +xmlns="http://www.w3.org/2000/svg" +xmlns:xlink="http://www.w3.org/1999/xlink" +height="%d" width="%d" +> +END +, $height, $width) + ~ @svg».svg.fmt( "\t%s", "\n" ) + ~ "\n" + ~ '</svg>' +} + +multi to-point-line (+@ ($cx, $cy) ) { + Circle.new: :$cx, :$cy +} + +multi to-point-line (+@ ($x1, $y1, $x2, $y2)) { + Line.new: :$x1, :$y1, :$x2, :$y2 +} + +multi MAIN (Int :$height = 400,Int :$width = 600 ) { + words() + andthen .map: *.split: ',' + andthen .map: &to-point-line + andthen svg $_, :$height, :$width + andthen .say +} + +multi MAIN (Bool :test($)!) { + use Test; + with to-point-line 23,10 { + isa-ok $_, Circle; + is (.cx,.cy),(23,10); + is .svg, '<circle cx="23" cy="10" fill="orange" r="2" />'; + } + with to-point-line 53,12, 23,10 { + isa-ok $_, Line; + is (.x1,.y1),(53,12); + is (.x2,.y2),(23,10); + is .svg, '<line stroke="blue" stroke-width="1" x1="53" x2="23" y1="12" y2="10" />'; + } + done-testing; +} diff --git a/challenge-165/wambash/raku/ch-2.raku b/challenge-165/wambash/raku/ch-2.raku new file mode 100644 index 0000000000..c27bb024ac --- /dev/null +++ b/challenge-165/wambash/raku/ch-2.raku @@ -0,0 +1,31 @@ +#!/usr/bin/env raku + + + + +sub line-of-best-fit (+@point) { + @point + andthen .map: { .[0]²,.[0], .[0],1, .[0] * .[1],.[1]}\ + andthen [Z,] $_ + andthen .map: *.sum + andthen (.[4]*.[3]-.[5]*.[2]),(.[0]*.[5]-.[1]*.[4]) X/ (.[0]*.[3]-.[1]*.[2]) +} + +multi MAIN (Bool :test($)!) { + use Test; + is line-of-best-fit((0,0),(1,1)),(1,0); + is line-of-best-fit((0,0),(1,2)),(2,0); + is line-of-best-fit((0,10),(1,20),(1,0)),(0,10); + done-testing; +} + +#| echo "333,129 39,189 140,156 292,134 393,52 160,166 362,122 363,89" | raku ch-2.raku -from=0 -to=400 | raku ch-1.raku -height=200 -width=400 > point-line.svg +multi MAIN (Numeric :$from=0,Numeric :$to=600) { + my $points= slurp(); + say $points; + $points.words() + andthen .map: *.split: ',' + andthen line-of-best-fit($_) + andthen $from,.[0]*$from+.[1], $to,.[0]*$to+.[1] + andthen .join(',').say +} |
