Cложить два числа-гиганта или почему я прошел квест на собеседовании а на работу в BigTech взяли ChatGPT?. ai.. ai. chatgpt.. ai. chatgpt. JavaScript.. ai. chatgpt. JavaScript. битрикс24.. ai. chatgpt. JavaScript. битрикс24. искусственный интеллект.. ai. chatgpt. JavaScript. битрикс24. искусственный интеллект. Машинное обучение.. ai. chatgpt. JavaScript. битрикс24. искусственный интеллект. Машинное обучение. Собеседование.. ai. chatgpt. JavaScript. битрикс24. искусственный интеллект. Машинное обучение. Собеседование. собеседование в it.

Евгений Жуков (@EvgeniiZhukov) написал статью “Сложить два числа-гиганта: как я прошел квест на собеседовании в Бигтех” https://habr.com/ru/companies/bitrix/articles/891574/

Краткое содержание:

Сценарий: вы на собеседовании, ожидаете вопросов про React, WebGL или хотя бы про Event Loop. А вместо этого получаете: “Напишите функцию сложения двух чисел в столбик, но числа передаются как массивы.”

Зачем это вообще кому-то нужно:

А интервьюер смотрит, как вы справляетесь с базовой задачей, которая проверяет:

  1. Умение работать с строковыми данными (ведь числа могут быть гигантскими, и bigint не спасет).

Предложенное решение:

function addArrays(arr1, arr2) {
	let i = arr1.length - 1;
	let j = arr2.length - 1;
	let carry = 0;
	const result = [];


	while (i >= 0 || j >= 0 || carry > 0) {
		const digit1 = i >= 0 ? arr1[i--] : 0; // Берем цифру или 0 (как замену)
		const digit2 = j >= 0 ? arr2[j--] : 0;
		const total = digit1 + digit2 + carry; // Сумма + 1 из прошлого
		carry = Math.floor(total / 10); // Новый 1
		result.push(total % 10); // Записываем остаток
	}
	return result.reverse(); // Переворачиваем
}

Тесты:

[9,9] + [9] = [1,0,8].
[5,4,4]  [4,5,6] = [1,0,0,0] 

Следующий кандидат – ChatGPT

Парень из BigTech:

Напишите функцию сложения двух чисел в столбик, но числа передаются как массивы.

function addColumnwise(arr1, arr2) {
    let carry = 0;
    let result = [];
    let maxLength = Math.max(arr1.length, arr2.length);

    for (let i = 0; i < maxLength; i++) {
        let digit1 = arr1[arr1.length - 1 - i] || 0;
        let digit2 = arr2[arr2.length - 1 - i] || 0;
        let sum = digit1 + digit2 + carry;

        result.unshift(sum % 10);
        carry = Math.floor(sum / 10);
    }

    if (carry) {
        result.unshift(carry);
    }

    return result;
}

// Пример использования
console.log(addColumnwise([1, 2, 3], [9, 8, 7])); // [1, 1, 1, 0]
console.log(addColumnwise([9, 9], [1])); // [1, 0, 0]

Добавь тестовые функции чтобы проверить что все работает.

Hе используй тестовые модули.

Просто добавь вызов функций с параметрами arr1,arr2 и expected.

Выведи в консоль: OK или Failed.

// Функция тестирования
function testAddColumnwise(arr1, arr2, expected) {
    const result = addColumnwise(arr1, arr2);
    const success = JSON.stringify(result) === JSON.stringify(expected);
    console.log(`Test ${success ? 'OK' : 'Failed'}:`, arr1, '+', arr2, '=', result, '| Expected:', expected);
}

// Запуск тестов
testAddColumnwise([1, 2, 3], [9, 8, 7], [1, 1, 1, 0]);
testAddColumnwise([9, 9], [1], [1, 0, 0]);
testAddColumnwise([0], [0], [0]);
testAddColumnwise([5, 6, 7], [2, 4, 3], [8, 0, 0]);
testAddColumnwise([9, 9, 9], [1], [1, 0, 0, 0]);
testAddColumnwise([1, 0, 0], [1, 0, 0], [2, 0, 0]);

У тебя ошибка в testAddColumnwise([5, 6, 7], [2, 4, 3], [8, 0, 0]);

ChatGPT:

Ты прав! Ошибка в ожидаемом результате. Должно быть [8, 1, 0], а не [8, 0, 0].

// Запуск тестов
testAddColumnwise([1, 2, 3], [9, 8, 7], [1, 1, 1, 0]); // OK
testAddColumnwise([9, 9], [1], [1, 0, 0]); // OK
testAddColumnwise([0], [0], [0]); // OK
testAddColumnwise([5, 6, 7], [2, 4, 3], [8, 1, 0]); // Исправлено, должно быть [8, 1, 0]
testAddColumnwise([9, 9, 9], [1], [1, 0, 0, 0]); // OK
testAddColumnwise([1, 0, 0], [1, 0, 0], [2, 0, 0]); // OK

Парень из BigTech:

Добавь тесты:

