aboutsummaryrefslogtreecommitdiff
path: root/challenge-165
diff options
context:
space:
mode:
authorJulien Fiegehenn <simbabque@cpan.org>2022-05-21 10:41:27 +0100
committerJulien Fiegehenn <simbabque@cpan.org>2022-05-21 10:41:27 +0100
commitf930157274cfb6bad199b5cdf134fdbc15bae5ab (patch)
treec3c6db73e6d2cfb8a30712231a8a14b7d727cd37 /challenge-165
parentf6169247b4a83c56d87590e5c476ad2d883a1b57 (diff)
downloadperlweeklychallenge-club-f930157274cfb6bad199b5cdf134fdbc15bae5ab.tar.gz
perlweeklychallenge-club-f930157274cfb6bad199b5cdf134fdbc15bae5ab.tar.bz2
perlweeklychallenge-club-f930157274cfb6bad199b5cdf134fdbc15bae5ab.zip
challenge 165, task 2 in node/typescript
This was hard. I learned a lot about the types. Also had to fix a few things I did wrong in task 1.
Diffstat (limited to 'challenge-165')
-rw-r--r--challenge-165/julien-fiegehenn/typescript/.nvmrc1
-rw-r--r--challenge-165/julien-fiegehenn/typescript/ch-1.ts8
-rw-r--r--challenge-165/julien-fiegehenn/typescript/ch-2.ts67
-rw-r--r--challenge-165/julien-fiegehenn/typescript/plot.ts23
4 files changed, 89 insertions, 10 deletions
diff --git a/challenge-165/julien-fiegehenn/typescript/.nvmrc b/challenge-165/julien-fiegehenn/typescript/.nvmrc
new file mode 100644
index 0000000000..b0c352f157
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/.nvmrc
@@ -0,0 +1 @@
+v11 \ No newline at end of file
diff --git a/challenge-165/julien-fiegehenn/typescript/ch-1.ts b/challenge-165/julien-fiegehenn/typescript/ch-1.ts
index 32a611a2f9..3df99b09f7 100644
--- a/challenge-165/julien-fiegehenn/typescript/ch-1.ts
+++ b/challenge-165/julien-fiegehenn/typescript/ch-1.ts
@@ -27,11 +27,15 @@
// Then, generate an SVG file plotting all points, and all lines.
// If done correctly, you can view the output .svg file in your browser.
-import { Plot, PlotData } from "./plot";
+import { Plot, PlotPoint, PlotLine } from "./plot";
const input: string = `53,10
53,10,23,30
23,30`;
-const plot = new Plot(input.split("\n").map((line) => line.split(",")));
+const plot: Plot = new Plot(
+ input
+ .split("\n")
+ .map((line) => line.split(",").map(parseInt) as PlotPoint | PlotLine)
+);
plot.toSvg();
diff --git a/challenge-165/julien-fiegehenn/typescript/ch-2.ts b/challenge-165/julien-fiegehenn/typescript/ch-2.ts
new file mode 100644
index 0000000000..6177c7968d
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/ch-2.ts
@@ -0,0 +1,67 @@
+#!/usr/bin/env node
+
+// Task 2: Line of Best Fit
+// When you have a scatter plot of points, a line of best fit is the line that
+// best describes the relationship between the points, and is very useful in
+// statistics. Otherwise known as linear regression, here is an example of what
+// such a line might look like:
+//
+// The method most often used is known as the least squares method, as it is
+// straightforward and efficient, but you may use any method that generates
+// the correct result.
+//
+// Calculate the line of best fit for the following 48 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
+//
+// Using your rudimentary graphing engine from Task #1, graph all points,
+// as well as the line of best fit.
+
+import { Plot, PlotData, PlotPoint } from "./plot";
+
+const input: string = `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
+`;
+
+// read the input and get all the points
+const points: PlotData = input
+ .split("\n")
+ .flatMap((line: string) => line.split(/\s+/))
+ .filter((e: string) => !!e)
+ .map((point: string) => point.split(",").map(Number) as PlotPoint);
+
+// get all the bits for the calculation
+const xSquared: number[] = [],
+ xY: number[] = [],
+ allX: number[] = [],
+ allY: number[] = [];
+points.forEach((p: PlotPoint) => {
+ xSquared.push(p[0] ** 2);
+ xY.push(p[0] * p[1]);
+ allX.push(p[0]);
+ allY.push(p[1]);
+});
+const numberOfPoints: number = points.length;
+
+// helper function to sum up the arrays
+const sum = (arr: number[]): number =>
+ arr.reduce((partialSum, a) => partialSum + a, 0);
+// m is the Slope of the line
+const m: number =
+ (numberOfPoints * sum(xY) - sum(allX) * sum(allY)) /
+ (numberOfPoints * sum(xSquared) - sum(allX) ** 2);
+
+// b is the Y interept
+const b: number = (sum(allY) - m * sum(allX)) / numberOfPoints;
+
+const plot: Plot = new Plot([...points, [1, m + b, 400, m * 400 + b]]);
+plot.toSvg();
diff --git a/challenge-165/julien-fiegehenn/typescript/plot.ts b/challenge-165/julien-fiegehenn/typescript/plot.ts
index 59fdcee5d2..cad483a752 100644
--- a/challenge-165/julien-fiegehenn/typescript/plot.ts
+++ b/challenge-165/julien-fiegehenn/typescript/plot.ts
@@ -3,30 +3,33 @@ import * as svg from "svg-builder";
import { SvgBuilder } from "svg-builder";
import * as fs from "fs";
-type PlotPoint = [number, number];
-type PlotLine = [number, number, number, number];
-export type PlotData = [PlotPoint | PlotLine];
+export type PlotPoint = [number, number];
+export type PlotLine = [number, number, number, number];
+// export type PlotPoint = number[];
+// export type PlotLine = number[];
+export type PlotData = Array<PlotPoint | PlotLine>;
export class Plot {
- svg: SvgBuilder = svg;
+ private svg: SvgBuilder = svg;
+
+ private size: number = 200;
input: PlotData;
- constructor(input: any) {
+
+ constructor(input: PlotData) {
this.input = input;
- console.log(input);
}
toSvg(): boolean {
this.input.forEach((record) => {
if (record.length === 2) {
- console.log(record);
this.addPoint(record);
} else {
this.addLine(record);
}
});
- this.svg = this.svg.width(200).height(200);
+ this.svg = this.svg.width(this.size).height(this.size);
try {
fs.writeFileSync("output.svg", this.svg.render());
@@ -44,6 +47,8 @@ export class Plot {
cx: point[0],
cy: point[1],
});
+
+ this.size = Math.max(this.size, ...point);
}
addLine(line: PlotLine): void {
@@ -56,5 +61,7 @@ export class Plot {
x2: line[2],
y2: line[3],
});
+
+ this.size = Math.max(this.size, ...line);
}
}