Guest User

Untitled

a guest
Dec 10th, 2017
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.09 KB | None | 0 0
  1. (() => {
  2. const pi2 = Math.PI * 2
  3. const getRingSize = (ring) => ring === 0 ? 1 : ring * 8
  4. let getRingStart = (ring) => {
  5. if(ring === 0) return 0
  6. let currSum = 0
  7. for(let i = 1; i < ring; i++) currSum += i * 8
  8. return currSum + 2
  9. }
  10. const getAngle = (dX, dY) => (Math.atan2(dY, dX) + pi2) % pi2
  11.  
  12. const getCoords = (n) => {
  13. if(n === 1) return [0, 0]
  14. let ring = 1
  15. while(getRingStart(ring + 1) <= n) ring += 1
  16. const ringSize = getRingSize(ring)
  17. const ringPos = n - getRingStart(ring)
  18. const angle = ((ringPos / ringSize) - (ring - 1) / ringSize) * pi2
  19. const opposite = Math.abs((ringPos % (ring * 2)) - (ring - 1))
  20. const diag = Math.sqrt(Math.pow(ring, 2) + Math.pow(opposite, 2))
  21. return [
  22. Math.round(Math.cos(angle) * diag) + 0,
  23. Math.round(Math.sin(angle) * diag) + 0
  24. ]
  25. }
  26. const cache = {}
  27. const getIndex = (() => (x, y) => {
  28. const cacheKey = `${x}/${y}`
  29. if(x === 0 && y === 0) return 1
  30. if(cache[cacheKey]) return cache[cacheKey]
  31. const ring = Math.max(Math.abs(x), Math.abs(y))
  32. const ringAdjust = ring - 1
  33. const ringSize = getRingSize(ring)
  34. const ringStart = getRingStart(ring)
  35. const angle = getAngle(x, y)
  36. const ringPos = (Math.round((angle / pi2) * ringSize) + ringAdjust) % ringSize
  37. return cache[cacheKey] = ringStart + ringPos
  38. })()
  39.  
  40. const getAdjacent = (n) => {
  41. const [x, y] = getCoords(n)
  42. const adj = [
  43. [x - 1, y + 1], [x, y + 1], [x + 1, y + 1],
  44. [x - 1, y] , [x + 1, y],
  45. [x - 1, y - 1], [x, y - 1], [x + 1, y - 1],
  46. ]
  47. return adj.map(([x, y]) => getIndex(x, y))
  48. }
  49.  
  50. const cache2 = []
  51. const calcIndex = (index) => {
  52. if(index === 1) return 1
  53. if(cache2[index]) return cache2[index]
  54. const adjacent = getAdjacent(index).filter((adjIndex) => adjIndex <= index).sort((a, b) => a < b ? -1 : 1)
  55.  
  56. return cache2[index] = adjacent.reduce((sum, adjIndex) => { return sum + calcIndex(adjIndex)}, 0)
  57. }
  58.  
  59.  
  60. let i = 0, result
  61. console.time('run')
  62. while((result = calcIndex(++i)) < 289326) {}
  63. console.timeEnd('run')
  64. console.log(result)
  65.  
  66. })()
Add Comment
Please, Sign In to add comment