[9,9] + [9] = [1,0,8].
[5,4,4] [4,5,6] = [1,0,0,0]

Добавляем тесты и поста

// Запуск тестов
testAddColumnwise([1, 2, 3], [9, 8, 7], [1, 1, 1, 0]); // OK
testAddColumnwise([9, 9], [1], [1, 0, 0]); // OK
testAddColumnwise([0], [0], [0]); // OK
testAddColumnwise([5, 6, 7], [2, 4, 3], [8, 1, 0]); // Исправлено, должно быть [8, 1, 0]
testAddColumnwise([9, 9, 9], [1], [1, 0, 0, 0]); // OK
testAddColumnwise([1, 0, 0], [1, 0, 0], [2, 0, 0]); // OK
// Тесты из сходного поста
testAddColumnwise([9,9], [9], [1, 0, 8]); // OK
testAddColumnwise([5,4,4], [4,5,6], [1, 0, 0,0]); // OK
"Test OK:", [1, 2, 3], "+", [9, 8, 7], "=", [1, 1, 1, 0], "| Expected:", [1, 1, 1, 0]
"Test OK:", [9, 9], "+", [1], "=", [1, 0, 0], "| Expected:", [1, 0, 0]
"Test OK:", [0], "+", [0], "=", [0], "| Expected:", [0]
"Test OK:", [5, 6, 7], "+", [2, 4, 3], "=", [8, 1, 0], "| Expected:", [8, 1, 0]
"Test OK:", [9, 9, 9], "+", [1], "=", [1, 0, 0, 0], "| Expected:", [1, 0, 0, 0]
"Test OK:", [1, 0, 0], "+", [1, 0, 0], "=", [2, 0, 0], "| Expected:", [2, 0, 0]
"Test OK:", [9, 9], "+", [9], "=", [1, 0, 8], "| Expected:", [1, 0, 8]
"Test OK:", [5, 4, 4], "+", [4, 5, 6], "=", [1, 0, 0, 0], "| Expected:", [1, 0, 0, 0]

Все тесты прошли. ChatGPT успешно справился с заданием.

Счет 1 : 1 – ничья

  • ChatGPT успешно реализовал функцию

  • Немного накосячил с тестом – выбрал неправильное ожидаемое значение

  • Учитывыя что он обойдется нам в 20 USD/месяц в редации Plus и 200 USD/месяц в редакции PRO – прощаем мелкий недочет

Что по поводу оптимизации?

Автор оригинально поста, в качестве одной из идей почему такая задача в принципе имеет место быть “Умение работать с строковыми данными (ведь числа могут быть гигантскими, и bigint не спасет).”

Т.е. предполагается что у нас лимит по используемой памяти и нам приходится городить огород, вместо того чтобы использовать встроенный тип: bigint

К сожалению в комменариях ни одного решения, которое помогло бы в этом случае не предлагалось.

Посмотрим как с этим справиться ChatGPT:

Парень из BigTech:

Есть функция для сложения двух чисел в столбик где числа передаются как массивы.

Функция может быть использована для сложения гигантских чисел, которые не поместятся в bigint.

Не меняя интрефейс функции addColumnwise(arr1, arr2). предложи решение чтобы уменьшить потребление памяти.

ChatGpt:

Чтобы уменьшить использование памяти, можно оптимизировать алгоритм так, чтобы не создавать новый массив result, а модифицировать один из входных массивов (например, arr1 или arr2).

Это сократит количество выделяемой памяти и уменьшит количество операций с массивами.

К сожалению первая реализация содержала ошибку и тесты упали. Но после подсказки:

Парень из BigTech:

не работает в случае если длина result.length > arr1.length + arr2.length

ChatGPT выдал рабочий код:

function addColumnwise(arr1, arr2) {
    let carry = 0;
    let maxLength = Math.max(arr1.length, arr2.length);
    let minArr = arr1.length < arr2.length ? arr1 : arr2;
    let result = arr1.length >= arr2.length ? arr1 : arr2; // Изменяем на месте

    let diff = Math.abs(arr1.length - arr2.length);

    for (let i = maxLength - 1; i >= 0; i--) {
        let digit1 = result[i] || 0;
        let digit2 = i - diff >= 0 ? minArr[i - diff] || 0 : 0;
        let sum = digit1 + digit2 + carry;

        result[i] = sum % 10;
        carry = Math.floor(sum / 10);
    }

    if (carry) {
        result.unshift(carry); // Это единственное место, где увеличивается размер массива
    }

    return result;
}

В общем и целом, не плохо, но интервьюер хотел бы увидеть другой подход, чтобы понять кандидат в чем-то кроме решений задач с LeetCode понимает или нет :)

Парень из BigTech:

Посказка. Что если использовать другую систему счисления при передаче параметров и получении результата?

тут наш ChatGPT себя показал – “задание партии выполним!”

ChatGPT:

Отличная подсказка! Если использовать другую систему счисления, например, основание 2³² (4294967296, 2^32) или 10⁹ (1000000000), то можно значительно сократить количество элементов в массиве, что существенно уменьшит потребляемую память и ускорит вычисления.

Парень из BigTech

напиши реализацию которая использует base 16. Незабудь, что числа передаются в виде текста.

Числа должны быть предствлены как: arr1: [’01’,’03’,’FF’], arr2: [’03’,’05’,AA’] и т.д.

после нескольких итераций:

unction addHexArrays(arr1, arr2) {
    let carry = 0;
    let maxLength = Math.max(arr1.length, arr2.length);
    let result = new Array(maxLength).fill('00'); // Результирующий массив

    for (let i = maxLength - 1; i >= 0; i--) {
        let digit1 = i - (maxLength - arr1.length) >= 0 ? parseInt(arr1[i - (maxLength - arr1.length)], 16) : 0;
        let digit2 = i - (maxLength - arr2.length) >= 0 ? parseInt(arr2[i - (maxLength - arr2.length)], 16) : 0;

        let sum = digit1 + digit2 + carry;
        result[i] = (sum % 256).toString(16).padStart(2, '0').toUpperCase(); // Формат 'XX'
        carry = Math.floor(sum / 256);
    }

    if (carry) {
        result.unshift(carry.toString(16).padStart(2, '0').toUpperCase());
    }

    return result;
}

// Функция тестирования
function testAddHexArrays(arr1, arr2, expected) {
    const result = addHexArrays([...arr1], [...arr2]);
    const success = JSON.stringify(result) === JSON.stringify(expected);
    console.log(`Test ${success ? 'OK' : 'Failed'}:`, arr1, '+', arr2, '=', result, '| Expected:', expected);
}

// Исправленные тесты
testAddHexArrays(['09', '09'], ['01'], ['09', '0A']); //OK
testAddHexArrays(['00'], ['00'], ['00']); // OK
testAddHexArrays(['05', '06', '07'], ['02', '04', '03'], ['07', '0A', '0A']); // OK
testAddHexArrays(['09', '09', '09'], ['01'], ['09', '09', '0A']); // OK
testAddHexArrays(['01', '00', '00'], ['01', '00', '00'], ['02', '00', '00']); // OK
testAddHexArrays(['09', '09'], ['09'], ['09', '12']); // OK (99 + 9 = 112)
testAddHexArrays(['05', '04', '04'], ['04', '05', '06'], ['09', '09', '0A']); // OK
testAddHexArrays(['FF'], ['01'], ['01', '00']); // OK 
testAddHexArrays(['FF', 'FF'], ['01'], ['01', '00', '00']); // OK
testAddHexArrays(['FF', 'FF'], ['FF', 'FF'], ['01', 'FF', 'FE']); // OK
testAddHexArrays(['01'], ['09', '09', '09'], ['09', '09', '0A']); // OK

ChatGPT побеждает со счетом 3 : 1 – и получает работу за 20 USD/Month….

  • ChatGPT без проблем реализовал исходный алгоритм как и автор оригинального поста

  • Предложил вариант оптимизации памяти за счет переиспользования массива

  • После нескольких итераций выдал рабочий код

  • С энтузиазмом воспринял идею кодировать данные используя base 16

  • После нескольких итераций выдал рабочее решение. В основом косячил с данными для тестов.

Парень из BigTech:

Оцени на сколько сократиться потребление памяти если кодировать строки как массив символов с основанием 64 по сравнению с основанием 10

ChatGPT:

Основание 64 сокращает количество цифр примерно в 1.8 раза.
Потребление памяти сокращается примерно в 2.44 раза за счёт уменьшения количества цифр и использования 6-битных значений вместо байтов.
Чем больше число, тем больше экономия!

Вывод: Использование основания 64 позволяет сократить память в 2.4 – 2.5 раза по сравнению с основанием 10, что делает его отличным выбором для работы с большими числами.

Парень из BigTech становиться “ChatGPT Team Lead”, получает бонус за сокращение издержек.

Желающие “войти в IT” отправляются массово учиться писать промты к ChatGpt, поскольку:

Это из собеседования на фронтенд разработчика? В гробу я видал авторов таких вопросов на собеседованиях на фронтенд позиции.

.. где важнее навыки нейминга, знание популярных тенденций и шаблонов проектирования UI систем и т.п. …

А вот эта вся математика, алгоритмика – это то, что вам понадобиться в <1% случаев при разработке фронтенд приложений, а скорей всего не понадобиться никогда.

Как оказалось мыслить современные разработчики могут в лучшем случае на уровне ChatGPT. И предложить решение которое выходит за рамки простого кодинга судя по комментариям к оригинальной статье не могут.

В общем – учимся писать промты для ChatGPT.

P.S. Если хотите обеспечить себе безбедное существование в недалеком будущем и без страха сражаться за рабочие места с AI, то подсисывайтесь на мой телеграм канал …

вернее не на мой а на: https://cs.stanford.edu/~knuth :)

Автор: Kahelman

Источник

Рейтинг@Mail.ru
Rambler's Top100