Комментарии 584
Я лично ненавижу задания на собеседовании, и этому несколько причин:
1. Я человек работающий, и как правило вырываюсь или на обеде, или вечером к 18. У меня нету лишних 4-х часов (или пары дней как в некоторых случаях).
2. Я не помню алгоритмы из головы (ну сортировку пузырьком конечно напишу :) ), а математику так и подавно (те вещи, которые по сложнее. Не лежит у меня к вышке).
Эти два пункта как правило то, из-за чего я просто не иду на некоторые собеседования, хотя по критериям подхожу на ура.
Прислать кусок кода если честно меня обычно тоже коробит. Просто потому, что ну пришлю я вам файл контроллера, или модели. И что? Половина там будет по стандартам фреймворка, вторая половина кастомного кода тоже в стиле фреймворка. Всё это будет завязано на события и хуки в связанных моделях и скорее всего толком ничего понятно не будет. А выслать вам целый модуль я не могу, потому что это чужой код и мне за него отвалили кучу бабла (мелочевкой я не занимаюсь, натягиванием сайтов на CMS тоже не занимаюсь).
Гораздо больше мне нравиться, когда просто спрашивают те или иные вещи и нужно просто дать ответы. Поинтересуются что я думаю по поводу тех или иных технологий, спросят о приведущих проектах, проблемах которые решал. Спросят пару базовых вещей по профилю. Всё это отвечается за 5-20 минут в зависимости от кол-ва вопросов и желания инвертирующего пообщаться по человечески. Последние 2 собеседования у меня выливались почти по часу, были очень интересные дискуссии и обмен опытом помимо стандартного интервью. Уходил с приятными ощущениями о работающих там людях и компании как таковой. Другое дело что не сложилось из-за некоторых обстоятельств (а на последнее место очень хотелось).
mov al, [dx]
xor al, 64
mov [dx], al
так? :) (15 лет на асме не писал и честно не гуглил синтаксис)
*ptr ^= 1 << 7;
Под «первым битом» всегда имелся ввиду самый наименее значимый бит. Аналогично первый байт, а не нулевой.
Но нумерация бит в байте, бит и байт в слове и в других многобайтовых объек-тах в различных вычислительных системах может быть различной.
www.kailib.ru/part2?start=3 — третий результат на момент написания коммента (страховка от сеошников :) ) по вашей ссылке
Вообще, всю жизнь воспринимал нормально как нумерацию битов (и байтов, и слов различной длины) как с нуля, так и с единицы (очень часто приходилось кодить параллельно на разных языках), но если по контексту не ясно, что нумерация конкретной сущности начинается с нуля, то всегда подразумевал нумерацию с единицы. Даже фраза «первый элемент массива имеет индекс ноль, а значит нулевой элемент равен первому» не вызывает диссонанса :D
По сути, это не значит, что это плохой программист, и его надо сразу прогонять. Просто именно в данных вопросах он неопытен, надо это помнить.
Лобовое решение вида:
#include <stdio.h>
int main (int argc, char **argv)
{
unsigned char *address = (unsigned char*)1234567;
unsigned char was = address[0];
printf("was %i\n",was);
unsigned char became;
if (was < 250){
became = was + 2;
}
else{
became = was - 2;
}
printf("became %i\n",became);
return 0;
}
не годится, это понятно: будет Segmentation Fault.
Кстати некоторые мудрые преподаватели сложных дисциплин разрешают пользоваться любыми материалами во время сдачи, т.к. в реальной жизни намного важнее умение быстро найти ответ, чем помнить его наизусть
Наконец-то я нашел человека, который пишет так же как я слышу!
PS только я тогда брал не деньгами (и нет не борзыми щенками), а дискетами. Так как дискеты от Verbatim часто дохли чуть ли не при первой попытке с них что-нибудь считать.
Странно, у меня вербатимки как на подбор были самыми качественными и долгоживущими, в отличие от остальных
Знаю некоторых вечерников-выпускников МИРЭА IT специальностей. Вопрос про шаблоны проектирования вешает мозг. :)
На втором курсе мой «заготовок для курсача по C++» купило 15 человек. Из них только шестеро додумались его хотя бы запустить на досуге, хотя я заранее говорил, что это полуфабрикат, который нужно будет самому доделать под себя. Остальные пришли с невинным лицом с день сдачи и обнаружили, что там в разделе About написано Made by Vasya Pupkin, чему препод был несказанно рад…
У меня сложилось мнение, что в России сколько человек пришло учиться, столько и будет выпущено с дипломами в итоге — главное хоть иногда появляться.
Я в свое время бросил НГТУ, специальность «Защита информации» (http://ciu.nstu.ru/kaf/zi) — работать нужно было. А мой одногруппник, успешно закончивший и получивший диплом инженера, недавно спросил меня, что такое SHA1. При этом он несколько лет работает в сфере webdev (правда, на ActionScript в основном, но не суть). Другие ребята, которые ушли от информатики дальше, боюсь, и того меньше знают. Печально это все.
А так как это была последняя капля то через некоторое время я из универа отчслился. 2 года армии (там итшники очень востребованы), а потом работаю по специальности. Админ, программер и т.д.
Но это всё равно армия с дисциплиной и идиотами )
Мне на 3-м или 4-м курсе (специальность 220100) поставили неуд на экзамене по «C++ и объектно-ориентированное программирование» за использование конструкции x?a:b; Препод сказал что такого вообще нет и это я сам всё придумал :-D
Что-то мне анекдот про крысу, хомяка и пиар вспомнился. :-)
Ни одному препаду не приходило в голову сомневаться в моих знаниях.
Правда приходилось преподам помогать понять почему не работают те или иные программки из задачника на паскале :)
А на самых модных факультетах вообще был бейсик :)
наверное 5 минут было по их мнению слишком долго:) А может им ваш почерк не понравился, прическа или еще что-нибудь в этом роде.
всего два условия на кратность, тут надо либо не знать про цикл for, либо не знать синтаксиса определения остатка/кратности какому-либо числу.
нет, неужели 199 из 200?
Даже здесь в комментах выложили нерабочие решения, что уж говорить…
а в дипломе всем напишут: «профессионал в области программирования»
1. Задача на минимальное программирование (чуть посложнее чем приведенные тут). Причем можно в превдо коде, а не на каком то языке
2. Технологческая задача — придумать как что то делать — без написания кода — например придумать свою сериализацию для какой то цели
Основная причина — люди не интересуются. Пишут свой кусочек, им код ревью не делают, их вся система, технологии, качество кода не интересует. И получаются люди с опытом в 3-5-7 лет пишущие ооочень плохо и ничего не знающие.
50% заваливаются на вопросе «опишите архитектуру продукта в котором вы работали последние Х лет»
for (n in 1..100) {
if (n%3 == 0 && n%5 != 0) println 'Fizz'
else if (n%5 == 0 && n%3 != 0) println 'Buzz' else
if (n%5 == 0 && n%3 == 0) println 'FizzBuzz' else
println n
}
fizzbuzz x | divides x 3 && divides x 5 = "FizzBuzz" | divides x 3 = "Fizz" | divides x 5 = "Buzz" | otherwise = show x where divides x n = x `mod` n == 0 main = mapM (putStrLn . fizzbuzz) [1..100]
— если кратно трем выведем Fizz
— если кратно пяти выведем Buzz
а если кратно и трем, и пяти — FizzBuzz получится само)
Можно конечно, но никто не может сказать, что этот вариант неправильный.
Он как раз видится мне тру-функциональным :)
Это лишь декларативное описание соответствия входных данных желаемым выходным не отражающее то, как оно будет вычисляться в реальности.
То есть в Хаскелле, конечно, можно присобачить эту императивщину и получить грязную функцию. Но это быдлокодинг и неуважение к такому языку.
мне вот надо писать максимально минимально, при этом чтобы задача была решена
o_O
«Спасибо, вы нам не подходите».
В тот момент, когда количество разработчиков проекта переваливает отметку «1», писать надо не «максимально минимально», а максимально понятно. Причём без понтов вида «на самом деле это понятно, а если кому-то непонятно, то он сам идиот, а я умный».
я с хаскеллом не знаком, может быть в двух словах скажете в чем выражается «императивность» языка?
В чисто функциональных языках принципиально по другому — программа описывается, как математическая функция.
императивное программирование — это когда вы описываете какие нужно выполнить действия и в каком порядке.
декларативное программирование — вы описываете что вы хотите получить задавая правила/формулы преобразования входных данных в выходные. Компилятор сам решает какие действия нужно выполнять и в каком порядке.
Почитайте все таки про Haskell — полезно для развития кругозора.
Вот благодаря своим оптимизациям вы бы и не попали туда на работу. ;)
Жаль, не могу добраться до того стада, которое бездумно плюсовало, не думая своей головой. ]:->
По плюсам сразу видно что тема актуальна )
perl -le '$_ % 3 ? $_ % 5 ? $_ : "Buzz" : $_ % 5 ? "Fizz" : "FizzBuzz" for 1 .. 100'
foreach my $i (1..100) {
unless($i % 3) {
print «Fizz»;
}
unless($i % 5) {
print «Buzz»;
}
if($i % 3 && $i % 5) {
print $i;
}
print "\n";
}
Если бы вы пришли ко мне на собеседование и написали решение в таком виде — вы бы не прошли :)
А может вы недостаточно глубоко смотрите?
>Кода в этой задаче маловато для того, чтобы оценивать его красоту.
Для того, чтобы оценить стиль кода — вполне достаточно. По крайней мере ваш стиль я уже «оценил» :)
foreach my $i (1..100) {
unless($i % 3) {
print «Fizz»;
}
unless($i % 5) {
print «Buzz»;
}
if($i % 3 && $i % 5) {
print $i;
}
print "\n";
}
Я вот, например, за unless руки отрываю :)
Посмотрите, например, Perl::Critic::Policy::ControlStructures::ProhibitUnlessBlocks.
Т.е. вместо if(!$a) пишу unless($a) или вместо if(!($a > 5)) пишу unless($a > 5).
perl -le 'print join "\n", map { ($_,«Fizz»,«Buzz»,«FizzBuzz»)[!($_%3)+2*!($_%5)] } 1..100'
На Ruby(не бейте больно, второй день трогаю — уверен, есть более лаконичный вариант)
def fizzbuzz
res=""
(1..100).to_a.each do |elem|
res+=«Fizz» if (elem%3).zero?
res+=«Buzz» if (elem%5).zero?
res+="#{elem}" unless ((elem%3).zero? or (elem%5).zero?);
res+=","
end
res
end
puts fizzbuzz
def fizzbuzz
res=""
(1..100).to_a.each do |elem|
res+="Fizz" if (elem%3).zero?
res+="Buzz" if (elem%5).zero?
res+="#{elem}" unless ((elem%3).zero? or (elem%5).zero?);
res+=","
end
res
end
puts fizzbuzz
res=""
100.times do |num|
elem = num+1
res+="#{elem}" unless ((elem%3).zero? or (elem%5).zero?)
res+="Fizz" if (elem%3).zero?
res+="Buzz" if (elem%5).zero?
res+=","
end
puts res
(1..100).map do |i|
puts i, [
(i % 3).zero? ? "Fizz" : nil,
(i % 5).zero? ? "Buzz" : nil
].compact.join
end.compact
Можно и еще более извращенными способами.
(1..100).each do |i|
puts i, [
(i % 3).zero? ? "Fizz" : nil,
(i % 5).zero? ? "Buzz" : nil
].compact.join
end
100.times do |i|
num=i+1
[ (num % 3).zero? ? "Fizz" : nil,
(num % 5).zero? ? "Buzz" : nil
].compact.join.display
num.display unless (num % 3).zero? or (num % 5).zero?
puts
end
(1..100).each do |i|
puts (a = [
(i % 3).zero? ? "Fizz" : nil,
(i % 5).zero? ? "Buzz" : nil
].compact.join).empty? ? i : a
end
100.times, в вашем случае, начнет отсчет с нуля и закончит на 99.
puts (1..100).map { |i| (a = [(i % 3).zero? ? "Fizz" : nil, (i % 5).zero? ? "Buzz" : nil].compact.join).empty? ? i : a }
1.upto(100){|i|s=i%3==0?'fizz': '';s+='buzz'if i%5==0;puts s==''?i: s}
100.times do |i|
num=i+1
[ (num % 3).zero? ? "Fizz" : nil,
(num % 5).zero? ? "Buzz" : nil,
((num % 3).zero? or (num % 5).zero?) ? nil : num,
","
].compact.join.display
end
(1..100).each do |i|
puts (s = "#{"Fizz" if (i % 3).zero?}#{"Buzz" if (i % 5).zero?}").empty? ? i : s
end
Если вы просто подсказали человеку, на каком языке этот тред, не имея в виду, что он мог сам посмотреть исходники, приношу свои искренние извинения.
for (1..100)
{
print ( (!($_%3) && !($_%5))?'FizzBuzz':(!($_%3)?'Fizz':(!($_%5)?'Buzz':$_)) );
}
Если бы меня не приняли из-за этого на работу, то я был бы только рад: нахер нужна ТАКАЯ работа?!
print [$_,"Fizz","Buzz","FizzBuzz"]->[!($_%3)+!($_%5)*2]."\n" foreach(1..100)
(Перл, на других языках аналогично)
Просто подумал что описанный вами подход вы считаете правильным (исходя из слова «нужно» в каменте), если это была ирония, гиперболизирующая ответ предыдущего комментатора — прошу прощения, не уловил.
for (int i = 0; i < 100; i++) {
bool byThree = (!(i % 3));
bool byFive = (!(i % 6));
if (byThree) std::cout << "Fizz";
if (byFive) std::cout << "Buzz";
if (!byThree && !byFive) std::cout << i;
std::cout << std::endl;
}
for ($i = 0; $i < 100; $i++) {
if ($i % 5 == 0 && $i % 3 == 0) print «FizzBuzz».PHP_EOL;
elseif ($i % 5 == 0) print «Buzz».PHP_EOL;
elseif ($i % 3 == 0) print «Fizz».PHP_EOL;
else print $i.PHP_EOL;
}
В Вашем варианте отдельное условие для вывода FizzBuzz необосновано.
for ($i = 1; $i <= 30; $i++)
{
if (($i % 3 != 0) AND ($i % 5 != 0)) echo $i;
else
{
if ($i % 3 == 0) echo 'Fizz';
if ($i % 5 == 0) echo 'Buzz';
}
echo '
';
}
А в начале 30 вместо 100 — это у меня экран на ноуте маленький, на 100 записях скролл появится...))
for($i = 1; $i <= 100; $i++) {
echo ((($s = (($i%3 == 0) ? 'Fizz' : '') . (($i%5 == 0) ? 'Buzz' : '')) == '') ? $i : $s) . '<br />';
}
//////// пост ////
Console.WriteLine(
string.Join(
Environment.NewLine,
Enumerable.Range(1, 100)
.Select(num =>
num % 5 == 0 && num % 3 == 0 ? "FizzBuzz" :
num % 3 == 0 ? "Fizz" :
num % 5 == 0 ? "Buzz" :
Convert.ToString(num)
)
)
);
let divs = [(3, "Fizz"); (5, "Buzz")]
let prefix i =
divs
|> Seq.filter (fun (d, _) -> (i % d) = 0)
|> Seq.map snd
|> String.concat ""
let convert i =
let special = prefix i
if special = "" then
string i
else
special
{1..100}
|> Seq.map convert
|> Seq.iter (fun x -> printfn "%A" x)
не говоря уже о недостатках логики, которая закладывается ещё в школе
Структуру красно-черного дерева в коде напишет 5-10%.
Алгоритм построения суффиксного дерева, который тут недавно постили — напишет по памяти думаю 0.001 процент.
Знаю по опыту, проводил собеседования.
Хотя для собственного общего развития тема интересная. Могу посоветовать почитать отличную книгу Кормена о деревьях и не только.
Ну и если очень грубо — хороший джуниор должен удовлетворять первому уровню Programmer Competency Matrix.
Придется читать PDF.
ИМХО, алгоритмами нужно именно заниматься, что бы быть в состоянии их написать с ходу по памяти. А когда оно тебе надо раз в 2 года — согласитесь, без гугла или документации/книги по алгоритмам нереально :)
Главное уметь найти и быстро вспомнить! :)
Если только это не какой нибудь Google/ MS Research :)
Никаких задач «на сообразительность» там не было.
Задачи, конечно, сложней, чем этот FizzBuzz, но без красно-черных деревьев.
По уровню сложности типа написания двоичной сортировки, но более практичные — т.е. не надо писать функции, которые есть в стандартных библиотеках.
Но конкретно в этих случаях можно придумать ответ самому довольно быстро, даже если не знать наперед. Вся необходимая информация давалась.
Этого и знания С в рамках любого учебника вполне достаточно, чтобы этот код написать, времени тоже давалось достаточно.
print ['fizz','',''][i%3] + ['buzz','','','',''][i%5] or i
print' '.join(''.join(['fizz']*(1-x%3)+['buzz']*(1-x%5)or str(x))
for x in range(1,100))
print ' '.join([(not i%3)*'Fizz'+(not i%5)*'Buzz' or str(i) for i in range(1,101)])
За декабрь просмотрел тестовые задания (написание калькулятора, вычисляющего расстояния между парами городов, с веб-интерфейсом) 3-4 кандидатов, после чего предполагалось что их будут собеседовать «вживую». К сожалению, ни один не дошел до этого собеседования :(
Я добавлю еще от себя один момент. Ощущение, что многие люди в подробном тестовом задании на 2/3 страницы читают только первый абзац (или первые два). Т.е. в их работе нет ни следа того, что в задании указано как обязательный компонент.
Если будет интерес, могу потом написать топик на тему, какие ошибки и антипаттерны встречал чаще всего в тестовом задании на знание Java / J2EE / MySQL.
Время вышло.
Нечго таким людям в программировании делать.
А где, собственно, ответ на вопрос «почему?» :)
Поверьте, если вы можете написать цикл от 1 до 10 на всех языках, указанных в вашем резюме, если вы можете решить в уме несложный арифметический пример и если вы знаете, как применить рекурсию в несложной (но взятой из реальной жизни) задаче — то вы уже на голову выше большей части людей, вращающихся в нашей индустрии.
Хм, честно говоря, даже умея спокойно решить такие задачки, я не считаю себя программистом. Такие базовые знания алгоритмов, имхо, необходимы сейчас практически в любой области ИТ. Все таки в моем понимании программист — это человек глубоко знающий алгоритмы, математику, парадигмы и паттерны программирования.
Сделать кольцевой сдвиг строки из M символов на N позиций, при этом используя минимальное количество памяти и минимальное количество операций чтения/записи из строки.
public class Main {
static private long NOD(long n1, long n2) {
if (n2 == 0)
return n1;
return NOD(n2, n1 % n2);
}
static private void shr(char[] arr, int N) {
for (int i = 0; i < NOD(arr.length, N); i++) {
int j = i;
char saved = arr[j];
do {
j = (j + N) % arr.length;
char nextVal = arr[j];
arr[j] = saved;
saved = nextVal;
} while (i != j);
}
}
public static void main(String[] args) {
char[] test = {'e', '2', 'i', '/', 'o', 'e', 'u', 'i', '/', 'o'};
shr(test, 2);
System.out.println(test);
}
}
Длина массива
N
i
j
saved
nextVal
Итого — 7.
Вообще на практике — не вижу особого смысла оценивать требования к памяти побайтно, обычно достаточно оценок «линейно», «квадратично», «константно», большой множитель зачастую скрывает в себе косвенную зависимость на непосредственно размер данных или другие характеристики, связанные с входными данными (как в radix сортировке).
Наймешь такого, а потом внезапно у тебя куча очень быстрого кода в одной функции на 2000000 строк, а разработчика сбил автобус)
А одним тестом нельзя измерить всех параметров, так что на стиль кодирование и умение проектировать нужны свои тесты.
P.S. Список заканчивается кольцом, если последний элемент списка указывает на один из элементов в середине списка.
Решение 2 — Можно пройти кареткой K=N, запомнить адрес останова, пройти K=2N, запомнить адрес останова (в той же переменной), потом K=4N K=8N и т.д. Тогда если список закольцован, как только мы попадем в кольцо и K будет равно длине кольца — мы обнаружим совпадение.
Сложность зависит от длины списка n линейно, т.к. когда мы дойдем до конца списка (+ максимум n-1 сверху) следующий K будет больше списка. Т.о. сделаем меньше 4n операций, что укладывается в линейные ограничения. Используем 1 ячейку памяти.
У меня 2 вопроса:
а) что такое N?
б) что если K никогда не будет равно длине кольца (скажем, кольцо длины 11)?
N — начальный «шаг», можно взять равным 1 для простоты
Для К конечно же «больше или равно».
И тогда уж исправлюсь с максимальной сложностью, она равна 3n.
Как работает:
Представим что у нас список длины n, n+1 вершина — это уже середина списка, т.е. кольцо.
Будем двигаться по указанной схеме, на каждом шаге запоминая вершину, в которой мы находимся
Возьмём тот шаг, когда мы ещё не прошли n вершин в сумме, но на следующем шаге пройдем, следовательно — попадем в кольцо.
Возьмем худший случай «оверхеда», предположим что на предыдущем шаге мы находились на самой последней вершине и (т.к. следующий шаг равен сумме всех предыдущих + 1) сделаем таким образом n+1 лишних переходов по списку.
Затем запоминаем текущее положение и делаем следующий «проход», т.к. он будет очевидно больше размера списка (т.к. мы уже прошли список, а каждый следующих ход больше всех предыдущих), то он и больше размера кольца
А раз ход больше размера кольца — то мы на нем то и наткнемся на нашу «помеченную» вершину. В данном случае худший вариант — если список закольцован на начало, тогда мы должны будем пройти весь список (n переходов), до того, как можем констатировать закольцованность.
Таким образом худший случай — 3n+1 операций чтения. Лучший случай — n операций чтения, когда при первом прохождении списка мы попадаем с последней вершины сразу на помеченную.
Хотя при использовании высокоуровневых классов/библиотек тоже нужно думать и хорошо понимать, что происходит у них внутри. Вот, буквально час назад попался шедевр (Java):
public void setResults(long[] uids) {
if (uids != null) {
int length = uids.length;
if (length > 0) {
User user;
User[] users = new User[0];
for (int i = 0; i < length; i++) {
user = UserStorageAccessor.getUser(uids[i]);
Arrays.add(users, user);
}
setResults(users, true);
}
}
}
вместо простого
public void setResults(long[] uids) {
if (uids != null) {
int length = uids.length;
if (length > 0) {
User[] users = new User[length];
for (int i = 0; i < length; i++) {
users[i] = UserStorageAccessor.getUser(uids[i]);
}
setResults(users, true);
}
}
}
Что происходит внутри Arrays.add(...) — догадываетесь? :)
Из Arrays.add() ведь нельзя изменить ссылку )
for (int i = 0; i < length; i++) {
User user = UserStorageAccessor.getUser(uids[i]);
Arrays.add(users, user);
}
if (uids != null && uids.length > 0) {...}
:)
Решение 2 сработает :-)
А если кто-то написал код, работающий с начинкой списка напрямую — то советую в первую очередь оторвать ему руки, и только потом садиться решать подобные задачи.
Если кто-то написал код, работающий с начинкой списка напрямую — то советую в первую очередь оторвать ему руки, и только потом садиться решать подобные задачи
Это очень хороший ответ, за него я поставлю мысленный плюс и скажу примерно следующее: «Да, действительно, это плохая практика, поэтому давайте мысленно перенесёмся в тот момент, когда руки автору уже оторвали, и теперь нужно решить задачу, когда у вас есть „сырой“ список, где каждый элемент содержит своё значение и указатель на следующий элемент. Исходные данные — указатель на головной элемент списка».
А решить всё-таки при наличии времени я бы посоветовал введением уровня абстракции целостного списка.
Способность более-менее алгоритмически формулировать свои мысли замечательно проверяют простенькие примеры с одним циклом и одним условием, за минуту и вне зависимости от специализации. Если ищется реально спец, то и вопросы к нему реально специальные, да и находятся они обычно адресно.
Абсолютно согласен по поводу тестовых заданий, но вот что мне не очень понятно, так это зачем нужно просить прислать образец кода. Что по этому образцу можно понять кроме стиля (отступов, фигурных скобок и т.д.)?
Так что мне действительно интересно что люди хотят увидеть в образцах кода присланных даже до телефонного собеседования. Намой взгля кроме стиля форматирования там ничего увидеть нельзя.
— пользуется ли собеседуемый каким-либо распространенным стилем кодирования;
— умеет ли более-менее сносно проводить декомпозицию;
Если посмотреть пару-тройку функций длиной в полэкрана, можно еще и понять предпочтения по проверке пред-условий, использование вложенных конструкций или вынос в метод, и т.д.
В общем, по коду можно понять, хороший это код или плохой.
— хороший программист пользуется тем стилем кодирования, который принят у него в фирме
— вы не сможете определить умеет ли он сносно проводить декомпозицию пока не проанализируете его код, что весьма сложно сделать не зная решаемой задачи, а кроме того, анализ подобного кода в данном ключе сводит на нет все преимущества получения этого кода до интервью.
Так что просить у соискателя код до интервью, врядли это хорошая практика.
Но за ответ спасибо, вы мне открыли глаза на логику которой пользуются когда практикуют подобную шему при принятии на работу.
Естественно, не гарантируют. Всё равно придётся на собеседовании выяснять, что он из себя представляет. Образцы кода, тестовые задания (когда их программист удалённо делает) — это быстрый отсев программистов от непрограммистов. И требовать трудозатрат от соискателя ещё до того, как обязался платить ему зарплату, я считаю некорректным. Вы для соискателя не один такой. Если каждый будет просить потратить часок времени, это создаст много неудобств кандидату.
Оный вполне может подойти в качестве примера.
Похожая ситуация с языком на среднее владение которым я претендую в резюме: для себя писал только прототипы, которые сам увидев на продакшене назвал бы «быдлокодом» ещё 10 лет назад (пускай такого термина и не было тогда) — никакой проверки пользовательских данных, никакой проверки на результаты операций с внешними сервисами типа БД или чужих сайтов, про архитектуру или хайлоад вообще молчу, мне были интересны либо практическая возможность реализации моих идей, либо привлечение инвестиций (то, что с некоторых пор в рунете стал модно называть «стартап»). Всегда подразумевалось, что в конечной реализации останется, максимум, то, что я сейчас называю «сценарии пользования». Всегда подразумевался корректный ввод и ожидаемая по типичному сценарию реакция (вплоть до того, что запрос к БД не может не вернуть хотя бы одну запись, а запрос к чужому сайту что-то отличное от того, что я вижу в браузере, заходя как реальный пользователь).
Что мне слать в качестве образца кода — то, что я сам считаю быдлокодом не только теперь, но и на момент написания?
fizzBuzz(100).
fizzBuzz(N) :-
I3 is N mod 3,
I5 is N mod 5,
print( I3, I5, N ), nl,
N2 is N + 1,
fizzBuzz(N2).
print( 0, 0, _ ) :-
write( 'FizzBuzz' ).
print( 0, _, _ ) :-
write( 'Fizz' ).
print( _, 0, _ ) :-
write( 'Buzz' ).
print( _, _, N ) :-
write(N).
Запускать: fizzBuzz(1).
fizzlist(0, [], M).
fizzlist(N, [H|T], M) :- N > 0, N1 is N - 1, M1 is M - N + 1, fizzbuzz(M1, H), fizzlist(N1, T, M).
fizzlist(N, L) :- fizzlist(N, L, N).
fizzbuzz(N, N) :- N mod 3 > 0, N mod 5 > 0.
fizzbuzz(N, 'Fizz') :- 0 is N mod 3, N mod 5 > 0.
fizzbuzz(N, 'Buzz') :- 0 is N mod 5, N mod 3 > 0.
fizzbuzz(N, 'FizzBuzz') :- 0 is N mod 3, 0 is N mod 5.
Соответственно,
?- fizzlist(100, L).
fizzBuzz(100, []).
fizzBuzz(N, [H|T]) :-
I3 is N mod 3,
I5 is N mod 5,
val( I3, I5, N, H ),
N2 is N + 1,
fizzBuzz(N2, T).
val( 0, 0, _, 'FizzBuzz' ).
val( 0, _, _, 'Fizz' ).
val( _, 0, _, 'Buzz' ).
val( _, _, N, N ).
? fizzBuzz(1, L).
:- module fizzbuzz.
:- interface.
:- import_module io.
:- pred main(io, io).
:- mode main(di, uo) is det.
:- implementation.
:- import_module int.
main --> fizzbuzz(1).
fizzbuzz(N) -->
( {N =< 100} ->
print_fizzbuzz(N),
print(" "),
fizzbuzz(N + 1)
; []
).
print_fizzbuzz(N) -->
( {N mod 3 = 0} ->
( {N mod 5 = 0} ->
print("fizzbuzz")
; print("fizz")
)
; {N mod 5 = 0} ->
print("buzz")
; print(N)
).
D:\TEST\mercury>mercury --infer-all fizzbuzz.m
fizzbuzz.m:016: Inferred :- pred fizzbuzz(int, io.state, io.state).
fizzbuzz.m:016: Inferred :- mode fizzbuzz(di, di, uo) is det.
fizzbuzz.m:024: Inferred :- pred print_fizzbuzz(int, io.state, io.state).
fizzbuzz.m:024: Inferred :- mode print_fizzbuzz(in, di, uo) is det.
D:\TEST\mercury>fizzbuzz.exe
1 2 fizz 4 buzz fizz 7 8 fizz buzz 11 fizz 13 14 fizzbuzz 16 17 fizz 19 buzz fiz
z 22 23 fizz buzz 26 fizz 28 29 fizzbuzz 31 32 fizz 34 buzz fizz 37 38 fizz buzz
41 fizz 43 44 fizzbuzz 46 47 fizz 49 buzz fizz 52 53 fizz buzz 56 fizz 58 59 fi
zzbuzz 61 62 fizz 64 buzz fizz 67 68 fizz buzz 71 fizz 73 74 fizzbuzz 76 77 fizz
79 buzz fizz 82 83 fizz buzz 86 fizz 88 89 fizzbuzz 91 92 fizz 94 buzz fizz 97
98 fizz buzz
1) Это внутренности той платформы, с которой человек проработал 3-5-7 лет. Вызвано тем, что нет мотивации и интереса копаться, или тем, что человек не сталкивался с сложными багами, проблемами при high-load, инфраструктурными задачами.
Например, (примеры из мира Java) мало кто внятно рассказывает следующее:
— Класслоадеры
— Сборка мусора подробнее, чем «это отслеживание мертвых ссылок и очистка памяти». Алгоритмы, generation-based подход.
— hot-swop кода
— чуть-чуть про архитектуру JVM и как она вообще работает (байткод, стековая машина, фреймы, стек операндов, пул констант и прочее)
— Некоторые ключи запуска JVM, из популярных (для управления памятью, например)
— из каких компонентов состоит сервер приложений? Тот, который использовал в своем резюме соискатель. Какие фичи появились в его последнем крупном релизе?
2) Язык / стандартная библиотека в тех частях, которые не используются в простом коде и простых проектах, и которые не описаны в некоторые книгах типа «Освой за 21 день».
Пример из Java:
— что такое soft / weak / phantom references?
— аннотации и их процессинг
— generics (вот это вообще kill-question)
— что такое неблокируюший (lock-free, wait-free) ввод-вывод?
— и т.д.
3) Инструменты, используемые в проектах и инфраструктура. Системы контроля версий, Ant, Maven, Continuous Integration серверы, скриптинг (простейший!) для Windows CMD / unix bash, профайлеры, инструменты для мониторинга и прочее.
— Что такое распределенная / централизованная система контроля версий?
— Что такое бранчевание, как сделать бранч / бекмерж в той системе, про которую вы написали, что вы с — ней работали?
— Что такое трехстороннее разрешение конфликта при коммите?
— Что такое антовский таск, таджет. Можете ли вы написать собственный таск, который делает что-то примитивное.
— Что такое управление зависимостями, что такое артефакт, репозиторий.
— Какие CI серверы их использовали? Если человек пишет про них в резюме, спросить про них.
— Пользовались ли вы когда-либо профайлером (каким?), какие результаты вы получали? Попросить рассказать об этом.
С PHP та же ситуация. Только у нас вообще наверно 99.99% смотрят на тебя огромными лемурными глазами, когда начинаешь спрашивать особенности работы. Про внутренности я вообще молчу.
Вопрос 2^7 вообще повергает народ в шок, а должно от зубов автоматом отскакивать :)
Навскидку для меня особенности ООП в PHP — нет перегрузки методов по сигнатуре и нет переопределения операторов. Ну и нет множественного наследования, не так давно это частично компенсировано интерфейсами, равно как и появились абстрактные классы/методы (в php4 их, кажется, не было). Наконец-то появилось позднее связывание. Какие ещё там особенности?
В этот раз пример из мира БД и оракла.
Если человек сдал на 5 курс по разработке БД, и прочитал книжку о программировании под оракл, и пишет в резюме «Имею опыт работы с оракл, разработка схемы бд, написание стандартных запросов» — очень хорошо.
Если человек сдал на 5 курс по разработке БД, и прочитал книжку о программировании под оракл, и пишет в резюме — «знаю оракл, или владею ораклом» — плохо. Он не понимает, что его знания — это 0.1 процент того, что в оракле есть. завышенное ЧСВ.
Если человек пишет в резюме, что был ведущим Oracle-разработчиком / главным админом в проекте для крупного банка / какой то иной нагруженной и сложной системы, и пишет об этом факте — хорошо. Но это он должен подтвердить. Сертификатами и / или на собеседовании.
Знакомый техлид рассказывал об одном случае, пришедший «ораклоид» в возрасте 40 лет, с указанным опытом работы с ораклом 5 лет, на собеседовании не смог написать умеренно-сложный запрос с having.
Вообще, по моему скромному мнению, лучше для каждой технологии, перечисленной в резюме добавлять пару слов — что конкретно на этой технологии делали и в какой роли. Например:
Visual Basic — разработал архитектуру CRM для компании в 300 человек, потом реализовали проект коллективом в 5 человек;
Oracle — лабы в институте.
Это куда информативнее, чем просто Oracle, VB. Если написать «Oracle, VB», вас пригласят на собеседования по Ораклу, где вы провалитесь. А если распишете подробно, то даже пусть там VB, который никому нахрен не нужен, вас запросто могут взять. Очередной императивный язык выучить — дело нехитрое, а умение проектировать большие коммерческие системы на дороге не валяется. Мне вот нужны перловые программисты, но если написать в требованиях «Perl», соискателей мало. А если не писать, а приглашать всех, то оказывается, что хороших программистов в разы больше, а Perl изучается по ходу дела на ура. И если у соискателя будет много-много всего перечислено в резюме с пометкой «just for fun», он 100% легко разберётся с любой незнакомой ему технологией.
Поэтому, к сожалению, хорошие ответы на такие вопросы тоже не всегда показатель — разве что того, что человек к собеседованию готовился.
window.onload = function () {
for (var i = 1; i < 101; i++) {
document.write(((q=((0==i%3?'fizz':'')+(0==i%5?'buzz':'')))?q:i)+'<br>');
}
};
<source lang=«javascript»>ваш код</source> дал бы
window.onload = function () {
for (var i = 1; i < 101; i++) {
document.write(((q=((0==i%3?'fizz':'')+(0==i%5?'buzz':'')))?q:i+'<br>'));
}
};
Это больше риторический вопрос… Тем ленивцам, которым поставить минус не влом, а написать почему — влом.
Об этом было написано где-нибудь в справке? Когда нужно было — не нашёл.
1. Придумать алгоритм отрисовки «прямой» линии, соединяющей 2 точки на растре.
1.1. Для тех кто вспоминал про тангенс объяснялось что это как минимум медленно и предлагалось отказатся о тригонометрии.
2. Даны одномерные координаты N отрезков на прямой. Придумать алгоритм нахождения количества наложений отрезков и оценить его сложность.
Не вижу смысла иметь дело с людьми не способных попытаться решить подобные задачи. Многие даже не пытались. Так и говорили, что не могу, пробовать не буду.
Только после этого шёл разговор о технологиях и высоких материях.
Но вы правы, предлагалось отказатся от плавающей точки и предложить реализацию в целых числах.
И что касается целочисленного алгоритма то знание конкретного алгоритма (Брезенхемом) не важно, важно начать думать и предлагать идеи.
важно начать думать и предлагать идеи
Это умение, по моему мнению, более значительный показатель, чем безоговорочное знание каких-либо, пусть даже некоторых базовых понятий. Конечно с оговоркой, что кандидат не абсолютный ноль в обсуждаемой области.
Мне нравится бывать на собеседованиях, где ставят подобные задачи и начинают обсуждать и расширять с тобой предлагаемую реализацию, в отличие от тех, которые проходят в виде анкетирования: вопрос из бумажки — ответ — галочка и молчаливое укоризненное покачивание головой: не угадал.
foreach (range(1,100) as $i)
{
if(!($i%3)) echo "Fizz";
if(!($i%5)) echo "Buzz";
if(($i%3)&&($i%5)) echo $i;
echo "<br />";
}
for ($n=1;$n
Так тож вариант, работает.
imm.io/38IJ
(1..100).each do |i| bf = ((i.to_f % 3).zero? ? 'Buzz':'') + ((i.to_f % 5).zero? ? 'Fuzz':'') puts bf.empty? ? i:bf end
Я бы на собеседовании скорее спросил «как работает».
А ещё лучше конкретную задачу, где это используется.
«ничего сверхсложного, просто небольшое упражнение на час-полтора» — просто шедевр.
Если упражнение небольшое, то почему оно должно занимать полтора часа — слабо придумать упражнение на 10 минут?
Извините, но если человек не в состоянии за полчаса определить уровень соискателя, значит, он сам недостотачно профессионален для проведения интервью и нефиг ему давать «мариновать» людей часами.
Алгоритмическую задачу на полтора часа я даже боюсь представить:)
Я решил показать себя с лучшей, имхо (сформированного в частности чтением статей и комментов на хабре о поддержке кода, внесении новых требований и т. п.), стороны, написал за 3 часа чуть-ли не фреймворк по обработке форм: я бы без костылей вписал к нему любое изменение формы в рамках одного «экрана», фиксированного набора полей, модели РСУБД со связми 1-1 и 1-М (при условии, что вводится сущность на первой стороне и, при необходимости, на второй) и валидации по регуляркам и целостности БД.
Отказ по причине: «слишком много написали, а значит долго это писали, код во многом излишен»
Наверно написавших такой код зовут истинными программистами, но я бы таких не взял. Такой код будет гораздо сложнее отлаживать, ибо правильное течение программы предполагает магию в своей работе.
У нас есть три четких требования. В нормальном варианте все три требования будут отражены в коде. Если их нет — более сложна система спрограммированная таким вот программером будет опираться на магические штуки, известные только самому разработчику. Думаю, много кому тут ясно, что эта за система будет в итоге.
echo '1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14
FizzBuzz 16 17 Fizz 19 Buzz Fizz 22 23 Fizz Buzz 26 Fizz 28 29
FizzBuzz 31 32 Fizz 34 Buzz Fizz 37 38 Fizz Buzz 41 Fizz 43 44
FizzBuzz 46 47 Fizz 49 Buzz Fizz 52 53 Fizz Buzz 56 Fizz 58 59
FizzBuzz 61 62 Fizz 64 Buzz Fizz 67 68 Fizz Buzz 71 Fizz 73 74
FizzBuzz 76 77 Fizz 79 Buzz Fizz 82 83 Fizz Buzz 86 Fizz 88 89
FizzBuzz 91 92 Fizz 94 Buzz Fizz 97 98 Fizz Buzz ';
echo str_replace(array('f','b','!'),
array('Fizz ','Buzz ','FizzBuzz '),
'1 2 f4 bf7 8 fb11 f13 14
!16 17 f19 bf22 23 fb26 f28 29
!31 32 f34 bf37 38 fb41 f43 44
!46 47 f49 bf52 53 fb56 f58 59
!61 62 f64 bf67 68 fb71 f73 74
!76 77 f79 bf82 83 fb86 f88 89
!91 92 f94 bf97 98 fb ';
{
null, null, «Fiz», null, «Buzz», «Fiz», null, null, «Fiz», «Buzz», null, «Fiz», null,
null, «FizBuzz»
};
for (int i = 1; i < 101; ++i)
{
Console.Write((ss[(i — 1) % 15] ?? i.ToString()) + " ");
}
static void Main(string[] args)
{
for (int i = 1; i <= 100; i++)
{
string symbol = i.ToString();
if (i % 3 == 0)
symbol = "Fizz";
if (i % 5 == 0)
symbol = "Buzz";
if ((i % 3 + i % 5) == 0)
symbol = "FizzBuzz";
Console.WriteLine(symbol);
}
}
string symbol; /* можно вынести из цикла, можно в for объявить */
if ((i % 3 ==0) && (i % 5 == 0))
symbol = "FizzBuzz";
else if (i % 3 == 0)
symbol = "Fizz";
else if (i % 5 == 0)
symbol = "Buzz";
else
symbol = i.ToString();
Console.WriteLine(symbol);
если условие выполняется, то остальные не проверяются, лишних присваиваний нет, если число выводить не нужно, то преобразования не происходит, невнятная операция сложения остатков заменена на обычную логическую. да и визулаьно понятно, что условия взаимоисключающие
А я хотел без «if-else» написать. Правда можно провалиться в какое-нибудь лишнее присваивание, будь условие задачи посложнее.
string symbol = ""; /* можно в for */
if (i % 3 ==0))
symbol = "Fizz";
if (i % 5 == 0)
symbol += "Buzz"; /* не помню, можно ли так, но смысл понятен надеюсь */
if (symbol == "")
symbol = i.ToString();
#!/bin/bash
for i in `seq 1 100`
do
if [ `expr $i % 3` = 0 ] && [ `expr $i % 5` = 0 ]; then
echo FizzBuzz
elif [ `expr $i % 3` = 0 ]; then
echo Fizz
elif [ `expr $i % 5` = 0 ]; then
echo Buzz
else
echo $i
fi
done
:)
#!/usr/local/bin/bash
for i in $(seq 100); do
array[${i}]=${i};
done
i=3
while [ $i -le 101 ]
do
array[${i}]="Fizz"
i=$(( $i + 3 ))
done
i=5
while [ $i -le 101 ]
do
array[${i}]="Buzz"
i=$(( $i + 5 ))
done
i=15
while [ $i -le 101 ]
do
array[${i}]="FizzBuzz"
i=$(( $i + 15 ))
done
echo ${array[*]}
for i in {1..100}
do
([ `expr $i % 3` == "0" ] && [ `expr $i % 5` == "0" ] && echo "FizzBuzz") ||
([ `expr $i % 3` == "0" ] && echo "Fizz") ||
([ `expr $i % 5` == "0" ] && echo "Buzz") || echo $i
done
Pascal:
for i := 1 to 100 do
if i mod 3 = 0 then
if i mod 5 <> 0 then
print('Fizz')
else
print('FizzBuzz')
else
if i mod 5 <> 0 then
print(i)
else
print('Buzz');
Я (и думаю меня многие поддержат) совершенно не доверяю программистам, делающим такие оптимизации, оптимизации могут быть только на уровне архитектуру и не в ущерб понятности системы.
Это уж если после профилирования приложения выяснится что ваш код — слабое место, тогда и надо переписать.
В embedded программировании или консолях — есть жесткие требования по производительности.
Не влезаем во фрейм — задача не решена. На понятность системы можно насрать, так как код обновляется довольно часто.
Нужна 100-строковая простыня на SIMD интринсиках вместо 10 строчек тормозного С-кода — она там будет без вопросов. Комплятор (gcc) не умеет вообще ничего, даже элементарщины. Векторизовать простейший цикл и применить modulo sheduling тем более. Я уже не говорю о распараллеливании какой-нить сложной обработки данных.
правильно, посему ваш совет
«оптимизации могут быть только на уровне архитектуру и не в ущерб понятности системы» не корректнен если не известна предметная область
Согласно вашей логике, ваш собственный предыдущий комментарий некорректен, т.к.
В embedded программировании или консолях — есть жесткие требования по производительности.Верно не для 100% embedded задач, бывает что и железка достаточно мощная, да и много можно придумать вариантов, когда понятность системы ставится гораздо выше производительности.
На понятность системы можно насрать.
Нужна 100-строковая простыня на SIMD интринсиках вместо 10 строчек тормозного С-кода — она там будет без вопросов.
Так что когда мы говорим о предмете в общем — советы касаются предмета в общем, и нет нужды в конце каждого сообщения дописывать «Это верно только если вы не: ...».
public class FizzBuzz { public static void main ( final String[] args ) { for ( int i = 1; i <= 100; i++ ) if ( ( i % 15 ) == 0 ) System.out.print ( "FizzBuzz " ); else if ( ( i % 3 ) == 0 ) System.out.print ( "Fizz " ); else if ( ( i % 5 ) == 0 ) System.out.print ( "Buzz " ); else System.out.print ( i + " " ); } }
Остальным потребуется день или два.
{
$f=$i%3?'':'Fizz';
$b=$i%5?'':'Buzz';
echo$f.$b?$f.$b:$i,',';
}
#include
#include
int main()
{
int i;
for (i=1; i
Вот
hvmnd.org/c0002q
буду очень признателен если укажете на ошибки и покажете как надо.
тьфуты блин
Во первых в стандарте Си нету <conio.h> это уже дос какой-то.
Во вторых main по феншую должен содержать передаваемые аргументы int argc, char *argv[]
и третьих он должен содержать return 0 в случае корректного завершения или же содержать код ошибки вместо нуля в случае возникновения нештатной ситуации.
В общем в универе вам херню преподают.
У вас в инклюдах conio.h — я надеюсь вы не думаете что это есть обязательным для всех программ на С? ) Это всего лишь заголовок, с помощью которого некоторые допотопные компиляторы 90-х(самого начала 90-х) годов создают текстовый интерфейс. И да, в частности старые версии borland.
Функция getch() — такой же анахронизм(собственно она входит в состав conio.h). Дабы окошко не закрывалось после выполнения программы обычно используют std::cin.get() входящую в состав iostream.h
И да, это не C++, это вполне себе С. Например stdio.h в С++ уже не используется, хотя и включается в состав для обратной совместимости, а вместо printf используется std::cout.
var s:String;
for (var i:uint = 1; i<=100; i++) {
(i%3 == 0 && i%5 == 0)?s = ("FuzzBuzz"):(i%3 == 0)?s = ("Fuzz"):(i%5 == 0)?s = ("Buzz"):s = String (i);
trace(s);
}
Потратил 15 минут… =)
Пил кофе, читал хабр, сделал 2 ошибки при написании, долго любовался результатом.
FuzzBuzz v 0.01:
function FuzzBuzz(arg1, arg2, num) {
var s:String;
for (var i:uint = 1; i<=num; i++) {
(i%arg1 == 0 && i%arg2 == 0)?s = ("FuzzBuzz"):(i%arg1 == 0)?s = ("Fuzz"):(i%arg2 == 0)?s = ("Buzz"):s = String (i);
trace(s);
}
}
FuzzBuzz(3, 5, 100);
И главное куда потом все эти люди деваются, они что-ли по собеседованиям не ходят?
*интересно, а что если попробовать задачу на голых шаблонах решить, теоретически все в compile time известно*
template<int T>
const char *FuzzBuzz()
{
if(T %15)
return "FuzzBuzz";
else if(T % 3)
return "Fuzz";
else
return "Buzz";
}
//а дальше нужно видимо рекурсивный шаблон делать или фигачить variadic template, у кого какие идеи?
* This source code was highlighted with Source Code Highlighter.
Нда… всё же когда что-то сложное на шаблонах делаешь синтаксис становится невыносимым. Особенно строки и их конкатенация доставляет %)
И ваще эти написания кода на бумажке подбешивают, если ты реально пишешь на 5 языках, тебе иногда надо 5-10 минут, чтобы загрузить в мозг конкретный синтаксис, путем заглядывания в ранее написанный код или получения пары ошибок от компиллятора )
for (var i = 1; i <= 100; i ++) {
var x = '';
if (i % 3 == 0) x += 'Fizz';
if (i % 5 == 0) x += 'Buzz';
console.log(x || i);
}
@echo off
rem 14:06
for /L %%n in (1,1,100) do call :PrintFizzBuzz %%n
goto :EOF
:PrintFizzBuzz
set /A aa3=%1 %% 3
set /A aa5=%1 %% 5
if NOT 0==%aa3% IF NOT 0==%aa5% set /P dummy="%1"<NUL
if 0==%aa3% set /P dummy="Fizz"<NUL
if 0==%aa5% set /P dummy="Buzz"<NUL
rem 14:49 и меня отвлекали! :)
И да! Я не программист. :)
(function() {
var str = '';
for(var i = j = k = 1;i<=100;i++, j++, k++) {
if (k != 5 && j != 3) {
str += ' ' + i + ' ';
}
else {
if (j == 3) {
str += 'Fizz';
j = 0;
}
if (k == 5) {
str += 'Buzz';
k = 0;
}
}
}
console.log(str);
}());
(function() {
var str = '';
for(var i = j = k = 1;i<=100;i++, j++, k++) {
if (k != 5 && j != 3) {
str +=i;
}
else {
if (j == 3) {
str += 'Fizz';
j = 0;
}
if (k == 5) {
str += 'Buzz';
k = 0;
}
}
}
console.log(str);
}());
Это вариант без пробелов
console.log(
(new Array(102)).join(' ').split('').map(function (i, j) {
return !(j%5||j%3) ? 'FizzBuzz' : !(j%5) ? 'Buzz' : !(j%3) ? 'Fizz' : j;
}).splice(1).join(' ')
);
console.log(
(''+new Array(102)).split('').map(function (i, j) {
return j%15 ? j%5 ? j%3 ? j : 'Fizz' : 'Buzz' : 'FizzBuzz';
}).splice(1).join(' ')
)
for (var i=1, str = '';i<=100;i++){
str += (i%15 ? i%5 ? i%3 ? i : 'Fizz' : 'Buzz' : 'FizzBuzz');
}
(''+new Array(102)).split('')
некошерна, ИМХО.console.log (
Array.apply(null, Array 101).map (i,j) ->
unless j%15 then 'FizzBuzz'
else unless j%5 then 'Buzz'
else unless j%3 then 'Fizz'
else j
).splice(1).join ' '
Вот так можно с дырками обходится.
fn main() {
let (fizz, buzz) = (3, 5);
let mut c_fizz = 3;
let mut c_buzz = 5;
for idx in 1..101 {
if idx == c_fizz && idx == c_buzz {
println!("FizzBuzz");
c_fizz = c_fizz + fizz;
c_buzz = c_buzz + buzz;
}
else if idx == c_fizz {
println!("Fizz");
c_fizz = c_fizz + fizz;
}
else if idx == c_buzz {
println!("Buzz");
c_buzz = c_buzz + buzz;
}
else {
println!("{}", idx);
}
}
}
echo file_get_contents(«fizbuzz.org/functions/?get-fizzbuzz-by-index.php?i=$i»);
}
реально работает :)
Знать наизусть все операторы не всегда представляется возможным, т.к. часто приходится выбирать какой-то новый инструмент, а то и новый язык.
Школьнику придётся изучать учебники, либо брать курсы, специалисту же достаточно воспользоваться краткой справкой и примерами кода.
«Почему Х не умеет Х-ть»
(iterate (for i from 1 upto 100) (with divides = (composition zero? mod)) (when (divides 3 i) (print "Fizz")) (when (divides 5 i) (print "Buzz")))
(iterate (for i from 1 upto 100) (with divides = (composition zero? mod)) (when (divides 3 i) (print "Fizz") (when (divides 5 i) (print "Buzz")) (continue)) (when (divides 5 i) (print "Buzz") (continue)) (print i))
Как вариант можно придумать макрос проверки условий в стиле императивного С-шного switch case break
(iterate (for i from 1 upto 100) (with divides = (composition zero? mod)) (switch-cond ((divides 3 i) (print "Fizz")) ((divides 5 i) (print "Buzz") (continue)) (default (print i))))
(let [divides? (comp zero? rem)]
(println (map #(cond
(divides? % 3) «Fizz»
(divides? % 5) «Buzz»
(divides? % 15) «FizzBuzz»
:else %) (range 1 101))))
clojure.pastebin.com/h8mZPzNS
Написал первое, что пришло в голову, вложенными ифами.
Можно тупо 4 условия подряд. Даже не знаю, какой вариант читабельнее.
Любой одногруппник способен написать такую прогу. Максимум — по невнимательности ошибется.
#include <iostream> int main(){ for(int i=1;i<=100;++i){ if(i%15==0){ std::cout << "FizzBuzz"; }else{ if(i%5==0){ std::cout<<"Buzz"; }else{ if(i%3==0){ std::cout<<"Fizz"; }else{ std::cout<<i; } } } if(i!=100)std::cout<<" "; // !!! ?? } }
#include <iostream>
int main(int argc, char* argv[]) {
for ( int i = 1; i <= 100; ++i ) {
if ( i % 3 != 0 && i % 5 != 0 ) {
std::cout << i << " ";
}
else {
std::cout << ( i % 3 == 0 ? "Fizz" : "") << ( i % 5 == 0 ? "Buzz" : "") << " ";
}
}
std::cout << std::endl;
return 0;
}
(define (f x)
(define (test x y)
(zero? (modulo x y)))
(cond ((test x 15) "FizzBuzz")
((test x 5) "Buzz")
((test x 3) "Fizz")
(else x)))
(define (range start stop)
(if (<= start stop)
(cons start (range (+ start 1) stop))
'()))
(display (map f (range 1 100)))
10 FOR i=1 TO 100
20 LET a$=""
30 IF i/3=INT (i/3) THEN a$=«Fizz»
40 IF i/5=INT (i/5) THEN a$=a$+«Buzz»
50 IF NOT LEN a$ THEN a$=STR$ i
60 PRINT a$
70 NEXT i
Я не пррограммист, но за минуту уложился :-)
(0 to 100).toList.map((x: Int) => {
if (x % 3 == 0) print("Fizz")
if (x % 5 == 0) print("Buzz")
if (x % 15 != 0) print(x)
println
})
>простейшие программы, имеет наглость называть себя программистом. Я считаю это
>оскорблением для тех, кто носит это звание по праву.
Эмоциональное заявление, но оно имеет право на жизнь :) По-моему, дело всего лишь в том, что речь идёт о разных программистах. Программисты (и не только, это любой профессии свойственно) есть по факту, а есть по должности. Я до сих пор с умилением вспоминаю одного “инженера-программиста” (одну, если уж честно :), которая как-то представила мне в непонятках программу свою на посмотреть в чём проблема. Как эта “инженер-программист” инициализировала массив на фортране:
REAL ARRAY(4,50)
ARRAY(1,1)=0.0
ARRAY(1,2)=0.0
ARRAY(1,3)=0.0
... 200 строк такого “кода”
ARRAY(4,49)=0.0
ARRAY(4,50)=0.0
А ведь программист :)
Инженеров-программистов в Советском Союзе было море разливанное. Законодательство такое. Ещё один пример из воспоминаний тех времён — в конторе был супер-головастик с золотыми руками на должности техника, ибо самоучка. И был куда менее сообразительный инженер-электронщик с образованием историка. А причина такого перекоса в должностях скрывалась именно в законодательстве страны советов — человека с высшим образованием нельзя было поставить на должность ниже инженерной. И пофигу, что образование его к предметной области не имело никакого отношения.
Вот и эта программистка была из той же области примерно — конструкции на фортране ваять могла, но программировать — увы.
The purpose is the reduction of the size of the bytecode. Consider creating a three element Object[] with null values:
*
* ANEWARRAY java/lang/Object
* DUP
* ICONST_0
* ACONST_NULL
* AASTORE
* DUP
* ICONST_1
* ACONST_NULL
* AASTORE
* DUP
* ICONST_2
* ACONST_NULL
* AASTORE
*
* with ArrayUtils you can have it like this:
*
* ACONST_NULL
* ACONST_NULL
* ACONST_NULL
* INVOKESTATIC ArrayUtils.createArray(Object,Object,Object)
*
* The number of needed instructions is thus reduced from 15 to 4. For every entry we save 3 bytecode instructions.
* This allows better readable bytecode and it allows the JIT to see less bytecode to optimize, helping under the
* inlining threshold here or there.
Ну чтож, разумно :) А вы исходники Javac читали? Там тоже есть прикольные места.
я сперва по привычке пролистнул комментарий в начале класса и просто начал читать методы.
на четвёртом методе понял, что меня дурачат, пролистал вниз (и вправо), на 5 секунд задумался о том, зачем это нужно было автору, прикинул что единственный известный мне резон поступать так — это оптимизировать то, что по каким-то причинам не оптимизируется компилятором/обфускатором.
вернулся на начало текста, прокитал комментарий и подтвердился в своей правоте (хотя еще проверю потом сам в помощью java-декомпилятора). может быть и воспользуюсь сам таким фокусом в моей программ, ибо как в некоторых случаях (в моем случае по крайней мере) я соглашусь на некоторую потерю «читабельности» кода ради выигрыша по памяти, объему, [скорости].
так что у меня к этому комментарий «УУУУУУУУУУУУУ!!!!!!»
public static Object[] createArray(Object... arg0)
{
return arg0;
}
Но такая фича появилась в JDK 1.5. Возможно, авторам требуется совместимость с более ранними версиями (либо писалось раньше).
имя этому миру — j2me
да в общем-то не в этом примере дело — подобные подходы, когда за счет какого-то ловкого фокуса можно достичь определенного результата существуют в разных языках (и даже сферах отличных от айти). если заранее в формулировке задания про ФиззБузз работодатель не сообщает дополнительные сведения, то соискатель с очень большой долей вероятности «промахнется» мимо того решения, которое предполагал работодатель как идеальное.
Расскажите своему товарищу про шаблоны новых файлов в IDE или даже прямо в ОС :)
Кстати, у меня синтаксис плюсов стал просто от зубов отскакивать, когда после Visual Studio с ее автодополнением и сниппетами перелез на vim:)
>+++++++[<+++++++>-]<.-----------------.>+++[<++++++>-]<.>+++[<------>
-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>++++
+++++[<---------->-]<.>++++[<+++++>-]<.>++++[<----->-]<.>+++++[<++++++
+>-]<-.>+++++[<++++++++++>-]<+.+++++..>+++++++++[<---------->-]<.>++++
++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<--
-------->-]<.>++++[<++++++>-]<-.>++++[<------>-]<+.>++++[<++++++>-]<.>
++++[<------>-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++
++++++..>+++++++++[<---------->-]<.>+++++[<+++++++>-]<-.>+++++[<++++++
++++>-]<+.+++++..>+++++++++[<---------->-]<.+++++++++++++++++..-------
----------.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++
..>+++++++++[<---------->-]<.+++++++++++++++++.++.>+++[<------>-]<-.++
+++++++++++++++.+++.>++++[<----->-]<.>++++++[<++++++>-]<++.>+++++[<+++
++++>-]<.+++++++++++++++++..>+++++++[<-------->-]<.>+++++[<++++++++++>
-]<+.+++++..>+++++++++[<---------->-]<.+++++++++++++++++.+++++.>+++[<-
------>-]<-.+++++++++++++++++.++++++.>++++[<------>-]<+.>++++++[<+++++
+>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->
-]<.+++++++++++++++++.++++++++.>+++++[<----->-]<.>+++++[<+++++++>-]<-.
>+++++[<++++++++++>-]<+.+++++..>+++++++++[<---------->-]<.>++++++[<+++
+++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------
->-]<.>+++[<++++++>-]<..>+++[<------>-]<.>+++[<++++++>-]<.+.>+++[<----
-->-]<-.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>
+++++++++[<---------->-]<.>+++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+
.+++++..>+++++++++[<---------->-]<.>+++[<++++++>-]<.++++.>+++[<-------
>-]<-.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>++
+++++++[<---------->-]<.>+++[<++++++>-]<.++++++.>++++[<------>-]<.>+++
[<++++++>-]<.+++++++.>+++++[<----->-]<.>++++++[<++++++>-]<++.>+++++[<+
++++++>-]<.+++++++++++++++++..>+++++++[<-------->-]<.>+++++[<+++++++++
+>-]<+.+++++..>+++++++++[<---------->-]<.>+++[<++++++>-]<+.--.--------
---------.>+++[<++++++>-]<+.-.>+++[<------>-]<.>++++++[<++++++>-]<++.>
+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>+++[
<++++++>-]<+.+.>++++[<----->-]<.>+++++[<+++++++>-]<-.>+++++[<+++++++++
+>-]<+.+++++..>+++++++++[<---------->-]<.>++++++[<++++++>-]<++.>+++++[
<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>+++[<+++++
+>-]<+.++++.>++++[<------>-]<+.>+++[<++++++>-]<+.+++++.>++++[<------>-
]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++
++++[<---------->-]<.>+++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.++++
+..>+++++++++[<---------->-]<.>++++[<+++++>-]<.---.-----------------.>
++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++
[<---------->-]<.>++++[<+++++>-]<.-.>+++[<------>-]<-.>++++[<+++++>-]<
..>++++[<----->-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++
++++++++..>+++++++[<-------->-]<.>+++++[<++++++++++>-]<+.+++++..>+++++
++++[<---------->-]<.>++++[<+++++>-]<.++.>+++[<------->-]<-.>++++[<+++
++>-]<.+++.>++++[<------>-]<+.>++++++[<++++++>-]<++.>+++++[<+++++++>-]
<.+++++++++++++++++..>+++++++++[<---------->-]<.>++++[<+++++>-]<.+++++
.>+++++[<----->-]<.>+++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++.
.>+++++++++[<---------->-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.
+++++++++++++++++..>+++++++++[<---------->-]<.>+++[<+++++++>-]<.---.>+
++[<------>-]<.>+++[<+++++++>-]<.--.>+++[<------>-]<-.>++++++[<++++++>
-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]
<.>+++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++..>+++++++++[<----
------>-]<.>+++[<+++++++>-]<.+.>+++[<------->-]<-.>++++++[<++++++>-]<+
+.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>+
++[<+++++++>-]<.+++.>++++[<------>-]<.>+++[<+++++++>-]<.++++.>+++++[<-
---->-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..
>+++++++[<-------->-]<.>+++++[<++++++++++>-]<+.+++++..>+++++++++[<----
------>-]<.>+++[<+++++++>-]<+.-----.-----------------.>+++[<+++++++>-]
<+.----.>+++[<------>-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++
++++++++++++++..>+++++++++[<---------->-]<.>+++[<+++++++>-]<+.--.>++++
[<----->-]<.>+++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++..>+++++
++++[<---------->-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++
++++++++++..>+++++++++[<---------->-]<.>+++[<+++++++>-]<+.+.>++++[<---
--->-]<+.>+++[<+++++++>-]<+.++.>++++[<------>-]<.>++++++[<++++++>-]<++
.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>++
+++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++..>+++++++++[<---------
->-]<.>++++[<++++++>-]<-.------.-----------------.>++++++[<++++++>-]<+
+.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>+
+++[<++++++>-]<-.----.>+++[<------>-]<-.>++++[<++++++>-]<-.---.>++++[<
----->-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++.
.>+++++++[<-------->-]<.>+++++[<++++++++++>-]<+.+++++..>+++++++++[<---
------->-]<.>++++[<++++++>-]<-.-.>+++[<------->-]<-.>++++[<++++++>-]<-
..>++++[<------>-]<+.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++
++++++++++..>+++++++++[<---------->-]<.>++++[<++++++>-]<-.++.>+++++[<-
---->-]<.>+++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++..>++++++++
+[<---------->-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.++++++++++
+++++++..>+++++++++[<---------->-]<.>++++[<++++++>-]<.------.>+++[<---
--->-]<.>++++[<++++++>-]<.-----.>+++[<------>-]<-.>++++++[<++++++>-]<+
+.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>+
++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++..>+++++++++[<--------
-->-]<.>++++[<++++++>-]<.--.>+++[<------->-]<-.>++++++[<++++++>-]<++.>
+++++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>++++
[<++++++>-]<..>++++[<------>-]<.>++++[<++++++>-]<.+.>+++++[<----->-]<.
>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.+++++++++++++++++..>+++++++[
<-------->-]<.>+++++[<++++++++++>-]<+.+++++..>+++++++++[<---------->-]
<.>+++++[<+++++>-]<.--------.-----------------.>+++++[<+++++>-]<.-----
--.>+++[<------>-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.++++++++
+++++++++..>+++++++++[<---------->-]<.>+++++[<+++++>-]<.-----.>++++[<-
---->-]<.>+++++[<+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++..>++++++++
+[<---------->-]<.>++++++[<++++++>-]<++.>+++++[<+++++++>-]<.++++++++++
+++++++..>+++++++++[<---------->-]<.>+++++[<+++++>-]<.--.>++++[<------
>-]<+.>+++++[<+++++>-]<.-.>++++[<------>-]<.>++++++[<++++++>-]<++.>+++
++[<+++++++>-]<.+++++++++++++++++..>+++++++++[<---------->-]<.>+++++[<
+++++++>-]<-.>+++++[<++++++++++>-]<+.+++++..
Снимаю шляпу.
>++++++++++>+++++++++<[>>[-]++++++++++>>[-]++++++++++<<<<[>>->>->+<<<<
<-]>>>>>[<<<<<+>>>>>-]<<<<<>>>[-]++++++++++>>[-]++++++++++<<<<[>>->>->
+<<<<<-]>>>>>[<<<<<+>>>>>-]<<<<<>>>>>>>>>>+<<<<<<<<<<>>>[>+<-]>[>+<-[>
+<-[>--<-[>+<-[>+<-[>--<-[>+<-[>+<-[>--<-[>+<-[>+<-[>--<-[>+<-[>+<-[>-
-<-[>+<-[>+<-[>--<-]]]]]]]]]]]]]]]]]]>>+<[>-<[-]]>[>>>>[-]<<<<++++++++
++++++++++++++++++++++++++++++++++++++++++.[-]]<<<<<[>>+>+<<<-]>>>[<<<
+>>>-]<<[>>+>+<<<-]>>>[<<<+>>>-]+<----------[>-<[-]]>[>>>>>[-]<<<<<+++
++++++++++++++++++++++++++++++++++++++++++++.[-]]<<[-]<[>+>+<<-]>>[<<+
>>-]+<-----[>-<[-]]>[>>>>>>[-]<<<<<<++++++++++++++++++++++++++++++++++
+++++++++++++.[-]]>>>>>>[<<<<<<<<<++++++++++++++++++++++++++++++++++++
++++++++++++.>++++++++++++++++++++++++++++++++++++++++++++++++.>>>>>>>
>-]<<<<<<<<[-]<[-]<-[>+>+<<-]>>[<<+>>-]+<+[>-<[-]]>[<<++++++++++<->>>[
-]]++++++++++.[-]<<<]
Она правда не слова выводит, а цифры. 3 если кратно 3, 0 если 5 и 30 если и то и то.
Вторая задачка, которую я всегда давал С++ программерам, это написание оператора присваивания шаблонного класса-контейнера (вектора) — сразу все видно — часть просто не знала, что это, еще часть понятия не имела, как выделять память, еще часть не проверяла входной параметр на нули, подавляющее большинство забывало освободить старый указатель. Зато были единицы, с кем можно было поговорить про оптимизацию инициализации копий по умолчанию и обработку исключительных ситуаций в процессе копирования.
Собственно, это не значит, что мы принимали только последних. Если человек писал хотя-бы простой вариант решения, и при обсуждении адекватно реагировал на намеки на недостатки, то это уже был неплохой кандидат (обучаемый, по крайней мере).
Давно уже использую резюме только для поиска нужных ключевых слов. Ну максимум опыт человека посмотреть (где работал). Далее — телефонное собеседование (от 5 до 20 мин) и только по его результатам живое интервью (с тестовыми заданиями, написанием кода FizzBuzz-ом и прочим, the whole 9 yards).
Так что совет всем начинающим «принимающим на работу» — забейте на резюме, общайтесь с человеком и попытайтесь максимально создать для него «боевые условия» (при этом абсолютно не давя на психику). Бывает попадаются настоящие гуру с одностраничным нелепо написанным резюме и люди, которых близко подпускать нельзя с 5-тистраничным офигенно составленным CV. Хотя и наоборот. В общем, резюме — это так, бумажка. Никогда не составляйте мнение по сему документу.
for i in xrange(1, 100): print ("" if i % 3 else "Fizz") + ("" if i % 5 else "Buzz") or i
Расплачиваться за уменьшение количества условий приходится бОльшим количеством (возможно снижающим читаемость) действий со строками.
def fizzbuzz(i=1) return if i > 100 if (i%15).zero?; puts "FizzBuzz" elsif (i%3).zero?; puts "Fizz" elsif (i%5).zero?; puts "Buzz" else; puts i; end fizzbuzz(i+1) end
ну пожалуйста, можно я скажу?
хабр — торт!
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:variable name="set" select="//node()"/>
<xsl:for-each select="$set[position() <= 100]">
<xsl:choose>
<xsl:when test="position() mod 3 = 0 and position() mod 5 = 0">FizzBuzz</xsl:when>
<xsl:when test="position() mod 5 = 0">Buzz</xsl:when>
<xsl:when test="position() mod 3 = 0">Fizz</xsl:when>
<xsl:otherwise>
<xsl:value-of select="position()"/>
</xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Для краткости кода использован метод Пиза, поэтому число узлов в обрабатываемом xml должно быть не менее ста.
<xsl:template name="FizzBuzz">
<xsl:param name="index" select="1"/>
<xsl:param name="index_end" select="100"/>
<xsl:choose>
<xsl:when test="$index mod 3 = 0 and $index mod 5 = 0">FizzBuzz</xsl:when>
<xsl:when test="$index mod 3 = 0">Fizz</xsl:when>
<xsl:when test="$index mod 5 = 0">Buzz</xsl:when>
<xsl:otherwise><xsl:value-of select="$index"/></xsl:otherwise>
</xsl:choose>
<xsl:text> </xsl:text>
<xsl:if test="($index + 1) <= $index_end">
<xsl:call-template name="FizzBuzz">
<xsl:with-param name="index" select="$index + 1"/>
<xsl:with-param name="index_end" select="$index_end"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
Однако он же и более ресурсоемкий.
Метод Пиза позволяет избавиться от рекурсии и тем самым оптимизировать выполнение шаблона. При этом, надо учитывать, что в реальных задачах можно в качестве содержимого переменной $set использовать не набор узлов обрабатываемого XML-документа, а набор узлов самого шаблона, записав переменную как
<xsl:variable name="set" select="document('')//node()"/>
, и тогда наш цикл не будет зависеть от обрабатываемого документа.(В данной, чисто условной задаче, это к сожалению, невозможно, из-за малого числа узлов в XSL-шаблоне цикл доходит только до 36. Но тут можно вспомнить о том, что каждый комментарий в шаблоне тоже считается узлом. Поэтому можно написать комментариев к каждой строке, и добить всеь шаблон пустыми комментариями в конце, чтобы цикл дошел до ста, пример ниже)
Ну и если уж совсем удариться в оптимизацию, то имеет смысл вынести деление в отдельные переменные и оптимизировать первое условие, проверяя в нем сначала делимость на 5 а потом только делимость на 3.
Тогда получится следующее:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<!--Программа FizzBuzz-->
<xsl:template match="/">
<!--Выберем все узлы текущего документа-->
<xsl:variable name="set" select="document('')//node()"/>
<!--Создадим цикл со счетчиком-->
<xsl:for-each select="$set[position() <= 100]">
<!--Вычислим значение остатка от деления текущего числа на 5-->
<xsl:variable name="mod5" select="position() mod 5"/>
<!--Вычислим значение остатка от деления текущего числа на 3-->
<xsl:variable name="mod3" select="position() mod 3"/>
<!--Проверим выполение условий задачи-->
<xsl:choose>
<!--Если число кратно и пяти и трем то выведем "FizzBuzz"-->
<xsl:when test="$mod5 = 0 and $mod3 = 0">FizzBuzz</xsl:when>
<!--Если число кратно трем то выведем "Buzz"-->
<xsl:when test="$mod3 = 0">Buzz</xsl:when>
<!--Если число кратно пяти то выведем "Fizz"-->
<xsl:when test="$mod5 = 0">Fizz</xsl:when>
<!--Во всех остальных случаях выведем само число-->
<xsl:otherwise>
<xsl:value-of select="position()"/>
</xsl:otherwise>
</xsl:choose>
<!--Выведем пробел-->
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
<!-- -->
</xsl:stylesheet>
Да, это извращение чистой воды, но… на профайлере ваш способ выполняется примерно 0,0184 с, а мой — 0,0104 с. При этом глубина стека в вашем варианте составляет 301, а в моем — 4.
По-моему это профит, однозначно! :)
Ну то есть я понимаю что именно в данной задаче подобная оптимизация не имеет никакого практического смысла, но мои рассуждения вообще-то к тому, что не стоит всегда пользоваться только стандартными походами. В одном из проектов учет подобных нюансов серёзно облегчил жизнь серверу, а в конечном итоге и мне :-)
Вот из-за того, что в XSLT нет нормального цикла по количеству итераций, приходится извращаться с методом Пиза, а если нужно обработать миллион итераций, будете формировать гигантский документ, состоящий из миллиона узлов? Хотя, XSLТ не предназначен для таких задач, лучше при формировании обрабатываемого документа сделать это более легким способом, и дать на обработку уже эти данные.
Потому что в таком случае действительно единственно верный способ — это учесть такую потребность еще на этапе формирования документа. Тут я с вами совершенно согласен.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script>
$(function() {
$.fn.FizzBuzz = function() {
var index = $(this).data('FizzBuzzIndex');
if ( ! index) index = 1;
var index_end = $(this).data('FizzBuzz');
var out = '';
if (index % 3 == 0) out += 'Fizz';
if (index % 5 == 0) out += 'Buzz';
if (out == '') out = index;
$(this).append(out + ' ');
index ++;
$(this).data('FizzBuzzIndex', index);
if (index <= index_end) $(this).FizzBuzz();
}
$('.FizzBuzz').FizzBuzz();
});
</script>
<div class="FizzBuzz" data-FizzBuzz="100"></div>
use 5.010;
say join ' ', map {
sub {
return 'FizzBuzz' unless $_ % 3 or $_ % 5;
return 'Fizz' unless $_ % 3;
return 'Buzz' unless $_ % 5;
return $_;
}->();
} 1..100;
* This source code was highlighted with Source Code Highlighter.
let fizzbuzz n =
let fb n =
match n mod 3, n mod 5 with
| 0, 0 -> "FizzBuzz"
| 0, _ -> "Fizz"
| _, 0 -> "Buzz"
| _, _ -> string_of_int n in
let rec loop = function
| n' when n'<=n -> fb n' :: loop (n'+1)
| _ -> []
in loop 1
let _ = print_endline (String.concat " " (fizzbuzz 100))
For i = 1 To 101: Print IIf((i Mod 3)*(i Mod 5), i, IIf((i Mod 5), "Fizz", "Buzz")): Next
Посту уже 2 года, никто и не заметит мой след в истории
for i in ("FizzBuzz" if i % 3 + i % 5 == 0 else "Fizz" if i % 3 == 0 else "Buzz" if i % 5 == 0 else i for i in xrange(100)):
print i
[{(1, 1): 'FizzBuzz', (1, 0): 'Fizz', (0, 1): 'Buzz'}.get( tuple([not x%y for y in (3, 5)]), x ) for x in xrange(1, 101)]
package main
import "fmt"
func main() {
for i := 1; i <= 100; i++ {
if i % 3 == 0 && i % 5 > 0 {
fmt.Println("Fizz")
} else if i % 3 > 0 && i % 5 == 0 {
fmt.Println("Buzz")
} else if i % 3 == 0 && i % 5 == 0 {
fmt.Println("FizzBuzz")
} else {
fmt.Println(i)
}
}
}
Ушло минут пять.
Объясните, пожалуйста, в чем подвох, т. к. у меня практически нулевой опыт в программировании.
Я еще только учусь, набросал работающий вариант за 5 минут. Могу ли я претендовать на место junior'а в IT-компании? :)
with a(id)
as (select 1 as id
union all
select id + 1 from a where id < 100)
select
isnull(
nullif(case when id % 3 = 0 then 'fizz' else '' end
+ case when id % 5 = 0 then 'buzz' else '' end,
''),
id) as v1,
case
when id % 15 = 0 then 'fizzbuzz'
when id % 5 = 0 then 'buzz'
when id % 3 = 0 then 'fizz'
else cast(id as varchar(3)) end as v2
from a
order by id;
for (let i = 1; i < 100 + 1; i++) {
let o3 = i % 3;
let o5 = i % 5;
let output = false;
output = (o3 === 0) ? 'Fizz' : '';
output += (o5 === 0) ? 'Buzz' : '';
output = (!output) ? i : output;
console.log(output);
}
Вот мой вариант: в виде функции с доктестами. Входные значения: верхний предел и словарь вида 'слово': делитель для возможностью расширения значений для замены. Вывод в виде списка. Python.
def fizzbuzz(substitutes={'Fizz': 3, 'Buzz': 5}, upper_limit=100):
"""
Replaces the numbers divisible
by 3 with Fizz
by 5 with Buzz
by both by FizzBuzz
and so on...
>>> fizzbuzz({'Fizz': 3, 'Buzz': 5}, 15)[5:]
['Fizz', 7, 8, 'Fizz', 'Buzz', 11, 'Fizz', 13, 14, 'FizzBuzz']
>>> fizzbuzz({'Fizz': 3, 'Buzz': 5, 'Fuzz': 7}, 200)[100:110]
[101, 'Fizz', 103, 104, 'FizzBuzzFuzz', 106, 107, 'Fizz', 109, 'Buzz']
"""
result = []
for number in range(1, upper_limit + 1):
replacement = ''
for substitute, divisor in substitutes.items():
replacement += substitute if number % divisor == 0 else ''
number_or_replacement = number if not replacement else replacement
result.append(number_or_replacement)
return result
Я не знаю, может я один такой, когда я прочитал про задание с числами кратными 3 и 5 я сразу представил что надо просто проверять на остаток от деления, но я не вспомнил как записать эту операцию(точнее сказать не сразу вспомнил). Я точно знаю что не вспомнил я ее просто потому что за ближайшие два месяца не использовал в коде. Я точно знаю что мне достаточно легкого намека и я вспомню что это %, но почему-то думаю что на собеседовании я растерялся бы
Люди! Где правда?! С одной стороны меня пугают что куда ни приди - везде гуглояндекс где ты должен отстоять 10 раундов против МС олимпиадного программирования, ПриМата-токсика (ессно, без шансов). С другой - вот этими циклами 1-10. А как на самом деле-то?
// звиняйте ежели байан :)
IntStream.iterate(1, n -> n + 1).limit(100)
.forEach(n -> {
if (n % 3 == 0 && n % 5 == 0) System.out.println("FizzBuzz");
else if (n % 3 == 0) System.out.println("Fizz");
else if (n % 5 == 0) System.out.println("Buzz");
else System.out.println(n);
});
Прочитал статью, продумал в голове код, посмотрел ответы - сходится. А все равно страшно, что я "ни в зуб ногой" в программирование - рекурсии я например никогда не использовал, с ней могут быть трудности, мой основной язык - шарп, и иногда мне даже приходится сверяться в гугле как писать циклы например на питоне, потому что я хоть и имею с ним опыт, но я даже PowerShell язык чаще использую чем его. Обидно
FizzBuzz, или почему программисты не умеют программировать