aboutsummaryrefslogtreecommitdiff
path: root/challenge-165
diff options
context:
space:
mode:
authorAdam Russell <ac.russell@live.com>2022-05-22 15:34:29 -0400
committerAdam Russell <ac.russell@live.com>2022-05-22 15:34:29 -0400
commit2c14aae1a4295a6ccc89d71d6a704a18c6f97b6b (patch)
tree5ca362ddc6b5db0f06f4a2860bba94b769140cff /challenge-165
parent1a6b4c6bbc7863ba26f2967d924b1abb476c11f3 (diff)
downloadperlweeklychallenge-club-2c14aae1a4295a6ccc89d71d6a704a18c6f97b6b.tar.gz
perlweeklychallenge-club-2c14aae1a4295a6ccc89d71d6a704a18c6f97b6b.tar.bz2
perlweeklychallenge-club-2c14aae1a4295a6ccc89d71d6a704a18c6f97b6b.zip
initial commit
Diffstat (limited to 'challenge-165')
-rw-r--r--challenge-165/adam-russell/blog.txt1
-rw-r--r--challenge-165/adam-russell/blog1.txt1
-rw-r--r--challenge-165/adam-russell/perl/ch-1.pl50
-rw-r--r--challenge-165/adam-russell/perl/ch-2.pl129
-rw-r--r--challenge-165/adam-russell/prolog/ch-1.p30
-rw-r--r--challenge-165/adam-russell/prolog/ch-2.p42
6 files changed, 253 insertions, 0 deletions
diff --git a/challenge-165/adam-russell/blog.txt b/challenge-165/adam-russell/blog.txt
new file mode 100644
index 0000000000..f471ff3243
--- /dev/null
+++ b/challenge-165/adam-russell/blog.txt
@@ -0,0 +1 @@
+http://www.rabbitfarm.com/cgi-bin/blosxom/perl/2022/05/22
diff --git a/challenge-165/adam-russell/blog1.txt b/challenge-165/adam-russell/blog1.txt
new file mode 100644
index 0000000000..638c7f06cc
--- /dev/null
+++ b/challenge-165/adam-russell/blog1.txt
@@ -0,0 +1 @@
+http://www.rabbitfarm.com/cgi-bin/blosxom/prolog/2022/05/22
diff --git a/challenge-165/adam-russell/perl/ch-1.pl b/challenge-165/adam-russell/perl/ch-1.pl
new file mode 100644
index 0000000000..3d42c6c29a
--- /dev/null
+++ b/challenge-165/adam-russell/perl/ch-1.pl
@@ -0,0 +1,50 @@
+use strict;
+use warnings;
+##
+# Plot lines and points in SVG format.
+##
+sub svg_begin{
+ return <<BEGIN;
+ <?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="100%" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+BEGIN
+}
+
+sub svg_end{
+ return "</svg>";
+}
+
+sub svg_point{
+ my($x, $y) = @_;
+ return "<circle cx=\"$x\" cy=\"$y\" r=\"1\" />";
+}
+
+sub svg_line{
+ my($x0, $y0, $x1, $y1) = @_;
+ return "<line x1=\"$x0\" x2=\"$x1\" y1=\"$y0\" y2=\"$y1\" />";
+}
+
+sub svg{
+ my @lines = @_;
+ my $svg = svg_begin;
+ for my $line (@_){
+ $svg .= svg_point(@{$line}) if @{$line} == 2;
+ $svg .= svg_line(@{$line}) if @{$line} == 4;
+ }
+ return $svg . svg_end;
+}
+
+
+MAIN:{
+ my @lines;
+ while(<DATA>){
+ chomp;
+ push @lines, [split(/,/, $_)];
+ }
+ print svg(@lines);
+}
+
+
+__DATA__
+53,10
+53,10,23,30
+23,30
diff --git a/challenge-165/adam-russell/perl/ch-2.pl b/challenge-165/adam-russell/perl/ch-2.pl
new file mode 100644
index 0000000000..a5918b948c
--- /dev/null
+++ b/challenge-165/adam-russell/perl/ch-2.pl
@@ -0,0 +1,129 @@
+use strict;
+use warnings;
+##
+# Compute a linear regression and output an SVG plot of the points
+# and regression line.
+##
+sub svg_begin{
+ return <<BEGIN;
+ <?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="100%" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+BEGIN
+}
+
+sub svg_end{
+ return "</svg>";
+}
+
+sub svg_point{
+ my($x, $y) = @_;
+ return "<circle cx=\"$x\" cy=\"$y\" r=\"1\" />";
+}
+
+sub svg_line{
+ my($x0, $y0, $x1, $y1) = @_;
+ return "<line x1=\"$x0\" x2=\"$x1\" y1=\"$y0\" y2=\"$y1\" />";
+}
+
+sub svg{
+ my @lines = @_;
+ my $svg = svg_begin;
+ for my $line (@_){
+ $svg .= svg_point(@{$line}) if @{$line} == 2;
+ $svg .= svg_line(@{$line}) if @{$line} == 4;
+ }
+ return $svg . svg_end;
+}
+
+sub linear_regression{
+ my(@points) = @_;
+ # 1. Calculate average of your X variable.
+ my $sum = 0;
+ my $x_avg;
+ map{$sum += $_->[0]} @points;
+ $x_avg = $sum / @points;
+ # 2. Calculate the difference between each X and the average X.
+ my @x_differences = map{$_->[0] - $x_avg} @points;
+ # 3. Square the differences and add it all up. This is Sx.
+ my $sx = 0;
+ my @squares = map{$_ * $_} @x_differences;
+ map{$sx += $_} @squares;
+ # 4. Calculate average of your Y variable.
+ $sum = 0;
+ my $y_avg;
+ map{$sum += $_->[1]} @points;
+ $y_avg = $sum / @points;
+ my @y_differences = map{$_->[1] - $y_avg} @points;
+ # 5. Multiply the differences (of X and Y from their respective averages) and add them all together. This is Sxy.
+ my $sxy = 0;
+ @squares = map {$y_differences[$_] * $x_differences[$_]} 0 .. @points - 1;
+ map {$sxy += $_} @squares;
+ # 6. Using Sx and Sxy, you calculate the intercept by subtracting Sx / Sxy * AVG(X) from AVG(Y).
+ my $m = $sxy / $sx;
+ my $y_intercept = $y_avg - ($sxy / $sx * $x_avg);
+ my @sorted = sort {$a->[0] <=> $b->[0]} @points;
+ my $max_x = $sorted[@points - 1]->[0];
+ return [0, $y_intercept, $max_x + 10, $m * ($max_x + 10) + $y_intercept];
+}
+
+MAIN:{
+ my @points;
+ while(<DATA>){
+ chomp;
+ push @points, [split(/,/, $_)];
+ }
+ push @points, linear_regression(@points);
+ print svg(@points);
+}
+
+
+__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/adam-russell/prolog/ch-1.p b/challenge-165/adam-russell/prolog/ch-1.p
new file mode 100644
index 0000000000..216512621e
--- /dev/null
+++ b/challenge-165/adam-russell/prolog/ch-1.p
@@ -0,0 +1,30 @@
+svg-->svg_begin, svg_body, svg_end.
+svg_body-->[].
+svg_body-->svg_line(_, _, _, _), svg_body.
+svg_body-->svg_point(_, _), svg_body.
+svg_begin-->['<?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="100%" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'].
+svg_point(X, Y)-->['<circle cx="', X,'" cy="', Y, '" r="1" />'].
+svg_line(X1, Y1, X2, Y2)-->['<line x1="', X1, '" x2="', X2, '" y1="', Y1, '" y2="', Y2, '" />'].
+svg_end-->['</svg>'].
+
+plot([], SVGAccum, SVG):-
+ phrase(svg_begin, Begin),
+ flatten([Begin|SVGAccum], SVG).
+plot([H|T], SVGAccum, SVG):-
+ length(H, 2),
+ [X, Y] = H,
+ phrase(svg_point(X, Y), Point),
+ plot(T, [Point|SVGAccum], SVG).
+plot([H|T], SVGAccum, SVG):-
+ length(H, 4),
+ [X1, Y1, X2, Y2] = H,
+ phrase(svg_line(X1, Y1, X2, Y2), Line),
+ plot(T, [Line|SVGAccum], SVG).
+plot(Lines, SVG):-
+ phrase(svg_end, End),
+ plot(Lines, [End], SVG).
+
+main:-
+ plot([[53,10], [53, 10, 23, 30], [23, 30]], SVG),
+ maplist(write, SVG), nl,
+ halt.
diff --git a/challenge-165/adam-russell/prolog/ch-2.p b/challenge-165/adam-russell/prolog/ch-2.p
new file mode 100644
index 0000000000..923b5c5921
--- /dev/null
+++ b/challenge-165/adam-russell/prolog/ch-2.p
@@ -0,0 +1,42 @@
+
+avg_difference(Avg, V, Difference):-
+ Difference is V - Avg.
+
+square(X, XSquared):-
+ XSquared is X * X.
+
+xy(X, Y, XY):-
+ XY is X * Y.
+
+linear_regression(Points, RegressionLineEndpoints):-
+ length(Points, NumberPoints),
+ % 1. Calculate average of your X variable.
+ maplist(nth(1), Points, Xs),
+ msort(Xs, XSorted),
+ nth(NumberPoints, XSorted, XMax),
+ sum_list(Xs, XSum),
+ XAvg is XSum / NumberPoints,
+ % 2. Calculate the difference between each X and the average X.
+ maplist(avg_difference(XAvg), Xs, XDifferences),
+ % 3. Square the differences and add it all up. This is Sx.
+ maplist(square, XDifferences, XDifferencesSquared),
+ sum_list(XDifferencesSquared, Sx),
+ % 4. Calculate average of your Y variable.
+ maplist(nth(2), Points, Ys),
+ sum_list(Ys, YSum),
+ YAvg is YSum / NumberPoints,
+ % 5. Multiply the differences (of X and Y from their respective averages) and add them all together. This is Sxy.
+ maplist(avg_difference(YAvg), Ys, YDifferences),
+ maplist(xy, XDifferences, YDifferences, XY),
+ sum_list(XY, Sxy),
+ % 6. Using Sx and Sxy, you calculate the intercept by subtracting Sx / Sxy * AVG(X) from AVG(Y).
+ M is Sxy / Sx,
+ B is YAvg - (Sxy / Sx * XAvg),
+ EndX is XMax + 10,
+ EndY is M * EndX + B,
+ RegressionLineEndpoints = [0, B, EndX, EndY].
+
+main:-
+ Points = [[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]],
+ linear_regression(Points, RegressionLine),
+ write(RegressionLine), nl.