-
Notifications
You must be signed in to change notification settings - Fork 17
/
knot.js
66 lines (55 loc) · 1.78 KB
/
knot.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
const { range } = require('lodash');
const assert = require('assert');
class Knot {
constructor(size, current_position = 0, skip = 0) {
this.string = range(size);
this.current_position = current_position;
this.skip = skip;
}
static stringToInputArray(str) {
return str
.split('')
.map(v => v.charCodeAt())
.concat([17, 31, 73, 47, 23]);
}
performTwists(twists, iterations = 1) {
for (let iteration = 0; iteration < iterations; iteration++) {
twists.forEach(twist => {
let indices = range(twist).map(
v => (v + this.current_position) % this.string.length
);
let points = indices.map(i => this.string[i]);
points.reverse();
indices.forEach((string_i, root_i) => (this.string[string_i] = points[root_i]));
this.current_position =
(this.current_position + twist + this.skip++) % this.string.length;
});
}
return this.string;
}
denseHash() {
let hash = [];
for (let i = 0; i < 16; i++) {
let slice = this.string.slice(i * 16, (i + 1) * 16);
hash.push(slice.reduce((a, b) => a ^ b));
}
return hash.map(v => v.toString(16).padStart(2, '0')).join('');
}
partOneAnswer() {
assert.ok(this.string.length >= 2);
return this.string[0] * this.string[1];
}
partTwoAnswer() {
return this.denseHash();
}
}
const getKnotHashOfString = str => {
let twists = Knot.stringToInputArray(str);
let knot = new Knot(256);
knot.performTwists(twists, 64);
return knot.denseHash();
}
module.exports = {
Knot,
getKnotHashOfString
};