diff options
| author | Adam Russell <ac.russell@live.com> | 2022-05-22 15:34:29 -0400 |
|---|---|---|
| committer | Adam Russell <ac.russell@live.com> | 2022-05-22 15:34:29 -0400 |
| commit | 2c14aae1a4295a6ccc89d71d6a704a18c6f97b6b (patch) | |
| tree | 5ca362ddc6b5db0f06f4a2860bba94b769140cff /challenge-165 | |
| parent | 1a6b4c6bbc7863ba26f2967d924b1abb476c11f3 (diff) | |
| download | perlweeklychallenge-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.txt | 1 | ||||
| -rw-r--r-- | challenge-165/adam-russell/blog1.txt | 1 | ||||
| -rw-r--r-- | challenge-165/adam-russell/perl/ch-1.pl | 50 | ||||
| -rw-r--r-- | challenge-165/adam-russell/perl/ch-2.pl | 129 | ||||
| -rw-r--r-- | challenge-165/adam-russell/prolog/ch-1.p | 30 | ||||
| -rw-r--r-- | challenge-165/adam-russell/prolog/ch-2.p | 42 |
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. |
