main.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. const fs = require('fs');
  2. const readline = require('readline');
  3. Array.prototype.count = function(fnc) {
  4. return this.reduce((total, i, index) => fnc(i, index) ? total+1 : total, 0);
  5. }
  6. Array.prototype.countUnique = function(fnc) {
  7. return this.reduce((total, i, index) => (total.indexOf(i) === -1 && fnc(i, index)) ? total.concat(i):total, []).length;
  8. }
  9. function getAdjascents(pos) {
  10. return [
  11. [ pos.coords[0] -1, pos.coords[1], pos.coords[2] ],
  12. [ pos.coords[0] +1, pos.coords[1], pos.coords[2] ],
  13. [ pos.coords[0], pos.coords[1] +1, pos.coords[2] ],
  14. [ pos.coords[0], pos.coords[1] -1, pos.coords[2] ],
  15. [ pos.coords[0], pos.coords[1], pos.coords[2] +1 ],
  16. [ pos.coords[0], pos.coords[1], pos.coords[2] -1 ]
  17. ];
  18. }
  19. function countShards(map) {
  20. return Object.keys(map).reduce((acc, i) => acc +getAdjascents(map[i]).map(i => i.join(',')).count(i => !map[i]), 0);
  21. }
  22. function isTrapped(map, arr, obj) {
  23. // FIXME
  24. return false;
  25. }
  26. function countShards2(map) {
  27. const keys = Object.keys(map);
  28. if (keys.length < 8) return countShards(map); // trivial out
  29. return Object.keys(map).reduce((acc, i) => acc +getAdjascents(map[i]).map(i => i.join(',')).count(i => !map[i] && !isTrapped(map, i)), 0);
  30. }
  31. function manhatan(a, b) {
  32. return a.reduce((acc, val, index) => acc + Math.abs(b[index]-val), 0);
  33. }
  34. function mergeIds(map, oldId, newId) {
  35. Object.keys(map).forEach(i => { if (map[i].gid === oldId) map[i].gid = newId;});
  36. }
  37. function computeShardShape(map) {
  38. const keys = Object.keys(map);
  39. let ids = [];
  40. let maxId = 0;
  41. for (let i =0; i < keys.length; ++i) {
  42. if (map[keys[i]].gid !== undefined) {
  43. for (let j = 0; j < i; ++j) {
  44. if (map[keys[i]].gid !== map[keys[j]].gid && manhatan(map[keys[i]].coords, map[keys[j]].coords) === 1)
  45. mergeIds(map, map[keys[i]].gid, map[keys[j]].gid);
  46. }
  47. continue;
  48. }
  49. map[keys[i]].gid = ++maxId;
  50. ids.push(maxId);
  51. for (let j = 1; j < keys.length; ++j)
  52. if (manhatan(map[keys[i]].coords, map[keys[j]].coords) === 1) {
  53. if (map[keys[j]].gid !== undefined)
  54. mergeIds(map, maxId, map[keys[j]].gid);
  55. else
  56. map[keys[j]].gid = maxId;
  57. }
  58. }
  59. return ids.map(i => keys.filter(j => i === map[j].gid).map(i => map[i])).filter(i => i.length).map(i => i.reduce((acc, i) => { acc[i.id] = i; return acc; }, {}));
  60. }
  61. async function main() {
  62. let shards = {};
  63. for await (let line of readline.createInterface({ input: process.stdin })) {
  64. shards[line] = {
  65. coords: line.split(',').map(i => parseInt(i)),
  66. gid: undefined,
  67. id: line
  68. }
  69. }
  70. let extShards = countShards(shards);
  71. console.log(extShards);
  72. //console.log(require('util').inspect(computeShardShape(shards), { showHidden: false, depth: null, colors: true }));
  73. console.log(computeShardShape(shards).reduce((acc, i) => countShards2(i)+acc, 0));
  74. };
  75. (main());