jsadvent/solutions/2015/8.js
2020-12-12 00:59:44 -06:00

85 lines
1.9 KiB
JavaScript

const { Glib, fn } = require('../../lib');
const MODES = {
NORMAL: Symbol('normal'),
ESCAPE: Symbol('escape'),
HEX: Symbol('hex'),
};
const BACKSLASH = '\\';
const QUOTE = '"';
const X = 'x';
const decode = (input) => {
let mode = MODES.NORMAL;
let storage = null;
return Glib.fromIterable(input).flatMap((char) => {
switch (mode) {
case MODES.NORMAL:
switch (char) {
case QUOTE:
return [];
case BACKSLASH:
mode = MODES.ESCAPE;
return [];
default:
return [char];
}
case MODES.ESCAPE:
switch (char) {
case BACKSLASH:
mode = MODES.NORMAL;
return [BACKSLASH];
case QUOTE:
mode = MODES.NORMAL;
return [QUOTE];
case X:
mode = MODES.HEX;
return [];
default:
console.log(char);
throw new Error('invalid escape');
}
case MODES.HEX:
if (storage == null) {
storage = char;
return [];
} else {
char = String.fromCharCode(parseInt(`${storage}${char}`, 16));
storage = null;
mode = MODES.NORMAL;
return [char];
}
default:
throw new Error('bad mode');
}
});
};
const encode = (input) =>
Glib.concat(
QUOTE,
Glib.fromIterable(input).flatMap((char) => {
switch (char) {
case QUOTE:
return [BACKSLASH, QUOTE];
case BACKSLASH:
return [BACKSLASH, BACKSLASH];
default:
return [char];
}
}),
QUOTE,
);
module.exports = {
'1': (input) =>
Glib.fromLines(input)
.map((i) => BigInt(i.length) - decode(i).length)
.sum(),
'2': (input) =>
Glib.fromLines(input)
.map((i) => encode(i).length - BigInt(i.length))
.sum(),
};