Advertisement
Marrin

Cyclical figurate numbers

Dec 21st, 2015
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'use strict';
  2.  
  3. var Immutable = require('immutable');
  4. var List = Immutable.List;
  5. var Map = Immutable.Map;
  6. var Range = Immutable.Range;
  7. var Set = Immutable.Set;
  8. var Stack = Immutable.Stack;
  9.  
  10. var isNotNull = function (x) { return x !== null; };
  11.  
  12. var createNode = function (func, number) {
  13.   return {
  14.     func: func,
  15.     number: number,
  16.     incoming: Math.floor(number / 100),
  17.     outgoing: number % 100,
  18.     neighbours: new List(),
  19.  
  20.     hasSameFunction: function (other) { return func === other.func; }
  21.   };
  22. };
  23.  
  24. var hasLessThanFourDigits = function (n) { return n < 1000; };
  25.  
  26. var hasMoreThanFourDigits = function (n) { return n >= 10000; };
  27.  
  28. var calculateFourDigitValues = function (func) {
  29.   return new Range(1)
  30.     .map(func)
  31.     .skipWhile(hasLessThanFourDigits)
  32.     .takeUntil(hasMoreThanFourDigits);
  33. };
  34.  
  35. var findSolution = function (expectedSize, nodes) {
  36.  
  37.   var find = function (node, result, usedFunctions) {
  38.     var newResult = result.push(node);
  39.  
  40.     if (newResult.size === expectedSize) {
  41.       if (newResult.first().outgoing === newResult.last().incoming) {
  42.         return newResult;
  43.       }
  44.     } else {
  45.       var subResult = node.neighbours.toSeq().map(function (neighbour) {
  46.         var newUsedFunctions = usedFunctions.add(node.func);
  47.         return (newUsedFunctions.contains(neighbour.func)) ?
  48.             null : find(neighbour, newResult, newUsedFunctions);
  49.       }).find(isNotNull);
  50.       if (subResult !== undefined) { return subResult; }
  51.     }
  52.     return null;
  53.   };
  54.  
  55.   return nodes.toSeq().map(function (node) {
  56.     return find(node, new Stack(), new Set());
  57.   }).find(isNotNull).map(function (node) { return node.number; });
  58. };
  59.  
  60. var connectNodes = function (nodes) {
  61.   var empty = new List();
  62.  
  63.   var incoming2nodes = nodes.reduce(
  64.     function (result, node) {
  65.       var incoming = node.incoming;
  66.       return result.set(incoming, result.get(incoming, empty).push(node));
  67.     },
  68.     new Map()
  69.   );
  70.  
  71.   nodes.forEach(function (node) {
  72.     node.neighbours = incoming2nodes
  73.       .get(node.outgoing, empty)
  74.       .filterNot(node.hasSameFunction);
  75.   });
  76. };
  77.  
  78. var main = function () {
  79.   var functions = List.of(
  80.     function (n) { return n * (n + 1) / 2; },
  81.     function (n) { return n * n; },
  82.     function (n) { return n * (3 * n - 1) / 2; },
  83.     function (n) { return n * (2 * n - 1); },
  84.     function (n) { return n * (5 * n - 3) / 2; },
  85.     function (n) { return n * (3 * n - 2); }
  86.   );
  87.   var nodes = functions.toSeq().flatMap(function (func) {
  88.     return calculateFourDigitValues(func).map(
  89.       function (number) { return createNode(func, number); }
  90.     );
  91.   }).cacheResult();
  92.   connectNodes(nodes);
  93.   var numbers = findSolution(functions.size, nodes);
  94.   console.log(numbers);
  95.   console.log(numbers.reduce(function (a, b) { return a + b; }, 0));
  96. };
  97.  
  98. if (require.main === module) { main(); }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement