Безопасность через неизвестность


Содержание
  1. День 4 Advent of Code 2016
  2. Часть 1
  3. Вперед!
  4. Простой regex для получения букв и цифр
  5. Подготовка извлеченных частей
  6. Подсчет встречаемости каждой буквы в строке
  7. Самая сложная часть: правильная сортировка букв
  8. Слишком много размышлений
  9. Мне просто нужно было sort().
  10. Завершение моего рабочего алгоритма
  11. Тестирование и празднование
  12. Часть 2
  13. Введите: charCodes, modulo и find...!
  14. Создание массива алфавита
  15. Определение правильной новой буквы
  16. Найти... правильное настоящее имя

    Когда мой полный алгоритм на JavaScript был завершен, пришло время просмотреть реальные имена для ссылок на storage.

    colorful egg storage radioactive flower storage magnetic fuzzy dye storage weaponized basket storage classified radioactive scavenger hunt storage cryogenic scavenger hunt storage fuzzy bunny storage northpole object storage Вход в полноэкранный режим Выйти из полноэкранного режима Это было последнее! Я ввел числовой идентификатор, и это был правильный ответ! У меня получилось!!! Я решил обе части! Я отработал кучу фундаментальных приемов программирования! Я написал подробные объяснения в надежде, что они помогут будущим начинающим программистам чувствовать себя более комфортно с JavaScript!
  17. У меня получилось!!!

День 4 Advent of Code 2016

Часть 1

  1. Принесите перчатку!
  2. Простой регекс для получения букв и цифр
  3. Подготовка извлеченных частей
  4. Подсчет встречаемости каждой буквы в строке
  5. Самая сложная часть: правильная сортировка букв
  6. Завершение моего рабочего алгоритма
  7. Тестирование и празднование

Вперед!

Набросок моих предстоящих задач:

  • Начать, как обычно, с многострочного ввода
  • Свести к сумме, как это часто бывает.
  • Извлечь буквы и цифры
  • Сократить строку до словаря с подсчетами каждой буквы
  • Сортировать ключи по номерам и в алфавитном порядке
  • Сохраните только первые пять ключей
  • Сравните со строкой
  • Если оба равны, добавьте к сумме, иначе добавьте 0.

Простой regex для получения букв и цифр

Из этой строки:

aaaaa-bbb-z-y-x-123[abxyz]
Войти в полноэкранный режим Выйти из полноэкранного режима

Мне нужно вот это:

aaaaa bbb z y x 123 abxyz 
Ввести полноэкранный режим Выйти из полноэкранного режима

Чтобы получить их, мне нужно вот это:

/w+/g
Войти в полноэкранный режим Выйти из полноэкранного режима

По сути, он сопоставляет и разделяет каждую часть, которая не является - или [ или ].

Подготовка извлеченных частей

Мой regex возвращает список совпадений, полный других метаданных.

Мне нужна только каждая совпавшая подстрока.

Используя spread и map(), я могу получить то, что мне нужно:

let parts = [...name.matchAll(/w+/g)].map(el => el[0])
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь у меня есть:

['aaaaa','bbb','z','y','x','123','abxyz']
Войти в полноэкранный режим Выйти из полноэкранного режима

Далее мне нужно разделить id и checksum:

let [id, checksum] = parts.slice(-2)
Войти в полноэкранный режим Выход из полноэкранного режима
  • Я сохраняю оба элемента в отдельные переменные, используя array deconstruction.

Наконец, мне нужна одна строка из оставшихся частей:

parts.slice(0,-2).join('')
Войти в полноэкранный режим Выйти из полноэкранного режима

Подсчет встречаемости каждой буквы в строке

Для данного примера:

'aaaaabbbzyx'
Войти в полноэкранный режим Выход из полноэкранного режима

Мне нужно создать этот массив:

[ ['a': 5], ['b': 3], ['z': 1], ['y': 1], ['x': 1] ]
Вход в полноэкранный режим Выход из полноэкранного режима

Мой алгоритм на JavaScript:

Object.entries(
  parts
    .slice(0,-2)
    .join('')
    .split('')
    .reduce(
      (tallies, letter) => {
        tallies[letter] = (tallies[letter] || 0) + 1
        return tallies
      }, {}
    )
)
Войти в полноэкранный режим Выход из полноэкранного режима

Самая сложная часть: правильная сортировка букв

Теперь, когда у меня все получилось:

[ ['a': 5], ['b': 3], ['z': 1], ['y': 1], ['x': 1] ]
Войти в полноэкранный режим Выход из полноэкранного режима

Я очень хочу этого:

[ ['a': 5], ['b': 3], ['x': 1], ['y': 1], ['z': 1] ]
Войти в полноэкранный режим Выйти из полноэкранного режима

Слишком много размышлений

Create an empty string
Create an index at 0
Do as long as the string's length is less than 5
  If the number associated with the letter in the nested array at the current index is the only instance of that number among all the nested arrays
    Add the letter to the string
  Else
    Create a collection of all nested arrays with that number
    Sort the collection alphabetically by key
    Add the letter of the first item in the sorted collection
    Remove the array with that letter from the original collection
Войти в полноэкранный режим Выйти из полноэкранного режима

