return true
February 27, 2021

return true: length

Привет! Разбираем решение задачки length из второго сезона RT.

⚠️ Статья наполнена спойлерами. Если вы хотите сами решить задачу, то вернитесь к статье только после того как решите ее сами или если у вас закончится терпение

Задача:

function length(x) {
  return typeof x !== 'object' && !Array.isArray(x) && x.length == 4
}

Нам необходимо передать такой аргумент, который и не объект и не массив, но его свойство length равно 4.

Передать { length: 4 } мы не можем, потому что это объект. [1,2,3,4] тоже не сработает.

Что кроме массивов имеет свойство length и не является при этом объектом?

  • Функции
  • Строки

Свойство length у функции возвращает количество параметров этой функции:

function f(a,b,c,d) {}
console.log(f.length); // 4

Пробуем передать function(a,b,c,d){} и получаем true за 19 байт ✅

Но, минимальный длина решения в лидерборде - 5 байт, а значит нам нужно придумать что-то еще. Попробуем сократить функцию до (a,b,c,d)=>1 - это 12 байт ✅

Лучше, но все равно не то.

Попробуем вариант со строками, например '1234' - получаем true за 6 байт ✅

Это еще лучше, но все еще не 5 байт.

Тут мы оказываемся в ситуации, когда ни функции, строковые литералы нам не подходят.

Как получиться строку длиной в 4 байта потратив при этом 5 байт?

Можно воспользоваться преобразованием типов и привести что-нибудь к строке.

Подробнее здесь (попроще) и здесь (посложнее).

1 + '' // '1'
[] + '' // ""
NaN + '' // 'NaN'
undefined + '' // 'undefined'
true + '' // 'true'

Строка 'true' как раз состоит из 4 байт, это то, что нам нужно!

Но true+'' - это 7 байт, но мы-то с вами знаем, что true можно еще записать как !0, поэтому попробуем сократить: !0+'' - получаем true за желанные 5 байт ✅

Хронология решений

  • function(a,b,c,d){} - 19
  • (a,b,c,d)=>1 - 12
  • '1234' - 6
  • true+'' - 7
  • !0+'' - 5 🏆