|
1 | 1 | /* eslint-disable no-bitwise */
|
2 | 2 |
|
| 3 | +const intToBin = (int) => (int >>> 0).toString(2).padStart(36, 0); |
| 4 | + |
3 | 5 | const bitwiseAnd = (value, mask) => {
|
4 |
| - const bin = (value >>> 0).toString(2).padStart(36, 0); |
| 6 | + const bin = intToBin(value); |
5 | 7 | const andMask = mask.replace(/X/g, '1');
|
6 |
| - return andMask.split('').map((bit, index) => bin[index] & bit).join(''); |
| 8 | + return andMask |
| 9 | + .split('') |
| 10 | + .map((bit, index) => bin[index] & bit) |
| 11 | + .join(''); |
7 | 12 | };
|
8 | 13 | const bitwiseOr = (bin, mask) => {
|
9 | 14 | const orMask = mask.replace(/X/g, '0');
|
10 |
| - return orMask.split('').map((bit, index) => bin[index] | bit).join(''); |
| 15 | + return orMask |
| 16 | + .split('') |
| 17 | + .map((bit, index) => bin[index] | bit) |
| 18 | + .join(''); |
| 19 | +}; |
| 20 | + |
| 21 | +const applyMaskToAdress = (address, mask) => |
| 22 | + intToBin(address) |
| 23 | + .split('') |
| 24 | + .map((bit, i) => { |
| 25 | + if (mask[i] === '0') { |
| 26 | + return bit; |
| 27 | + } |
| 28 | + if (mask[i] === '1') { |
| 29 | + return 1; |
| 30 | + } |
| 31 | + return 'X'; |
| 32 | + }) |
| 33 | + .join(''); |
| 34 | + |
| 35 | +const getNumberOfAddresses = (mask) => |
| 36 | + 2 * |
| 37 | + mask.split('').reduce((sum, bit) => { |
| 38 | + if (bit === 'X') { |
| 39 | + sum += 1; |
| 40 | + } |
| 41 | + return sum; |
| 42 | + }, 0); |
| 43 | + |
| 44 | +const replaceX = (addressMask) => { |
| 45 | + const index = addressMask.indexOf('X'); |
| 46 | + if (index === -1) { |
| 47 | + return addressMask; |
| 48 | + } |
| 49 | + return [ |
| 50 | + replaceX( |
| 51 | + `${addressMask.substring(0, index)}0${addressMask.substring(index + 1)}`, |
| 52 | + ), |
| 53 | + replaceX( |
| 54 | + `${addressMask.substring(0, index)}1${addressMask.substring(index + 1)}`, |
| 55 | + ), |
| 56 | + ]; |
| 57 | +}; |
| 58 | + |
| 59 | +const getAdresses = (address, mask) => { |
| 60 | + const addressMask = applyMaskToAdress(address, mask); |
| 61 | + |
| 62 | + return replaceX(addressMask) |
| 63 | + .flat(20) |
| 64 | + .map((address) => parseInt(address, 2)); |
11 | 65 | };
|
12 | 66 |
|
13 | 67 | const write = (value, mask) => {
|
@@ -44,8 +98,24 @@ const util1 = (input) => {
|
44 | 98 | };
|
45 | 99 |
|
46 | 100 | const util2 = (input) => {
|
47 |
| - console.log(input); |
48 |
| - return input; |
| 101 | + const result = input.reduce(({ memory, currentMask }, row) => { |
| 102 | + const [, mask] = row.match(/mask = ([X01]+)/) || []; |
| 103 | + const [, address, value] = row.match(/mem\[(\d+)\] = (\d+)/) || []; |
| 104 | + if (mask !== undefined) { |
| 105 | + currentMask = mask; |
| 106 | + } |
| 107 | + if (address) { |
| 108 | + const addresses = getAdresses(address, currentMask); |
| 109 | + addresses.forEach((address) => { |
| 110 | + memory[address] = value; |
| 111 | + }); |
| 112 | + } |
| 113 | + return { memory, currentMask }; |
| 114 | + }, { memory: {}, currentMask: '' }); |
| 115 | + return Object.values(result.memory).reduce((sum, value) => { |
| 116 | + sum += Number(value); |
| 117 | + return sum; |
| 118 | + }, 0); |
49 | 119 | };
|
50 | 120 |
|
51 |
| -module.exports = { util1, util2, write }; |
| 121 | +module.exports = { util1, util2, write, getAdresses }; |
0 commit comments