{"data":{"mdx":{"id":"62be82f0-6c6a-5aac-be63-42fc09986182","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-04\",\n  \"order\": 6,\n  \"title\": \"Either These Are Getting Easier or I'm Getting Better\",\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, \"Day Four has us figuring out when to sneak by a sleeping guard, based on a set of notes about when each guard starts a shift, falls asleep, and wakes up. The data format looks like this:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {}), \"[1518-11-01 00:00] Guard #10 begins shift\\n[1518-11-01 00:05] falls asleep\\n[1518-11-01 00:25] wakes up\\n\")), mdx(\"p\", null, \"We're told all the sleeping / waking events happen between midnight and 1am, so only the minute part matters for those. (The date part of the datetime stamps is in the distant past because of a cute backstory involving time travel.) For part one, we need to find which minutes each guard is asleep (for instance, one guard might always be asleep at 12:15). We also need to find which guard has the most minutes asleep.\"), mdx(\"p\", null, \"The first step may look familiar:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const fs = require('fs')\\nconst data = fs\\n  .readFileSync('./input/day4.txt', 'utf8')\\n  .trim()\\n  .split('\\\\n')\\n  .sort()\\n\")), mdx(\"p\", null, \"The input text file isn't sorted properly, but because each line starts with a datetime stamp, \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".sort()\"), \" is able to get it in the right order.\"), mdx(\"p\", null, \"Once I had the data sorted (so to speak), I started to think about what kind of JavaScript structure I wanted to use to store it. I'll have data about each of several guards, which means I'll need some kind of container, which in JavaScript makes me think of either object or array (and usually object). Every guard has a numerical id, but the ids aren't zero-indexed and the order of them doesn't seem important, so I will make an object and use the guard ids as keys. The value associated with a key will be the information about a guard. What will that look like? At first, I thought I had to keep track of two pieces of information per guard, so I made a little object:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"{ numberOfMinutesAsleep: 0, whichMinutes: [] }\\n\")), mdx(\"p\", null, \"Then I realized that \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"numberOfMinutesAsleep\"), \" could be calculated by \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"whichMinutes.length\"), \", so I simplified the object to have just one property:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"{\\n  whichMinutes: []\\n}\\n\")), mdx(\"p\", null, \"Then I realized having an object just makes it a little harder to get to the array in which I'm keeping track of the minutes, so I ended up just using an array to represent the minutes a guard spends asleep. The array which tracks the minutes a guard spends asleep gets paired with the key which is that guard's id. For example, using the example guard data above (id #10, falls asleep at 00:05, wakes up at 00:25), I could write:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"{ 10: [ 5, 6, 7, 8, 9, 10, 11, 12,...24 ] }\\n\")), mdx(\"p\", null, \"OK, I have an array of strings in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data\"), \", and I want to end up with an object. My initial inclination is to do that with\", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".reduce()\"), \". That feels a bit tricky here, because unlike previous times that I've used \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".reduce()\"), \" I don't have the same kind of information in each line of my array. Some lines talk about a guard waking up, some about the guard falling asleep, and some about a new guard starting a shift. I think I'll need to hold on to information about which guard it is from one line of data to the next. That can be done with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".reduce()\"), \", but somehow it feels more natural to do that while iterating with plain old \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".forEach()\"), \". I'll iterate and do something different for each line depending on what each line tells me:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"data.forEach(line => {\\n  if (line.includes('begins shift')) {\\n    // remember which guard this is\\n  } else if (line.includes('falls asleep')) {\\n    // remember what time the current guard falls asleep\\n  } else {\\n    // end of nap - record which minutes this guard slept\\n  }\\n})\\n\")), mdx(\"p\", null, \"According to my first conditional and comment, I will need to remember the id of the guard when a shift begins. A guard's id is mentioned at the start of the shift; it's the numerical characters after a '#'. You might think I could do that with a variable and a regular expression like\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"  if (line.includes('begins shift')) {\\n    const currentGuardId = line.match(/#(\\\\d+)/)[1]\\n\")), mdx(\"p\", null, \"The problem with that is all of my conditional logic lives inside the body of the callback function for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".forEach()\"), \", which means if I declare a variable in there (with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"const\"), \" or \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"let\"), \" or even \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"var\"), \"), the variable will be scoped to that body. That means it will vanish and get replaced the next time I go through the callback function, which I do for each line of data. The solution is to declare the variable \", mdx(\"em\", {\n    parentName: \"p\"\n  }, \"outside\"), \" of the callback:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let currentGuardId\\ndata.forEach(line => {\\n  if (line.includes('begins shift')) {\\n    currentGuardId = line.match(/#(\\\\d+)/)[1]\\n\")), mdx(\"p\", null, \"I also want to remember what time the current guard falls asleep, which means I'll need another variable defined outside the scope of the callback function:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let currentGuardId\\nlet sleepStart\\ndata.forEach(line => {\\n\")), mdx(\"p\", null, \"I'll get that variable from another call to \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".match()\"), \", when the data gets to a line that says when the guard falls asleep:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"  } else if (line.includes('falls asleep')) {\\n    sleepStart = Number(line.match(/:(\\\\d+)/)[1])\\n\")), mdx(\"p\", null, \"That regular expression is similar to what I used before. The use of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Number()\"), \" is new. Remember \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".match()\"), \" returns an array\", 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\")), \" of strings, and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Number()\"), \" can transform a string that looks like a number into an actual number. I didn't need to do that with the id, because I was only ever going to use the id as the key in an object, which means JavaScript would force it to be a string anyway.\"), mdx(\"p\", null, \"Once I have gone through the first two lines of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data\"), \", I should have the id of the guard whose shift started and the minute the guard fell asleep. The only other kind of information in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"data\"), \" is what time the guard wakes up, so I can be sure if a line doesn't iclude either \\\"begins shift\\\" or \\\"falls asleep\\\", it's a wake up time. I'll be able to read that time and transform it into a number the same way I did with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sleepStart\"), \". At that point, I will be able to store the record of the minutes the guard was asleep in my data storage object.\"), mdx(\"p\", null, \"Ah, nuts. I never made my data storage object.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let currentGuardId\\nlet sleepStart\\nlet guardNaps = {}\\n\")), mdx(\"p\", null, \"OK, by the time I reach a line that tells me when a guard wakes, I must already have values for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"currentGuardId\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sleepStart\"), \". I can use those values, along with the time the guard wakes up, to say which minutes the guard has slept during the latest nap. I wrote that really quickly for the example data - the guard fell asleep at 12:05 and woke up at 12:25, and that resulted in an array with every integer from 5 to 24. In some other languages, it's easy to make an array out of two endpoints (ah, Ruby). JavaScript makes you work for it a little.\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let currentGuardId\\ndata.forEach(line => {\\n  if (line.includes('begins')) {\\n    currentGuardId = line.match(/#(\\\\d+)/)[1]\\n    if (!guards[currentGuardId]) {\\n      guards[currentGuardId] = []\\n    }\\n  } else if (line.includes('falls')) {\\n...\\n\")), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".match()\"), \" takes a regular expression as an argument. I used \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"/#(\\\\d)+/\"), \" as the regular expression. That sequence of characters means \\\"a literal '#', then one or more digits - and hold on to the digits for later\\\". The return value of \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".match()\"), \" is an array, and the 1st element is the first captured group from the match (the digits I held on to). That's how I get the id out of the line. I use the id as a key in my \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"guards\"), \" object. If it's the first time I've seen the id, I initialize a value for it as an empty array. That will hold the list of minutes the guard spends asleep.\"), mdx(\"p\", null, \"I can do basically the same thing to find the time a guard falls asleep:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"let currentGuardId\\nlet sleepStart\\ndata.forEach(line => {\\n  if (line.includes('begins')) {\\n    currentGuardId = line.match(/#(\\\\d+)/)[1]\\n    if (!guards[currentGuardId]) {\\n      guards[currentGuardId] = []\\n    }\\n  } else if (line.includes('falls')) {\\n    sleepStart = Number(line.match(/:(\\\\d+)/)[1])\\n  } else {\\n...\\n\")), mdx(\"p\", null, \"Once again, a regular expression capture group extracts some digits from a string. This time, I have to feed that value into the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"Number\"), \" function, because I will need to treat it as a number in a minute (so to speak). I also initialized the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sleepStart\"), \" variable outside of the callback function so it survives from one loop to the next.\"), mdx(\"p\", null, \"If a line doesn't say a guard's shift begins and it doesn't say a guard falls asleep, it must say the guard wakes up. These things happen in order, so by the time I reach a line that tells me when a guard wakes, I must already have values for \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"currentGuardId\"), \" and \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sleepStart\"), \". I can use those values, along with the time the guard wakes up, to say which minutes the guard has slept during the latest nap:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"  } else if (line.includes('falls')) {\\n    sleepStart = Number(line.match(/:(\\\\d+)/)[1])\\n  } else {\\n    const wakeTime = Number(line.match(/:(\\\\d+)/)[1])\\n    const newMinutes = (new Array(wakeTime)).fill(1)\\n                                            .map((_, i) => i)\\n                                            .slice(sleepStart,)\\n    const guard = guards[currentGuardId]\\n    guards[currentGuardId] = [ ...guard, ...newMinutes ]\\n  }\\n\")), mdx(\"p\", null, mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"wakeTime\"), \" works exactly the same way \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"sleepStart\"), \" did. Those two variables together mark the start and end of the interval the guard was asleep. I can use them together to make \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"newMinutes\"), \", the array with each minute in that interval. First \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"new Array(wakeTime)\"), \" makes an array with \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"wakeTime\"), \" slots in it. (Due to a quirk in JavaScript, I can't do anything useful with that array right off, so I have to fill the empty slots in it by calling \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".fill(1)\"), \", which gives me an array of all 1's.) I can convert the array to a sequence of integers by calling \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".map()\"), \" and returning the index value of each element in the array. At that point, I'll have an array of 0 to just before \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"wakeTime\"), \". For example, if the guard woke up at 12:06, the array will be \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"[0, 1, 2, 3, 4, 5]\"), \". I still need to remove the numbers at the front end from before the guard fell asleep, which is what \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \".slice(sleepStart,)\"), \" does.\"), mdx(\"p\", null, \"Once I have the array with the minutes the guard slept during that nap, I spread them into the array stored at \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"guards[currentGuardId]\"), \". Then it is the work of but a moment to find the id of the guard who slept the most. I have to turn the \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"guards\"), \" object into an array of the object's values, then map those values to their lengths, then get the biggest length. That will tell me the largest number of minutes any guard spent asleep. Then iterate over the keys in \", mdx(\"inlineCode\", {\n    parentName: \"p\"\n  }, \"guards\"), \" to find the guard who slept that much:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-javascript\"\n  }), \"const times = Object.values(guards).map(guard => guard.length)\\nconst maxTime = Math.max(...times)\\nconst sleepyGuardId = Object.keys(guards).find(\\n  guardId => guards[guardId].length === maxTime\\n)\\n\")), 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-1\"\n  }), \"sort of\", 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":"62be82f0-6c6a-5aac-be63-42fc09986182","slug":"/2018-advent-of-code-day-four/","timeToRead":6,"wordCount":1473,"frontMatter":{"date":"2019-05-04","title":"Either These Are Getting Easier or I'm Getting Better","tags":["education","javascript","Advent of Code"]},"prev":{"id":"cb6d6810-510d-555f-a232-2f3dff5d787b","parent":{"name":"2018-advent-of-code-day-three"},"excerpt":"Today's problem involves a lot of rectangles, and just a few drawings. The Problem The input data describes a set of rectangles. The…","fields":{"slug":"/2018-advent-of-code-day-three/"},"timeToRead":9,"wordCount":{"words":2343},"frontmatter":{"date":"2019-05-04","title":"This Would Be Easier If I Had Graph Paper","tags":["education","javascript","Advent of Code"]}},"next":null}}