Я не смог заставить это работать.

Но это не страшно, потому что я нашел гораздо более простое, красноречивое и лаконичное решение!

Мне просто нужно было sort().

Sort the nested arrays by tally in descending order
If two or more tallies are equal, sort those by letter in alphabetical order
Войти в полноэкранный режим Выйти из полноэкранного режима

Мой алгоритм на JavaScript:

.sort(
  (a, b) => b[1] - a[1] || (a[0] > b[0] ? 1 : -1)
)
Вход в полноэкранный режим Выход из полноэкранного режима

Я был потрясен, когда заметил, что это работает!

И был очень рад!

Завершение моего рабочего алгоритма

Теперь у меня есть отсортированный вложенный массив.

Остальная часть моего цепного метода выглядит следующим образом:

parts
// earlier methods
.slice(0,5)
.map(el => el[0])
.join('') ? +id : 0
Войти в полноэкранный режим Выйти из полноэкранного режима

Мой полный алгоритм на JavaScript:

return input.reduce((sum, line) => {
  let parts = [...line.matchAll(/w+/g)].map(el => el[0])
  let [id, checksum] = parts.slice(-2)
  return sum += checksum == Object.entries(
    parts
      .slice(0,-2)
      .join('')
      .split('')
      .reduce(
        (tallies, letter) => {
          tallies[letter] = (tallies[letter] || 0) + 1
          return tallies
        }, {}
      )
    ).sort(
      (a, b) => b[1] - a[1] || (a[0] > b[0] ? 1 : -1)
     )
     .slice(0,5)
     .map(el => el[0])
     .join('') ? +id : 0
}, 0)
Войти в полноэкранный режим Выход из полноэкранного режима

Части, которые я опустил до сих пор:

Тестирование и празднование

  • Это сработало на примерах строк!
  • Это сработало на моем вводе головоломки!

Часть 2

  1. Введите: charCodes, modulo и find...!
  2. Создание алфавитного массива
  3. Определение правильной новой буквы

Введите: charCodes, modulo и find...!

Создание массива алфавита

Мне нужно следующее:

['a', 'b', '...', 'y', 'z']
Войти в полноэкранный режим Выход из полноэкранного режима

Я, конечно, мог бы сделать это вручную, напечатав полностью.

Но я бы предпочел создать его программно.

Мне нужен массив с 26 элементами:

new Array(26)
Вход в полноэкранный режим Выход из полноэкранного режима

Где каждый элемент — это буква.

Но у меня есть только индексы для работы:

new Array(26).fill(null).map((el, index) => //??? )
Войти в полноэкранный режим Выход из полноэкранного режима

Что я могу использовать для оценки букв a-z?

charCodes!

'a'.charCodeAt(0) // 97
'b'.charCodeAt(0) // 98
'z'.charCodeAt(0) // 113
Войти в полноэкранный режим Выход из полноэкранного режима

И чтобы получить букву, сопоставленную с charCode:

String.fromCharCode(97) // 'a'
Войти в полноэкранный режим Выйти из полноэкранного режима

Таким образом, заполняя ??? в моем алгоритме:

new Array(26).fill(null).map(
  (el, index) => String.fromCharCode(index + 97)
)
Войти в полноэкранный режим Выход из полноэкранного режима

Вуаля! У меня есть мой алфавитный массив!

Определение правильной новой буквы

  • Допустим, буква b, а id40.
  • 1 + 40 = 41
  • 41 % 26 = 15
  • Настоящая буква находится в индексе 15: p

При кодировании в виде алгоритма вышеописанные действия выполняются для любой буквы в этой единственной строке:

alphabet[(alphabet.indexOf(letter) + id) % alphabet.length]
Войти в полноэкранный режим Выйти из полноэкранного режима

Мой полный алгоритм на JavaScript:

input.forEach(line => {
  let parts = [...line.matchAll(/w+/g)].map(el => el[0])
  let [id, checksum] = parts.slice(-2)
  let alphabet = new Array(26).fill(null).map(
    (el, index) => String.fromCharCode(i + 97)
  )
  console.log(
    parts
      .slice(0,-2)
      .join('-')
      .split('')
      .map(letter => {
        return letter == '-' ? ' ' : 
        alphabet[
          (alphabet.indexOf(letter) + +id) % alphabet.length
        ]
      })
      .join(''), id
  )
})
Войти в полноэкранный режим Выход из полноэкранного режима

Найти... правильное настоящее имя

Когда мой полный алгоритм на JavaScript был завершен, пришло время просмотреть реальные имена для ссылок на storage.

colorful egg storage
radioactive flower storage
magnetic fuzzy dye storage
weaponized basket storage
classified radioactive scavenger hunt storage
cryogenic scavenger hunt storage
fuzzy bunny storage
northpole object storage
Вход в полноэкранный режим Выйти из полноэкранного режима

Это было последнее!

Я ввел числовой идентификатор, и это был правильный ответ!

У меня получилось!!!

  • Я решил обе части!
  • Я отработал кучу фундаментальных приемов программирования!
  • Я написал подробные объяснения в надежде, что они помогут будущим начинающим программистам чувствовать себя более комфортно с JavaScript!

Оцените статью
devanswers.ru
Добавить комментарий