60 lines
1.6 KiB
JavaScript
60 lines
1.6 KiB
JavaScript
const { Glib } = require('../../lib');
|
|
|
|
const calculateChecksum = (string) => {
|
|
return Array.from(string.characterFrequencies.entries())
|
|
.sort(([a, af], [b, bf]) => {
|
|
if (af > bf) {
|
|
return -1;
|
|
} else if (af < bf) {
|
|
return 1;
|
|
}
|
|
return a.charCodeAt(0) - b.charCodeAt(0);
|
|
})
|
|
.glib.take(5)
|
|
.map(([a]) => a).string;
|
|
};
|
|
|
|
const START_CHAR_CODE = 'a'.charCodeAt(0);
|
|
const decrypt = (name, sectorId) => {
|
|
let outputString = '';
|
|
for (let i = 0; i < name.length; i++) {
|
|
const letterNum = name.charCodeAt(i) - START_CHAR_CODE;
|
|
const decryptedLetterNum = (letterNum + sectorId) % 26;
|
|
outputString += String.fromCharCode(decryptedLetterNum + START_CHAR_CODE);
|
|
}
|
|
return outputString;
|
|
};
|
|
|
|
const parse = (input) =>
|
|
Glib.fromLines(input)
|
|
.map((room) => {
|
|
let [first, checksum] = room.split('[');
|
|
checksum = checksum.slice(0, -1);
|
|
const splits = first.split('-');
|
|
const name = splits.slice(0, -1).join('-');
|
|
const sectorId = parseInt(splits.slice(-1), 10);
|
|
return { name, sectorId, checksum };
|
|
})
|
|
.filter(({ name, checksum }) => {
|
|
const cleanName = name.split('-').join('');
|
|
return calculateChecksum(cleanName) === checksum;
|
|
});
|
|
|
|
module.exports = {
|
|
'1': (input) =>
|
|
parse(input)
|
|
.map(({ sectorId }) => sectorId)
|
|
.toInts()
|
|
.sum(),
|
|
'2': (input) =>
|
|
parse(input)
|
|
.filter(
|
|
({ name, sectorId }) =>
|
|
name
|
|
.split('-')
|
|
.map((component) => decrypt(component, sectorId))
|
|
.join('-') === 'northpole-object-storage',
|
|
)
|
|
.first().sectorId,
|
|
};
|