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; }