{"data":{"mdx":{"id":"c46df0df-2d72-5d4d-bbcc-07440881ed2d","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\": \"That's React_ion_, not React\",\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(\"h2\", null, \"The Problem\"), mdx(\"p\", null, \"There is a (\", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"really\"), \" long) string made up of a mix of uppercase and lowercase letters. The string is to be shortened by removing any lowercase letter if it's next to the corresponding uppercase letter (like \\\"a\\\" and \\\"A\\\"). The process can repeat. For instance,\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"dabA_cC_aCBAcCcaDA  The first 'cC' is removed.\\ndab_Aa_CBAcCcaDA    This creates 'Aa', which is removed.\\ndabCBA_cCc_aDA      Either 'cC' or 'Cc' are removed (the result is the same).\\ndabCBAcaDA        No further actions can be taken.\\n\")), mdx(\"p\", null, \"The desired solution is the length of the final string. Not much code for this one. Get the initial input:\"), 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/day5.txt`, 'utf8')\\n  .trim()\\n  .split('')\\n\")), mdx(\"p\", null, \"-and we're already 1/8 done. Note that I use \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".split('')\"), \" and not \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".split('\\\\n')\"), \", because I want an array of single characters.\"), mdx(\"p\", null, \"The key feature of the polymerization reaction described here is that there's a process which has to happen an indeterminate number of times - it goes until it stops. I don't know yet how to describe each pass through the process, other than to give it a catchy name, like \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"onePass\"), \". I do know that since the effect of one pass through the process is to shorten the length of the input, we can have the process start, then say it continues until the length of the input stops changing:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const polymerize = input => {\\n  let nextInput = onePass(input)\\n  while (input.length !== nextInput.length) {\\n    input = nextInput\\n    nextInput = onePass(input)\\n  }\\n  return input.length\\n}\\n\")), mdx(\"p\", null, \"In one pass through the process, every element in the input is compared to the one before it, and if certain conditions are met, they're both eliminated. I'll deal with how to determine the conditions later. Since every element is represented by a letter, elements can be marked for removal by replacing them with a non-letter character, then removed by filtering that character out:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const onePass = input => {\\n  for (let i = 1; i < input.length; i++) {\\n    if (condition(input[i - 1], input[i])) {\\n      input[i - 1] = '-'\\n      input[i] = '-'\\n    }\\n  }\\n  return input.filter(c => c !== '-')\\n}\\n\")), mdx(\"p\", null, \"Note that I'm starting with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"i = 1\"), \" not \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"i = 0\"), \". That's because I want to compare each element to the one before it, and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input[0]\"), \" doesn't have anything before it.\"), mdx(\"p\", null, \"The condition that has to be met for the two elements to be eliminated is that they must be the uppercase and lowercase versions of the same letter. If that is the case, the elements themselves will \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"not\"), \" be equal (because JavaScript doesn't consider 'a' to be equal to 'A') but they can be made equal by converting them both into the same case (upper or lower). Turning that idea into code:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const condition = (first, second) =>\\n  first !== second && first.toLowerCase() === second.toLowerCase()\\n\")), mdx(\"p\", null, \"That's all the code needed for part one! Here it is written all together:\"), 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/day5.txt`, 'utf8')\\n  .trim()\\n  .split('')\\n\\nconst condition = (first, second) =>\\n  first !== second && first.toLowerCase() === second.toLowerCase()\\n\\nconst onePass = input => {\\n  for (let i = 1; i < input.length; i++) {\\n    if (condition(input[i - 1], input[i])) {\\n      input[i - 1] = '-'\\n      input[i] = '-'\\n    }\\n  }\\n  return input.filter(c => c !== '-')\\n}\\n\\nconst polymerize = input => {\\n  let nextInput = onePass(input)\\n  while (input.length !== nextInput.length) {\\n    input = nextInput\\n    nextInput = onePass(input)\\n  }\\n  return input.length\\n}\\nconsole.log(polymerize(input))\\n\")), mdx(\"p\", null, \"Part two is even shorter than that. The goal of part two is to see which letter should be removed at the outset to drive the reaction the furthest. We'll need a representation of the whole alphabet, and writing out all the letters is for noobs.\"), mdx(\"p\", null, \"One approach is to create a 26 element array with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Array(26)\"), \", then transform that array into letters with the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"String.fromCharCode()\"), \" method. For some reason, calling \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".map()\"), \" directly on an array created with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Array(n)\"), \" doesn't really work, so I spread the array into a new array first. (Yesterday I did \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"(new Array(wakeTime)).fill(1)\"), \" to accomplish the same thing.) At that point we're cooking with gas. \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"String.fromCharCode()\"), \" takes a numerical argument and returns a character:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"String.fromCharCode(97) // \\\"a\\\"\\nString.fromCharCode(98) // \\\"b\\\"\\n\")), mdx(\"p\", null, \"So we can produce the whole alphabet with\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const alphabet = [...Array(26)].map((_, i) => String.fromCharCode(i + 97))\\n\")), mdx(\"p\", null, \"Another approach is\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const alphabet = 'abcdefghijklmnopqrstuvwyxz'.split('')\\n\")), mdx(\"p\", null, \"-but how fun is that?\"), mdx(\"p\", null, \"Anyway, once the alphabet is ready, map from each letter to the polymer length produced by filtering the letter out of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"input\"), \" before invoking \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"polymerize()\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const partTwo = alphabet.map(letter => {\\n  const inputWithoutLetter = input.filter(\\n    character => character.toLowerCase() !== letter\\n  )\\n  return polymerize(inputWithoutLetter)\\n})\\n\")), mdx(\"p\", null, \"The answer is the smallest number in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"partTwo\"), \":\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"console.log(Math.min(...partTwo))\\n\")), mdx(\"p\", null, \"The End.\"));\n}\nMDXContent.isMDXComponent = true;"}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"id":"c46df0df-2d72-5d4d-bbcc-07440881ed2d","slug":"/2018-advent-of-code-day-five/","timeToRead":2,"wordCount":508,"frontMatter":{"date":"2019-05-05","title":"That's React_ion_, not React","tags":["education","javascript","Advent of Code"]},"prev":null,"next":{"id":"9cc5cc71-dce2-5e6a-977d-334313740f40","parent":{"name":"2018-advent-of-code-day-six"},"excerpt":"These geometry problems are tough. The Problem This is best explained by the Advent of Code site itself, so I'm going to copy. For example…","fields":{"slug":"/2018-advent-of-code-day-six/"},"timeToRead":10,"wordCount":{"words":2562},"frontmatter":{"date":"2019-05-05","title":"Again with the Geometry","tags":["education","javascript","Advent of Code"]}}}}