Может (x++! == x) && (x++ === x); return true?

Мой друг встречает этот вопрос на собеседовании

Найдите значение x, которое заставит эту функцию возвращать true

function f(x) {
    return (x++ !== x) && (x++ === x);
}

Интервьюер добавил: x должно быть не более 5 символов

Я нашел несколько ответов из 7 символов:

[["2**53-1"],["2*3**33"],["2-5**23"],["5**23-2"],["3**33*2"]]

Но я не смог найти тот, у которого было 5 персонажей. (даже не 6). Я сомневался, что есть решение с 5 символами. Но после исследования я нашел этот сайт: https://alf.nu/ReturnTrue, который предлагает тот же вызов, и оказывается, что есть решение с 5 символами:

enter image description here

Кто-нибудь может помочь узнать, что это такое?

Ответ 1

Это просто сделать исчерпывающий поиск решений с использованием разных операций.

Поскольку единственными решениями, которые делают f true, являются значения >= чем Number.MAX_SAFE_INTEGER, мы сразу же думаем об Number.MAX_SAFE_INTEGER или научной нотации для их достижения в небольшом пространстве.


возведения

Мы используем 2 символа, и осталось только 3 для цифр:

// n**mm
for (n = 0; n <= 9; ++n)
for (m = 0; m <= 99; ++m)
    if (f(n**m))
        console.log(n, m, n**m);

// nn**m
for (n = 0; n <= 99; ++n)
for (m = 0; m <= 9; ++m)
    if (f(n**m))
        console.log(n, m, n**m);

Поскольку осталось только 3 цифры, мы не можем использовать сложение/вычитание здесь для смещения вещей (требуется не менее двух символов).


Научная нотация

Мы используем 1 символ, поэтому мы остаемся с 4 потенциальными цифрами:

// nEmmm
for (n = 0; n <= 9; ++n)
for (m = 0; m <= 999; ++m)
    if (f(n*(10**m)))
        console.log(n, m, n*(10**m));

// nnEmm
for (n = 0; n <= 99; ++n)
for (m = 0; m <= 99; ++m)
    if (f(n*(10**m)))
        console.log(n, m, n*(10**m));

// nnnEm
for (n = 0; n <= 999; ++n)
for (m = 0; m <= 9; ++m)
    if (f(n*(10**m)))
        console.log(n, m, n*(10**m));

Однако в этом случае мы можем делать сложение/вычитание:

// nEm+d
for (n = 0; n <= 9; ++n)
for (m = 0; m <= 9; ++m)
for (d = 0; d <= 9; ++d)
    if (f(n*(10**m)+d))
        console.log(n, m, d, n*(10**m)+d);

// nEm-d
for (n = 0; n <= 9; ++n)
for (m = 0; m <= 9; ++m)
for (d = 0; d <= 9; ++d)
    if (f(n*(10**m)-d))
        console.log(n, m, d, n*(10**m)-d);

Поиск полного выражения

Мы также можем выполнить полный исчерпывающий поиск по всему пространству строк, учитывая, что это всего 5 символов.

Чтобы немного ускорить его, позвольте использовать только символы, которые, как мы думаем, могут заставить нас там (например, цифры, арифметические операторы и т.д.). Если мы используем 24 символа, как показано ниже, это 24**5 возможностей, которые проверяются всего на несколько миллионов (это займет примерно минуту или около того на современном компьютере):

const s = [
    "0","1","2","3","4","5","6","7","8","9",
    "e",".",
    "*","+","-","/","%",
    "!","^","&","|","<",">","~"
];
const l = s.length;
for (var n1 = 0; n1 < l; ++n1)
for (var n2 = 0; n2 < l; ++n2)
for (var n3 = 0; n3 < l; ++n3)
for (var n4 = 0; n4 < l; ++n4)
for (var n5 = 0; n5 < l; ++n5)
    try {
        const expr = s[n1] + s[n2] + s[n3] + s[n4] + s[n5];
        if (f(eval(expr)))
            console.log(expr);
    } catch (e) {};

Примечание: мы должны использовать try...catch, так как многие из выражений будут недействительными. Кроме того, будьте осторожны с именами переменных, которые вы используете (например, если вы используете e в качестве счетчика циклов, вы получите строки, такие как --e которые приведут вас в бесконечный цикл!