85 lines
1.9 KiB
JavaScript
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(),
|
|
};
|