aboutsummaryrefslogtreecommitdiff
path: root/challenge-165
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2022-05-23 01:26:50 +0100
committerGitHub <noreply@github.com>2022-05-23 01:26:50 +0100
commited5917c3c3a3ab53630c5d7b3039952a64b27a87 (patch)
tree522bfcf24fc0a4388fb8be83869f1ca4b70eaaeb /challenge-165
parent8b9573190a579cd67a29910d92e131c27370cfcf (diff)
parentf930157274cfb6bad199b5cdf134fdbc15bae5ab (diff)
downloadperlweeklychallenge-club-ed5917c3c3a3ab53630c5d7b3039952a64b27a87.tar.gz
perlweeklychallenge-club-ed5917c3c3a3ab53630c5d7b3039952a64b27a87.tar.bz2
perlweeklychallenge-club-ed5917c3c3a3ab53630c5d7b3039952a64b27a87.zip
Merge pull request #6139 from simbabque/challenge-165
Challenge 165 in typescript and node
Diffstat (limited to 'challenge-165')
-rw-r--r--challenge-165/julien-fiegehenn/typescript/.gitignore3
-rw-r--r--challenge-165/julien-fiegehenn/typescript/.nvmrc1
-rw-r--r--challenge-165/julien-fiegehenn/typescript/ch-1.ts41
-rw-r--r--challenge-165/julien-fiegehenn/typescript/ch-2.ts67
-rw-r--r--challenge-165/julien-fiegehenn/typescript/package-lock.json57
-rw-r--r--challenge-165/julien-fiegehenn/typescript/package.json9
-rw-r--r--challenge-165/julien-fiegehenn/typescript/plot.ts67
-rw-r--r--challenge-165/julien-fiegehenn/typescript/tsconfig.json7
8 files changed, 252 insertions, 0 deletions
diff --git a/challenge-165/julien-fiegehenn/typescript/.gitignore b/challenge-165/julien-fiegehenn/typescript/.gitignore
new file mode 100644
index 0000000000..5f76cd577a
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/.gitignore
@@ -0,0 +1,3 @@
+/*.js
+/node_modules
+/output.svg \ No newline at end of file
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
new file mode 100644
index 0000000000..3df99b09f7
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/ch-1.ts
@@ -0,0 +1,41 @@
+#!/usr/bin/env node
+
+// Task 1: Scalable Vector Graphics (SVG)
+//
+// Scalable Vector Graphics (SVG) are not made of pixels, but lines, ellipses,
+// and curves, that can be scaled to any size without any loss of quality. If
+// you have ever tried to resize a small JPG or PNG, you know what I mean by
+// “loss of quality”! What many people do not know about SVG files is, they
+// are simply XML files, so they can easily be generated programmatically.
+//
+// For this task, you may use external library, such as Perl’s SVG library,
+// maintained in recent years by our very own Mohammad S Anwar. You can instead
+// generate the XML yourself; it’s actually quite simple. The source for the example
+// image for Task //2 might be instructive.
+//
+// Your task is to accept a series of points and lines in the following
+// format, one per line, in arbitrary order:
+//
+// Point: x,y
+// Line: x1,y1,x2,y2
+//
+// Example:
+// 53,10
+// 53,10,23,30
+// 23,30
+//
+// 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, PlotPoint, PlotLine } from "./plot";
+
+const input: string = `53,10
+53,10,23,30
+23,30`;
+
+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/package-lock.json b/challenge-165/julien-fiegehenn/typescript/package-lock.json
new file mode 100644
index 0000000000..c4c36fc17d
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/package-lock.json
@@ -0,0 +1,57 @@
+{
+ "name": "typescript",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "dependencies": {
+ "svg-builder": "^2.0.0",
+ "typescript": "^4.6.4"
+ },
+ "devDependencies": {
+ "@types/node": "^17.0.35"
+ }
+ },
+ "node_modules/@types/node": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz",
+ "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==",
+ "dev": true
+ },
+ "node_modules/svg-builder": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/svg-builder/-/svg-builder-2.0.0.tgz",
+ "integrity": "sha512-v89FptvyrOy1Gf9KPkIo2jxroCLEZLiGBRTSutL3pzqZe2xnCFltkCLnEjV8QOEJ99PzBa9NGPGEDP9l8MWIrw=="
+ },
+ "node_modules/typescript": {
+ "version": "4.6.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
+ "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ }
+ },
+ "dependencies": {
+ "@types/node": {
+ "version": "17.0.35",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.35.tgz",
+ "integrity": "sha512-vu1SrqBjbbZ3J6vwY17jBs8Sr/BKA+/a/WtjRG+whKg1iuLFOosq872EXS0eXWILdO36DHQQeku/ZcL6hz2fpg==",
+ "dev": true
+ },
+ "svg-builder": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/svg-builder/-/svg-builder-2.0.0.tgz",
+ "integrity": "sha512-v89FptvyrOy1Gf9KPkIo2jxroCLEZLiGBRTSutL3pzqZe2xnCFltkCLnEjV8QOEJ99PzBa9NGPGEDP9l8MWIrw=="
+ },
+ "typescript": {
+ "version": "4.6.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz",
+ "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg=="
+ }
+ }
+}
diff --git a/challenge-165/julien-fiegehenn/typescript/package.json b/challenge-165/julien-fiegehenn/typescript/package.json
new file mode 100644
index 0000000000..0db323f71e
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/package.json
@@ -0,0 +1,9 @@
+{
+ "dependencies": {
+ "svg-builder": "^2.0.0",
+ "typescript": "^4.6.4"
+ },
+ "devDependencies": {
+ "@types/node": "^17.0.35"
+ }
+}
diff --git a/challenge-165/julien-fiegehenn/typescript/plot.ts b/challenge-165/julien-fiegehenn/typescript/plot.ts
new file mode 100644
index 0000000000..cad483a752
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/plot.ts
@@ -0,0 +1,67 @@
+//import svg = require("svg-builder");
+import * as svg from "svg-builder";
+import { SvgBuilder } from "svg-builder";
+import * as fs from "fs";
+
+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 {
+ private svg: SvgBuilder = svg;
+
+ private size: number = 200;
+
+ input: PlotData;
+
+ constructor(input: PlotData) {
+ this.input = input;
+ }
+
+ toSvg(): boolean {
+ this.input.forEach((record) => {
+ if (record.length === 2) {
+ this.addPoint(record);
+ } else {
+ this.addLine(record);
+ }
+ });
+
+ this.svg = this.svg.width(this.size).height(this.size);
+
+ try {
+ fs.writeFileSync("output.svg", this.svg.render());
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }
+
+ addPoint(point: PlotPoint): void {
+ this.svg = this.svg.circle({
+ r: 3,
+ fill: "orange",
+ stroke: "orange",
+ cx: point[0],
+ cy: point[1],
+ });
+
+ this.size = Math.max(this.size, ...point);
+ }
+
+ addLine(line: PlotLine): void {
+ this.svg = this.svg.line({
+ stroke: "blue",
+ fill: "blue",
+ "stroke-width": 3,
+ x1: line[0],
+ y1: line[1],
+ x2: line[2],
+ y2: line[3],
+ });
+
+ this.size = Math.max(this.size, ...line);
+ }
+}
diff --git a/challenge-165/julien-fiegehenn/typescript/tsconfig.json b/challenge-165/julien-fiegehenn/typescript/tsconfig.json
new file mode 100644
index 0000000000..3e3ab9fae8
--- /dev/null
+++ b/challenge-165/julien-fiegehenn/typescript/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "compilerOptions": {
+ "target": "ES6",
+ "module": "CommonJS",
+ "lib": ["ES6", "DOM"]
+ }
+} \ No newline at end of file