Skip to content

Instantly share code, notes, and snippets.

@L3afMe
Last active December 8, 2020 19:14
Show Gist options
  • Select an option

  • Save L3afMe/477a2f01a39463a72638eb017ddc63a4 to your computer and use it in GitHub Desktop.

Select an option

Save L3afMe/477a2f01a39463a72638eb017ddc63a4 to your computer and use it in GitHub Desktop.
Advent of Code Javascript One Liners

AoC Javascript One Liners

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


Day 1 - Report Repair


Part 1

Given a list of numbers, find two which when added together result in 2020. The flag is the product of these numbers.


One Liner


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]}`));

Documentation


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]}`));

Part 2 - Password Philosophy

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.


One Liner


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]}`));

Documentation


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]}`));

Day 2 - Password Philosophy


Part 1


One Liner


Documentation


Part 2


One Liner

Documentation


Day 3 - Toboggan Trajectory


Part 1


One Liner


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}`));

Documentation


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 :)

Part 2


One Liner

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));

Documentation


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 hit

Day 4 - Passport Processing


Part 1


One Liner


part1 = () => this.input.reduce((p, c) => `${p} ${c}`).split('  ').map(l => l.split(' ').filter(l => !l.startsWith('cid'))).filter(l => l.length === 7).length;

Documentation


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 length

Part 2


One Liner

part2 = () => 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;

Documentation


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!

Day 5 - Binary Boarding


Part 1


One Liner


Documentation


Part 2


One Liner

Documentation


Day 6 - Custom Customs


Part 1


One Liner


part1 = () => this.input.map(line => line.split('').filter((v, i, s) => s.indexOf(v) === i).length).reduce((a, b) => a + b);

Documentation


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!

Part 2


One Liner

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);

Documentation


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!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment