Skip to content

Instantly share code, notes, and snippets.

@davidwhitney
Created April 20, 2021 13:02
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 davidwhitney/e8ada5d6c66e9e5f46a319ebb0918228 to your computer and use it in GitHub Desktop.
Save davidwhitney/e8ada5d6c66e9e5f46a319ebb0918228 to your computer and use it in GitHub Desktop.
Diamond kata ts
import { DiamondMaker } from ".";
describe("DiamondMaker makes diamond", () => {
let sut: DiamondMaker;
beforeEach(() => {
sut = new DiamondMaker();
});
it("given A, returns only A", () => {
const result = sut.make("A");
expect(result[0]).toBe("A");
});
it("given not-A, not-A-char is on middle line", () => {
const target = noneACharacter();
const result = sut.make(target);
const middleLine = Math.floor(result.length / 2);
expect(result[middleLine]).toContain(target);
});
it("given not-A, diamond is correct height", () => {
const target = noneACharacter();
const alphaNumber = target.charCodeAt(0) - 64;
const expectedHeight = (alphaNumber * 2) - 1;
const result = sut.make(target);
expect(result.length).toBe(expectedHeight);
});
it("given not-A, midpoint letter occurs twice", () => {
const target = noneACharacter();
const result = sut.make(target);
const middleLine = Math.floor(result.length / 2);
const midLine = result[middleLine];
const countOfLetters = midLine.split('').filter(x => x === target).length;
expect(countOfLetters).toBe(2);
});
it("given not-A, non-midpoint lines also contain two letters", () => {
const target = "C";
const result = sut.make(target);
const nonMiddleLine = result[1];
const countOfLetters = nonMiddleLine.split('').filter(x => x === "B").length;
expect(countOfLetters).toBe(2);
const nonMiddleLine2 = result[3];
const countOfLetters2 = nonMiddleLine2.split('').filter(x => x === "B").length;
expect(countOfLetters2).toBe(2);
});
it("given not-A, middle line correctly spaced", () => {
const target = "B";
const result = sut.make(target);
const middleLine = Math.floor(result.length / 2);
expect(result[middleLine]).toBe("B B");
});
it("given not-A, lines correctly padded", () => {
const target = "B";
const result = sut.make(target);
expect(result[0]).toBe(" A ");
});
it("demo", () => {
const target = "F";
const result = sut.make(target);
console.log(result);
})
});
function noneACharacter() {
const options = "BCDEFGHIJKLMNOPQRSTUVWXYZ";
const rnd = Math.floor(Math.random() * options.length) + 1;
return options[rnd];
}
export class DiamondMaker {
public make(midpoint: string): string[] {
const topHalf: string[] = [];
const aCode = "A".charCodeAt(0);
const midpointCode = midpoint.charCodeAt(0);
for (let i = aCode; i <= midpointCode; i++) {
const lastLine = topHalf[topHalf.length - 1] ?? "";
const spaces = lastLine.length;
const line = this.formatLine(i, spaces);
topHalf.push(line);
}
const maxWidth = topHalf[topHalf.length - 1].length; //?
const bottomHalf = topHalf.slice(0, topHalf.length -1);
bottomHalf.reverse();
const diamond = [ ...topHalf, ...bottomHalf] //?
for (let i = 0; i < diamond.length; i++) {
const currentLine = diamond[i];
const spaces = maxWidth - currentLine.length;
const eachSide = spaces / 2;
const spaced = " ".repeat(eachSide) + diamond[i] + " ".repeat(eachSide);
diamond[i] = spaced;
}
return diamond;
}
private formatLine(asciiCode: number, spaces: number): string {
if (asciiCode === 65) {
return "A";
}
const letter = String.fromCharCode(asciiCode);
return letter + " ".repeat(spaces) + letter;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment