Comments 29
"Думал ты тут самый умный?"
прочитал на одном дыхании, просто приключенческая поэма
мне вот это больше понравилось, там тот же сюжет (чувак порешал на типах), но и задача прикольнее, и стиль изложения)
на хабре много такого но вот эта функциональщина мне понравилась https://habr.com/ru/articles/578198/
7. Вместо чисел, кратных 3 и 5, программа должна выводить FizzBuzz.
просто кратному 15
душераздирающая история
Насколько я понял, это перевод не от автора. Но вопросы есть.
Как может такой мощный язык, который практически является прикладной теорией категорий, не быть ЛУЧШИМ языком для категоризации строк на два класса эквивалентности
Это как? Какое отношение теории категорий имеет к задаче категоризации? Или это как с теорией групп, которая нужна для группировки вкладок в браузере, а теория полей — это раздел агрономии?
Теперь о предложенном в статье решении:
Решение в 15-ричном представлении, безусловно, короткое. Но следующее же изменения в правилах о замене 5 на 55 делает решение непригодным. И если бы было правило «DATA есть массив строк в 10-ричном представлении».
Я не понял правило №13. Во-первых, в оригинале «the input can (т.е. могут, но не обязаны) contain decimals». Кажется, что просят добавить в DATA строки вида "15.00" и "21.33", причём первое из них должно считаться кратным 3 и 5, верно? Если так, то решение автора не подходит.
Про 13 – там дальше в 14 пункте (выделение жирным моё):
Decimal 0 (0.0) and negative decimal zero (-0.0) must have their own representation and be treated as decimal numbers (produce the empty string). (This rule seemed a bit odd if they actually intended integer zero not to make FizzBuzz)
То есть, хотя в 13 пункте это явно почему-то не оговорено, видимо, имеется в виду, что во входных данных могут быть дробные числа, но их нужно считать некорректными, и возвращать пустую строку. Возможно, это уточнили устно, или автор забыл явно записать эту деталь.
Числовые типы, числовые литералы и связанные с ними методы и операции запрещены. Во входном массиве должны содержаться строковые представления чисел
Пройдя собеседования в не самые последние компании (например, тот же Яндекс), впервые вижу такого рода вещи на собеседовании. Я бы в таком случае спросил "У Вас реально на работе код такое требует?" и закончил бы интервью сам.
Этот fizzbuzz был написан в собеседовании на удалённую должность в маленькой компании из Нидерландов. В Linkedin написано, что в ней меньше 50 сотрудников.
Т.е. в разных там компаниях FAANG такого на собеседованиях не спрашивают, насколько я могу судить, а тут прям вот так с ходу? Что же, узнаю маленькие компании, в которых начинают извращаться. Либо, если я правильно понимаю, здесь применяется подход, зачастую имеющий место в РФ при закупках оборудования - когда в условия вписываются настолько специфические вещи, что их сможет выполнить ровно один поставщик, которым случайно владеет знакомый организатора тендера. Здесь такое собеседование, если не считать компанию сборищем идиотов, нужно строго для того, чтобы взять по знакомству человека, но при этом не огрести от трудовой инспекции по жалобе кого-то другого.
У Вас реально на работе код такое требует?
Причем тут рабочий код? Тут собственно я вижу было желание провести сессию живого кодирования. Так как действие происходит удаленно, то собеседующие не могут быть уверены, что там рядом не сидит какой-то гуру-помощник. Меняя задание на ходу можно видеть собственно работу человека вживую, его реакции и видно, что ему никто не подсказывает. Так что такой формат собеседования вполне валиден. Решение автора выбило из колеи собеседующих и им пришлось что-то на ходу додумывать.
То, что не взяли автора на работу и даже ничего не ответили, тут компания показала себя мудаками. Такое есть во всех странах. Я и сам тут в Нидерландах страдал на собеседованиях и не получал ответы по результатам. Бесит страшно.
Тут прекрасные типы, но где сам код?
Тайпскрипт тоже в удивлении
Система типов в TypeScript обладает полнотой по Тьюрингу. Любую задачу можно решить на типах. В данном примере результат работы — это значение типа Result.
Блин, дошло. В лес такого кандидата.
Тут двояко. С одной стороны, он реально шарит в системе типов TS, а таких людей в мире очень мало. И он явно умнее того товарища, который его собеседовал.
С другой стороны не умеет пока отличать ремесло от искусства. Крутой высокохудожественный код, который никто не понимает, лучше оставить для программерских контестов.
Прекрасный пример чтобы понять что не нужно такое делать на собеседовании
Кажется, что этот FizzBuzz устойчив к LLM (ChatGPT, DeepSeek), потому что условия не чёткие, выдаются не сразу и при этом есть зависимость от прошлых решений (нельзя менять язык)
Ждём что-то подобное у нас на собеседованиях
Этот FizzBuzz устойчив к LLM только потому, что он сложный. По этой же причине он устойчив и к человекам.
ChatGPT вполне справляется с нечеткими условиями и переделкой предыдущих вариантов, лишь бы размера контекста хватило. А с правилом 7 не справляется:
Скрытый текст

