Как стать автором
Обновить

Комментарии 516

Все зависит от области! Игродел за секунду напишет решение, программист десктопных приложений на java или c# напишет, наверное, за то же время, а вот вэб программист наверное будет долго думать. И все дело в том что для первых двух категорий обычный код тот, который для вэб программистов фраймворк.
Бездарных игроделов существует дюжинное количество. Десктопных — не меньшее. Вот с вебными всё действительно много хуже и для их поиска надо указать что нужен нод.жс, паттерны проектирования и знание алгоритмической сложности. И всё равно 90% приходящих не могут на клочке бумаги обсёрвабл нарисовать.
по большей части Вы правы, но везде есть свои нюансы. У игроделов плохой программист, это тот который плохо знает математику-физику. Но зато у игроделов намного все серьезней с проектированием, сильнее даже чем у обычных серверистов, которые пишут сервера для сайтов-приложений. Они просто не могут не разбираться в DDD, чего не всегда хватает дескопщикам, хотя им математика нужна меньше чем архитектура.
А вот в вэбе DDD это вообще как Йоулупукки для российских детей, чье имя может если не рассмешить, то даже напугать. Но тут я не говорю о людях которые пришли в вэб из других java c# с++ языков. И в этом не их вина, они свято верят что разработчики фраймворков просто боги которые лучше всех знают как нужно делать и если они делают так, то это единственно верное решение. То есть они учатся на увиденном. Да и куда скрыть тот факт что jQ и всякие верстки для cms до сих пор являются приоритетными.
А вот в вэбе DDD это вообще как Йоулупукки для российских детей, чье имя может если не рассмешить, то даже напугать. Но тут я не говорю о людях которые пришли в вэб из других java c# с++ языков.

Не преувеличивайте. В мире PHP уж точно DDD имеет место быть. Будущий мажорный релиз Symfony в частности обещает упрощения разработки по DDD.

Даже такой бесполезный ларавельщик-пыхобыдлокодер как я и то юзает DDD и сейчас буду пихать интеракторы в органайзер и материться что laravel не все зависимости в контекст инжектировал по интерфейсам и писать для них сервис-провайдеры которые позволят DI отрезольвить их.

НЛО прилетело и опубликовало эту надпись здесь
Это… это… это же потрясающе! О_о
О.О Я боюсь спросить сколько ушло на написание этого кода :-)
Там еще и 159 ишуков заведено, люди докер, к примеру, требуют :D

А в docker'е надо WildFly Swarm, как минимум.

Это просто прекрасно! Не думал, что смогу рыдать от смеха глядя на код)

ну а серьёзно, я вот не видел других вариантов решения, где предусматривается изменение требований к работе системы, например на fizz-buzz-heraz, где последнее выдавать при делимости на 7

Есть у меня, конечно, наколеночное решение с хардкодом, но это не наш метод! :)
Я не согласен, задание очень простое, кто не может его сделать в редакторе до 10 минут — не программист, а оператор компьютера. Я такие задачи не делаю, все что мне понадобилось — это перепроверить в гугле, что % проверяет кратность и все.

Проблема в том, что новое поколение ребят с курсов задают такой вопрос «А что, Jquery это тоже Javascript? Не может быть!».
Если человек пошёл на курсы — значит не смог освоить самостоятельно, что само по себе довольно странно.

Если человек пошёл в университет — значит не смог освоить самостоятельно, что само по себе довольно странно.

Как бы там ни было, странно самостоятельно усвоить университетские курсы. Всетаки, там не 1 или 2 области, а много.
Во время учёбы мне не раз приходила в голову мысль, что если бы мне просто дали список того, что нужно знать для приобретения квалификации инженера, я запросто изучил бы это сам. В конце концов, какая разница, по лекциям учиться или по учебникам?

Если же Вы намекаете на «корочку», то я с трудом верю, что где-то котируется корочка JQuery-разработчика…
если бы мне просто дали список того, что нужно знать для приобретения квалификации инженера, я запросто изучил бы это сам

Это есть, и называется сдать экзамены экстерном.

Немного не так оно есть, как в комментарии. Списки эти в пригодном для самоподготовки виде с боем нужно выбивать из деканатов/кафедр. По крайней мере лет 20 назад.

Не знаю… В моем ВУЗе такие вещи описывались в программах по предмету xyz, обновлялись регулярно и лежали на сервере кафедры бери-не хочу. Нам, заочникам, было на руку.
PS 2014 год.

Меня всегда на форумах удивляла фраза: "да на кой мне этот js, есть же jq!"

"да на кой мне этот asm, есть же c++!"

Хоть это и шутка, но несогласным хочу напомнить, что ассемблер это тоже язык программирования. И если с jQuery аналогия неточная, то с каким-нибудь TypeScript вполне. jQuery можно считать аналогом CRT, без CRT тоже можно программы писать.

Ассемблер, это не язык программирования, это транслятор в машинные коды и какой он будет, завист от того, какие машинные коды есть и какова архитектура процессора. Если вы хотите собирательное название, то можно говорить «языки низкого уровня», но при этом не понятно о чём речь. Есть, конечно, технологии на стыке, типа PI-код, или виртуальная машина типа JVM, которые могут иметь конкретный стандарт, но тогда про них конкретно и надо упоминать.

Академически — да, ассемблер это транслятор. А язык программирования называется "язык ассемблера".


Но если не придираться к словам, то слово "ассемблер" может прекрасно обозначать оба понятия.

То есть, стековый процессор и DSP чип, это один и тот же ассемблер, верно?
Язык программирования без стандарта, это не язык программирования, вам не гарантируют ни метод адресации, ни даже наличие регистров, возьмите мультиклет, к примеру с его ассемблером.
Фактически, вы пытаетесь меня убедить, что x86 ассемблер, в виду его распространённости следует считать идолом ассемблера, я с этим не согласен. Если же речь не про x86, то совершенно не понятно что вы понимаете под языком ассемблера, может быть лисп машины в чипе, которые вполне себе ассемблер, потому что хардварны?

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


Языки ассемблера для некоторого стекового процессора, DSP чипа и x86 — это три разных языка. Каждый из них, согласно правилам русского языка, можно назвать языком ассемблера или просто ассемблером, одинаковыми они от этого не станут.

Исключите слово язык из фразы «язык ассемблера» и включите множественное число.
Согласно правилам русского языка, можно назвать их ассемберами, или просто ассемблерами, одинаковыми они от этого не станут, и вот тут я уже придираюсь. Потому что речь шла о языках, а не правилах русского языка.

Все языки можно называть ассемблерами. А любой конкретный из них будет ассемблером.

Я не буду с вами спорить, вы этой фразой очень сильно понизили планку разговора, пэтому я сомневаюсь что он вам вообще интересен. Для остальных оставлю выдержку непосредственно связанную с языками, по которой можно саморазвиватсья в данном вопросе.
Форма Бэкуса — Наура (сокр. БНФ, Бэкуса — Наура форма) — формальная система описания синтаксиса, в которой одни синтаксические категории последовательно определяются через другие категории.

В русском языке есть выражение "написано на ассемблере", которое имеет вполне понятный смысл. Как-то странно, что вы одни части русского языка учитываете, а другие игнорируете)

А ещё в русском языке есть мир холодильников, которое имеет вполне понятный смысл и я не буду одёргивать человека, когда мне говорят как к этому месту пройти, но когда человек начинает мыслить категориями таких миров, сам генерируя подобный контекст, потому что смысл он не понимает, но уже все так говорят, то промолчать я не могу.
И да, писать можно и в ассемблере который имеет почти всегда встроенный редактор и для ассемблера, можно даже писать машинные коды. Если вы не слишком заморачиваетесь правилами русского языка, то можно писать в машинных когдах и на ассемблере, но «язык программирования» это конкретное понятие, которое даже не эквивалентно просто языку, до которого его сокращают, что почти всегда позволяет контекст. К чему заметка-то? Я не о правилах русского языка, я computer science, формальные грамматики, алгоритмы, языки программирования… не чувствуется связь, конекст какой-нибудь, не? И как-то страно, что алгоритм имеет определение, и язык программирования тоже и можно рассждать не в стиле, что мой дедушка так гвоорил и мне завещал?

Это разные диалекты одного языка и он разный на разных процессорах, C более стандартизован, а вариантов Бейсика — великое множество, Паскаля поменьше.


Фактически, вы пытаетесь меня убедить, что x86 ассемблер

Нет. фактически вы приписываете оппоненту свои фантазии, ибо x86 (другого не знаете?) ранее упомняут не был.

Я и машинные коды, в тетрадке в клетку, писал под z80 не имея ассемблера. Это было сказано, только что бы понять что подразумевает оппонент под своими словами. Если вам хочется перйти на личности, пишите в личку.

А я писал на языке ассемблера и в голове транслировал в машкоды — у меня был ассемблер или я им был? :) Тем не менее, в подавляющем большинстве случаев по контексту слово "ассемблер" ассоциируется вполне однозначно, уточнений "программа?", "язык?", "для какой архитектуры?", "какой диалект?" практически всегда не делаю.

Если человек записывает на бумаге цифры, на каком языке он это делает?
Почему запись программы не может быть просто в машинных кодах или в мнемониках комманд процессора? Я например, совершенно точно писал машинные коды, потому что не было кода установки энного бита в байте и я по маске модифицировал три бита в самом коде комманды, превращая конкретную установку в нужную мне. Не зная, за что отвечают биты в коде комманды такое нельзя сделать, опираясь только на мнемонику.
Я и машинные коды, в тетрадке в клетку

Что не делает из языка ассемблера не язык программирования (низкоуровневый).

Читаю интернет, будем считать что спор я проиграл. Я не знаю, когда в транслятор сборщик(assembler) кода запихнули рекурсию и он стал не транслировать мнемоники собирая машинные коды, а внезмпно собирать-собираемое записанное на собираемое. Пусть будет Ассемблер ассемблера, раз уж интернет уже думает так же. Я из другого мира. Тема закрыта.

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


Язык ассемблера — машинно-ориентированный язык низкого уровня
Совершенно верно, но ключевое слово здесь «машинно-ориентированный», что приобретает некоторый смысл при указании в контексте арихтектуры и совершенно не несёт никакой конкретики в абстрактном плане. Это всё равно как сказать, естественный язык, в контексте нации можно понять, что это английский или может быть японский, но без контекста даже не понятно, используется ли там голос, или это естественность глухонемых.
Сам же смысл языка программирования в абстрагировании от архитектуры, в том, что он чётко сформулирован и есть понимание что в нём можно делать, что нельзя. А если этих правил нет (выше я приводил пример, что даже регистров может не быть, не говоря уже про способы адресации и троичную логику как в Сетунь), может это всё-таки не язык?
Сам же смысл языка программирования в абстрагировании от архитектуры

Вы пропустили словосочетание "высокого уровня"

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

Это ваше личное понимание. Может имеет какое-то отношение к языкам высокого уровня (но далеко не во всех из них есть полная абстракция от архитектуры даже в таких базовых вещах как размер целого числа), но к языкам условного среднего (C например или Forth) и низкого (машинные языки, ассемблеры) точно не относится. Лишь немногие из популярных языков высокого уровня создавались изначально с целью полностью абстрагироваться от архитектуры, да и то подавляющее большинство пошло путем спецификации виртуальной машины, в машинный язык или ассемблер которой транслируется язык высокого уровня, то есть по сути язык не абстрагирован от архитектуры машины, а наоборот, жёстко привязан к одной-единственной, просто машина виртуальная, сама абстрагирует от реального железа.

Хорошо, зайдём с другой стороны, опишите правила «языка ассемблера», как на нём писать?

На разных диалектах по разному :)

Которого их?

Опишите правила «языка Бейсик».

Смысл языка программирования в возможности написания программ. Абстракция это уровень выше, и относится только языкам программирования высокого уровня, а не ко всем.


Язык ассемблера для x86 это один язык программирования, для ARM это другой. В пределах одного языка есть синтаксис и есть правила, что можно делать и что нельзя.

Даже в рамках одной архитектуры существуют ассемблеры с разным синтаксисом, например синтаксис АТ&Т вам о чём-нибудь говорит?
Кроме того, написание программ возможно и без всякого языка и транслятора, прямо в машинных когдах, смысл же языка программирования именно в синтаксисе, что вы упрямо отрицаете.
Например вики:
Язык программи́рования — формальный язык

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

Вот в той статье, откуда вы привели определение, есть фраза "пользовались непосредственно машинным кодом,… который принято считать языком программирования первого поколения".


К первому поколению (англ. first-generation programming language, 1GL) относят машинные языки — языки программирования на уровне команд процессора конкретной машины.

И нет, смысл языка программирования не в синтаксисе, а в возможности записи компьютерных программ. У русского языка есть синтаксис, но он не является языком программирования. Также, не каждый формальный язык является языком программирования.


И у любого ассемблера есть свой синтаксис. C ваших же слов:


синтаксис АТ&Т вам о чём-нибудь говорит
смысл же языка программирования именно в синтаксисе
Любая запись сама по себе имеет какой-то синтаксис. Под синтаксисом языка программированя я имел ввиду формальные правила, прошу прощения за сумбур.

В той же статье, откуда я привёл описание, написано:
Фактически, эти термины в то время не использовались.
Зато ассемблер — использовался.
Читаем дальше:
языки программирования… лучше представлять как среды разработки

Моё мнение о этой статье: писал человек который хочет систематизировать всё и вся не разбираясь в предмете. Но цитата которую привёл я — важна и не сама по себе, а в связи. Почитайте про формальные грамматики, про то, как описываются языки программирования. Вообще, я не вижу смысла в нашем споре, если вы хотите называть языком и машинные коды и IDE, это ваше право. Я очень хорошо высказал своё мнение в письмах, более подробно разжевать мою позицию уже нельзя. И думаю, что вы её прекрасно поняли.
Мне на собеседовании как-то объявили, что если я не знаю тонкости jq, я не знаю js :(

Значит не туда собеседовались, а может и туда, просто сейчас фраза не так всплыла, но, если это какая-то маломальская дизайнерская студия, то там знания jq просто обязательны, и для них это является очень большим фактором, но если при этом они сказали, что незнание библиотеки является незнанием языка, то это уже точно маломаломаломальская дизайн студия с теми, кто сам не знает js...

НЛО прилетело и опубликовало эту надпись здесь

Ну скажем так, код на бумашке писать — дело первых программистов, вроде Ады) А мне это тупо не удобно, но я понимаю, что мне IDE только в помощь дана, она за меня ничерта не придумает. Поэтому к таким тестам я отношусь вполне нормально. Меня больше прикалываются такие тесты:


напишите на <придуманный язык/язык, который вообще не связан с предметом собеседования> программу, выполняющую <какое-то задание>

Такие задания реально интересны и показывают насколько у тебя бошка думает, а вот тесты типа


с помощью jq вставьте 3 разных случайных числа от 6 до 21 в блоки #test, .test и третий найденный b

Вот это мрак, направленный чисто на знание библиотеки, а не оценки твоих умственных способностей.

НЛО прилетело и опубликовало эту надпись здесь
«Писать на бумажке» — это, к тому же, вовсе необязательно значит написать компилируемый, абсолютно правильный код. Мы, в конце концов, не в эпоху устройств подготовки данных и перфокарт живем. Это может быть блок-схема, плгоритмический язык, да просто веральное описание алгоритма. По крайней мере, мне именно так видится нормальное «собеседование с кодом на бумажке».

Стоп, а обычно пишут на реальном коде? Я просто обычно использовал помесь python и js, ибо читаемость в python больше, а на js собеседуюсь...

Я как раз об аргументе противной стороны — «мне», мол, «в реальных условиях, IDE и компилятор подсказывать будут».
Не раз замечал, что придумываешь один алгоритм, а когда начинаешь его реализовывать, то получается несколько иначе. Иногда кардинально иначе.
И да, ИДЕ, очень сильно ускоряет написание кода и корректирует ход мыслей в правильном направлении.
Написание кода — да, но тут речь об алгоритме. Если проверяют, может ли человек составить алгоритм — да пусть хоть блок-схемы или диаграммы Несси-Шнейдермана рисует.

и корректирует ход мыслей в правильном направлении.

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

Ну тут еще вопрос, что больше показывает способность думать самостоятельно) Когда человек сам пишет решение задачи, с которой он возможно уже сталкивался и потратил какое-то время на поиск этого решения, или когда человек ищет информацию в интернете, а значит точно ее не знает, и потом полученные знания правильно применяет для решения задачи.


Я конечно преувеличиваю, но по-моему этот тест не очень показательный.

НЛО прилетело и опубликовало эту надпись здесь

Ну это в ваших тестах нет ничего такого. Я просто к тому, что в общем случае это утверждение не истинно. Это зависит от задачи.


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

НЛО прилетело и опубликовало эту надпись здесь
И не нужно понимать буквально, я не о всех же говорю, а в общей массе.
Странные варианты ответа. А где «менее чем за 10 минут»?

Справедливо. Убрал "более чем", теперь работает округление.

10 минут — большой порог, в изначальном тексте говорилось о паре минут на полное решение, лично у меня где-то так и ушло. Правда, писал на Go.

Боюсь, что многие не осознают ошибку. Судя по количеству заявленных правильных ответов. Наверно надо бы предложить задержку в 1 секунду.

Each print must be asynchronous call console.log function with a 50ms delay.

Скорее всего, это вы не осознаете, что это условие неоднозначно, и не обязательно требует задержки 50ms между каждым принтом.

Да, я уже понял — тынц

Хуже того, там не сказано, должна ли быть задержка перед первым принтом.

именно

Все равно не вижу проблем.


[...Array(100)].map((_, i) => i+1).reduce((x, y) => x.then(() => new Promise(resolve => {
    if (y % 3 == 0 && y % 5 == 0) console.log("MissKiss");
    else if (y % 3 == 0) console.log("Miss");
    else if (y % 5 == 0) console.log("Kiss");
    else console.log(y);
    setTimeout(resolve, 50);
})), Promise.resolve())

Написал за 2 минуты без гугла, причем большая часть времени ушла на постоянные взгляды в условие на английском. Можно и понятнее написать — но это уже не на время.

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

А кто вам сказал что я всегда пишу в таком стиле?


У этой задачи есть 4 решения.


  1. Через async/await
  2. Через библиотеку async
  3. Через рекурсию
  4. Через reduce

Первые два — понятные и красивые, но первое требует babel или tcs для старых браузеров, а второе — отдельной библиотеки. Подключать их дольше, чем писать решение.


Варианты 3 и 4 — одинаково ужасны, но не требуют дополнительных инструментов.


PS кстати, прочтите решение еще раз. Там вообще-то есть декомпозиция.

А ещё можно через SetIntverval и замыкание труЪ-олдскул стиле…

Покажите пример кода, пожалуйста!

!function() {
  var n = 0;
  var interval = setInterval(function() {
      if (n++ == 100) return clearInterval(interval);

      // ...

      console.log(...);
  }, 50);
}()
Самое смешное, что это вообще единственный вариант, который таки решает грёбаную задачу полностью, как ожидалось.
Задержка 50мс для 100 элементов как бы неявно предполагает, что последняя надпись будет выведена через 5 секунд (5000 миллисекунд), плюс-минус точность таймеров операционной системы.
И это только setInterval.
Во-первых, setTImeout на 50 мс вызывается не ранее, чем через 50 мс, но чаще — более.
Во-вторых, если мы не под QNX сидим, у нас практически никогда ОС не выдаст событие таймера ровно через 50 мс. В винде по умолчанию например таймер тикает 64 раза в секунду, это 15.6мс в каждом тике. Т.е. в случае setTimeout на 50 вы будете получать в реальности один тик каждые 62 милисекунды. Нефиговая такая погрешность в 24%, не так ли?
Ну дальше ещё браузер своё откушает (ему нужно самому интерфейс перерисовать, анимации всякие покрутить, сборщик мусора запустить), потом запустит event loop для вашего скрипта, и только потом дойдёт до собственно вашего обработчика.
Так что любой код на setTimeout будет выполнятся секунд 7 вместо 5.

Это все от задачи зависит. Например, если задержка является эмуляцией сетевого запроса — то только новый setTimeout после предыдущего будет корректным.

Проверьте в хроме, плиз.

function kissMiss(){
  for(let i = 1, t=50; i<=100; i++, t+=50) {
    setTimeout(()=>{
		let  s = '';
		s = !(i%3) ? 'Miss': '';
		s += !(i%5) ? 'Kiss': '';
		s = s ? s : i;
		console.log(t +' >> '+s);		
	},t);
  }
}
А что проверяем-то? То что хром умеет к переменной 50 прибавлять?
Наверно вот такой код имелся ввиду:

function kissMiss(){
   let startTime = new Date();
  for(let i = 1, t=50; i<=100; i++, t+=50) {
    setTimeout(()=>{
		let  s = '';
		s = !(i%3) ? 'Miss': '';
		s += !(i%5) ? 'Kiss': '';
		s = s ? s : i;
		console.log((new Date() - startTime) + ' >> ' + t +' >> '+s);		
	},t);
  }
}


Но по большому счеты, эксперимент показывает что setTimeout вполне подходит, у меня в хроме ровно 50мс между вызовами, хотя до первого чуть-больше.
А что проверяем-то? То что хром умеет к переменной 50 прибавлять?

Да не, это я ступил. Сорри. Хром сам умеет выводить таймштамп перед логами. https://www.screencast.com/t/Wj4Wedqfrh
Я уже настолько привык к этой фиче, что забыл, что это не настройка по умолчанию.
А что такого ужасного в рекурсии?

Вроде бы короткий и понятный код
function PrintRangeWithDelay( begin, end, delay ){
    var recursion = function( current ){
        if( current > end ) return;
        setTimeout( function( ){
            var miss = "";
            var print = "" + current;
            if( current % 3 === 0 ) print = miss = "Miss";
            if( current % 5 === 0 ) print = miss + "Kiss";
            console.log( print );
            recursion( ++current );
        }, delay );
    };
    recursion(begin);
}

PrintRangeWithDelay( 1, 100 ,50 );


И за счёт setTimeout стек не забивается.

Мой код настолько же понятен. И точно так же не забивает стек.


Но цикл через await все равно понятнее.

Так я же и не говорил, что ваш код чем-то плох. По поводу стека написал просто потому, что забивание стека это «классический» недостаток рекурсии. А в данном случае этого недостатка нет.
Извините, но я не понимаю причем тут таймер(/задержка), если в задачи про него ничего не написано?
Напишите программу, которая печатает числа от 1 до 100. Но для кратных трём значений «Fizz» вместо номера и для кратных пяти «Buzz». Для чисел, одновременно кратных трём и пяти — «FizzBuzz»


Это я решил на добром С++
main()
{
  for(int i=0;i<100;i++)
  {
  if(i/3%10 == 0)
    if(i/5%10 == 0)
      cin<<"FizzBuzz"<<endl;
    else
      cin<<"Fizz";
  else 
    if(i/5%10 == 0) cin<<"Buzz"<<endl;
    else 
      cin<<i<<endl;
  }
  system("pause");
}

Тут обсуждается другая задача. Читайте пост внимательнее.

Ваш си++ слишком уж добр. Это не компилируется, во-первых у функции мейн должен быть возвращаемый тип int, во-вторых нет инклюдов, в третьих — cin служит для ввода информации, для вывода cout.
Теперь по более серьезному — i / 3 % 10 это вообще что у вас? Проверка делится ли (i/3) без остатка на 10? А зачем? В задаче нужно проверить делится ли i без остатка на 3 и на 5, то есть i % 3 == 0 было бы достаточно.

system(«pause») — си++ он может запускаться на разных платформах но этой строкой кода вы намерство прибили программу к винде.
НЛО прилетело и опубликовало эту надпись здесь

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


Да, обычно это студенты или школьники. Но не обязательно.

Часть ещё используют getc/gets, тут от препода зависит, видимо. Мало у кого видел, чтобы этого не было вообще. Видимо, не осиливают в vs поставить соответствующую галочку, чтобы терминал не закрывался автоматически.

Не подскажете, где эту галочку поставить? Если скомпиленый бинарник в консоли запускать, а не из студии, консоль тоже не закроется?
НЛО прилетело и опубликовало эту надпись здесь

Нет конечно, с чего бы?

Окно консоли же закрывается не потому что программа завершилась — а потому что не осталось процессов, связанных с этим окном (т.е. все программы завершились).


Если вы запускаете программу из командной строки, то процесс командной строки (cmd.exe) остается привязан к консольному окну пока вы не напишете команду exit.

НЛО прилетело и опубликовало эту надпись здесь

Алгоритм там как раз самый оптимальный, хоть это и экономия на спичках.

НЛО прилетело и опубликовало эту надпись здесь

Так он же так и проверяет...

НЛО прилетело и опубликовало эту надпись здесь
Ну в Vs2005, на котором нас обучали на первых порах, мы работали через void main(), препод все боялся и не давал нам сложные материалы чтоб не было глупых вопросов, но сейчас я понимаю что будь по другому, я бы не словил минуса. Когда уже начали изучать MFC уже перешли на новые визуалки а там и не смотрели как там был стандартно инициализирован main. Только сейчас заметил что перед main() у меня ничего не стоит… торопился.
На счет инклюдов думал и решился их не писать. А с cin/cout дырявая башка, дай пирожка, вечно путаю.
Про i/3%10, что первым пришло в голову, опыта не хватило додуматься.
system(«pause») то же самое что и выше, можно конечно с getchar().
А с кроссплатформенностью никогда не встречался, вот и не задумываюсь перед тем использовать одно или другое. Всю жизнь на винде, так и помру с ней.
Могу сказать только спасибо, иначе даже сам не смог бы понять с чего так заминусовали.

Проблема вашего кода — не в void main, а в том, что тип вообще не написан.

В сообщений написано что я это уже поздно заметил
НЛО прилетело и опубликовало эту надпись здесь
Ну, а я полез на VB6 такое писать.)) Сейчас и мне минусов подкинут.

Особенно, если после десятка-другого человек, прочитав комментарии и т. п., не осилите прочитать условие.

куда лучше юзать Array.from => Array.from({length: 100}, (_, i) => i + 1)…
Ну и вообще изучить синтаксис async/await

Cинтаксис async/await не работает в старых браузерах, а babel подключать — дольше, чем решать задачу.


Array.from делает абсолютно то же самое, что и spread operator.

Ну тот факт что не нужен лишний map ну и еще пару нюансов

Не понял за что вас заминусили, спасибо за идею с reduce и [...Array(n)]

Но ваш код не идеален. Тут достаточно двух условий

А задачи писать идеальный код и не стояло.

Смотрю и не понимаю (с JS ушел полностью на Javu лет 15 назад и эти новомодности не застал) — а зачем городить огород с массивам/мапами и прочем? Че просто не пробежать for-ом, с тремя if-ами в нем?..

В простой цикл на js нельзя включить задержку (в версиях языка до ES2017).

… зато можно синхронно повесить 100 setTimeout с задержкой i*50. Не айс, конечно, но технически можно.

Да, для этой задачи это тоже правильное решение будет.

А оно надо? У меня ушло 4:20 как раз на вот это:


let q = v => new Promise(resolve => setTimeout(() => 
    { 
        console.log(v); 
        resolve(); 
    }, 50));
let p = Promise.resolve();

for(let i = 1; i <= 100; ++ i)
{
    let msg = i;
    if(i % 3 === 0 && i % 5 === 0) msg = 'MissKiss';
        else if (i % 3 === 0) msg = 'Miss';
            else if (i % 5 === 0) msg = 'Kiss';
    p = p.then(() => q(msg));
}

На красоту и оптимальность не претендую. Писал на скорую руку прямо в отладчике. Но тут как раз простой цикл.

Ваше решение почти такое как у меня, вся разница — только в месте вычисления строки для вывода.

И создавать строчку каждый раз необязательно

НЛО прилетело и опубликовало эту надпись здесь
Вы не читаете ветку?)
y % 3 == 0 && y % 5 == 0 эквивалентно y % 15 == 0

Вообще ненужно

Нет, математику прогуливал интерпретатор. Если посмотреть бенчмарк — то становится видно, что в Хроме условие y % 3 == 0 && y % 5 == 0 работает быстрее чем y % 15 == 0!

Кстати, почему так? Оптимизатор/кеш выносит за блок условий результаты «y % 3 == 0» и «y % 5 == 0» и второй раз это не считает? Тогда где у вас «типо» 4 проверки на самом деле их 3. И третья совсем крошечная "&&"

Скорее всего так и есть.

Таки менее 10 минут. Результат идентичен, но я в процессе использовал массив который быстро наполнил, а потом выводил сдвигая указатель на начало пока он не кончился. В ответе решение с разновидностью «генератора» что лучше.

Покажите код, пожалуйста. Интересно же!

Вот тут есть одна реализация.
Но для кратных трех значений «Fizz» вместо номера и для кратных пяти «Buzz».
Написано по-русски, но совершенно непонятно. Я бы тоже, пожалуй, не смог решить задачу, если бы условие выглядело таким образом.

Купить палку колбасы, если будут яйца — купить десяток

А потом эти недопрограммисты идут на хабр и сливают карму адекватным людям.

Потому задание оставил на английском. Знаю, что переводчик из меня никакой.

«Между» применено не к месту. Должно быть что-то вроде «Как и X, Y, Z, я начинаю немного волноваться»

3 минуты. В правильном варианте принты хоть и асинхронные, но последовательные, я делал параллельные — это считается надеюсь?

Покажите код, пожалуйста. Интересно же!

Думаю. почти как мой.
for (let i = 1; i <= 100; i++) {
	let print = '';
	if (i % 3 == 0)  {
		print = 'Miss';
	}
	if (i % 5 == 0)  {
		print += 'Kiss';
	}
	if (!print) {
		print = i;
	}
	(function(text){
		setTimeout(function(){
			console.log(text);
		}, 50 * i);
	})(print);
}
я тоже параллельные делал, вот решение:
for (var i = 1; i <= 100; i++) {
  if (i % 3 === 0 && i % 5 === 0) {  
    setTimeout(print('miss kiss'), 1000);	   
  } else if (i % 3 === 0) {
    setTimeout(print('miss'), 1000);   
  } else if (i % 5 === 0) {
    setTimeout(print('kiss'), 1000);   
  } else {
    setTimeout(print(i), 1000);
  }	
}    

function print(str) {
  return function() {
    console.log(str);
  }
}

Они не параллельные, они последовательные, просто не упорядоченные.

for (let i = 1; i <= 100; i++) {
  setTimeout(() => { 
    var r = ""; 
    r += i % 3 == 0 ? "Miss" : "";
    r += i % 5 == 0 ? "Kiss" : "";
    r = (r.length == 0) ? i : r;
    console.log(r); 
  }, 50);
} 
Хм… был уверен, что при таком коде во всех вызовах i=101, но как оказалось, если i объявлен через let, а не var, то замыкается его текущее значение.
Я ещё не привык рассчитывать на ES6, поэтому по привычке написал костыль для этой темы:

function printNum(num) {
    if (num % 3 == 0 && num % 5 == 0) {
        console.log("MissKiss");
    } else if (num % 3 == 0) {
        console.log("Miss");
    } else if (num % 5 == 0) {
        console.log("Kiss");
    } else {
        console.log(num);
    }
}

function makePrintNum(i) {
    return function () {
        printNum(i);
    }
}

for (var i = 1; i <= 100; i++) {
    setTimeout(makePrintNum(i), i * 50);
}

Ваш код выплевывает все значения сразу. Попробуйте изменить задержку на 1 секунду, чтобы увидеть ошибку.

Each print must be asynchronous call console.log function with a 50ms delay

В задаче не указано, что задержка должна быть от каждого предыдущего принта, а не от точки старта. Я изначально понял эту задачу именно так, поэтому так и реализовал.
Да, скорее всего разумнее было бы делать задержку между вызовами, тем не менее — неточность в задании я трактовал в свою пользу

Да, убедительно.

Аналогично.

Более того (ИМХО) решение автора не удовлетворяет условию в том виде, как он его трактует.

В его случае задержка также должна быть уменьшена время выполнения кода предыдущего шага.
В текущем примере это слабо заметно, но, думается мне, что если поставить «Number.MAX_SAFE_INTEGER» вместо 100, то можно будет увидеть, что время между первым и последним выводом будет не Number.MAX_SAFE_INTEGER*50, а на несколько миллисекунд больше.
А вот и мой код
function ExecR(i) {
        var wrtext = "";
        if (i % 3 == 0) wrtext = "Miss";
        if (i % 5 == 0) wrtext += "Kiss";
        if (wrtext == "") wrtext = i;
        console.log(wrtext);
        if (i < 100) window.setTimeout(function () { ExecR(i + 1); }, 50);
    }
ExecR(0);
Согласен, условие по поводу асинхронности вывода сформулировано двояко, я тоже так понял.
But for multiples of three print «Miss» instead of the number and for the multiples of five print «Kiss»
т.е. кратное 3 = Miss
кратное 5 = Kiss
А у вас по ссылке (n % 3 === 0)? 'Kiss'
т.е. 99 = Kiss, 100 = Miss

Итого, решение не правильно (не соответствует условию). И за сколько в итоге вы решили? (Если это ваше решение)
Признаюсь, что у меня ушло 67 минут, применяя гугление
На тот момент когда я смотрел, решение по ссылке
было
(function fn(n) {
if (n <= 100) setTimeout(() => {
let s = (n % 3 === 0)? 'Kiss': '';
if (n % 5 === 0) {
s += 'Miss';
} else if (s === '') {
s = n;
}
console.log(s);
fn(++n);
}, 50);
})(1);

Т.е. задача еще не решена (решена не правильно), и время значит еще идет.

Гы-гы. Спасибо! Исправил.

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

Всё правильно. Это как на выпускном экзамене в школе. Один из класса выполнил все пять задач, но допустил арифметическую ошибку. В итоге все равно оценка 4.

НЛО прилетело и опубликовало эту надпись здесь
Как минимум, не то, то, что все условия проверяются дважды. Не то то, что условие дележа на 15 вынесено отдельно, хотя этот случай решается сам собой — просто два последовательных вызова.
Ошибка что не на JavaScript. ) Автор задачи хочет подловить испытуемого на задержке вывода значения. При неправильном коде это приведет к тому что последнее значение переменной выведется на экран 100 раз.

Это если со скоупами напутать...

Простите, но где здесь:
Write a program that prints into console the numbers from 1 to 100. But for multiples of three print «Miss» instead of the number and for the multiples of five print «Kiss». For numbers which are multiples of both three and five print «MissKiss». Each print must be asynchronous call console.log function with a 50ms delay.
Хоть слово про JavaScript?
Видимо, console.log function подразумевает
Это есть только в javascript? И вообще этот метод относиться к стандартной библиотеке js?

В javascript и языках на его основе. Само название метода несет в себе наследие браузера, где консоль — нечто опциональное. В языках, которые начинали как языки системного программирования такой метод не может называться log, он будет называться write или print :-)


Да, он относится к стандартной библиотеке.

Тестовое задание должно быть сформулировано максимально чётко.
И должно «подразумевать» подобным образом минимальное количество ограничений.
В противном случае, это просто неуважение к кандидату.

Я думаю, конкретно это задание было придумано для проверки именно js-разработчиков. Т.е. язык программирования не попал в цитату потому что уже был указан в наименовании вакансии.

Скорее всего. И я прекрасно понимаю, где именно здесь разложена «засада» по сравнению с оригинальным «FizzBuzz». Более того, я допускаю, что такие задачи могут быть полезны при собеседовании юниоров, но… получив такую задачу (например на собеседовании) без соответствующего уточнения, я оставляю за собой право решать её на любом языке. Например на C# или на Lisp-е или на чём-то ещё более экзотическом. В результате, вполне может получиться как здесь. И это будет даже не сознательный троллинг, а просто защитная реакция.

Вы невнимательно прочитали задание. Только и всего. "Предлагаю решить задачу на JavaScript".

Я читал постановку задачи на английском. Несколько раз и очень внимательно.
Предлагаю закончить эту дискуссию.

Строго говоря, это можно считать методом стандартной библиотеки в современных браузерах и nodejs. Например, в IE <= 9 console.log не отпределён (undefined) пока не открыты dev tools.


Другой стандартный пример js без console.log:


-> % jjs
jjs> console.log("test");
<shell>:1 ReferenceError: "console" is not defined
jjs>
Не смог распознать сарказм, поэтому
1. GoTo
2. Лишние проверки
3. Нет асинхронности и задержки
Перевод ужасен, извините.
Автором, которого он имеет в виду, является Имрана Гхори

который, очевидно, отворачивается от многих программистов

люди, которые борются за код,

самопровозглашенные старшие программисты

терпит неудачу во время интервью

их просят выполнить основные задачи программирования

не могут запрограммировать свой путь из бумажного мешка.

кто пишет программное обеспечение для жизни.


и так далее и тому подобное
Перевод ужасен, извините.

Знаю :( Я совсем не переводчик. Очень впечатлила статья. Не мог удержаться.

Судя по переводу, вы под впечатлением не особо поняли даже её текст.

Как любят повторять в одной конторе, где мне посчастливилось трудиться: критикуешь-предлагай.

критикуешь-предлагай


Не сочтите за попытку уязвить, но я бы предложил для начала дать прочитать переведенный материал кому-нибудь и спросить «что непонятно»? Когда перевод стилистически коряв, но хотя бы понятен на русском языке — это одно. У вас совершенно другое.

люди, которые борются за код

«struggle to code» — испытывают проблемы с написанием кода
Они борются с крошечными проблемами

«They struggle with tiny problems» — испытывают проблемы с решением крошечных задачек
терпит неудачу во время интервью

«fail (during interview) when asked to carry out basic programming tasks» — Не справляются, кода их просят решить простейшие задачи (на собеседовании)
Я более чем готов сократить ограничения

«I'm more than willing to cut freshly minted software developers slack at the beginning of their career» — Я более чем готов (пойти на уступки / дать поблажки) новоиспеченным программистам на старте их карьеры.

Большое спасибо. Внёс правки. Рассчитываю на вашу помощь в дальнейшем.

а я вот только что решил потыкать англоязычные ссылки и был весьма удивлен, что вся статья базируется на статьях 2005-2007 годов
очень странный временной откат в статье на злободневную тему, вероятность достоверности данных низкая

Есть 1 ссылка на статью 2014 и одна на 2016 год :D

При желании можно интерпретировать результаты опроса, что за прошедшие 10 лет уровень программистов вырос. :)

самопровозглашенные старшие программисты

Тут все верно — в оригинале так же self-proclaimed. Ну, «старшие» некий аналог Senior, допустимый по контексту, кмк.
«Самопровозглашенный» в русском языке почти исключительно про государства. Имеется в виду, что старшие программисты сами себя так называют, но на деле старшими не являются.
То есть «так называемые старшие программисты» или «люди, которые называли себя старшими программистами» или что-то более изящное. Но «Самопровозглашенные» не пойдет.

Спасибо, поправил: "кандидаты на старшего программиста".

Это тоже неверно, даже более неверно, чем предыдущий вариант. Смысл именно в том, что эти люди объявили себя старшими сами. «Кандидаты» — совсем иное.

Как лучше?

Самоназванный или самозванец
кандидаты, подававшие резюме на вакансию «Senior developer»

подсмотрел тут

Вы подсмотрели неправильный перевод. Самопровозглашённые было гораздо лучше, потому что верно отражало смысл. Зря вы его убрали :)

Ну мне тоже самопровозглашённые понравилось больше, но тут сказали эксперты переводчики, к которым я себя не отношу, что этот перевод не правильный, поэтому автор и исправил.

Официально — да, но по смыслу подходит замечательно — все то же самое «сам себя назначил». Будь то монарх, государство, или что-то еще, такое же патетическое. Как по мне, такое легкое косноязычие проходит как pun, именно так я воспринял эти слова в переводе.
Не, в переводе лучше либо придумать изящную формулировку, выражающую иронию по отношению к «старшим» программистам, либо уж передавать смысл.
Впрочем, окей, если бы это была единственная проблема с переводом — сошло бы за немного тяжеловесный каламбур.

Ну "самопровозглашенный" по отношению к людям, а не государствам и звучит как ирония, разве нет?

Именно так! Даже если это вышло случайно, получилась микро-шутка, так что — к месту.
Как фигура речи и «самопровозглашенные» неплохо выглядит. А так вообще, вполне подойдет слово «самозванцы».
Самозванцы тоже мимо. Это про царей. И вообще, одним из умений хорошего программиста является умение понимать нечёткие техзадания или «хотелки». Особенно для самостоятельных, работающих без аналитического отдела. Так что умение работать с нечеткими формулировками я бы отдельно оценивал.

Впрочем, речь в статье об элементарной неграмотности. Увы, это так. Это случилось от того, что вместо аналитических способностей оценивается соответствие неким абстрактным требованиям. Причем имеющим малое отношение к реальным нуждам программирования. Решение принимают люди, далекие от программирования. HR, коммерсы. У них не то, что понятия нет о программировании, они говорят на другом языке, мыслят по другому.

5 минут на решение. Мне 17 на работу возьмёте? :) Эти задачи может решить любой школьник просто почитав w3schools до конца. Если это единственное препятствие на собеседовании (нет последующих этапов) то набёрете много новичков.

Если внимательно прочитать данный материал (очень важно для программистов, и Вы этот микротест провалили), можно понять, что элементарные задачи на очевидные умения нужны на предварительном отборе, чтобы не тратить Время на серьёзное собеседование с самозванцами.

Поправьте описание на русском, чтобы там было указано про 50мс.
А то я сначала сильно удивился зачем столько намудрено для обычного цикла, а только потом увидел описание на английском.

Писал в консоли хрома, поэтому не пугайтесь форматирования, у него жутко неудобно писать несколько строк.
Это «синхронный» вариант. Минут 5 и то из-за того, что копировал эти Kiss/Miss из задания.

let n = 1;
let interval = setInterval(() => {
if (n % 3 == 0 && n % 5 == 0) {console.log('MissKiss');}
else if (n % 3 == 0) {console.log('Kiss');}
else if (n % 5 == 0) {console.log('Miss')}
else {console.log(n)};
n++;

if (n == 101) {clearInterval(interval)}
}, 50);


Но вообще странно, где он берет 99 «программистов», которые не могут вообще ничего написать на это задание.

Строго говоря, вы не решили задачу, как и я. Мы вместе допустили ошибки на этапе знакомства с задачей (у меня было перепутано Kiss и Miss).

После прочтения задания в голове уже сложилась картина решения и кода, написал на листке бумаги, потом сравнил с Вашим примером, отличие только в том что Вы написали на новом ECMA, ну и реализаций можно было бы придумать даже несколько вариантов (но это уже так для интереса).
Спасибо за статью!
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
	pusha
	xor ah, ah
	mov dl, al
	mov cl, 15
	div cl

Ну что ты будешь делать, а...?
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

js знаю поверхностно
поэтому без всяких let и функций


var i, a, b;
for (i=1; i<101; i++) {
a=i % 3;
b=i % 5;
if (a==0 && b==0) {
console.log('MissKiss');
} else if (a==0) {
console.log('Miss');
} else if (b==0) {
console.log('Kiss');
} else {
console.log(i);
}}

И это неправильный ответ :)

И что тут неправильного? Если вы про


Each print must be asynchronous call console.log function with a 50ms delay.

, то я как бы и не владею полноценно js
Это уже нюанс, на решение которого надо потратить еще чуток времени

Ну нельзя же быть наполовину беременной, например.

соглашусь, но.


  1. я не программист ни разу, на задание потратил 4 минуты
  2. исходя из п.1 с огромной вероятностью следует, что тот, кто программист — напишет этот код быстрее и добавит асинхронность вывода с задержкой.
    А значит автор статьи гиперболизирует проблему и ее нет

Проблема не в том, что программисты не справляются с задачей — а в том что "не программисты" приходят на собеседования на должности программистов и иногда даже их принимают.

Насколько я понял из статьи, все собеседующиеся имеют какие-то должности, спец.образование. Если все же ситуация имеет вероятность часто быть, то я бы сделал вывод о том, что
а) проблема с образованием (отсутствие качественно проверки и т.п.)
б) проблема в перенасыщенности информацией, когда люди на простых задачах впадают в ступор, но при этом отлично решают более сложные задачи

Где вы в тексте данной статьи нашли про 50см?

про 50 см нигде, про 50 мс — в задании

Где-то в конце десятых пропал термин кодер. Остался только негативный термин говнокодер или быдлокодер.
Все стали программистами — 1с-программистами, css-программистами, html-программистами.
Прочитал первые 10 страниц книги по программированию, и уже программист.
Мало того, я считаю 90% текущих программистов отнести к кодерам.
А кодеру незазорно не смочь создать решение.

Квалификация "программист" присваивается выпускникам ПТУ согласно действующим нормативным документам.

Пора вводить понятие категорий.
Инженер корпоративных систем 3 разряда.
Инженер веб-решений 7 разряда.
И прочее.

В нормативных документах категории есть :)

Даже стало интересно, дайте ссылочку, если не трудно.
Смотрите по слову ОКПДТР. Интересно, что классификатор допускает такие должности, как «пятый помощник программиста», «участковый программист», «районный программист» и «горный программист» :)

Человека, который не сумел написать FizzBuzz, нельзя отнести даже к кодерам.

Кодер пишет то, что ему скажут и так, как ему скажут. Решением задачи, а тем более оптимизацией решения занимается программист.

Тут задача уже решена: описан чёткий алгоритм работы. Надо просто его закодировать.

Правда ваша.

В том-то и вопрос, что масса програмистов учили и умеют синхронный код программировать. Почему так мало смыслят в асинхронное программирование на бумаге — вот это совсем другая тема и как-то не очень корректно путать топлое с мягким.

FizzBuzz.py (нужно только расставить отступы согласно вложенности):
for i in range(1,101,1):
if i % 3 == 0 and i % 5 == 0:
print("FizzBuzz");
elif i % 3 == 0:
print("Fizz");
elif i % 5 == 0:
print("Buzz");
else:
print(i);

Вот как вы думаете, это задание написано криво и моё решение имеет право на жизнь, или я дурак?
for(var i=1; i<=100; ++i){
    var s = '';
    if(i%3==0){
	s = 'Miss';
    }
    if(i%5==0){
	s = s+'Kiss';
    }
    if(s=='') s = i;
    setTimeout(( function(){ var x = s; return function(){ console.log(x) }})(), 51);
}


Вишенкой на торте задержка в 51мс, потому что когда я полез смотреть решение сразу увидел строку
// Боюсь, что многие не осознают ошибку. Судя по количеству заявленных правильных ответов. Попробуйте изменить задержку на 1 секунду.

и недоумевая таки изменил её на 1 секунду, после чего уже прочёл решение

Попробуйте изменить на 1000 мс. Ваш вариант выплевывает в консоль все ответы сразу.

Я знаю, но в задании нигде не сказано что он должен делать задержку между последовательными ответами, там сказано что каждый вывод на консоль должен быть асинхронным и с задержкой в 50мс.

Правильное окончание задания звучало бы как «между выводами чисел должна быть не блокирующая задержка в 50 мс»
Где в тесте статьи есть про 50мс?
Задержка должна быть между шагами вывода, а не перед выплевыванием.

Вместо var x=s; можно было бы перед s написать let, а не var и использовать s на вывод. :)
setTimeout измеряет задержки в миллисекундах, потому у вас получилось увеличить задержку только на 1 миллисекунду
Мысленно представил, как сделал бы на шарпе через пару условий или свитчей, но подумал, что это, наверное, костыльно и есть способы лаконичнее, однако в ответе именно такой. Думаю, за пару минут не уложился бы, но за 10 вполне.

Не поленился и накарябал, не подглядывая в жс, в 10 минут уложился.
Заголовок спойлера
var range = Enumerable.Range(1, 100);

foreach (var item in range)
{
    if (item % 3 == 0 && item % 5 == 0)
    {
        Console.WriteLine("FizzBuzz");
    }

    if (item % 3 == 0)
    {
        Console.WriteLine("Fizz");
    }

    if (item % 5 == 0)
    {
         Console.WriteLine("Buzz");
    }

    else
    {
        Console.WriteLine(item);
    }
}


continue; после каждого ифа забыл… А тут еще и задержка какая-то всплыла. В общем прошу считать вышенаписанный камент недействительным и вообще меня тут не было.

Ну, на шарпе задержка как раз не проблема. Можно хоть Thread.Sleep, хоть await Task.Delay использовать.


Вот на старых версиях js необходимость задержки полностью перекореживает код.

Аналогично, зашел сначала с шарпа. Минут пять потратил. Если я правильно понял про асинхронность, то мой вариант ниже:

   static void Main(string[] args)
        {
            for (int i = 0; i <= 100; i++)
            {
                string s = "";
                if (IsDivisableBy(i, 3))
                {
                    s += "Kiss";
                }
                if (IsDivisableBy(i, 5))
                {
                    s += "Miss";
                }
                if (s.Length == 0)
                {
                    s = i.ToString();
                }
                PrintAsync(s);
                Thread.Sleep(50);
            }

            Console.ReadKey();
        
        }

        static bool IsDivisableBy(int sourceNum, int divisor)
        {
            return ((sourceNum % divisor) == 0) ? true : false;
        }

        static async void PrintAsync(string s)
        {
            await Task.Run(() => Console.WriteLine(s));
        }

Зачем, ну зачем IsDivisableBy? Что оно делает?


Это на тут случай если кто-то не знает что в шарпе делает оператор %?


Не говорю уже про ? true : false;...

Написать
s += ((i % 3) == 0) ? "Kiss" : "";

слишком просто :))
В принципе, всё делалось ряди погони за удобочитаемостью. Не меняя времени, затраченного на решение, можно было добавить сахарку за счет extension method для int:

        public static bool IsDivisableBy(this int source, int divisor)
        {
            return ((source % divisor) == 0 ? true : false);
        }

тогда тело цикла было бы как раз более читаемо с применением ?:
                string s = "";
                s += (i.IsDivisableBy(3) ? "Kiss" : "");
                s += (i.IsDivisableBy(5) ? "Miss" : "");
                if (s.Length==0)
                {
                    s = i.ToString();
                }

Почему вы в таком случае пишите s += ..., а не s = string.Concat(s, ...)?

Ну можно и через concat(), согласен :)
Ещё больше «сахара»:
public static IEnumerable<string> Names(this int index)
{
   if (index.IsDivisableBy(3))
      yield return "Kiss";
   if (index.IsDivisableBy(5))
      yield return "Miss";
}

string s = string.Concat(i.Names());
if (s.Length == 0)
// ...

Вы правда считаете такое хорошим кодом — или издеваетесь?

Тут вроде про код кажущийся чем-то сложным ветка, а не про элегантное решение в 3 строки.

Т.е. вы считаете нормальным намеренно раздувать код, чтобы он начал казаться чем-то сложным?

Речь, скорее, о демонстрации на данном примере из собеседования, что кроме решения непосредственно задачи можно ещё показать умение пользоваться методами расширения, yield return'ом и async/await.
Ясное дело, что решение с минимальным читаемым кодом — это про другое.

Нет. Задачи класса FizzBuzz проверяют именно тот факт, что вы в принципе в состоянии писать код и держать при этом простой код простым.


Написание FizzBuzzEnterpriseEdition на собеседовании будет провалом.

Вспомнилась прекрасная серия от Kyle Kingsbury (aka Aphyr): Reversing the technical interview, Hexing the technical interview и Typing the technical interview. Крайне рекомендую к прочтению всем у кого с английским более-менее.

"Если бы я нанимал программиста" :), я бы сто пудов предпочёл того, кто не будет усложнять простое. Ибо нужен человек, который решает задачи за минимальную цену, а не "изображает из себя профессионала" (намеренное усложнение простой задачи вряд ли можно назвать иначе). Профессионал способен дозировать усилие (умное слово YAGNI).

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

А вам про что в посте написали? Не верите? Ну вот оно… теже яйца, только в профиль

class Program
    {
        static async Task FizzBazz()
        {
            for (var i = 1; i < 101; i++)
            {
                await Task.Delay(50);
                switch ((i % 3, i % 5))
                {
                    case var t when t.Item1 == 0 && t.Item2 == 0:
                        Console.WriteLine("MissKiss");
                        break;
                    case var t when t.Item1 == 0:
                        Console.WriteLine("Miss");
                        break;
                    case var t when t.Item2 == 0:
                        Console.WriteLine("Kiss");
                        break;
                    default:
                        Console.WriteLine(i);
                        break;
                }
            }
        }

        static void Main(string[] args)
        {
            FizzBazz().Wait();
            Console.ReadKey();
        }
    }


Так вроде проще.
Хоть и не жабаскриптер, но можно else if превратить вот в такую конструкцию:

if (n % 5 === 0) {
s += 'Kiss';
}
console.log((s==='')? n: s);
Циклом правильную задержку не сделать, рекурсией элементарно решается
const delay = 50, f = function _f(i) {
	if (i > 100) return;
	setTimeout(() => {
		let s = '';
		if (i % 3 === 0) s += 'Miss';
		if (i % 5 === 0) s += 'Kiss';
		console.log(s ? s : i);
		_f(++i);
	}, delay);
};
f(1);
Это уже было на Хабре: https://habrahabr.ru/post/298134/
Любителям однострочников:
for (let i = 1, s = ''; i < 101; i++) (s = (i % 3 ? '' : 'Miss') + (i % 5 ? '' : 'Kiss')) && setTimeout(function() { console.log(s); }, 50 * i);
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Сначала сделал через setTimeout 50, потом прочитал, что это неправильно, перепугался и сделал через промисы.


var printOne = (i) => new Promise((resolve) => setTimeout(() => {
  if (i % 3 === 0 && i % 5 === 0) {
    console.log('MissKiss')
  } else if (i % 3 === 0) {
    console.log('Miss')
  } else if (i % 5 === 0) {
    console.log('Kiss')
  } else {
    console.log(i)
  }
  resolve();
}, 50));

var printIteration = (i) => {
  if (++i > 100) return;
  return printOne(i)
    .then(() => printIteration(i));
}

printIteration(0);

Может отредактировать условие задачи чтобы сразу было понятно что они должны друг за другом следовать по 50 мс, а не просто "каждый console.log — асинхронный через 50мс"?

LOL


(timeout => new Promise(async res => {
    for (let i = 1; i <= 100; i += 1) {
        await new Promise(cb => setTimeout(cb, timeout));

        if (!(i % 5) && !(i % 3)) {
            console.log('MissKiss');
        } else if (!(i % 5)) {
            console.log('Kiss');
        } else if (!(i % 3)) {
            console.log('Miss');
        } else {
            console.log(i);
        }
    }
    res();
}))(50);

Внешний Promise у вас — лишний, достаточно было (async timeout => ... )(50)

Действительно, спасибо
Пока не привык до конца к async/await
Более оптимальный код, плюс уточнил по условию, что console.log должен быть вызван асинхронно


(async timeout => {
    for (let i = 1; i <= 100; i += 1) {
        const log = async str => new Promise(cb => setTimeout(() => {
            console.log(str);
            cb();
        }, timeout));

        if (!(i % 5) && !(i % 3)) {
            await log('MissKiss');
        } else if (!(i % 5)) {
            await log('Kiss');
        } else if (!(i % 3)) {
            await log('Miss');
        } else {
            await log(i);
        }
    }
})(50);

А теперь async лишний :-)

Чорт %) Пора отдохнуть )


(async timeout => {
    for (let i = 1; i <= 100; i += 1) {
        const log = str => new Promise(cb => setTimeout(() => {
            console.log(str);
            cb();
        }, timeout));

        if (!(i % 5) && !(i % 3)) {
            await log('MissKiss');
        } else if (!(i % 5)) {
            await log('Kiss');
        } else if (!(i % 3)) {
            await log('Miss');
        } else {
            await log(i);
        }
    }
})(50);

Пожалуйста, поясните причину минусов, а то я не понимаю что я сказал не так.

Each print must be asynchronous call console.log function with a 50ms delay.

У меня вот на это уйдет большая часть времени. Более, того, я даю 100% гарантию, что не напишу такое на собеседовании, так как:


  1. Во многих языках работа с асинхронными вызовами не такая простая. Привет от python 3.4, например.
  2. Зачем?

Потому что в этой задаче console.log заменяет собой асинхронный вызов. Вы не верите, что в реальной работе вам однажды понадобится сделать подряд 100 асинхронных вызовов?

Ну так и надо взять библиотеку, это правильное решение (одно из)! А не заявлять, что задача слишком сложная и ее не получится написать на собеседовании.

  1. Я сказал, что задача сложная для тех, кто не работает в языках, в которых асинхронные вызовы приняты. Давайте я вам предложу решить эту задачу на python 3.4 или, например, на Free Pascal?
  2. Обычно выбор библиотеки от проекта к проекте отличается, и какой смысл предлагать человеку сделать то, что он 100% не будет использовать ни на вашем проекте, ни вполне возможно, на других, а потом говорить "ну… это похоже на реальную задачу". В какой реальной задаче мне нужно будет самому написать такой код?


  3. Касательно библиотек. Внезапно, но я довольно часто не помню синтаксис, команды и прочее для библиотек, которые использую редко. Более того, я часто могу не помнить, как та или иная функция называется или какие ей нужны параметры и их порядок. И это нормально даже для senior разработчика, а мы говорим про джуна. У него, очевидно, может вполне не получится написать правильный код на листочке, а особено если он еще сверху оденет либу.
Я сказал, что задача сложная для тех, кто не работает в языках, в которых асинхронные вызовы приняты. Давайте я вам предложу решить эту задачу на python 3.4 или, например, на Free Pascal?

Для тех языков, где асинхронные вызовы не приняты, такой задачи просто не будет. Обсуждаемая тут задача в текущей формулировке — это именно что задача на js.


Обычно выбор библиотеки от проекта к проекте отличается, и какой смысл предлагать человеку сделать то, что он 100% не будет использовать ни на вашем проекте, ни вполне возможно, на других, а потом говорить "ну… это похоже на реальную задачу". В какой реальной задаче мне нужно будет самому написать такой код?

Надо решать эту задачу любым методом. Смысл тут — в проверке что вы вообще знаете что такое асинхронный код.


У него, очевидно, может вполне не получится написать правильный код на листочке, а особено если он еще сверху оденет либу.

Так пусть пишет за компьютером...

Так пусть пишет за компьютером...

А вы не сталкивались с:


  • Нам нужно что бы ты не гуглил, а решал задачу
  • С докой каждый может
  • IDE не используй

И так далее?

Это отдельная проблема, не имеющая никакого отношения к обсуждаемой задаче.

Первый пункт на собеседовании ещё можно понять и простить. Но если мне скажут, что я не должен использовать документацию или IDE, то я, наверное, встану и уйду.
Ну и в конце концов, можно дать человеку компьютер без доступа к Интернету, с голой операционкой и простым текстовым редактором. Я, например, вообще не могу писать код на бумаге. Стоит мне открыть скобу, как я её тут же закрываю. Строки я обычно пишу не последовательно, нужна возможность добавлять строки сверху, или в середину. Написав какое-нибудь длинное выражение, понимаю что результат мне нужен в нескольких местах, и надо его сохранить в переменную. И еще много всего в таком духе. Так что без IDE это одно, а на бумаге это уже совсем другое. Чтобы нормально писать код на бумаге нужно специально тренироваться. Процесс слишком отличается.

На бумаге это ещё ничего. А вот когда просят в google docs. Да ещё и фокус из окна нельзя уводить, а то вдруг ты гуглишь чего, негодяй. Бррр. В Hola так собеседуют. Я больше не задачки их решал а с отступами в "коде" воевал. Хорошо хоть не в Paint-е.

Что мешает гуглить с другого устройства?

Мне помешала честность. Но это нюансы. Тут сам подход смерительной рубашки раздражает. Стресс-эффект что-ли хотят? )

Ну на коленке так на коленке…
for(let i=0;i<101;i++)console.log(i%3||i%5?(i%3?(i%5?i:"Buzz"):"Fizz"):"FizzBuzz")

Я правильно понял, что каждый следующий вывод в консоль должен отстоять на 50мс от предыдущего?

Да, правильно. Остальные варианты понимания условия слишком простые.

Неправильно. В условиях ничего о задежке не говорится не усложняйте себе жизнь. А те говноревьюверы которые говорят что надо через промисы и вообще в отдельный класс и обернуть в слушатель а потом еще и 2х сторонний байдинг прикрутить и вообще ваш скрипт не похож на новый фреймворм, а нам сказали что вы профессионал… идут лесом.
Write a program that prints into console the numbers from 1 to 100. But for multiples of three print "Miss" instead of the number and for the multiples of five print "Kiss". For numbers which are multiples of both three and five print "MissKiss". Each print must be asynchronous call console.log function with a 50ms delay.
В тексте статьи:
Напишите программу, которая печатает числа от 1 до 100. Но для кратных трём значений «Fizz» вместо номера и для кратных пяти «Buzz». Для чисел, одновременно кратных трём и пяти — «FizzBuzz».

Это другая задача.

Вы бы хоть исправили ошибки за гуглом.



Или это гугл у вас научился?

нам надоело разговаривать с кандидатами, которые не могут запрограммировать свой путь из бумажного мешка

Если вы можете успешно написать цикл, который <...>, вы уже опережаете пакет!

Что?
Ну вот, а я уже разошелся программировать путь из мешка — если громкие звуки то затаиться, пауза, вернуться к началу, иначе проверить ближнюю стенку на целостность, если просвета нет, то проверить наличие ключей в карманах…
А тут вдруг «ни в зуб ногой». Это же скучно!
Покажите код (iced-coffee-script):
for i in [1 .. 100]
  if i % 3 == 0 and i % 5 == 0
    console.log "MissKiss"
  else if i % 3 == 0
    console.log "Miss"
  else if i % 5 == 0
    console.log "Kiss"
  else
    console.log i
  await setTimeout defer(), 50

А самое бесящее всех программистов на чистом JS
Вот это всё можно было сделать еще задолго до ES6.

Я придумал burning-hot-espresso-script.


Это как ваш кофескрипт, но для удобства символы можно писать в любом порядке (shuffle(str.split('')).join(''))
Транспилятор сам разберется какой символ куда поставить


=t
lol0

l f"ls=so iio o c
ciorct  0.l =l%ds1[Kw s% n laoe s 3   e s i
 "elei  0iie%ea.i  i  %    amns"0"cKoii=si  0, =.o.  so3o    lse]   M5. .fsfsgons

e (g r 5e 
n  )
euiliTess n  e  =fn e" M 5=  ggdi  oli"s fe0o o0=t1
Прикольно, но уже есть async await в js через babel через webpack.

С чего бы это бесило программистов на чистом JS?

По ссылке нет доказательств того, что именно эта возможность бесит программистов на чистом js.


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

Для меня необ'яснимая загадка, чем не нравится coffescript подавляющему большинству

Думаю, дело в том, что он не вводит ничего нового в язык, а синтаксис меняет, причём ещё и в сторону некрасивого Ruby. Его использование говорит о том, что программист не квалифицирован оценивать соотношение рисков и пользы от добавления в проект дополнительной зависимости. В таком ключе реакция большинства на coffeescript должна быть очевидной.

Так и не понял, при чем тут заморочки конкретно JavaScript к умению программировать.

Написал решение с циклом и потом понял прикол с рекурсией.


На самом деле, для js-разработчиков асинхронное программирование musthave. Иметь скилы работы с асинхронным кодом это хорошо, но если на сервере не нужно работать с ним, то что, вешаться? Поэтому странно судить всех по 1 критерию.

А где это на сервере нету асинхронных вызовов?

В Apache :)


А если серьёзно, то "нету" и "не нужно работать с ними" (вся асинхронность скрывается ОС и рантаймом как в PHP по дефолту) — две большие разницы.

Ну окей. Тогда понятно почему у php программеров, которые пытаются на js писать встают волосы (личный опыт).

От опыта зависит. Я чуть ли не 20 лет назад матерился из-за отсутствия в PHP более менее нормальной асинхронности, доступной на среднем шаред-хостинге. Что-только не выдумывал, включая запросы скрипта самого себя через HTTP :)

Ну тк там есть асинхронность, просто она скрыта. Но там возвращается вопрос того, что всё равно нужно знать, что это и как это использовать.

Как-то так
function missKiss () {
    for (let i = 1; i < 100; i++) {
        const triply = i % 3 === 0,
              fivy   = i % 5 === 0

        switch (true) {
            case triply && fivy:
                print('MissKiss');
                break;
            case triply:
                print('Miss');
                break;
            case fivy:
                print('Kiss');
                break;
            default:
                print(i);
        }
    }
}

function print (what) {
    setTimeout(
        () => {
            console.log(what);
        },
        50
    )
}

Тот редкий миг, когда понимаешь, что в лоб решение на golang аккуратнее, чем js:
package main

import (
	"bytes"
	"fmt"
	"strconv"
	"time"
)

func print(ch <-chan string, delay time.Duration, done chan struct{}) {
	for toPrint := range ch {
		time.Sleep(delay)
		fmt.Println(toPrint)
	}

	close(done)
}

const (
	miss = "Miss"
	kiss = "Kiss"
)

func main() {
	printCh := make(chan string, 100)
	doneCh := make(chan struct{})
	buf := bytes.Buffer{}

	go print(printCh, 50*time.Microsecond, doneCh)

	for i := 1; i <= 100; i++ {
		if i%3 == 0 {
			buf.WriteString(miss)
		}
		if i%5 == 0 {
			buf.WriteString(kiss)
		}
		if buf.Len() == 0 {
			buf.WriteString(strconv.Itoa(i))
		}

		printCh <- buf.String()
		buf.Reset()
	}

	close(printCh)
	<-doneCh
}


На все около 7 минут ушло.
А по теме статьи — да, проблема есть, но я не понимаю, зачем давать такие задания после ознакомления с кодом кандидата. А это бывает, к сожалению, часто. Как и тестовые задания на несколько дней…

C#


for (var i = 1; i <= 100; i++) {
    var message = string.Empty;
    if (i % 3 == 0) {
        message = "Miss";
    }
    if (i % 5 == 0) {
        message += "Kiss";
    }
    Console.WriteLine(message);
    Thread.Sleep(50);
}

Вы забыли выводить само число когда оно не кратно ни 3, ни 5.

Кроме, как уже сказано, вывода самого числа, нет непосредственно и асинхронного вызова console.writeline.

Да, вы правы, виноват.

А что если пренебречь временной погрешностью и сделать в стиле С решение?

    function wait(msecond) {
        var timeStart = Date.now();
        var timeStop = timeStart + msecond;
        for (;;) if (Date.now() > timeStop) break;
    }

    for (var i=1;i<=100;i++) {
        var num = i;
        var res3 = (num % 3 === 0) ? 'Kiss' : '';
        var res5 = (num % 5 === 0) ? 'Miss' : '';
        console.log((res3 || res5) ? res5 + res3 : num);
        wait(50);
    }

В условиях есть async

Интересно, мне одному глаза режет двойная проверка условия и лишние соединения строк? Почему то никто не предложил чуть более оптимизированный вариант внутреннего цикла:
if (y % 3 == 0) {
    console.log((y % 5 == 0) ? "MissKiss" : "Miss");  
} else {
    console.log((y % 5 == 0) ? "Kiss" : y);
}
Зато стало сложнее воспринимать код
мне тяжело воспринять фразу «сложнее воспринимать код», который состоит из 5 строчек))))
Вы предположили, что сравнение строк в этой задаче в проде вдруг станет критической по производительности процедурой, выполняемой на микроконтроллере с 1кб памяти.

Другие предположили, что задача пойдёт в реалии веб-дева, где завтра может прийти заказчик и сказать «Знаешь, там при делении не на 3 и 5 надо выводить MissKiss, а на 47 и 82. И ещё на 25 выводить Bingo!» и поэтому максимально прозрачно перевели условия в код, не экономя сравнения.

С искусственными задачами всегда так, кто что додумал, тот так и сделал. Хотя из условий задачи (JavaScript), по умолчанию, я бы не стал экономить на копеечных операциях.
Не одному, но я бы писал через промежуточную переменную, но с асинхами не рабтаю:
var
 out_str: String;
begin

...
 
 if (value % 5) = 0 then out_str:="Miss";
 if (value % 3) = 0 then out_str:=out_str+"Kiss";
 Print(out_str);

end

Типа такого.
Я джавист, поэтому выделять переменную, да и еще и генерить несколько строк в результате их соединения, для меня лютый оверхед, если можно просто вынести их как константы)))
НЛО прилетело и опубликовало эту надпись здесь
Ну, давайте попробуем:
Код теста
package test;

import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;

import java.util.concurrent.TimeUnit;

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {

    @Benchmark
    public void testOptMethod(Blackhole bh) {
        for (int y = 0; y < 100; y++) {
            if (y % 3 == 0) {
                bh.consume(y % 5 == 0 ? "MissKiss" : "Miss");
            } else {
                bh.consume(y % 5 == 0 ? "Kiss" : Integer.toString(y));
            }
        }
    }

    @Benchmark
    public void testMethod(Blackhole bh) {
        for (int y = 0; y < 100; y++) {
            String outStr =  "";
            if ((y % 5) == 0) outStr="Miss";
            if ((y % 3) == 0) outStr=outStr + "Kiss";
            bh.consume(outStr.isEmpty() ? Integer.toString(y) : outStr);
        }
    }
}


Результаты:
# Run complete. Total time: 00:13:27

Benchmark _______________ Mode _ Cnt __ Score ___ Error __ Units
MyBenchmark.testMethod ____ avgt _ 200 _ 1755,979? 22,389 _ ns/op
MyBenchmark.testOptMethod _ avgt _ 200 _ 1415,720? 14,703 _ ns/op
Ну вообще-то переменная в Паскале выделяется вне цикла, для этого есть специальный раздел var. Если вы спросите, а как можно выделить позже, то отвечу — можно, но не везде. Например, был такой ТМТ Паскаль, там есть очень хороший оператор declare, позволяющий делать это в любом месте. Так что тест не совсем идентичен, хотя за результат — спасибо, всегда интересно знать, что потенциально понятный тебе язык — незнаком на самом деле.

Конкатенация строк создаёт новую строку в любом языке. Такие же проблемы были бы и на С++. В этой задаче просто не стоит использовать +=.

Разница в том, что в Паскале (да и в С++ при использовании std::string) копирование строки происходит не только при конкатенации, но и при простом присвоении, из-за чего конкатенация теряет свою относительную стоимость.

Неправда, в С++ есть move semantics. Если строка создана как temporary и присваивается в переменную, копирования не будет.

Конечно же правильно вынести переменную вне цикла.
Можно даже сделать её полем класса (но это не самый лучший вариант, т.к. код становиться не многопоточным).
Проблема в том, что соединение строк — это всегда создание нового объекта в джаве и соответствующие копирование памяти 2х строк, в новый буфер.

НЛО прилетело и опубликовало эту надпись здесь
names = { 1: "Fizz", 2: "Buzz", 3: "FizzBuzz" }
for x in [(i, int(i%3==0) + (int(i%5==0)<<1)) for i in range(0,100)]:
     print(x[0] if x[1] == 0 else names[x[1]])
Да, я тоже подумал, что наиболее красиво будет условие сформулировать таким образом. Хотя наиболее удобочитаемо — проверить тупо три раза. В этом и есть настоящая изюминка задачи.
Это не изюминка, а проверка на скилл. Два или три IF это базовая оптимизация, которая говорит о том, думает ли человек вообще о производительности. Удобочитаемость совершенно не страдает. Код который привел Ogoun пошел еще дальше, и оптимизировал использование оперативной памяти. И это хорошо. Когда много такого кода видишь, то все тоже удобочитаемо. Признайтесь, вы же вообще не задумывались/искали профайлером сколько нагружают память и GC спам обычных строк?

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

Вот так может и ненадо, но иметь коллекцию нужных строк и переиспользовать их — шаг в правильном направлении

Не вижу преимуществ перед обычными строковыми литералами, до тех пор пока каждый из них встречается всего 1 раз.

Более того, движки всё умнее становятся, и вполне могут оптимизировать сами если несколько раз строка одна строка встречается.

Я говорил не про оптимизацию, а про поддержку кода. Нетривиальная неименованная магическая константа в коде, которая встречается более одного раза — путь к ошибкам.

тут есть конкатенация без использование массива

Не во всех решениях. В моем, например, ее нет.


Что лишняя конкатенация строк — это нехорошо, я с вами согласен. Но, во-первых, эта задача слишком простая чтобы конкатенация успела стать проблемой — а во-вторых, не обязательно настолько корежить код чтобы от нее избавиться.

Я не столько про память думал, сколько вообще про красоту кода. Противно два раза подряд проверять одно и то же. А сыграть это может, если целые числа заменить на какие-нибудь активные объекты (имеющие конструкторы, или вычисляющиеся в результате вызова функций, или асинхронно изменяющиеся).

Уважаемого товарища Ogoun я бы взял на работу без дальнейшего интервью, если бы он написал на собеседовании такой код, сопроводив замечанием об удобочитаемости (даже несмотря на ошибку на единицу в range). Видно, что программист дельный.
И да, я посыпаю голову пеплом. Так как не знаком с языком не увидел, что здесь используется все теже три условия. Остается только оптимизация памяти…
Он проверяет каждое деление по одному разу, в то время как большинство других примеров дважды проверяют делимость на 3.
Я про то, что в коде есть три "==", и в худших случаях все три условия будут проверяться. Можно сделать в два условия.

А то что тут типографическую показывают, «какой я молодец» по типу
if (i%3 ==0 && i%5 ==0){
console.log("MissKiss")}
else if (i%3 ==0) { console.log('Miss')}
else if(i%5==0) { console.log('Kiss')}

Это вообще трындец с 4 проверками
А, ну в печати-то, конечно, можно дальше оптимизировать. Я про саму схему проверки.

А ещё можно избавиться от &&, который в ассемблере всё равно будет дополнительным условием. Достаточно вспомнить, что если что-то делится на 3 и 5, то оно делится на 15.

И вам тоже стоит посмотреть бенчмарк — https://jsperf.com/misskiss


Проверка делимости на 15 работает медленнее чем две проверки делимости на 3 и на 5.

Нельзя оптимизировать код без бенчмарков — очень легко завести оптимизацию не в ту сторону.


Вот и вы зачем-то считаете проверки, из чего делаете вывод о "трындеце" c 4 проверками. А на самом деле операция обращения к элементу массива или свойству объекта съедает намного больше времени чем какая-то проверка. По крайней мере, в Хроме.


Вот сравнение: https://jsperf.com/misskiss

Изините, я кажется запутался и сломал страничку своей ревизией =(
А теперь по теме:
Я почти испугался =) Только я постоянно говорил про проверки, а самый быстрый результат как раз с 2 проверками. И конечно массив проигрывает константам, но на грани погрешности(у меня пару раз выигрывал) 2%. Массив нужен уже для больших задач, когда GC и аллокации начинают давить на мозг.

var names = ["Miss", "Kiss", "MissKiss"]
for (var i=1; i<=100; i++) {
  if (i%5==0) {
    if(i%3==0) console.log(names[2]);
    else console.log(names[1]);
  } else {
    if(i%3==0) console.log(names[0]);
    else console.log(i);
  } 
}

Зачем? Что вы ускоряете столь странным образом?

Этот вариант использует «самые быстрые две проверки», но использует массив, что бы не разбрасываться памятью и он по сути не уступает самому быстрому варианту(две проверки с константами)

Каким образом исходный вариант "разбрасывался памятью"?

Конечно я усложнил пример, для этой маленькой задачи.
Разбрасываться начнет, когда эти строчки («Miss», «Kiss», «MissKiss») будут использоваться из разных источников и в разных частях программы.

Тоесть в моем утрированном случае по всюду будут зааллоцированы строки «Kiss», вместо того, что бы ссылаться на одну строку.

И заметьте: там было два варианта, в который вообще не было проверок.


Один из них (switch) по скорости — немного хуже чем вариант с 4 проверками, второй (array 15) — и вовсе является самым медленным!


PS вы ничего не сломали, вы выпустили новую ревизию бенчмарка. Только немного странную :-)

switch это куча проверок. И хорошо работает только на огромных вариациях. При маленьком количестве это все разворачивается в иф елсе(верно для c#, js незнаю)

А насчет array 15 это класическая ошибка новичков, из-за которой кеш процессора постоянно промахивается, из-за непоследовательного обращения к элементам + там не значения, а лямбды

Вот что я об этом думаю)

Добавил вариант с рекурсией — намного хуже, чем перебор.

for (var i=0; i< 20; i++){ 
	if (i%3 ==0 && i%5 ==0){
		console.log("MissKiss")}
	else if (i%3 ==0) { console.log('Miss')}
	else if(i%5==0) { console.log('Kiss')}
	else { console.log(i)}
}


Очень простое решение, минуты 3, после пива и при том что Python изучаю. Это серъёзно про 199 из 200 не могут написать?

Более того, большинство не может распознать свои ошибки. Очевидно.

Задержки нехватает
Очень простое, но очень неэффективное: 2 лишних сравнения, 2 лишних вычисления остатка от деления, один лишний if и 2 лишних else.
Напишите более эффективное решение раз уж критикуете.
Так тут такие выше и ниже уже написаны. Просто посмотрите на код и задайте себе вопросы: а нужно ли в нём дублирование проверок «i%3 ==0» и «i%5 ==0»? Может быть можно по одному раз проверять? Нужны ли в двух местах кода строки «Miss» и «Kiss» — возможно, будет достаточно по одному их экземпляру? И код вырисовывается сам.

Мне кажется, что даже правильный ответ в статье не совсем правильный. Ибо между выводами не 50мс, а 50мс + (время работы функции). Чтобы вызовы были действительно асинхронными, я думаю, правильнее будет писать так

Тоже это заметил в решениях. Но правильный путь это подготовить результаты, а в нужное время лишь брать их. В js завезли многопоточность? Можно мультипоточно заполнять очередь?

Можно относительно легко организовать два псевдопотока — один заполняет очередь, а другой читает из неё по интервалу 50мс.


const queue = [];
const interval = window.setInterval(() => {
    console.log(queue.shift());
    if (queue.length === 0) {
        window.clearInterval(interval);
    }
}, 50);

for(let i=1; i<=100; ++i) {
    let str;
    if (i % 3 === 0) {
        if (i % 5 === 0) {
            str = 'KissMiss';
        } else {
            str = 'Kiss';
        }
    } else if (i % 5 === 0) {
        str = 'Miss'
    } else {
        str = i;
    }
    Promise.resolve().then(() => queue.push(str));
}

Многопоточность завезли в виде Worker-ов.

Задачу решил меньше чем за 5 минут, ограничен я был в решении только скоростью печати. Если честно не представляю как на подобное можно больше часа потратить.


const fn = () => {
  for (let i = 1; i <= 100; i++) {
    setTimeout((number) => {
      if (number % 3 === 0 && number % 5 === 0) {
        console.log('MissKiss')
      } else if (number % 3 === 0) {
        console.log('Miss')
      } else if (number % 5 === 0) {
        console.log('Kiss')
      } else {
        console.log(number)
      }
    }, i * 50, i)
  }
}
fn()
Я вообще с трудом представляю, почему на хабре статья про FizzBuzz имеет 150+ комментариев, а не заминусована в хлам.
Комменты выше, где такую задачу решают с промисами, асинхронностью, дополнительными функциями, переменными, проверок потом этих переменных и прочей жестью, напоминают мне консольный Hello World на VB6:
Option Explicit

    Declare Function AllocConsole Lib "kernel32" () As Long
    Declare Function FreeConsole Lib "kernel32" () As Long
    Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
    Declare Function GetStdHandle Lib "kernel32" (ByVal nStdHandle As Long) As Long
    Declare Function WriteConsole Lib "kernel32" Alias "WriteConsoleA" _
           (ByVal hConsoleOutput As Long, lpBuffer As Any, ByVal _
           nNumberOfCharsToWrite As Long, lpNumberOfCharsWritten As Long, _
           lpReserved As Any) As Long
    Declare Function Sleep Lib "kernel32" (ByVal dwMilliseconds As Long) As Long

Private Sub Main()
    'create a console instance
    AllocConsole
    'get handle of console output
    Dim hOut As Long
    hOut = GetStdHandle(-11&)
    'output string to console output
    Dim s As String
    s = "Hello, World!" & vbCrLf
    WriteConsole hOut, ByVal s, Len(s), vbNull, vbNull
    'make a pause to look at the output
    Sleep 2000
    'close the handle and destroy the console
    CloseHandle hOut
    FreeConsole
End Sub
#!/bin/bash
for i in {1..100}
do
    a=0
    [ $(( $i % 3 )) -eq 0 ] && echo -n 'Fizz' && a=1
    [ $(( $i % 5 )) -eq 0 ] && echo -n 'Buzz' && a=1
    [ $a -eq 1 ] && echo
done

Таки меньше 10 минут
Я прошу прощения, что не на джава-скрипте, просто задачка подходит для любого языка просто отлично
Тогда как-то так
#!/bin/bash

console.log(){
    local i=$1
    local result=""
    a=0
    [ $(( $i % 3 )) -eq 0 ] && result+='Fizz' && a=1
    [ $(( $i % 5 )) -eq 0 ] && result+='Buzz' && a=1
    [ $a -eq 0 ] && result+="$i"
    echo $result
}

for i in {1..100}
do
(
    sleep 0.05
    console.log $i
) &
done
wait

Даже console.log есть

Но если у меня правильно работает интерпретатор bash в голове, то это код не будет ждать между выводами значений — вместо этого он подождет 50 мс только при запуске, а потом выплюнет все сразу, т.к. sleep происходит вомножестве подпроцессов одновременно. Нужно, чтобы паузы были между выводами, но при этом чтобы каждый вывод был асинхронным.

Вы уверены, что в условии так написано?

Абсолютно уверен, посмотрите дискуссию в этом посте :) Просто пауза перед выводом любых значений не добавляет в задачу сложности.

Можно, поменять местами wait и done, но это все равно будет не совсем то. В результате накладных расходов еще на 0.4 секунды. Спасибо за уточнения
Что-то цифры то не выводит.
PHP, 4 минуты

for($i=1;$i<=100;$i++){
	if($i%3==0 && $i%5==0){
		echo "KISSMISS";
		echo "\n";
	}elseif($i%3==0){
		echo "MISS";
		echo "\n";
	}elseif($i%5==0){
		echo "KISS";
		echo "\n";
	}else{
		echo $i;
		echo "\n";
	}
}
Я так понимаю, минусы получают за:
1. Другие языки
2. Неоптимизированность кода

Но задача решена ведь, в чем проблема? Да, можно уложиться в меньшее кол-во строк, но это уже потом, после того, как получится правильное решение. Или у нас набег лютых ненавистников PHP?

Задержки нет в 50 мс нет.

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

Интересно.
Задачка с подвохом.
Я вот тоже набрал текст за 2 минуты в консоли браузера, а потом прочёл, что надо асинхронно.
Сделал асинхронно, а потом увидел, что хотя вывод через console.log и был верным, но первый вызов функции пишет в консоль результат undefined, что абсолютно корректно, но портит вывод.
«Правильное» решение по ссылке из статьи тоже пишет undefined в самом начале, так что его я бы тоже не засчитал.

Undefined пишет консоль браузера, показывая вам возврат по об'явлению функции

Это особенность именно что интерактивной консоли. При запуске из скрипта первого undefined не будет.

— T SQL
declare @i int;
set @i = 1;

CREATE TABLE #test ([Step] int, [Result] nvarchar (10));

WHILE @i <= 100
BEGIN

INSERT INTO #test
select
@i as [Step]
,case
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) and cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'FizzBuzz'
when cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'Buzz'
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) then 'Fizz'
else cast (@i as nvarchar)
end as [Result]
;
set @i = @i + 1;

END

select [Result] from #test;


Потратил 20 минут… Плохо…

И задержки нет :) Правда, я даже не знаю, как сделать задержку в T-SQL, разве что через UDF?

зачем таблицу создавать?
DECLARE test TABLE
А иначе вывод некрасивый :)))

Result
------------------------------
1

(1 row(s) affected)

Result
------------------------------
2

(1 row(s) affected)

Result
------------------------------
Fizz

(1 row(s) affected)

Result
------------------------------
4

(1 row(s) affected)

Result
------------------------------
Buzz

(1 row(s) affected)

Result
------------------------------
Fizz

(1 row(s) affected)

и т.д.

Да с чего бы такой вывод был из табличной переменной-то?

Какая табличная переменная?
Вот первый вариант (просто написал «в лоб», обычно циклы для таких задач не использую):
declare @i int;
set @i = 1;

WHILE @i <= 100 
BEGIN 

select 
case
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) and cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'FizzBuzz'
when cast(@i as decimal) / 5 = round ((cast(@i as decimal) / 5), 0) then 'Buzz'
when cast(@i as decimal) / 3 = round ((cast(@i as decimal) / 3), 0) then 'Fizz'
else cast (@i as nvarchar)
end as [Result]
;
set @i = @i + 1;

END 


Вывод не понравился и немного доработал.

Цитирую:


зачем таблицу создавать?
DECLARE @test TABLE
Чтобы сделать более красивый вывод.
Или вопрос звучит как: «Почему таблицу, а не табличную переменную?»
Я с табличными переменными обычно не работаю, в основном с временными таблицами. Вот и создал временную таблицу.
Select… Into… в данном случае работать не будет — мы селект выполняем 100 раз.
Это же троллинг такой, да? Как можно на это потратить больше 10 секунд? Ну ладно, если человек редко пишет что-то связанное с математикой, ему понадобится вспомнить, что % — это остаток от деления, может нагуглить, чтоб убедиться, это максимум 5 минут. Но не 67 же! С другой стороны, если ситуация и вправду такая печальная, у меня будет больше шансов устроиться на работу :)
Минусы от jquery-программистов?

для того, чтобы за 10 секунд набрать приблизительно 400 знаков, не считая пробелы, вы должны просто необыкновенно быстро печатать. Но несколько минут — да, реалистичная оценка.

Я имел ввиду продумывание алгоритма. И да, в первоначальной задаче не указан язык, на C++ это будет примерно 250)

Позвольте вас вызвать на поединок — я хочу посмотреть, как вы выполните условие с асинхронностью (каждый print в отдельном потоке), уложившись в 250 знаков без учета whitespace. Только без читерства с созданием одной огромной строки из смеси пробелов и tab-ов, в которой закодирована остальная реализация :)


Продумывание да, 10 секунд от силы, согласен.

На js не пишу, но как вариант что-нибудь такое
var i=1;function doIt(){var r="";if(i% 3== 0|| i% 5== 0){if(i% 3== 0){r+= "Miss"};if(i% 5== 0){r+= "Kiss"}}else {r+= i};console["log"](r);i++;if(i<= 100){setTimeout(doIt,50)}}doIt()

182 символа
на C++ это будет примерно 250)

Но это не C++ :)

Так на C++ не было условия задержки, асинхронности и многопоточности, если без них, то вот:
#include <iostream>

int main()
{
        for(int i = 1; i <= 100; i++) {
                if (i % 3 == 0 || i % 5 == 0) {
                        if (i % 3 == 0)
                                std::cout << "fizz";
                        if (i % 5 == 0)
                                std::cout << "buzz";
                } else 
                        std::cout << i;
                std::cout << std::endl;
        }
}

Можно поизвращаться с оптимизацией
#include <iostream>

int main()
{
        for(int i = 1; i <= 100; i++) {
                bool ch1 = i % 3;
                bool ch2 = i % 5;
                if (!ch1)
                        std::cout << "fizz";
                if (!ch2)
                        std::cout << "buzz";
                if(ch1 && ch2)
                        std::cout << i;
                std::cout << std::endl;
        }
}

по идее переменные будут регистровыми и процессору на пару операций меньше нужно будет делать, но по факту всё упрётся в медленный вывод на экран. А многопоточность конечно можно добавить и не сильно много символов будет, но смысла от неё в этой задаче не будет никакого.

Ну так и на JS смысла от задержки нет никакого, как, впрочем, и у самой задачи нет особого смысла. Просто нужно так сделать :)

#include <iostream>
#include <future>
using namespace std;

auto&& s=cout;

void f(int i)
{
    this_thread::sleep_for(chrono::milliseconds(50));
    if (!(i%15)) s << "MissKiss";
    else if (!(i%3)) s << "Miss";
    else if (!(i%5)) s << "Kiss";
    else s << i;
    s << endl;
    if (i == 100) return;
    return async(f, ++i).get();
}
int main()
{
    async(f,1).get();
    return 0;
}


~275-300 символов и 15 минут из которых 10 потрачено на попытки ужать в 250 символов, но это возможно только если выкинуть заголовочники.
#include <iostream>
#include <future>
using namespace std;

auto&& s=cout;

int f(int i)
{
    this_thread::sleep_for(chrono::milliseconds(50));
    if(!(i%15))s<<"MissKiss";
    else if (!(i%3))s<<"Miss";
    else if (!(i%5))s<<"Kiss";
    else s<<i;s<<endl;
    return i<100?async(f,++i).get():0;
}
int main()
{
    return async(f,1).get();;
}


Всё. Теоретический минимум 285 символов без учета переноса строк. 257, если не считать пробелы.

Ну и какой смысл в чудесной комбинации async(...).get()?

Я правильно понимаю, что в приведенном коде все равно будет интервал в 50мс между выводами, как в простом синхронном цикле, а не 50*n от начала времен?

Код выше — это и есть синхронный цикл. Только он зачем-то использует 100 потоков, оставаясь при этом синхронным...

асинхронностью (каждый print в отдельном потоке)

Для асинхронности не нужны отдельные потоки.

Ровно пять минут, и то это долго. В гугл не смотрел, т.к. без необходимости. Запускать в node --harmony.

Вы по моим наблюдением побили рекорд. Даже не четыре, а пять проверок условий вместо двух Оо

@Lailore, я всё никак в толк не возьму, вы шутите или таки серьёзно? Объясните мне неразумному, какой смысл акцентировать внимание на количестве примитивных условий в JS-коде, который на каждую итерацию создаёт новый анонимный метод и promise? Если уж пытаться где-то сэкономить, то уж точно не на вот таких вот проверках. А если вспомнить ещё во что превращается async-await код (конечный автомат, нечто вроде большого switch-case), то вам наверное вообще поплохеть должно? )

ну, на практике т.к. тут нет closure в function sleep, поэтому новый анонимный метод не будет создаваться каждый раз — вместо этого движок один раз скомпилирует шаблон функции и будет использовать его в дальнейшем. Но да, в этом была суть моего комментария чуть ниже вашего.


И в данном случае тут async/await ни во что не превращается, т.к. node 7.9.0 уже умеет async/await из коробки. Ну и в принципе в ES6 окружении это уже скорее были бы генераторы… не знаю даже, что хуже :)

поэтому новый анонимный метод не будет создаваться каждый раз — вместо этого движок один раз скомпилирует шаблон функции и будет использовать его в дальнейшем

Понимаю, оптимизациям быть. Но думаю это тоже не совсем "бесплатно".


И в данном случае тут async/await ни во что не превращается, т.к. node 7.9.0 уже умеет async/await из коробки.

Ну дык в AST будет тот же самый конечный автомат? Разве нет? Тут с пол года назад публиковали статью, как на основе generators в Edge js-движок добавили async-await (первыми). Там это детально расписывалось.

Бесплатного ничего не бывает — скорее всего, несколько итераций цикла у движка займет анализ того, что поведение функции не меняется, т.к. не сорвется ни одна проверка на деоптимизацию (я не помню, как называются эти внутренние assert-ы, увы). Если бы fizzbuzz выполнялся на хотя бы тысячах итераций, возможно, это было бы заметно.


Ну дык в AST будет тот же самый конечный автомат?

Не-а, именно в AST будет ровно то же, что видно глазами. Вы имели в виду IR, Intermediate Representation — там, возможно, мог бы быть конечный автомат, но не факт, т.к. async-функции имеют более сложную семантику, чем одна перезапускающаяся функция с параметром, равным состоянию автомата. Но я понимаю, к чему вы — async-функции можно выразить через генераторы, а генераторы в свою очередь можно выразить через конечные автоматы. Результат будет монструозным, и с повсеместным введением поддержки ES5 в нем больше нет необходимости.

Да, с этим я согласен. Свой вариант решения этой проблемы я описал тут
Но правильный путь это подготовить результаты, а в нужное время лишь брать их.

Категоричное утверждение. Каждой задаче свой инструмент. Каждому инструменту — свой стиль, свои требования. Когда вы пишете js-код, то чаще всего, правильнее будет написать:


  • простой
  • очевидный
  • легко расширяемый и легко тестируемый

код. Перед задачами, которые решаются на этом языке, чаще всего стоит несколько другие требования, чем, скажем, перед теми, кто пишет на C++. И если стоимость такой вот оптимизации (время=деньги) не превалирует над преимуществами от этого решения, то эта оптимизация ― пустая трата денег. В JS когда речь заходит о производительности, обычно есть места, которые могут ускорить работу нагруженного участка на порядок или более. И почти всегда это не спички, а аллокация в цикле или что-нибудь в таком духе.

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

Если что, то выше обсуждают ассамблер. Люблю хабр.

Вы еще x <= 100 в проверки посчитайте, будет шесть. Какой смысл экономить на сравнениях, когда в функции используется передача управления в event loop? Это называется "микрооптимизация", или "экономия на спичках".


Цель проверки — сделать быстро и читабельно. Посильную помощь оптимизатору, явно указав результат сравнений как константы, я оказал. И я могу быть не прав, но на мой взгляд, мой пример кода на порядок читабельнее решений типа этого.

Но пока никто не сделал на ассемблере асинхронный пример :) Ждем того самого смельчака, который напишет на асме реализацию кооперативной многозадачности.

Ваш код более читабельный, но код по ссылке менее хрупкий (fragile).

Ваш код (и другие приведённые здесь подобные ответы) порождает раздумья сопровождающего его программиста вот над какой проблемой: если мы в одном месте поменяли, например, by3 на какое-то другое условие, надо ли проводить такую же замену в другом месте? Эта дилемма возникает при кодировании совершенно на пустом месте, потому что постановка задачи её не предопределяет, и в коде по ссылке её просто нет.
by3 объявлен через const, потенциальные «другие места» заканчиваются в конце блока на пять строчек.
Ну в реальной жизни-то будет посложнее задача и побольше кода. А паттерны в голове у программиста – те же самые.

Отвечу вам контрпримером. Если нужно будет добавить новое условие, по которому в случае деления на 7 без остатка надо выводить "Piss" — сколько изменений потребуется в моем коде и сколько в "менее хрупком"?

Вопрос же не в том, сколько символов и в каком месте менять, а в том, как это заметить. Вы описываете внесение двух изменений: добавление проверки делимости на 7 и добавление вывода строки «Piss». Очевидно, обе эти вещи надо где-то прописать. В Вашем случае они будут находиться в одной строке, а в примере выше – в разных строках, но это ничего не меняет.

Если говорить о новых изменениях, представьте себе, например, что заказчик решил буквально чуть-чуть уточнить условия задачи и ввести список чисел, которые делятся на 3, но не относятся к категории Fizz, делятся на 5, но не относятся к категории Buzz и т.п., в результате чего условия by3 и by5 – это теперь запросы к базе данных исключений из правил, которые занимают по 10 минут.

Тут можно много чего напридумывать.

А вот перечисленное вами — еще одна из причин, почему "программисты не могут программировать".


Речь не только об отсечении тех, кто никогда строчки кода не набрал, речь еще и о тех, кто в размышлениях на тему "а что если деление на 3 будет в будущем реализовано как длительное обращение к базе данных, надо предусмотреть механизм для этого", "а вдруг у заказчика появится необходимость добавить новые условия, и еще настраивать их через конфиг-файл, давайте сделаем декларативный DSL для определения делителей и требуемого действия", и т.д. заходит в дебри полного паралича, т.к. никогда не получится сделать идеально гибкое решение, которое предусмотрит все возможные будущие юзкейсы, которые, возможно, никогда не наступят.


И это уже называется "оверинжиниринг".

Идеал недостижим, но определённые предпосылки вполне можно создать без особых затрат.

Вот когда заказчик уточнит условия задачи — тогда и будем думать что с этим делать. Пока что надо просто оставить будущим коллегам понятный код.

Читая споры про эти 50ms в условиях задачи мне волей не волей вспомнился ACM. Когда я был ещё студентом, и пытался участвовать в ACM нашей недокоманде очень сильно не хватало знания языка. Я его понимал на уровне beginner, а мои товарищи на уровне lower intermediate. В итоге на олимпиадки мы ездили со здоровенным техническим англо-русским словарём. Тяжеленным таким. Все задачи на английском. Авторы задач никогда не утруждали себя в том, чтобы максимально очевидно и понятно донести до студентов задачу. Все задачи заключали в себе такой текст, что если хорошо приглядеться и призадуматься, то каких-то вольностей толкований условий не остаётся. Но это разве что для native speaker-ов. Для всех остальных это было серьёзной преградой. Многие тонкости лежали за той гранью лингвистики, которую мы могли осилить. На тот момент было очень обидно, ибо ситуации когда какая-нибудь едва приметная мелочь переворачивала всё вверх ногами были весьма частыми.

Да, тоже когда-то от этого страдал. В ретроспективе это даже кажется правильным. Согласитесь, программисты без знания английского языка никому не нужны. Если не преподают необходимый английский на достаточном уровне, то команда АСМ займёт места намного ниже, и это скажется на рейтинге вуза.

Согласитесь, программисты без знания английского языка никому не нужны.

С этим не соглашусь. Мне вообще кажется, что сейчас очень большая потребность в относительно слабых и немощных программистах, способных разворачивать готовые коробочные решения и подтачивать их под нужды малого бизнеса. И всё это за сравнительно небольшие деньги. Во всяком случае, я наблюдаю это сплошь и рядом. Эта область процветает.


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

И в этом большая проблема =( Это портит имя профессии. Тут надо ввести новое название, как например: есть врач, а есть фельдшер.

А вы вспомните про "Тыжпрограммист, холодильник мне почини". Не вижу особого смысла в большом разнообразии названий. Понимающий народ начнёт плавать (как сейчас происходит в англ. языке). А непонимающий всё также будет объединять всё то, что связано с компьютерами в одну отрасль :)

Перечитал свой комментарий. Какой-то он высокомерный получился, я вовсе не это хотел донести :) Поэтому уточню: эти самые готовые коробочные решения, в случае если они популярны, как правило располагают большим количеством русскоязычной документации и разного рода статей, на том же хабре. И можно быть весьма успешным специалистом в этой области без достаточных познаний в языке.


Это, правда, не отменяет того факта, что хороший (даже очень хороший) программист может обладать весьма зачаточными знаниями языка, и читать зарубежные материалы через "боль и страдания" (но таки читать, куда же он денется). Ну хотя бы потому, что самые легендарные бессмертные издания давно уже переведены, а сама работа не подразумевает под собой лингвистических изысков. Но такой программист будет постоянно испытывать неудобства.


В целом, моё мнение, невысокий уровень языка как среди IT-ов, так и среди народа в целом во многом обеспечен тем, что ареал и "популяция" языка (русского) огромные. Насколько я помню, русскоязычные интернеты идут вторым номером среди всех языковых интернетов (после англ, разумеется). Поэтому острой необходимости учить какой-либо другой язык не стоит. А человек по природе своей — ленив.

Насколько я помню, русскоязычные интернеты идут вторым номером среди всех языковых интернетов (после англ, разумеется)

А как же срединное государство? Или у них локальный интернет маленький?

У них написание текстов — исторически занятие немногих.
НЛО прилетело и опубликовало эту надпись здесь

И такого уровня знания английского достаточно для понимания условий всех задач на финале :-)

А Вы не пробовали знаки препинания расставлять когда задание пишете? «Но для кратных трём значений «Fizz» вместо номера...» пять минут потратил чтобы понять, что же здесь хотят)
¯ \ _ (ツ) _ / ¯
function KissMiss(next = 1, msg = ((next % 3?'':'Miss') + (next % 5?'':'Kiss')) || next) {
  next++ <= 100 && setTimeout(() => (console.log(msg), KissMiss(next)), 50)
}
KissMiss()
На мой взгляд самый красивый лаконичный вариант =)
Мне так понравилось ваше решение, что я взял на себя смелость сделать его чуть более лаконичным и чуть более человекопонятным.

Сначала я просто думал избавиться от путающих неподготовленного человека тернарных операторов, но потом решил, что лучше уж избавиться сразу ото всех операций сравнения.

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

Представляю вам решение задания без единой операции сравнения(а не только с отсутствующими if/switch/тернарками):

(K=(n,m='Miss',k='Kiss',s=[[m+k,k,k],z=[m,n,n],z,z,z][n%5][n%3])=>{p=(101-n++);p/=p;try{eval(p+''+p);setTimeout(()=>(console.log(s),K(n)),50)}catch(e){}})(1)


Скрытый текст
На правах шутки.


P.S.: В принципе можно обойтись и без try/catch ради еще большего сокращения кодобазы, но тогда программа будет выплевывать ошибку в консоль, что может быть расценено как лишний вывод и несоответствие условию задачи.
Чуть оптимизировал и сократил еще на 6 символов: https://codepen.io/anon/pen/xdyBZq

Если кто знает более красивое решение вместо eval'a — отпишитесь, пожалуйста.
Да ну блин, дурь всё это, для молодняка членомерки.

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

Сейчас на первом месте способность к совместному кодированию в рамках единой концепции(фреймворка).

Уважаемый, вы не поняли суть. Это не проверка умения быстро составлять "алгоритмы" (алгоритмы у fizzbuzz, серьезно?). Это своеобразный smoke test, чтобы отличить программиста (любого уровня) от человека, который умеет с умным видом говорить баззворды.


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

Я понятия не имею что такое «с умным видом говорить баззворды» :)

В общем, наверное я действительно не понял в чем суть сабжа.

Какой смысл человеку не умеющему писать программы устраиваться на работу программистом? *ритор.*
НЛО прилетело и опубликовало эту надпись здесь

Он-то считает, что умеет — отличные оценки в дипломе и работающий сайт на ВордПресс

Увы, почти 15 минут.
#include <iostream>
#include <future>
#include <chrono>
#include <thread>

using namespace std;

int main() {
        for (int i = 1; i <= 100; ++i) {
            async(launch::async, [=](){
                this_thread::sleep_for(chrono::milliseconds(50));
                if (i % 3 == 0) {
                    cout << "Miss";
                    if (i % 5 == 0) {
                        cout << "Kiss";
                    }
                } else {
                    if (i % 5 == 0) {
                        cout << "Kiss";
                    } else {
                        cout << i;
                    }
                }
                cout << endl;
            });
        }
    
        return 0;
}

А я вот на c++ с ходу не осилил :(
#!/usr/bin/env perl

use strict;
use threads;
use Time::HiRes qw( usleep );

sub out_tomorrow{
  my ($delay,$str)=@_;
  usleep($delay*50000);
  print $str;
  threads->detach();
}

for( my ($i,$c3,$c5)=(1,2,4); $i<=100; $i++, $c3--, $c5-- ){
  my $s = ( ( (!$c3) || (!$c5) ) ? '' : $i ) .
          ( $c3 ? '' : ($c3=3,"Fizz") ) .
          ( $c5 ? '' : ($c5=5,"Buzz") ) .
          "\n" ;
  threads->create( {'void' => 1}, \&out_tomorrow, $i, $s );
}
while( threads->list(threads::running) ){};
И хоть я уложился в менее 10 минут, я всё равно не могу считать себя программистом, т.к. программисты бывают разные, вот когда научусь писать математические задачи под цели NASA то да возможно, а так можно сказать необъективно все эти тесты, другими словами надо учитывать, что порог вхождения в программирование с каждым годом по факту усложняется, но и методы программирования упрощаются. Вообщем. Что хочу сказать, учиться, учиться и ещё раз учиться писать АЛГОРИТМЫ.

Большинству программисто особо сложные алгоритмы писать (составлять) на практике редко приходится — алгоритмы решения задач даются в ТЗ от аналитиков и прочих экспертов предметной области. Им (нам) остаётся их закодировать, алгоритмизируя в основном лишь технические вопросы, типа как обрабатывать фатальные ошибки, а не решения бизнес-задач.

Зато на собеседованиях любят эти глупости :)

20 минут без гугления =)

(function f(i, max){
    setTimeout(() => {
        console.log(
            i % 15 == 0 ? 'MissKiss' :
            i % 5 == 0  ? 'Kiss' :
            i % 3 == 0  ? 'Miss' :
            i
        );
        if (i + 1 <= max) f(i + 1, max);
    }, 50);
})(1, 100);
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь

Конечно же не нравится. Просили-то в одной...

НЛО прилетело и опубликовало эту надпись здесь
5 минут. Еще 5 на то, чтобы удостовериться, что правильно поняла условие задачи.
function missKiss(x) {
	if (x > 100) return;
	if (x % 15 === 0) console.log("MissKiss");
	else if (x % 3 === 0) console.log("Miss");
	else if (x % 5 === 0) console.log("Kiss");
	else console.log(x);
	setTimeout(fizzBuzz, 1000, x+1)
}
missKiss(1);
И в результате вы несправились с задачей

Хм. Сколько лет уже пишу на JS, но никогда бы не подумал, что сигнатура setTimeout включает в себя ...rest параметры, которые будут переданы в указанный метод. Полез гуглить ― и правда, оно так и работает. Но не все сайты с js-документацией об этом знают. Правда IE10+.

VM535:7 Uncaught ReferenceError: fizzBuzz is not defined

setTimeout(fizzBuzz, 1000, x+1) — вот здесь вы вызываете функцию fizzBuzz, которая у вас нигде не определена.

Да, писала с физзбазз, а для сайта переделала на мисскисс, и не везде заменила

Задача намеренно составлена так, чтобы было непонятно, нужно просто сделать 50мс задержку перед каждым вызовом console.log или нужно чтобы между вызовами прошло 50мс.


Я предположил второе и угадал, видимо в этом и был подвох. Но в реальной жизни я бы задавал уточняющие вопросы, конечно же.


Наколенное решение за пару минут
miss_kiss = function(i) {
  if(i % 3 == 0) {
    return 'Miss'
  }
  if(i % 5 == 0) {
    return 'Kiss'
  }
  if(i % 3 == 0 && i % 5 == 0) {
    return 'MissKiss'
  }
  return i.toString()
}

foo = function(i, limit) {
    if(i < limit) {
        setTimeout(function() {
        console.log(miss_kiss(i));
      foo(i + 1, limit);
    }, 50);
  }
}

foo(1, 101);

Each print must be an asynchronous call to the console.log function with a 50ms delay.

Помимо мутной формулировки, ещё и неграмотный английский дополнительно сбивает с толку.

И что тут неграмотного?

А разве не "call of the console.log function"?

"Почему программисты не могут программировать" — вот это скандал!!!!


Открываю стаью, только тут замечаю в тегах JavaScript....


Закрываю статью

НЛО прилетело и опубликовало эту надпись здесь
Синхронное решение и тратить на это 3 минуты больно много)
НЛО прилетело и опубликовало эту надпись здесь
В статье написано что это нужно сделать в асинхронных потоках

… а вы этого не сделали.

НЛО прилетело и опубликовало эту надпись здесь
В условии задачи результаты должны выводиться асинхронно с задержкой в 50мс между каждой строкой ответа. В вашем коде, указанном выше, вывод синхронный.
Не в асинхронных потоках, а асинхронный вызов. Допустим, это не JS, и мы делаем вывод в буферизованный канал. Т.е. сами вызовы — синхронные, но мгновенно возвращающиеся, плюс задержка.

Только вот в чем проблема: это js.

Ой-йой. Если посмотреть на комментарии, то можно внезапно обнаружить решения и обсуждение решений на множестве языков.
Соре за с++ просто я скрипт не знаю написал на 1 что попалось.Задача простая вот код, выводит все в консоль решил меньше 5 минут, использовал гугл для остатка от деления.Думаю на других языках не сложнее, принцип тот же
Код:

#include using namespace std;
main(void)
{
for(int i=1;i<=100;i++){
if(i%3==0 && i%5==0)
cout<<«MissKiss»<<endl;
else if(i%3==0)
cout<<«Miss»<<endl;
else if(i%5==0)
cout<<«Kiss»<<endl;
else cout<<i<<endl;
}
}
неужели с++ такой отвратительный на вид? Даже хуже obj-c?
неужели <любой яп> такой плохой

Вот эта фраза сразу показывает, что человек нифига не знает про ЯП :D
Не может быть ЯП отвратительным на вид. Его синтаксис может быть непонятным, но это дело только личного отношения, а точнее собственного чувства мнимого превосходства над кем-то...

Я не сказал ни слова про «превосходство». И я знаю что код на плюсах может выглядеть в разы лучше, чем этот. Мой коммент был направлен именно в эту сторону.

И да, синтаксис может быть отвратительным. Brainfuck тому явный пример. Или вы и тут будете утверждать, что это только мое личное отношение?

Brainfuck нормальный язык, всего его хайпят, хотя есть яп, которые вообще рвут шаблоны, а bf очень даже нормальный.
И всё же это ваше личное отношение. Не может быть яп плохой, каждый яп делается под свои цели, и только если он с ними не справляется, его можно считать отвратительными, Вы таких явно не знаете.

Я знаю один! Он должен был уметь простую арифметику и ветвления. Я так и не доделал его.

Кто должен? Вы о чём?

Вы таких явно не знаете.

Я знаю один!

Я так и не доделал его.

А… Ну окей, я то знаю доделанный, который точно будет выглядеть очень нехорошо.

3 минуты без гугления. В цикле считается строка output сразу, по таймауту console.log.bind(console, output).

Новичок. Ушло 30 минут. Многовато…
for (var i=1; i <= 100; i++){
    
    if (i%3 === 0 && i%5 === 0){
        setTimeout(function() {
            console.log("MissKiss");
        }, i * 50);
    } else if (i%3 === 0){
        setTimeout(function() {
            console.log("Miss");
        }, i * 50);
    } else if (i%5 === 0){
        setTimeout(function() {
            console.log("Kiss");
        }, i * 50);
    }
    
}
Интересный тест. Решил попробовать свои силы, хоть я и не программист, не веб-дизайнер и вообще, никак не связан с кодом и скриптами. Написал на php за 3 минуты 32 секунды.

$fizzbizz = array();
for($i=0;$i<101;$i+=3) $fizzbizz[$i] = 'Fizz';
for($i=0;$i<101;$i+=5) $fizzbizz[$i] .= 'Buzz';
for($i=0;$i<101;$i++) if(empty($fizzbizz[$i])) $fizzbizz[$i] = $i;

unset($fizzbizz[0]);
ksort($fizzbizz);
print '<PRE>';
print_r($fizzbizz)
print '</PRE>';


Правда, на отладку вывода ушло ещё 11 минут 18 секунд из-за простейшей опечатки и последующего перфекционизма. Итого 14 минут 50 секунд. Хуже, чем я думал, но всё же могу утешить Реджинальда и Инрама.

Скажете, код избыточно нагружает процессор? Зато программиста не нагружает :-)
" я и не программист" не нагружает, а программиста нагружает довольно сильно.
Где тут перфекционизм?

Или это такой тролинг?)
Перебирал различные варианты вывода массива. По коду этого, конечно, не видно.
Почитал доп.условие про асинхронность и задержку вывода. Думал-думал, но так и не понял, что значит «асинхронно».
Это значит что код отработал сейчас, а вывелось попозже. В данном случае в задаче попросили чтобы между выводом каждого из значений была задержка 50мс. Особая сложность возникает именно в языке JS, потому что там нет возможности сделать это синхронно, плюс там очень странные области видимости переменных =)

P.S. у вас в ответе выводятся лишние теги, из-за которых задача считалась бы решённой неверно.
P.P.S. Ваш код выводит ворнинги

Это для javascript термины.

Спасибо, понял.

На PHP можно писать асинхронно :)

Но если для js асинхронное программирование нужно каждому, то в PHP это уже продвинутый уровень.

Оно не нужно (в редких случаях нужно), просто нет альтернатив (может быть и можно через async/await что-то придумать, но это сложно понимается при разборе кода)

async/await является упрощением асинхронного программирования, а не заменой.


И принципиальное отсутствие альтернатив как раз и означает что его нужно знать всем.

Конечно. В нашем случае это
foreach ($fizzbizz as $fizz) {
    print $fizz;
    time_nanosleep (0, 50000);
}

Но выводить нужно в консоль, а не в html.
В свое время решал на собеседованиях, решил даже тесты запилить быстрой проверки чужих заданий: https://github.com/DarkScorpion/FizzBuzz
У меня на написание кода ушло примерно 60 минут, но так как я не «настоящий программист» то мне простительно.
П.С. Штатными методами 50 мс задержку сделать не получилось, только кратную 1 сек. Собственно поэтому и получилось так много времени на выполнение задания.

&НаКлиенте
Процедура FizzBuzz()
	Оповещение = Новый ОписаниеОповещения("ВывестиСообщение", ЭтотОбъект);
	Для ы = 1 По 100 Цикл
		Остаток3 = ы / 3 - Цел(ы / 3);
		Остаток5 = ы / 5 - Цел(ы / 5);
		Если Остаток3 = 0 и Остаток5 = 0 Тогда
			ТекстСообщения = "FizzBuzz";
		ИначеЕсли Остаток3 = 0 Тогда
			ТекстСообщения = "Fizz";
		ИначеЕсли Остаток5 = 0 Тогда
			ТекстСообщения = "Buzz";
		Иначе
			ТекстСообщения = Строка(ы);
		КонецЕсли;
		Оповещение = Новый ОписаниеОповещения("ВывестиСообщение", ЭтотОбъект, ТекстСообщения);
		ПоказатьПредупреждение(Оповещение, ТекстСообщения, 1);
	КонецЦикла;
КонецПроцедуры

&НаКлиенте
Процедура ВывестиСообщение(ТекстСообщения) Экспорт
	Сообщение = Новый СообщениеПользователю();
	Сообщение.Текст = ТекстСообщения;
	Сообщение.Сообщить();	
КонецПроцедуры


Вот мой вариант, за 3:22 сек:

function missKiss(from, to, delay) {
  if(from <= to) {
    setTimeout(function() {
      missKiss(from + 1, to);
      console.log([from % 3 ? '' : 'Miss', from % 5 ? '' : 'Kiss'].join('') || from);
    }, delay);
  }
}
missKiss(1, 100, 50);
Не очень «правильное» решение, но вместе с толпой выложу.
var i = 1;
var interval = setInterval($_$, 50);
function $_$(){
  var m = !(i%3), k = !(i%5);
  console.log(!m && !k? i : ( m ? "Miss" : '' ) + ( k ? "Kiss" : ''));
  if(++i > 100) clearInterval(interval);
}
название функции показывает энтузиазм работника по поводу зп?
Серьезно? Асинхронность достигается за счет тупо задержки? Бредятина, не?
Прочитал комментарии касательно предложенной в конце задачи — и ужаснулся.

Кто-то цепляется к погрешности в миллисекундах (если уж на то пошло, то абсолютной точности в принципе нельзя достичь из-за особенностей исполнения кода JS), другие предлагают для решения простой задачи перегруженный и усложненный код в стиле «вырвиглаз». Показательно в плане ответа на вопрос «Почему программисты не могут программировать».
Извините но такие сказки что программисты не могу программировать(199 из 200) меня задолбали.
Получается что только 0.5% могут писать код. Извините, но это же бред.
Откуда тогда столько приложений, сайтов у кучи людей свои проекты на Гитхабе?

Все это напиминает поиски мифического 10X программиста. Да еще чтоб хотел зарплату ниже рынка.

Вы бы пост прочитали сначала. Там объясняется откуда получается такая цифра.


А еще почитайте комментарии, тут много таких набралось.

Публикации

Истории