LINUX.ORG.RU

Ответ на: комментарий от vertexua

Или обязательно в Guards? Не, угадывать - это к прологу.

ИМХО - ленивое решение тоже достаточно красивое

vertexua ★★★★☆ ()
numDigits 0 = 1
numDigits n = truncate (logBase 10 n) + 1
quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

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

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

vertexua ★★★★☆ ()
Ответ на: комментарий от vertexua

TC уже давали ссылки и на RWH и на LYH :)

numDigits1 :: Int -> Int
numDigits1 0 = 1
numDigits1 n = [ k + 1 | k <- [0..n], 10^k <= n && n < 10^(k+1) ] !! 0

numDigits2 0 = 1
numDigits2 n = truncate (logBase 10 n) + 1

numDigits1 10^30   => 1073741824
numDigits1 10^50   => 0
numDigits1 10^100  => 0
numDigits1 100^100 => -818408495

numDigits2 100^100  => 515377520732011331036461129765621272702107522001

т.е. логарифмы от больших чисел работают быстро.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

Хотя нет, логарифмы почему-то плохие:

numDigits1 :: (Integral t) => t -> t
numDigits1 0 = 1
numDigits1 n = [ k + 1 | k <- [0..n], 10^k <= n && n < 10^(k+1) ] !! 0

numDigits2 :: (RealFrac t, Integral b, Floating t) => t -> b
numDigits2 0 = 1
numDigits2 n = truncate (logBase 10 n) + 1

numDigits1 (1000^1000) => 3001
numDigits2 (1000^1000) => врёт

и вообще

logBase 10  (1000^1000) => Infinity
quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

Всё-таки с хорошими целочисленными логарифмами быстрее:

numDigits1 :: (Integral t) => t -> t
numDigits1 0 = 1
numDigits1 n = [ k + 1 | k <- [0..n], 10^k <= n && n < 10^(k+1) ] !! 0

myLogBase :: (Integral a, Num t) => a -> a -> t
myLogBase b n = if n < b then 0 else iter b n 0
                where iter b n i = if (n `div` b) < b
                                   then i + 1
                                   else iter b (n `div` b) (i + 1)

numDigits2 :: (Integral t) => t -> t
numDigits2 0 = 1
numDigits2 n = truncate (myLogBase 10 n) + 1

numDigits1 (1000^1000) => 3001
numDigits2 (1000^1000) => 3001
numDigits1 (1000^10000) => не стал дожидаться
numDigits2 (1000^10000) => 30001
quasimoto ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.