115 lines
3.2 KiB
TypeScript
115 lines
3.2 KiB
TypeScript
import 'mocha';
|
|
import assert from 'assert';
|
|
import { readFileSync } from 'fs';
|
|
|
|
let example: string =
|
|
`1-3 a: abcde
|
|
1-3 b: cdefg
|
|
2-9 c: ccccccccc`
|
|
;
|
|
let expect01: number = 0;
|
|
let expect02: number = 0;
|
|
|
|
let input = readFileSync('./input/2020-day-02.txt', 'utf-8')
|
|
.split('\n')
|
|
.map(l => parseInt(l.trim(), 10));
|
|
|
|
let tasksResults: any[] = ['N/A', 'N/A'];
|
|
|
|
describe('Day 02', () => {
|
|
|
|
let sample: PassEntry[];
|
|
before(() => {
|
|
sample = getData(example);
|
|
})
|
|
describe('task01', () => {
|
|
describe('parse', () => {
|
|
it('matches a line', () => {
|
|
assert.strictEqual(sample[0].min, 1);
|
|
assert.strictEqual(sample[0].max, 3);
|
|
assert.strictEqual(sample[0].letter, 'a');
|
|
assert.strictEqual(sample[0].pass, 'abcde');
|
|
});
|
|
it('makes a table', () => {
|
|
let table = mkTable(sample[0]);
|
|
assert.strictEqual(table.a, 1);
|
|
})
|
|
it('validate rules', () => {
|
|
let valid = checkRulesTask01(sample);
|
|
assert.strictEqual(valid.length, 2);
|
|
})
|
|
});
|
|
it('Calculate', () => {
|
|
let rules = getData(readFileSync('./input/2020-day-02.txt', 'utf-8'));
|
|
tasksResults[0] = checkRulesTask01(rules).length;
|
|
});
|
|
});
|
|
describe('test02', () => {
|
|
it('Calculate', () => {
|
|
assert.strictEqual(checkRulesTask02(sample).length, 1);
|
|
let rules = getData(readFileSync('./input/2020-day-02.txt', 'utf-8'));
|
|
tasksResults[1] = checkRulesTask02(rules).length;
|
|
});
|
|
});
|
|
after(() => {
|
|
console.log('\ntask 01:', tasksResults[0]);
|
|
console.log('\ntask 02:', tasksResults[1]);
|
|
});
|
|
});
|
|
|
|
function task01(input: number[]): number {
|
|
return 0;
|
|
}
|
|
|
|
function task02(input: number[]): number {
|
|
return task01(input);
|
|
}
|
|
|
|
interface PassEntry {
|
|
min: number;
|
|
max: number;
|
|
letter: string;
|
|
pass: string;
|
|
}
|
|
|
|
let rePwLine = /^(\d+)-(\d+)\s(\w+):\s(.*)$/;
|
|
function getData(raw: string): PassEntry[] {
|
|
return raw.split('\n').map(line => {
|
|
let match = line.match(rePwLine);
|
|
if (!match) {
|
|
throw new Error('Not a match: ' + line);
|
|
}
|
|
return {
|
|
min: +match[1], max: +match[2], letter: match[3], pass: match[4]
|
|
};
|
|
});
|
|
}
|
|
|
|
function checkRulesTask01(rules: PassEntry[]): PassEntry[] {
|
|
return rules.filter((rule) => {
|
|
let table = mkTable(rule);
|
|
let c = table[rule.letter]
|
|
return (c >= rule.min) && (c <= rule.max);
|
|
});
|
|
}
|
|
|
|
function checkRulesTask02(rules: PassEntry[]): PassEntry[] {
|
|
return rules.filter(rule => {
|
|
let p1 = rule.pass.charAt(rule.min - 1);
|
|
let p2 = rule.pass.charAt(rule.max - 1);
|
|
let m1 = (p1 === rule.letter);
|
|
let m2 = (p2 === rule.letter);
|
|
if (m1 && m2) return false;
|
|
if (!m1 && !m2) return false;
|
|
return true;
|
|
});
|
|
}
|
|
|
|
function mkTable(rule: PassEntry) {
|
|
let table: any = {};
|
|
for (let i = 0; i < rule.pass.length; i++) {
|
|
let c = rule.pass.charAt(i);
|
|
table[c] = (table[c]) ? table[c] + 1 : 1;
|
|
}
|
|
return table;
|
|
} |