1. Куча / Говнокод #14217

    +136

    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
    countDigits :: (Integral a) => a -> Int
    {-# INLINE countDigits #-}
    countDigits v0 = go 1 (fromIntegral v0 :: Word64)
      where go !k v
               | v < 10    = k
               | v < 100   = k + 1
               | v < 1000  = k + 2
               | v < 1000000000000 =
                   k + if v < 100000000
                       then if v < 1000000
                            then if v < 10000
                                 then 3
                                 else 4 + fin v 100000
                            else 6 + fin v 10000000
                       else if v < 10000000000
                            then 8 + fin v 1000000000
                            else 10 + fin v 100000000000
               | otherwise = go (k + 12) (v `quot` 1000000000000)
            fin v n = if v >= n then 1 else 0

    Хаскельная магия из исходников Data.Text.

    Запостил: Yuuri, 12 Декабря 2013

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

    • {$ INLINE countDigits}

      Прям дельфи


      Хаски к нам давно не заглядывал
      Ответить
    • Копипаста в хаски - популярная методика.
      Макросы - ни асилили.
      Достаточно вспомнить объявление типа кортежа в стандартной библиотеке.
      Ответить
      • > Макросы - ни асилили.
        Там совсем макросов нет, или народ не использует? Где-то видел разговоры про #define, но либо это для констант, либо я ничего не понял, поскольку хаскель почти не знаю.
        Ответить
        • Гуглим Template Haskell
          Ответить
        • #define — это из расширения, позволяющего использовать сишный препроцессор. Вроде бы в основном используется для FFI.
          Ответить
    • оу, а что оно делает? у них там умножение что ли такое? пардон в хаскеле ни ногой
      Ответить
      • Умножение там есть нормальное, Вы не беспокойтесь.
        Тут, судя по всему, считают количество цифр в числе, причём операции деления экономят (т.к. целые числа могут быть любой длины), используют только в 18 строке и делят сразу на 1000000000000.
        В коде имеется "обрубок числа" v и количество цифр k в обрубленной части. Когда число большое, от него отрезают по 12 разрядов, увеличивая k на 12. Когда остаётся менее 12 разрядов, в зависимости от раскидистых условий k увеличивается на нужное число.
        Ответить
        • пиздец какой-то. код из разряда - "ты словами скажи что хотел, а я напишу как надо"
          константы вида 1000000000000 доставляют
          Ответить
          • Можо подумать на сишке этот код смотрелся бы лучше ;)

            Оптимизация, мать ее.
            Ответить
            • я про язык и не говорил ничего) Только про конкретный код.
              Можно было хотя бы константы привести к удобоваримому виду.
              Ответить
              • > Можно было хотя бы константы привести к удобоваримому виду.
                one ten hundreed... что ли ?:)

                Если пофиг на скорость: countDigits = length . takeWhile (>0) . iterate (`div` 10)
                Ответить
                • > one ten hundreed
                  Похоже на что-то вроде:
                  data MyNumber = Hundred | Thousand
                  one Hundred  = 100
                  one Thousand = 1000
                  Ответить
            • Я не совсем понимаю что делает код)
              на первый взгляд - а не проще ли перевести в текст и работать с ним?
              Ответить
              • > а не проще ли перевести в текст

                Может потому, что эта функция и используется для перевода в текст?
                http://hackage.haskell.org/package/text-1.0.0.0/docs/src/Data-Text-Lazy-Builder-Int.html
                Ответить
        • Спасибо за развернутый ответ
          Ответить

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