Just a prewarning; none of these are optimised or made to be super fast. These were all for fun and to see if I was able to solve them in one line <3
Given a list of numbers, find two which when added together result in 2020. The flag is the product of these numbers.
new Promise(resolve => input.map(n => parseInt(n)).forEach((el1, inx, arr) => arr.filter(el2 => el1 + el2 === 2020).map(el2 => [el1, el2]).forEach(resolve))).then(els => console.log(`Part 1\nValue 1: ${els[0]}\nValue 2: ${els[1]}\nFlag: ${els[0] * els[1]}`));new Promise(resolve => input // Create new Promise so we can log in the same line
.map(n => parseInt(n)) // Map each line string to integer
.forEach((el1, _, arr) => // Loop through each element, including the base array so we can loop through it again
arr.filter(el2 => el1 + el2 === 2020) // Filter the array based on the element from the above line
.map(el2 => [el1, el2]) // Map to include the first element
.forEach(resolve))) // Call resolve with the list of valid numbers
.then(els => // Log everything to console :)
console.log(`Part 1\nValue 1: ${els[0]}\nValue 2: ${els[1]}\nFlag: ${els[0] * els[1]}`));Pretty much the same as above but with a second loop but instead of finding two numbers that add up to 2020, find three instead.
new Promise(resolve => input.map(n => parseInt(n)).forEach((el1, _, arr) => arr.forEach(el2 => arr.filter(el3 => el1 + el2 + el3 === 2020).map(el3 => [el1, el2, el3]).forEach(resolve)))).then(els => console.log(`Part 2\nValue 1: ${els[0]}\nValue 2: ${els[1]}\nValue 3: ${els[2]}\nFlag: ${els[0] * els[1] * els[2]}`));new Promise(resolve => input // Create new Promise so we can log in the same line
.map(n => parseInt(n)) // Map each line string to integer
.forEach((el1, _, arr) => // Loop through each element twice
arr.forEach(el2 => // Including the base array so we can loop through it again
arr.filter(el3 => el1 + el2 + el3 === 2020) // Filter the array based on the elements from the above line
.map(el3 => [el1, el2, el3]) // Map to include the other elements
.forEach(resolve)))) // Call resolve with the list of valid numbers
.then(els => // Log everything to console :)
console.log(`Part 2\nValue 1: ${els[0]}\nValue 2: ${els[1]}\nValue 3: ${els[2]}\nFlag: ${els[0] * els[1] * els[2]}`));new Promise(resolve => resolve(input.map((line, idx) => ({line: line, x: idx * 3 % line.length})).filter(el => el.line.charAt(el.x) === '#').length)).then(part1 => console.log(`Part1: ${part1}`));part1 = () => this.input
.map((line, idx) => // Map each line to include the x axis module line.length
({line: line, x: idx * 3 % line.length})) // as we act as if the line repeats over and over
.filter(el => el.line.charAt(el.x) === '#') // Filter checking if we hit a tree!
.length)) // Count how many lines are left
.then(part1 => console.log(`Part1: ${part1}`); // Log everything to console :)part2 = () => [{x: 1, y: 1}, {x: 3, y: 1}, {x: 5, y: 1}, {x: 7, y: 1}, {x: 1, y: 2}].map(slope => this.input.filter((_, idx) => idx % slope.y === 0).map((line, idx) => ({line: line, x: idx * slope.x % line.length})).filter((el) => el.line.charAt(el.x) === '#').length));part2 = () => [
{x: 1, y: 1}, {x: 3, y: 1}, {x: 5, y: 1}, {x: 7, y: 1}, {x: 1, y: 2}]
.map(slope => this.input // Map the slopes to the their value
.filter((_, idx) => idx % slope.y === 0) // Filter every x lines based on the slope's y value
.map((line, idx) => // Map each line to include their respective x axis
({line: line, x: idx * slope.x % line.length})) // You could include this in the line below but this makes it slightly more readable
.filter((el) => el.line.charAt(el.x) === '#') // Filter by checking if the value is a tree!
.length)); // Get the length as this will be how many trees we hitpart1 = () => this.input.reduce((p, c) => `${p} ${c}`).split(' ').map(l => l.split(' ').filter(l => !l.startsWith('cid'))).filter(l => l.length === 7).length;part1 = () => this.input
.reduce((p, c) => `${p} ${c}`) // Neat little trick I discovered to split arrays at empty lines
.split(' ') // and join them into seperate arrays by joining all items by a
.map(l => l.split(' ') // space or newline and then splitting at two of them
.filter(l => !l.startsWith('cid'))) // Filter out 'cid' as this isn't required
.filter(l => l.length === 7) // Filter arrays that aren't 7 in length
.length; // Return the lengthpart2 = () => this.input.reduce((p, c) => `${p} ${c}`).split(' ').map(l => l.split(' ').filter(l => !l.startsWith('cid'))).filter(l => l.length === 7).filter((_l) => _l.map(l => ({key: l.match(/.*(?=:)/)[0], val: l.match(/(?<=:).*/)[0]})).map(l => ({key: l.key, val: l.val, intVal: parseInt(l.val.match(/[0-9].*/g))})).filter(l => !(l.key === 'byr')||(l.intVal >= 1920 && l.intVal <= 2002)).filter(l => !(l.key === 'iyr')||(l.intVal >= 2010 && l.intVal <= 2020)).filter(l => !(l.key === 'eyr')||(l.intVal >= 2020 && l.intVal <= 2030)).filter(l => !(l.key === 'hgt')|| (l.val.endsWith('cm') ? (l.intVal >= 150 && l.intVal <= 193) : l.val.endsWith('in') ? (l.intVal >= 59 && l.intVal <= 76) : false)).filter(l => !(l.key === 'pid')||(l.val.match(/[0-9].*/g)[0].length === 9)).filter(l => !(l.key === 'ecl')||('amb blu brn gry grn hzl oth'.includes(l.val))).filter(l => !(l.key === 'hcl')|| (!(l.val.length === 9 && l.val.startsWith('#'))|| (l.val.substring(1).split('').filter(c => 'abcdef0123456789'.includes(c)).length === 8))).length === 7).length;part2 = () => this.input
.reduce((p, c) => `${p} ${c}`) // See Day 4 Part 1
.split(' ') // for explanation
.map(l => l.split(' ') // of this :)
.filter(l => !l.startsWith('cid'))) // Again filter out 'cid' then
.filter(l => l.length === 7) // arrays that aren't 7 in length
.filter((l) => l //
.map(l => ({ // Map the line to an object containing
key: l.match(/.*(?=:)/)[0], // The key; everything before ':'
val: l.match(/(?<=:).*/)[0] // The value; everything after ':'
intVal: parseInt(l.match(/(?<=:).*/)[0] // Get value again then extract the
.match(/[0-9]*/g)[0]) // numbers and parse them
})) //
.filter(l => !(l.key === 'byr')|| // If the key is equal to 'byr' check if
(l.intVal >= 1920 && l.intVal <= 2002)) // int value is between 1920 and 2002
.filter(l => !(l.key === 'iyr')|| // If the key is equal to 'iyr' check if
(l.intVal >= 2010 && l.intVal <= 2020)) // int value is between 2010 and 2020
.filter(l => !(l.key === 'eyr')|| // If the key is equal to 'eyr' check if
(l.intVal >= 2020 && l.intVal <= 2030)) // int value is between 2020 and 2030
.filter(l => !(l.key === 'hgt')|| // If the key is equal to 'hgt' check if
(l.val.endsWith('cm') ? // if the value ends with 'cm' check if
(l.intVal >= 150 && l.intVal <= 193) : // int value is between 150 and 193
l.val.endsWith('in') ? // else if the value ends with 'in' check if
(l.intVal >= 59 && l.intVal <= 76) : // int value is between 59 and 76
false)) // and if it ends with neither return false
.filter(l => !(l.key === 'pid')|| // If the key is equal to 'pid' match all
(l.val.match(/[0-9].*/g)[0].length === 9)) // sequential numbers and check if length is 9
.filter(l => !(l.key === 'ecl')|| // If the key is equal to 'ecl' check if
('amb blu brn gry grn hzl oth'.includes(l.val))) // val is a valid eye color listed
.filter(l => !(l.key === 'hcl')|| // If the key is equal to 'hcm' check if
(!(l.val.length === 9 && l.val.startsWith('#'))|| // the length of val is 9 and starts with '#'
(l.val.substring(1) // Substring after the first char
.split('') // Split all chars and check if they're valid
.filter(c => 'abcdef0123456789'.includes(c)) // hex characters
.length === 8))) // Count how many chars are left and return len == 8
.length === 7) // Check if the length is still 7 after filtering
.length; // Return the length of valid passports!part1 = () => this.input.map(line => line.split('').filter((v, i, s) => s.indexOf(v) === i).length).reduce((a, b) => a + b);part1 = () => this.input
.map(line => line.split('') // For each line, split at every character then filter by checking if the
.filter((v, i, s) => s.indexOf(v) === i).length) // first index of the array that matches the value is equal to the current value indiex and return the left
.reduce((a, b) => a + b); // Add everthing together and return!part2 = () => this.input.reduce((p, c) => `${p}\n${c}`).split('\n\n').map(l => l.split('\n').reduce((p, c) => p + c).split('').filter((v, i, s) => s.indexOf(v) === i).length).reduce((p, c) => p + c);part2 = () => this.input
.reduce((p, c) => `${p}\n${c}`) // See Day 4 Part 2
.split('\n\n').map(l => l.split('\n') // for explanation on
.reduce((p, c) => p + c) // how this works :)
.split('') // split
.filter((v, i, s) => s.indexOf(v) === i) //
.length) // Return the length
.reduce((p, c) => p + c); // Add everything together and return!