1. Ruby / Говнокод #3394

    −92

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    def get_next_line(max_level, current_level, current_line_items)
            next_line_items = []
            result_string = ''
    
            if current_level == 1
                    next_line_items.push(1)
                    result_string = "1\n"
            else
                    current_line_number = false
                    current_line_number_count = 0
                    current_index = 0
    
                    current_line_items.each do |line_number|
                            if current_index == 0
                                    current_line_number = line_number
                                    current_line_number_count = 1
                            else
                                    if line_number == current_line_number
                                            current_line_number_count = current_line_number_count + 1
                                    else
                                            next_line_items.push(current_line_number_count)
                                            next_line_items.push(current_line_number)
    
                                            current_line_number_count = 1
                                            current_line_number = line_number
                                    end
                            end
    
                            if current_index >= current_line_items.length - 1
                                    next_line_items.push(current_line_number_count)
                                    next_line_items.push(current_line_number)
                            end
    
                            current_index = current_index + 1
                    end
    
                    result_string = next_line_items.join(' ') + "\n"
            end
    
            if current_level < max_level
                    result_string = result_string + get_next_line(max_level, current_level + 1, next_line_items).to_s
            end
    
            # return result
            result_string
    end
    
    puts 'Input max level:'
    level = gets
    
    puts ''
    puts get_next_line(level.to_i, 1, [])

    реальное тестовое задание кандитата.
    задача - вывести несколько членов последовательности
    1
    11
    21
    1211
    ....

    Запостил: malleus, 04 Июня 2010

    Комментарии (63) RSS

    • кандидат гениальный) в полностью объектном языке писать в процедурном стиле, да ещё так криво =)) на работу взяли его? )
      Ответить
      • отправили замечания. следующую версию не прислал, пишет еще наверно ( полгода прошло)
        Ответить
        • послал наверное он вас. я бы тоже послал если бы мне настолько отдаленный от практики тест дали. по принципу: тебе шашечки или ехать?
          Ответить
          • быдлокодите на пхп? считаете алгоритмы изжившей практикой? написать абы как, лишь бы работало? написано раз - не читается никогда? выпей йаду. такие "программисты" не нужны.
            Ответить
            • я больше про то что на практике, алгоритмы бывают нужны крайне редко и в 90% случаев вычитываются из книжек.

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

              это нужно в программировании каждый божий день - и создает больше проблем чем неэлегантный алгоритм.
              Ответить
              • а в данном случае что? на входе одна строка, на выходе - другая. Или на входе массив - на выходе массив.
                обычная в общем то задача, где надо чуть чуть пошевелить межушным узлом. нет там никаких сложных алгоритмов, надо просто написать простой и понятный код.

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

                  да и мне уже интересно чья идея это была на Ruby писать. вроде как бы в универах такое еще не проподается. если перевести вышеприведенную программу на Prolog, где рекурсия есть норма жизни, то она будет почти не говно.
                  Ответить
                  • задача - написать программу выводящую заданную последовательность. как она формируется обычно говорим, если сам не догадался.

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

                    А что касается отсутсвия преподавания ruby в универе - и что? мы теперь должны брать людей без опыта, обучать их за свой счет? поэтому и даются простые задания, что бы понять - есть способности к программированию, или сколько не учи, один хрен выйдет быдлокодер с амбициями.
                    Ответить
                    • >что бы понять - есть способности к программированию
                      Вот меня тоже мучает вопрос, какое отношение эта говнозадача имеет к реальному программированию. Или у вас фирма спортивным занимается?
                      Ответить
                    • Знание ruby - не суть. Если человек хоть на чем то нормально кодит переход не составит труда.
                      Ответить
                  • > где рекурсия есть норма жизни, то она будет почти не говно.

                    ололо, таки сумел сделать говнище несмотря на рекурсию =)
                    detect :: (Eq a) => [a] -> Int
                    detect []     = 0
                    detect (h:t)  = detect' t 1
                    	where
                    		detect' []    r = r
                    		detect' (u:k) r | u == h    = detect' k (r+1)
                    						| otherwise = r
                    
                    dropFront :: (Eq a) => [a] -> [a]
                    dropFront []    = []
                    dropFront (h:t) = dropWhile (== h) t
                    
                    newList :: [Int] -> [Int]
                    newList old = newList' old []
                    	where
                    		newList' []  acc = acc
                    		newList' lst acc = newList' (dropFront lst) (acc ++ [detect lst] ++ [head lst])
                    
                    createSeq n | n <= 1    = [1]
                                | otherwise = create' n [1]
                    				where
                    					create' 0 p = p
                    					create' r p = create' (r-1) (newList p)
                    
                    main = do
                    	s <- getContents
                    	let t = (read $ head $ lines s) :: Int
                    	mapM_ (print . createSeq) (take t [1..])
                    Ответить
                    • (defun series-1-11-21-1211 (n)
                        (labels ((%series (n so-far)
                                   (if (= 0 n) so-far
                                       (%series (1- n)
                                        (loop
                                           :with acc := 1
                                           :for (a . b) :on so-far
                                           :if (and b (= a (car b))) :do (incf acc)
                                           :else :nconc (prog1 (list acc a) (setf acc 1)))))))
                          (%series n '(1 1))))

                      Чет длинновато как-то.
                      Ответить
                      • Да, что-то длинновато :)
                        import Data.List
                        
                        step = concatMap (\s -> (show $ length s) ++ [head s]) . group
                        
                        main = do
                            mapM_ putStrLn $ take 10 $ iterate step "1"
                        http://ideone.com/ztuitx
                        Ответить
                        • Блин, не могу до конца понять, как оно работает-то?
                          Ответить
                          • С какого места непонятно?

                            group "112322" = ["11", "2", "3", "22"]
                            show $ length [1,1] = "2"
                            [head "11"] = "1"
                            concatMap f = concat . map f
                            iterate step "1" = ["1", step "1", step (step "1"), ...]
                            Ответить
                            • concatMap - это я так понимаю джойн в одну строку пар (кол-во, цифра)
                              >\s -> (show $ length s) ++ [head s]
                              Тут тоже ясно - генерирует эту пару.

                              Но каким образом оно дуплит где дубликаты и проходит по ним.
                              group?
                              Ответить
                              • > concatMap - это я так понимаю джойн в одну строку пар (кол-во, цифра)
                                Ну да, это комбо конката и мапа, чтобы их по-отдельности не писать.

                                > group?
                                Ага. group собирает подряд идущие одинаковые элементы в группы.

                                grpoup [1,2,2,3,3,1,1,1] = [[1], [2,2], [3,3], [1,1,1]]

                                P.S. Не забываем, что в хаскеле String = [Char], и поэтому "111" = ['1', '1', '1'] и наоборот.
                                Ответить
                                • >в хаскеле String = [Char], и поэтому "111" = ['1', '1', '1'] и наоборот.

                                  Да уж это понятно.
                                  Меня больше в тупик ставило что group написан был в конце, а должен выполнятся в начале.
                                  Ответить
                                  • > Меня больше в тупик ставило что group написан был в конце, а должен выполнятся в начале.

                                    Композиция такая композиция ;)
                                    (f . g) x = f (g x)

                                    P.S. Кстати формула, которую я написал, это настоящее определение точки. Можно даже вбить его в интерпретатор и потестить.
                                    Ответить
                                    • f |> g = g . f
                                      step = group |> concatMap (\s -> (show $ length s) ++ [head s])
                                      фшарпненько
                                      Ответить
                                      • > |>
                                        Кстати, а хаскель умеет в юникодные операторы? В духе а ↣ b.
                                        Ответить
                                        • Конечно умеет. GHC вроде несколько встроенных преобразований для всяких стрелочек имеет. Бёрд целую книжку написал, используя уникодные символы для почти всех операций.
                                          Только по ушам за такое бить надо.
                                          Ответить
    • Чо за последовательность-то? по какому принципу формируется, не могу понять?
      Ответить
      • 1211 = это одна двойка, одна единица. - то есть 21
        Ответить
        • Не вдуплился че-то тоже. Напиши хотя бы десяток членов.
          Ответить
    • показать все, что скрытоА разве на руби по другому пишут?
      Мне кажется что в языке, где уважают haml -- все такие.. нет?
      Ответить
    • на скорую руку:
      NumCount = Struct.new(:number, :count)
      
      def next_line(prev_line)
        prev_line.split('').inject([]) do |line, char|
          new_num = char.to_i
          if line.empty? or line[-1].number != new_num
            line << NumCount.new(new_num, 1)
          else
            line[-1].count += 1;
          end
          line
        end.map { |elem| elem.count.to_s + elem.number.to_s }.join('')
      end
      
      def result_at_level(num)
        return ["1"] unless num > 1
        prev = result_at_level(num - 1)
        prev << next_line(prev[-1])
      end
      
      puts result_at_level(ARGV.shift.to_i).join("\n")
      Ответить
      • ну вот примерно с такими или подобными тестовыми заданиями и приходится иметь дело.
        структуру для хранения промежуточного результата ищо никто правда не догадался использовать
        Ответить
    • class String
      def look_and_say
      gsub(/(.)\1*/){|s| "#{s.size}#{s[0,1]}"}
      end
      end
      
      s = '1'
      12.times {p s; s = s.look_and_say}


      via http://www.rubyquiz.com/quiz138.html

      Ruby - это не "язык", это и есть говно, как и сам Matz.

      P.S. обосрите меня пожалуйста..
      Ответить
      • аргументацию и пруфлинки в студию, плиз. голословным утверждениям не место здесь
        Ответить
        • Если задача на "алгоритмы", то регекс - читерство.
          Ответить
          • читерство? какое отношение это слово имеет к работе?
            задача на пошевелить мозгом.
            простое, читабельное, поддерживаемое решение в разумные сроки.
            Ответить
            • Это не работа, а тестовое задание. Тут нужно показать, как ты можешь думать, а регексы - это просто знание регексов. Всё равно, что вместо написания тестовой программы найти гем.
              Кстати, написанное на руби собственное решение работает чуточку быстрее)
              Ответить
              • Это в теории, на практике же, решений на регекспе было меньшинство. и большинство этих решений - копипаста из интернетов без малейших изменений. тоже показатель, как человек может думать)
                Чаще всего это задание срабатывало как детектор неопытных разработчиков - каких только косяков не было в этом маленьком кусочке кода.
                Ответить
    • Свои 5 копеек

      C# (можно сделать кошернее сделав функцию, которая сразу генерит n строк и юзать 2 StringBuilder (невиданная оптимизация, ня!))
      static private StringBuilder GetNext(StringBuilder inSB)
              {
                  var cnt = 1;
                  var num = inSB[0];
                  var outSB = new StringBuilder();
                  inSB.Append(0);
                  for (var j = 1; j < inSB.Length; j++)
                  {
                      if (inSB[j] != num)
                      {
                          outSB.Append(cnt);
                          outSB.Append(num);
                          num = inSB[j];
                          cnt = 0;
                      }
                      cnt++;
                  }
                  return outSB;
              }
      Ответить
      • Also в последовательности никогда не будет чисел больше 3
        ибо 4 может получиться только из цепочки X,X,X,X -> предыдущая строка имела вид Х раз Х, затем Х раз Х -> 2*X раз Х -> следующая строка не Х,Х,Х,Х а 2*Х, Х.
        Также для любой входной цифры Y> 1 строка всегда будет иметь вид ХХХ1Y
        Ответить
        • Ага. На проджект эйлер даже задачка есть посвященная этой последовательности: http://projecteuler.net/problem=419.
          Ответить
          • Спасибо за ссылку - люблю математические задачки
            Ответить
      • О. Вот это по-нашему!

        > юзать 2 StringBuilder (невиданная оптимизация, ня!)
        Я бы написал стрим/appendable(char), который аккумулирует значения и передает свой вывод по цепочке другому такому же стриму. Остановка по -1.
        Ответить
        • Это я так понимаю чтобы искать n'ю строку, если 1..n-1 не нужны? Ведь данные из промежуточных стримов пропадут...

          Или тут хитрый план - сложить стримы в массив, и потом сделать им всем какой-нибудь toString?
          Ответить
          • > чтобы искать n'ю строку, если 1..n-1 не нужны
            Да. Хотя наверняка есть способы лучше. По сути ведь получается та же рекурсия.

            >Или тут хитрый план - сложить стримы в массив, и потом сделать им всем какой-нибудь toString?
            Но считать так сразу все - тупо. Надо много памяти.
            И тогда рулит итеративный подход .
            Ответить
            • > По сути ведь получается та же рекурсия.
              Ну она, по идее, уложится в 3*n памяти, т.к. каждому слою надо 1-3 цифры, чтобы понять сколько из них совпало. При том, что строки довольно быстро растут, это будет неплохой экономией. Но вот по процу оно один хер считает все полностью ;(

              А вон в задачке с PE надо сказать, сколько 1,2 и 3 при n = 10^12... Там уже явно другой подход нужен.

              P.S. На вики пишут, что Конвей когда-то доказал, что через некоторое время последовательность рассыпается на независимые "атомы", которые дальше крутятся не затрагивая друг-друга. Может в эту сторону надо копать?
              Ответить
              • >это будет неплохой экономией
                >уложится в 3*n памяти
                Плюс оверхед на объектах и счетчиках.

                > которые дальше крутятся не затрагивая друг-друга
                Кстати да. Возможно, типичные строки.
                Но я заметил другую закономерность:
                132113
                111312
                311311
                Начала строк идут с периодом в 3 и повторяются.
                Причем общий префикс увеличивается, сначала
                1
                1
                3
                Потом
                11
                13
                31
                итд
                Ответить
                • http://www.se16.info/js/lands2.htm
                  Ответить
                  • На этом можно автомат построить и не париться
                    Ответить
                • Там все строки начинают повторяться. Только я закономерность повторения строк и повторениями не нашел
                  Ответить
              • Можно, только строка на 40 итерации уже состоит из over 60000 символов - замучаешься вычленять подпоследовательности. Ну ее нах.
                Ответить
                • Сохранять префикс для последующего использования. Их всего три штуки. Достаточно понять сколько отрезать.
                  Правда идея Конвея с переходами из состояния в состояние смотрится еще выгоднее.
                  Ответить
                  • Но что-то меня пугает фраза 92 of these elements dominate the evolution, in that they either soon make up the whole string, or if not then as the string lengthens to infinity, they make up "almost all" (a measure theory term) of the string.
                    Ответить
          • Ну так а что мешает их выводить?

            >сложить стримы в массив

            Можно и так, только пользы от этих строк никакой.) Я просто в цикле из печатаю
            Ответить
        • >appendable(char)

          а можно узнать где об этом почитать?
          Ответить
          • То, очевидно, писал человек с жавизмом головного мозга.
            http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Appendable.html
            Ответить
            • Осталось только узнать, как его зовут в шарпе) Спс
              Ответить
    • В ЛицоКнига такую же задачку спрашивают. Типа это модно и молодёжно?
      Ответить
      • В собеседовании на должность кухарки?)
        Ответить
    • ОП конечно мудоёб из палаты мер и весов
      Ответить

    Добавить комментарий