2014-10-13 10 views
1

나는 시그마 표기법을 필요로하는 문제를 해결하려고 노력해 왔지만, 적어도 하스켈에서 시그마 표기법을 구현할 때마다 그 표제 변수를 사용하지 않는다. 기능. 내가 복제하려고했는데 특별한 공식은 다음과 같습니다인덱스가있는 시그마 표기법

enter image description here

그것은 N에서 0을 후행의 수를 계산하는 데 사용!하지만 내가 가진 것 중에 최고는 것 :

sigma :: (Enum a, Num b) => a -> a -> (a -> b) -> b 
sigma i k fn = sum . map fn $ [i..k] 

zeros :: Int -> Int 
zeros n = sigma 1 n (???) 

나는 또한 일반적인 시그마 함수를 만들려고하는데, 그 함수는 f에있는 인덱스 변수와 함께 작동한다. 이 방법이 효과가 있지만 100의 경우에는 -11 뒤에 0이옵니다. 과다?

zeros :: Int -> Int 
zeros n = sigma 1 n (\i -> n `div` 5^i) 
     where sigma i k fn = sum $ map fn [i..k] 

P. 컴파일 타임을 제한하는 인 브라우저 IDE에 관한 것. (속도 카운트)

+0

가되지 않는'(???) (\ i -> floor (n/5^i))'? 당신의 수식이'1'에서'n '까지 합쳐 졌다고 가정하면 –

+0

이미 시도해 보았습니다. 그리고 저에게 맞지 않습니다. 오류 메시지는 암호화되어 있습니다. – Haskelier

+0

/tmp/haskell114913-7-1k7mzh6/Zeros.hs:7:28 : 'floor'를 사용하여 발생하는 (RealFrac Int) 인스턴스가 없습니다. 가능한 수정 : (RealFrac Int) 에 대한 인스턴스 선언 추가 식 : floor (n/5^i) '시그마'의 세 번째 인수 인 '(\ i -> floor (n/5^i)) ' 다음 식에서는 시그마 1 n > floor (n/5^i)) – Haskelier

답변

2

문제가 유형 불일치로 인한 것입니다. 마지막으로 truncate을 수행하고 나누기, 지수 및 합계에 분수 산술을 사용하고 끝 부분에서 결과를 자릅니다.

당신에 대해 걱정할 필요가 여기
zeros :: Integral a => a -> a 
zeros n = truncate $ sigma 1 n (\i -> fromIntegral n/5^i) 

세부 사항은 Num b => bIntegral a => a에서 n를 변환 fromIntegral n이다는 ^ 운영자는 Integral a => a 인수를 허용 :이 때문에, 당신은 단지 zeros n = sigma 1 n something보다 조금 더 필요합니다 지수가 있으므로 변환 할 필요가 없습니다. truncateIntegral으로 다시 변환됩니다. 우리는이 서명을 더욱 일반적으로 만들 수 있고 우리가 입력 한 다른 Integral을 반환 할 수 있습니다. 그러나 이것은 실제적으로 유용하지는 않습니다.

그래서 지금 우리가 할 수있는 입력 중 하나 Int 또는 Integer, 당신은 100! 요소 목록을 심하게 먹을려고하고있다 (당신이 100!을 언급 한 이후)이 함수에 입력해야하지만 경고 얼마나 큰 숫자의에 따라 최대 RAM 및 CPU 시간. 당신이 정말로 많은 수의 후행 0을 계산하고자하는 경우, 아마 많게 쉬울 것 같이 문자열로 변환

:

zeros :: (Show a, Integral a) => a -> Int 
zeros = length . takeWhile (== '0') . reverse . show 
+0

문자열이있는 마지막 것이 전체 계승을 계산해야하므로, 그 엄청난 숫자의 본질적으로 작동하지 않습니다. (브라우저 내 IDE의 시간 제한 때문에 첫 번째 브라우저가 작동하지 않습니다.). 나는이 문제가 내 능력을 뛰어 넘는 일종의 진보 된 수학을 필요로한다고 확신한다. – Haskelier

+0

@ Haskelier'fac n = product [2..n]'및'0 = length. takeWhile (== '0'). 반대. 보여 주다 . fac'? – bheklilr

+0

아니, 다시 천천히 ... 모든 댓글은 거기에 수학 트릭의 일종이며, 그것이 당신이 생각하는 것이 아니라고 말하고 있습니다. (www.codewars.com) – Haskelier

1
sigma i k fn = sum $ map fn [i..k] 
zeros n = sigma 1 n (\i -> fromIntegral n/5**(fromIntegral i)) 

하스켈은 정수와 부동 소수점 사이를 자동으로 변환하지 않습니다. 그래서 fromIntegral이 필요합니다.

+0

예상치 못한 타입'a0 -> [c0] '과 실제 타입'[b0]'을 일치시키지 못했습니다. 'map '호출의 리턴 타입에 있음 가능성 있음 원인 : 너무 많은 인수에'map '이 적용됨 '(.)'의 두 번째 인수, 즉'map fn [i .. k] ' 표현식에서 : sum. map fn [i .. k] 적어도 브라우저 내장 인터프리터에서 사용하고 있습니다. – Haskelier

+0

제 잘못입니다. 나는 당신의'시그마 (sigma) '기능을 바꾸었지만 그 점을 달러로 바꾸는 것을 잊었다. 편집을 참조하십시오. – svenningsson

+0

은 작동하지만 100 이상의 숫자는 작동하지 않습니다! 우리가 Int보다 더 큰 것을 허용하기 위해 타입 시그니처를 추가 할 수 있을까요? 나는 몰라. 게시물 수정을 참조하십시오. – Haskelier