Можно было бы дать правило 7 самым первым, и результат был бы примерно такой же, что для LLM, что для человека.
До четких условий кандидат должен договориться с собеседующим.
Решение, безусловно, красивое, но не практичное.
type Digit = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9';
type DivisibleBy3<T extends string> =
T extends '' ? true :
T extends '0' | '3' | '6' | '9' ? DivisibleBy3<RemoveFirst<T>> :
T extends '1' | '4' | '7' ? DivisibleBy3<Add2<RemoveFirst<T>>> :
T extends '2' | '5' | '8' ? DivisibleBy3<Add1<RemoveFirst<T>>> :
false;
type DivisibleBy5<T extends string> =
T extends '' ? true :
T extends `${string}${'0' | '5'}` ? true :
false;
type RemoveFirst<T extends string> = T extends `${Digit}${infer R}` ? R : '';
type Add1<T extends string> =
T extends '' ? '1' :
T extends `${infer F}${infer R}` ?
F extends '9' ? `0${Add1<R>}` :
F extends '0' ? '1' :
F extends '1' ? '2' :
F extends '2' ? '3' :
F extends '3' ? '4' :
F extends '4' ? '5' :
F extends '5' ? '6' :
F extends '6' ? '7' :
F extends '7' ? '8' :
F extends '8' ? '9' :
never : never;
type Add2<T extends string> = Add1<Add1<T>>;
type FizzBuzz<T extends string> =
DivisibleBy3<T> extends true
? DivisibleBy5<T> extends true
? 'FizzBuzz'
: 'Fizz'
: DivisibleBy5<T> extends true
? 'Buzz'
: 'Grok';
// Примеры использования:
type Test1 = FizzBuzz<'3'>; // 'Fizz'
type Test2 = FizzBuzz<'5'>; // 'Buzz'
type Test3 = FizzBuzz<'15'>; // 'FizzBuzz'
type Test4 = FizzBuzz<'7'>; // 'Grok'
никаких чисел и числовых операторов означающих неявное преобразование в число
что-то на другом языке и не смог
В плейграунде тест2 и тест4 приводят к "Type instantiation is excessively deep and possibly infinite.(2589)".
Чуть упростил, вот ссылка. В целом, проверка деления на 3 делается довольно простым конечным автоматом, автору статьи не стоило заморачиваться с 15-ричной системой
Мы обсудили это с собеседующим: он сказал, что 0 не кратен 3 и 5.
Это потребовало бы больше работы, потому что простой проверки последней цифры было бы недостаточно для проверки на кратность 5, ведь «0» не прошёл бы тест. Это было бы не так сложно, но я бы предпочёл не делать этого, поскольку обратное потребовало бы добавления всего 4 символов. К счастью, его коллега согласился, чтобы ноль был кратным любому числу, поэтому моё решение приняли.
Математически - кратность означает что остаток от деления на число равен нулю. Остаток от деления нуля на любое целое число всегда равен нулю. Так что ноль кратен любому целому числу.
Вообще, если собеседующий говорит, что 0 не делится на 3 — это красный флаг. Можно дать такой компании ещё один шанс и попросить заменить интервьюера.
FizzBuzz, который не помог мне найти работу