diff options
| author | Dave Jacoby <jacoby.david@gmail.com> | 2022-05-16 17:34:31 -0400 |
|---|---|---|
| committer | Dave Jacoby <jacoby.david@gmail.com> | 2022-05-16 17:34:31 -0400 |
| commit | 0f7d859ac857c9345d9d3a90a568ed1c0944f8c5 (patch) | |
| tree | b0e1a6d12b6736e2aea90fd2b21dcf823f342ccc | |
| parent | 1a6b4c6bbc7863ba26f2967d924b1abb476c11f3 (diff) | |
| download | perlweeklychallenge-club-0f7d859ac857c9345d9d3a90a568ed1c0944f8c5.tar.gz perlweeklychallenge-club-0f7d859ac857c9345d9d3a90a568ed1c0944f8c5.tar.bz2 perlweeklychallenge-club-0f7d859ac857c9345d9d3a90a568ed1c0944f8c5.zip | |
Plotting Revenge!
| -rw-r--r-- | challenge-165/dave-jacoby/blog.txt | 1 | ||||
| -rw-r--r-- | challenge-165/dave-jacoby/perl/ch-1.pl | 60 | ||||
| -rw-r--r-- | challenge-165/dave-jacoby/perl/ch-2.pl | 126 |
3 files changed, 187 insertions, 0 deletions
diff --git a/challenge-165/dave-jacoby/blog.txt b/challenge-165/dave-jacoby/blog.txt new file mode 100644 index 0000000000..6c35511988 --- /dev/null +++ b/challenge-165/dave-jacoby/blog.txt @@ -0,0 +1 @@ +https://jacoby.github.io/2022/05/16/plotting-revenge-weekly-challenge-165.html diff --git a/challenge-165/dave-jacoby/perl/ch-1.pl b/challenge-165/dave-jacoby/perl/ch-1.pl new file mode 100644 index 0000000000..8bf60ba071 --- /dev/null +++ b/challenge-165/dave-jacoby/perl/ch-1.pl @@ -0,0 +1,60 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use experimental qw{ say postderef signatures state }; + +use SVG; + +my $config = <<'END'; + +53,10 +53,10,23,30 +23, 30 + +END + +my @config = grep { /\d/ } split /\n/, $config; +my $svg = SVG->new( + height => 100, + width => 100, +); + +for my $entry (@config) { + my @coords = map { int $_ } split /,/, $entry; + add_line( $svg, \@coords ) if scalar @coords == 4; + add_point( $svg, \@coords, 'red' ) if scalar @coords == 2; +} + +my $output = $svg->xmlify; +say $output; +exit; + +sub add_line ( $svg, $coords, $color = 'black' ) { + $svg->line( + x1 => $coords->[0], + y1 => $coords->[1], + x2 => $coords->[2], + y2 => $coords->[3], + style => { + stroke => $color, + 'stroke-width' => 0.5, + fill => $color, + } + ); + +} + +sub add_point ( $svg, $coords, $color = 'black' ) { + $svg->circle( + cx => $coords->[0], + cy => $coords->[1], + r => 0.5, + style => { + stroke => $color, + 'stroke-width' => 0.5, + fill => $color, + } + ); +} + diff --git a/challenge-165/dave-jacoby/perl/ch-2.pl b/challenge-165/dave-jacoby/perl/ch-2.pl new file mode 100644 index 0000000000..ea42a23b39 --- /dev/null +++ b/challenge-165/dave-jacoby/perl/ch-2.pl @@ -0,0 +1,126 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use experimental qw{ say postderef signatures state }; + +use List::Util qw{ max min product sum0 }; +use SVG; +use Getopt::Long; + +my $verbose = 0; +GetOptions( 'verbose' => \$verbose, ); + +my $config = <<'END'; +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 +END + +# invert Y axis +my $w = 400; +my $h = 200; +my @config = map { + [ map { int } split /,/, $_ ] +} grep { /\d/ } split /\s+/, $config; + +say STDERR join "\n", map { join ',', $_->@* } + sort { $a->[0] <=> $b->[0] } @config + if $verbose; + +# transform the Y axis because with SVG, 0 is in the +# upper left corner, but for traditional mathematics, +# it is in the lower left corner. +@config = map { $_->[1] = $h - $_->[1]; $_ } @config; + +# a good next step might be to scale and orient the +# graph to a hardcoded maybe 500x500 plot size + +my $svg = SVG->new( + height => $h, + width => $w, +); + +# outline the box +add_line( $svg, [ 0, 0, 0, $h ], 'gray', 3 ); +add_line( $svg, [ 0, 0, $w, 0 ], 'gray', 3 ); +add_line( $svg, [ $w, $h, 0, $h ], 'gray', 3 ); +add_line( $svg, [ $w, $h, $w, 0 ], 'gray', 3 ); + +# plot every entry +for my $entry (@config) { + my @coords = $entry->@*; + add_point( $svg, \@coords, 'red', 2 ); +} + +# lots of math +my $maxx = max map { $_->[0] } @config; +my $minx = min map { $_->[0] } @config; + +my $N = scalar @config; +my $sumx = sum0 map { $_->[0] } @config; +my $sumx2 = sum0 map { $_->[0]**2 } @config; +my $sumy = sum0 map { $_->[1] } @config; +my $sumxy = sum0 map { product $_->@* } @config; + +my $m = sprintf '%.2f', + ( $N * $sumxy - ( $sumx * $sumy ) ) / ( $N * $sumx2 - ( $sumx**2 ) ); +my $bi = sprintf '%.2f', ( $sumy - ( $m * $sumx ) ) / $N; + +my $miny = $m * $minx + $bi; +my $maxy = $m * $maxx + $bi; + +say STDERR <<"END" if $verbose; + N: $N + sumx: $sumx + sumx2: $sumx2 + sumy: $sumy + sumxy: $sumxy + m: $m + b: $bi + maxx: $maxx + maxy: $maxy + minx: $minx + miny: $miny + y = ${m}x + $bi + +END + +# plot the +add_line( $svg, [ $maxx, $maxy, $minx, $miny ], 'blue' ); + +my $output = $svg->xmlify; +say $output; +exit; + +sub add_line ( $svg, $coords, $color = 'black', $width = 0.5 ) { + $svg->line( + x1 => $coords->[0], + y1 => $coords->[1], + x2 => $coords->[2], + y2 => $coords->[3], + style => { + stroke => $color, + 'stroke-width' => $width, + fill => $color, + } + ); + +} + +sub add_point ( $svg, $coords, $color = 'black', $width = 0.5 ) { + $svg->circle( + cx => $coords->[0], + cy => $coords->[1], + r => 0.7, + style => { + stroke => $color, + 'stroke-width' => $width, + fill => $color, + } + ); +} + |
