Skip to content

Instantly share code, notes, and snippets.

@pseale
Last active December 12, 2016 06:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pseale/109501d0bfacba4be42d5e1f1778e8d4 to your computer and use it in GitHub Desktop.
Save pseale/109501d0bfacba4be42d5e1f1778e8d4 to your computer and use it in GitHub Desktop.
/* test results:
PASS __test__\day3.test.js
Acceptance tests
√ 5 10 25
√ 5 10 25, but not in any order of size
√ valid triangle 5 5 5
Vertical parsing
√ Input with wrong number of rows will throw an error (15ms)
√ Vertical triangles are parsed in groups of 3
*/
//-----------------------------------------------
//test file
import triangulator = require("../triangulator")
import input = require("../input")
describe("Acceptance tests", () => {
test("5 10 25", () => {
var result = triangulator.isTriangle(5, 10, 25)
expect(result.isLegalTriangle).toBe(false)
})
test("5 10 25, but not in any order of size", () => {
var result = triangulator.isTriangle(10, 25, 5)
expect(result.isLegalTriangle).toBe(false)
})
test("valid triangle 5 5 5", () => {
var result = triangulator.isTriangle(5, 5, 5)
expect(result.side1).toBe(5)
expect(result.side2).toBe(5)
expect(result.side3).toBe(5)
expect(result.isLegalTriangle).toBe(true)
})
})
describe("Vertical parsing", () => {
test("Input with wrong number of rows will throw an error", () => {
var lines = `1 2 3
1 2 3
1 2 3
1 2 3`
expect(() => input.parseInputForPartB(lines)).toThrow()
})
test("Vertical triangles are parsed in groups of 3", () => {
var lines = `3 4 5
6 7 8
9 10 11`
var result = input.parseInputForPartB(lines)
expect(result.length).toBe(3)
var triangle1 = result[0]
expect(triangle1.side1).toBe(3)
expect(triangle1.side2).toBe(6)
expect(triangle1.side3).toBe(9)
var triangle2 = result[1]
expect(triangle2.side1).toBe(4)
expect(triangle2.side2).toBe(7)
expect(triangle2.side3).toBe(10)
var triangle3 = result[2]
expect(triangle3.side1).toBe(5)
expect(triangle3.side2).toBe(8)
expect(triangle3.side3).toBe(11)
})
})
//---------------------------------------------
// main JS file
import _ = require("lodash")
import triangulator = require("./triangulator")
import color = require('cli-color')
import input = require("./input")
var partAResults = _(input.parseInputForPartA()).map(x => triangulator.isTriangle(x.side1, x.side2, x.side3)).value()
var partBResults = _(input.parseInputForPartB()).map(x => triangulator.isTriangle(x.side1, x.side2, x.side3)).value()
console.log("~~~~~~")
console.log("PART A")
console.log("~~~~~~")
_(partAResults).each(x => console.log(x.isLegalTriangle ? color.green([x.side1, x.side2, x.side3]) : color.red([x.side1, x.side2, x.side3])))
console.log("\n\n~~~~~~")
console.log("PART B")
console.log("~~~~~~")
_(partBResults).each(x => console.log(x.isLegalTriangle ? color.green([x.side1, x.side2, x.side3]) : color.red([x.side1, x.side2, x.side3])))
var numberOfTrianglesPartA = _(partAResults).filter(x => x.isLegalTriangle === true).value().length
console.log(`Part A Triangles: ${numberOfTrianglesPartA}`)
var numberOfTrianglesPartB = _(partBResults).filter(x => x.isLegalTriangle === true).value().length
console.log(`Part B Triangles: ${numberOfTrianglesPartB}`)
//-----------------------------------------------
//input parser
import _ = require("lodash")
interface Triangle {
side1 : number,
side2 : number,
side3 : number
}
export function parseInputForPartA(inp? : string) : Triangle[] {
var lines = input.split("\n")
return _(lines)
.filter(x => x.trim() !== "")
.map(x => x.trim())
.map(x => {
var sides = _(x.split(" "))
.map(y => y.trim())
.filter(y => y)
.value()
if (sides.length !== 3) {
throw `Cannot understand the triangle '${x}' - expected 3 sides, got {sides.length}`
}
var side1 = Number(sides[0])
var side2 = Number(sides[1])
var side3 = Number(sides[2])
return { side1: side1, side2: side2, side3: side3 }
})
.value()
}
function parseNumbers(line : string) : number[] {
return _(line.split(" "))
.filter(x => x !== "")
.map(n => {
var num = Number(n)
if (typeof(num) === "undefined") {
throw `Failed to interpret triangle side '${n}' as a number. Entire line: '${line}'`
}
return num
})
.value()
}
export function parseInputForPartB(inp? : string) : Triangle[] {
var inputToUse = typeof(inp) !== "undefined" ? inp : input
var lines =_(inputToUse.split("\n"))
.filter(x => x !== "")
.value()
if (lines.length % 3 !== 0) {
throw `Impossible to parse input with ${lines.length} lines - expected a multiple of 3`
}
var verticalTriangles = []
var linesInGroup = _(_.range(0,(lines.length / 3)))
.map(x => {
var group = _(lines.slice(x * 3, x * 3 + 3))
.map(line => parseNumbers(line))
.value()
return [
{ side1: group[0][0], side2: group[1][0], side3: group[2][0] },
{ side1: group[0][1], side2: group[1][1], side3: group[2][1] },
{ side1: group[0][2], side2: group[1][2], side3: group[2][2] }
]
})
.value()
return _.flatten(linesInGroup)
}
//-----------------------------------------------------
// triangulator
import _ = require('lodash')
interface TriangleMeasurement {
side1: number,
side2: number,
side3: number,
isLegalTriangle: boolean
}
export function isTriangle(side1 : number, side2 : number, side3 : number) : TriangleMeasurement {
var sortedSides = _([side1, side2, side3])
.sortBy(x => x)
.value()
var isLegalTriangle = sortedSides[0] + sortedSides[1] > sortedSides[2]
return { side1, side2, side3, isLegalTriangle }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment