{"data":{"mdx":{"id":"9cc5cc71-dce2-5e6a-977d-334313740f40","code":{"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"date\": \"2019-05-05\",\n  \"order\": 7,\n  \"title\": \"Again with the Geometry\",\n  \"tags\": [\"education\", \"javascript\", \"Advent of Code\"]\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"These geometry problems are tough.\"), mdx(\"h2\", null, \"The Problem\"), mdx(\"p\", null, \"This is best explained by the Advent of Code site itself, so I'm going to copy.\"), mdx(\"p\", null, \"For example, consider the following list of coordinates:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"1, 1\\n1, 6\\n8, 3\\n3, 4\\n5, 5\\n8, 9\\n\")), mdx(\"p\", null, \"If we name these coordinates A through F, we can draw them on a grid, putting 0,0 at the top left:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"..........\\n.A........\\n..........\\n........C.\\n...D......\\n.....E....\\n.B........\\n..........\\n..........\\n........F.\\n\")), mdx(\"p\", null, \"This view is partial - the actual grid extends infinitely in all directions. Using the Manhattan distance\", mdx(\"sup\", _extends({\n    parentName: \"p\"\n  }, {\n    \"id\": \"fnref-manhattan\"\n  }), mdx(\"a\", _extends({\n    parentName: \"sup\"\n  }, {\n    \"href\": \"#fn-manhattan\",\n    \"className\": \"footnote-ref\"\n  }), \"manhattan\")), \", each location's closest coordinate can be determined, shown here in lowercase:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"aaaaa.cccc\\naAaaa.cccc\\naaaddecccc\\naadddeccCc\\n..dDdeeccc\\nbb.deEeecc\\nbBb.eeee..\\nbbb.eeefff\\nbbb.eeffff\\nbbb.ffffFf\\n\")), mdx(\"p\", null, \"Locations shown as . are equally far from two or more coordinates, and so they don't count as being closest to any.\"), mdx(\"p\", null, \"The goal is to find the coordinate that has the largest finite (that is, not infinite) number of spaces that are closer to it than to any of the other coordinates.\"), mdx(\"h2\", null, \"The Solution\"), mdx(\"p\", null, \"It starts with the usual data read, plus a bit of processing to turn each line into an array of two numbers:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const fs = require('fs')\\nlet input = fs\\n  .readFileSync(`./input/day6.txt`, 'utf8')\\n  .trim()\\n  .split('\\\\n')\\n  .map(line => line.split(', ').map(Number))\\n\")), mdx(\"p\", null, \"This goes a bit against my philosophy of always preferring objects over arrays to store data unless there's a good reason to choose arrays. In this case my reason was that arrays seemed just a little bit easier.\"), mdx(\"p\", null, \"Then gather all the x values and all the y values and find maxes:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const xMax = Math.max(...input.map(([x, y]) => x))\\nconst yMax = Math.max(...input.map(([x, y]) => y))\\n\")), mdx(\"h2\", null, \"Clearly a Bad idea\"), mdx(\"p\", null, \"At first I thought I would have to iterate over the whole grid, measuring the distance from each point on the grid to the nearest point from the input. That was going to be a lot of calculation; the grid is about 350x350, meaning over a million points, and there are about 250 points in the input list. I didn't see an obvious solution for deciding which input was closest to a given grid point without calculating every distance.\"), mdx(\"h2\", null, \"So Many Questions\"), mdx(\"p\", null, \"Instead I decided to measure outward, starting at each input point and finding its neighboring points, then all the neighbors of those points, etc. I would sort of build concentric circles around each input point\", mdx(\"sup\", _extends({\n    parentName: \"p\"\n  }, {\n    \"id\": \"fnref-1\"\n  }), mdx(\"a\", _extends({\n    parentName: \"sup\"\n  }, {\n    \"href\": \"#fn-1\",\n    \"className\": \"footnote-ref\"\n  }), \"1\")), \", and each loop through the code would increase the radius of the circles. Then the total area for each point would be the sum of the points in all of the concentric circles. How would I know when to stop looping? I had no idea. What would I do when the expanding circles around each input point started to overlap? Not sure. What did I know how to do? Well, given a point, I could find the four points adjacent to it, and check to find which of them were on the grid:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const findNeighbors = ([x, y]) => {\\n  let prospects = [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1]]\\n  return prospects.filter(\\n    ([X, Y]) => X >= 0 && Y >= 0 && X <= xMax && Y <= xMax\\n  )\\n}\\n\")), mdx(\"h2\", null, \"On to Data Storage\"), mdx(\"p\", null, \"Once I found the nearest neighbors for an coordinate, I'd need to store them somewhere. An object didn't seem like the right answer, because there was no clear candidate for a key to associate with each value. The other option was an array.\"), mdx(\"h3\", null, \"A Confession\"), mdx(\"p\", null, \"I tried to solve the Advent of Code problems, and write up these explanations, as the problems came available, during December 2018. I got almost all of the problems done on the day they were released. I wrote up most of the explanations as soon as I had the solutions. Apparently for this problem, my explanation write up got as far as the end of the last paragraph. I haven't touched this write up since December 7, 2018. It is now May 5, 2019. The rest of this explanation is going to be an attempt to recreate my thoughts based on my code.\"), mdx(\"h2\", null, \"Back to Data Storage\"), mdx(\"p\", null, \"I want to store all of the coordinates that are nearest to each of the coordinates in the input list. The problem with using an object to store each neighbor by itself is figuring out the right key. Suppose I wanted all the neighbors for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"[1, 1]\"), \", which would include the points \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"[0, 1]\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"[2, 1]\"), \". I couldn't do something like\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"{ \\\"1, 1\\\": [0, 1], \\\"1, 1\\\": [2, 1] }\\n\")), mdx(\"p\", null, \"because the keys in an object have to be unique. Another option would be to store everything in an object, but have each value be an array of the points closest to the coordinate represented by the key. Taking the above example, the data structure would look like\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"{ \\\"1, 1\\\": [ [0, 1], [2, 1] ] }\\n\")), mdx(\"p\", null, \"The key is a coordinate from the input list, the value is an array, and each element of that array is a point closer to the coordinate key than to any other coordinate in the input list.\"), mdx(\"p\", null, \"That didn't seem quite right either. I was pretty sure I wanted to work with expanding concentric circles around each input coordinate. In order to build the next concentric circle, it would help to know where the last concentric circle was. To do that, I should store all of the points that made up each \\\"circle\\\" together in the data structure, without mixing all of the coordinates from \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"every\"), \" \\\"circle\\\" together. I finally settled on something like this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const concentricCircles = {\\n  \\\"key representing an input coordinate\\\": [\\n    [ /* the input coordinate itself */ ],\\n    [ /* the points 1 space out from the coordinate */ ],\\n    [ /* the points 2 spaces out from the coordinate */ ],\\n    ...\\n  ]\\n}\\n\")), mdx(\"p\", null, \"My strategy would be to create a loop, which would:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"iterate over the input coordinates\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"find the array associated with each coordinate, in my data structure\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"take the last element of that array, representing the biggest concentric circle so far\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"build a new concentric circle using that (somehow)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"stop expanding a circle when I detected I was running into another coordinate's neighbors (somehow)\")), mdx(\"p\", null, \"and then stop the overall loop (somehow). \\\"Strategy\\\" is perhaps too strong a word.\"), mdx(\"h2\", null, \"Creating a Starting Point\"), mdx(\"p\", null, \"I could start my \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles\"), \" object by associating each input coordinate with an empty array, to hold the concentric circles around the coordinate. The first element of that array would be an array containing the center of the circles: the coordinate itself.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let concentricCircles = input.reduce((total, current) => {\\n  total[current] = []\\n  total[current][0] = [current]\\n  return total\\n}, {})\\n\")), mdx(\"h2\", null, \"Beginning by Hand\"), mdx(\"p\", null, \"I could start creating the concentric circles \\\"by hand\\\", without an ongoing loop, by iterating over the input coordinates. I can use my \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"findNeighbors\"), \" function from a while ago to get the neighbors of each input coordinate, and store them in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const findNeighbors = ([x, y]) => {\\n  let prospects = [[x - 1, y], [x + 1, y], [x, y - 1], [x, y + 1]]\\n  return prospects.filter(\\n    ([X, Y]) => X >= 0 && Y >= 0 && X <= xMax && Y <= xMax\\n  )\\n}\\ninput.forEach(point => {\\n  const neighbors = findNeighbors(point)\\n  concentricCircles[point][1] = neighbors\\n})\\n\")), mdx(\"p\", null, \"That gets me one \\\"circle\\\" around each of my input coordinates. Let me draw one example to remind you why I use quote marks when I talk about a \\\"circle\\\" using Manhattan distances. The \\\"0\\\" marks the center, and all the \\\"1\\\"s form the \\\"circle\\\":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \".....\\n..1..\\n.101.\\n..1..\\n.....\\n\")), mdx(\"p\", null, \"Since diagonal movement isn't allowed, only those four places are part of the first \\\"circle\\\". Now I'll add the next \\\"circle\\\":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"..2..\\n.212.\\n21012\\n.212.\\n..2..\\n\")), mdx(\"p\", null, \"It was pretty straightforward to use JavaScript to calculate where all the \\\"1\\\"s should go: they are all of the neighbors of the \\\"0\\\". But how can we calculate where all of the \\\"2\\\"s should go? That takes a few steps:\"), mdx(\"ul\", null, mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"take \", mdx(\"em\", {\n    parentName: \"li\"\n  }, \"all\"), \" of the \\\"1\\\"s\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"find all of \", mdx(\"em\", {\n    parentName: \"li\"\n  }, \"their\"), \" neighbors\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"without double-counting (because some \\\"2\\\"s are neighbor to two \\\"1\\\"s)\"), mdx(\"li\", {\n    parentName: \"ul\"\n  }, \"and excluding the \\\"0\\\" (which is a neighbor to all the \\\"1\\\"s but is obviously not a \\\"2\\\")\")), mdx(\"p\", null, \"Moving back from the example to the real problem, I want to write code to run through those steps for every point in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \". That...is a lot. I'll start with the first two steps.\"), mdx(\"h3\", null, \"Take All of the \\\"1\\\"s\"), mdx(\"p\", null, \"Getting all of the \\\"1\\\"s can be done quickly. I calculated those in the last bit of code. For one point in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \", which in my diagram would be the \\\"0\\\", the \\\"1\\\"s - that is, the neighbors of the point - are in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point][1]\"), \", That's an array.\"), mdx(\"h3\", null, \"Find All of Their Neighbors\"), mdx(\"p\", null, \"I have an array with a lot of points, and I want to make a different array that has all of the neighbors of those points. My first thought in that situation is to reach for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".map()\"), \". But nobody ever says that kind of thing unless This Time Is Different. And this time \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"is\"), \" different. Why is that? Why is \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".map()\"), \" not a good choice? The problem is that \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".map()\"), \" produces an array that's the same size as the one you start with, and I know from my last diagram that there will be more \\\"2\\\"s in the array I make than \\\"1\\\"s in the array I start with. You know what will work better, despite its name? \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".reduce()\"), \". It's a strange name to make something bigger, but it really means \\\"reduce into just one thing\\\". The \\\"one thing\\\" I want is an array. Just happens to be a relatively large array.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"input.forEach(point => {\\n  const lastCircle = concentricCircles[point][1]\\n  const nextCircle = lastCircle.reduce((total, pt) => {\\n    const neighbors = findNeighbors(pt)\\n    return [...total, ...neighbors]\\n  }, [])\\n  concentricCircles[point][2] = nextCircle\\n})\\n\")), mdx(\"p\", null, \"That \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"almost\"), \" works. I will get every neighbor of all of the \\\"1\\\"s into \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"nextCircle\"), \", but I'll get most of them twice. I need to prevent those duplicates.\"), mdx(\"h3\", null, \"Without Double-Counting\"), mdx(\"p\", null, \"There are npm packages that eliminate duplicate entries in an array, but I'm not going to install any of those. That's not just me being Grumpy Old Dev, either. I don't just want to keep out duplicates as I create my next current concentric circle, I also want to keep out elements from the \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"last\"), \" concentric circle. It would be easy enough to get rid of the single \\\"0\\\" this time around, but when I go through this loop again, and find all the \\\"2\\\"s' neighbors, I'll want to make sure I don't include any of the \\\"1\\\"s, and so on.\"), mdx(\"p\", null, \"In order to avoid duplicates, and elements in previous circles, I need to keep track of what those elements are. I'll do that with a second data structure. This new data structure has to be able to store points, which are two-element arrays, and tell me if it's already storing a particular point or not. I thought a Set would work for that, but it doesn't, which makes me a little up...a little annoyed, but our old friend the object works fine. I'll use the points as the keys, and the value will always be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"true\"), \", because all I care about is whether the point has been handled in the code already. I'll want to use the same object for all of my input values, so I'll have to scope it to outside all of the callback functions:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let accountedFor = {}\\ninput.forEach(point => {\\n\")), mdx(\"p\", null, \"Then I'll use it to filter out each group of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"neighbors\"), \", and add the neighbors that make it through the filter back to the object so they don't get duplicated:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let accountedFor = {}\\ninput.forEach(point => {\\n  const lastCircle = concentricCircles[point][1]\\n  lastCircle.forEach(pt => (accountedFor[pt] = true))\\n  const nextCircle = lastCircle.reduce((total, pt) => {\\n    const neighbors = findNeighbors(pt).filter(pt => !accountedFor[pt])\\n    neighbors.forEach(pt => (accountedFor[pt] = true))\\n    return [...total, ...neighbors]\\n  }, [])\\n  concentricCircles[point][2] = nextCircle\\n})\\n\")), mdx(\"p\", null, \"That works great for the situation in my last diagram. Unfortunately, it has a flaw that can come up if there is more than one point in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \".\"), mdx(\"h3\", null, \"Describing the Bug\"), mdx(\"p\", null, \"Here's a closeup of the second diagram from the example problem at the start of this article:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"..dDde\\nbb.deE\\nbBb.ee\\n\")), mdx(\"p\", null, \"The \\\".\\\"s are at points that are the same distance from two of the points in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \". Every one of them is as far from B as from D. According to the rules, they don't count towards the total area for either B or D. But my algorithm doesn't mark any point as \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accountedFor\"), \" until \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"after\"), \" it has been added to some point's neighbors. Instead of the diagram above, my algorithm would result in a grid that looks like this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"bbdDde\\nbbbdeE\\nbBbbee\\n\")), mdx(\"p\", null, \"I need a way to track the points that have been added as neighbors to more than one input, and ensure those points don't end up counted as neighbors at all. I can't get that with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accountedFor\"), \", because that sets all the values to just true. I need \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"occountedFor\"), \" to track how many times each \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pt\"), \" is a neighbor. If \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pt\"), \" shows up as a neighbor once, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accountedFor[pt]\"), \" should be one. The next time \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pt\"), \" shows up as a neighbor, I increment \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accountedFor[pt]\"), \" to two. I can't just write\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"accountedFor[pt] = accountedFor[pt] + 1\\n\")), mdx(\"p\", null, \"The problem is that if \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"pt\"), \" has never been a neighbor, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accountedFor[pt]\"), \" will be undefined, and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"undefined + 1\"), \" doesn't work. I'll have to make sure the code replaces any undefined with 0:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"accountedFor[pt] = (accountedFor[pt] || 0) + 1\\n\")), mdx(\"p\", null, \"That updates \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accountedFor\"), \" to keep track of numbers. Next I need to put those numbers to use. I won't know how many neighbors get double-counted until I've iterated over every point in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \", so I'll need to deal with the double counts after the iteration. At that point, I'll need to remove the doubles. I can do another iteration over \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" to filter out any point that appears in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"accountedFor\"), \" as appearing more than once:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let accountedFor = {}\\ninput.forEach(point => {\\n  const lastCircle = concentricCircles[point][1]\\n  lastCircle.forEach(pt => (accountedFor[pt] = (accountedFor[pt] || 0) + 1))\\n  const nextCircle = lastCircle.reduce((total, pt) => {\\n    const neighbors = findNeighbors(pt).filter(\\n      _point => !total.some(([x, y]) => _point[0] === x && _point[1] === y)\\n    )\\n    return [...total, ...neighbors]\\n  }, [])\\n  nextCircle.forEach(pt => (accountedFor[pt] = (accountedFor[pt] || 0) + 1))\\n  concentricCircles[point][2] = nextCircle\\n})\\ninput.forEach(point => {\\n  concentricCircles[point][2] = concentricCircles[point][2].filter(\\n    pt => accountedFor[pt] === 1\\n  )\\n})\\n\")), mdx(\"p\", null, \"That gets the second concentric circle around each \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" point, with no duplicates, and no points that are equidistant between two points from \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \". I'd like to generalize that to get \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"all\"), \" the concentric circles, and figure out when I can stop making the circles.\"), mdx(\"h3\", null, \"A One, and a Two, and a....\"), mdx(\"p\", null, \"Looking through the code to make the second circle, there are only a few specific numbers that tie the code to the \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"second\"), \" circle instead of the third or fourth etc: the places that use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point][1]\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point][2]\"), \". I could make the code block more general by using a variable, like \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"let i =\"), \". Then I could replace \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point][1]\"), \" with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point][i]\"), \", and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point][2]\"), \" with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point][i + 1]\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let accountedFor = {}\\nlet i = 1\\ninput.forEach(point => {\\n  const lastCircle = concentricCircles[point][i]\\n  lastCircle.forEach(pt => (accountedFor[pt] = (accountedFor[pt] || 0) + 1))\\n  const nextCircle = lastCircle.reduce((total, pt) => {\\n    const neighbors = findNeighbors(pt).filter(\\n      _point => !total.some(([x, y]) => _point[0] === x && _point[1] === y)\\n    )\\n    return [...total, ...neighbors]\\n  }, [])\\n  nextCircle.forEach(pt => (accountedFor[pt] = (accountedFor[pt] || 0) + 1))\\n  concentricCircles[point][i + 1] = nextCircle\\n})\\ninput.forEach(point => {\\n  concentricCircles[point][i + 1] = concentricCircles[point][i + 1].filter(\\n    pt => accountedFor[pt] === 1\\n  )\\n})\\n\")), mdx(\"p\", null, \"Now, I could wrap the whole thing in a loop, and increment \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"i\"), \", and it would work for the second, third, whatever circle I want. But I don't want the loop to go on forever. I don't have a pre-existing collection of circles to iterate over, so I can't use another \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"forEach\"), \". I don't know how many circles I'm going to make, so a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"for\"), \" loop doesn't quite seem right. This looks like a job for a \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"while\"), \" loop. I need to figure out the condition that lets the loop continue. How do I know when the loop should continue?\"), mdx(\"p\", null, \"Well, what am I doing the looping for? I'm trying to figure out all of the areas that surround each \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" point. What do I know about those areas? I know they're a set of points, closer to one \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" point than to any other \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" point, and they can't go \\\"out of bounds\\\" of my grid. What does the loop do with those points? Each time through the loop, I look at the outermost ring around each \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" point, and find the neighbors of all of those. I eliminate any neighbors that are \\\"out of bounds\\\", or closer to another \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" point than to the one I'm checking at the moment. Any neighbors that make it through the filtering become a part of the newest outermost ring. What if no neighbors make it through filtering?\"), mdx(\"p\", null, \"Aha. If no neighbors make it through filtering, for any \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \", then I can stop. I continue so long as at least one \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" point has an outermost ring that has at least one point in it. In JavaScript terms,\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let i = 1\\nwhile(input.some(point => concentricCircles[point][i].length > 0)) {\\n  input.forEach(point => {\\n    ...\\n  })\\n  input.forEach(point => {\\n    concentricCircles[point][i + 1] = concentricCircles[point][i + 1].filter(\\n      pt => accountedFor[pt] === 1\\n    )\\n  })\\n}\\n\")), mdx(\"p\", null, \"That loop will continue until the whole grid gets filled up. Then I have to deal with the areas that would expand past the grid.\"), mdx(\"h3\", null, \"Finite Only\"), mdx(\"p\", null, \"At that point, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"areas\"), \" has been calculated for the entire grid from (0, 0) to the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"xMax\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"ymax\"), \" values we calculated at the beginning. Any area that reaches an edge of that grid will go on forever, and the problem statement said we're concerned only with the finite areas. We can filter out areas that reach an edge, and we can identify those areas because at least one point in them will have at least one of the following:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"x coordinate of 0\\nx coordinate of xMax\\ny coordinate of 0\\ny coordinate of yMax\\n\")), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const finites = input.filter(point => {\\n  return !areas[point].some(points =>\\n    points.some(([x, y]) => {\\n      return x === 0 || y === 0 || x === xMax || y === yMax\\n    })\\n  )\\n})\\n\")), mdx(\"h3\", null, \"Finally\"), mdx(\"p\", null, \"Once we have the inputs that have finite areas, the last task is to identify the biggest one. To figure out how many points are in one, remember that \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"concentricCircles[point]\"), \" is the array of arrays of points that are closest to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"point\"), \". To get the total number of points in that nested array, we can turn the array of arrays into an array of numbers with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".map()\"), \", then turn the array of numbers into a single number with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".reduce()\"), \".\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const finiteAreas = finites.map(pt => {\\n  return concentricCircles[pt]\\n    .map(d => d.length)\\n    .reduce((total, current) => total + current, 0)\\n})\\nconsole.log(Math.max(...finiteAreas))\\n\")), mdx(\"p\", null, \"Part Two is \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"so\"), \" much simpler.\"), mdx(\"div\", {\n    \"className\": \"footnotes\"\n  }, mdx(\"hr\", {\n    parentName: \"div\"\n  }), mdx(\"ol\", {\n    parentName: \"div\"\n  }, mdx(\"li\", _extends({\n    parentName: \"ol\"\n  }, {\n    \"id\": \"fn-manhattan\"\n  }), \"calculate the distance as though you were walking in a city - diagonal movement isn't allowed, because there are buildings in the way.\", mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"#fnref-manhattan\",\n    \"className\": \"footnote-backref\"\n  }), \"\\u21A9\")), mdx(\"li\", _extends({\n    parentName: \"ol\"\n  }, {\n    \"id\": \"fn-not really circles\"\n  }), \"Approximately circles. Hard to make a really round shape using points on a grid.\", mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"#fnref-not%20really%20circles\",\n    \"className\": \"footnote-backref\"\n  }), \"\\u21A9\")), mdx(\"li\", _extends({\n    parentName: \"ol\"\n  }, {\n    \"id\": \"fn-1\"\n  }), \"not really circles\", mdx(\"a\", _extends({\n    parentName: \"li\"\n  }, {\n    \"href\": \"#fnref-1\",\n    \"className\": \"footnote-backref\"\n  }), \"\\u21A9\")))));\n}\nMDXContent.isMDXComponent = true;"}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"id":"9cc5cc71-dce2-5e6a-977d-334313740f40","slug":"/2018-advent-of-code-day-six/","timeToRead":10,"wordCount":2562,"frontMatter":{"date":"2019-05-05","title":"Again with the Geometry","tags":["education","javascript","Advent of Code"]},"prev":{"id":"c46df0df-2d72-5d4d-bbcc-07440881ed2d","parent":{"name":"2018-advent-of-code-day-five"},"excerpt":"The Problem There is a ( really  long) string made up of a mix of uppercase and lowercase letters. The string is to be shortened by removing…","fields":{"slug":"/2018-advent-of-code-day-five/"},"timeToRead":2,"wordCount":{"words":508},"frontmatter":{"date":"2019-05-05","title":"That's React_ion_, not React","tags":["education","javascript","Advent of Code"]}},"next":{"id":"0cdd69b2-0e03-5f82-bff9-41f38dbf0905","parent":{"name":"2018-advent-of-code-day-six-part-two"},"excerpt":"The Problem For Part Two, we're asked to find every point that has a  total  distance to every  input  point of less than 10000. I didn't do…","fields":{"slug":"/2018-advent-of-code-day-six-part-two/"},"timeToRead":1,"wordCount":{"words":130},"frontmatter":{"date":"2019-05-05","title":"This is Anti-Climactic","tags":["education","javascript","Advent of Code"]}}}}