2009-09-30 8 views
2

저는 Euler 프로젝트에서 문제 99를 푸는데 Haskell을 사용하고 있습니다. 여기서 기본 지수 쌍 목록에서 최대 결과를 찾아야합니다.지도를 Haskell에서리스트로 사용하는 문제

내가이 함께했다 :

숫자 양식에
prob99 = maximum $ map ((fst)^(snd)) numbers 

:

numbers = [[519432,525806],[632382,518061],[78864,613712].. 

하지 않는 이유는이 작품? 숫자의 형식을 변경해야합니까? 좀 더 효율적인 지수 연산과 같은 간단한 최적화가 있습니까?

+1

는 @Jonno_FTW : B 다음 hoogle 토론에 대해 나는 당신이 수 또한 제 1 및 제 2 요소 밖으로 패턴 일치, 즉 최대 $지도 (\ (A hlint 너무 – yairchu

답변

4

fst와 snd는 쌍 (형식 fst :: (a, b) -> a 및 snd :: (a, b) -> b)으로 정의되기 때문에. 그리고 두 번째 문제는 (fst)^(snd)와 함께, 당신은 기능에 대한 기능을 강화할 수 없습니다.

prob99 = maximum $ map (\xs -> (head xs)^(head (tail xs))) numbers 

또는 작동하지 않습니다 무엇

prob99 = maximum $ map (\xs -> (xs !! 0)^(xs !! 1)) numbers 
+0

을 살펴 가지고하는 것이 좋습니다 > a^b) 숫자 – Will

+3

또는 심지어 :'(\ [a, b] -> a^b) ' – sth

5

는 프로그램의 유형 일관성이다. 함수 (^), 단순화 된 유형 Int -> Int -> Int(a,a) -> a (Int가 아님) 인수에 적용하려고합니다.

가장 쉬운 방법은 목록 목록 대신 쌍 목록을 직접 생성하는 것입니다. 그런 다음 (거의) 직접적으로 (^) 함수를 적용하여 먼저 uncurrying 할 수 있습니다. 당신이 당신의 하위 목록에 붙어있는 경우

numbers = [(519432,525806),(632382,518061),(78864,613712)... 
prob99 = maximum $ map (uncurry (^)) numbers 

, 당신은 Matajon의 솔루션에 약간의 개선, 직접 패턴과 일치 수 : 모든 지점이없는 스타일에 있다면

prob99 = maximum $ map (\[x,y] -> x^y) numbers 

또는, 그런데, 당신은 Control.Arrow에있는 통신 수를 잘 활용할 수 있습니다. (상세가는이 경우에 훨씬까지 도움이되지 않는)

prob99 = maximum $ map ((!!0) &&& (!!1) >>> uncurry (^)) numbers 
+0

주 목록의 어떤 위치에 최대 숫자가 나타나는지 어떻게 알 수 있습니까? –

+0

그건 완전히 다른 질문입니다! 한 가지 분명한 방법은 최대 값을 먼저 찾은 다음 색인을 찾는 것입니다. 그러나 목록을 느리게 생성하는 이점은 대부분 낭비됩니다. 더 좋은 방법이 있지만, 당신이하려는 일에 대해 더 많은 맥락이 필요합니다. (덧없는 것보다 더 많은 공간이 필요합니다.) –

+0

Prelude에는 'uncurry'가 있는데, 'Data.Function'에서 가져올 필요가 없습니다. – Nefrubyr

12

하는 사람에게 물고기를주고, 당신에게, 하루 동안 그에게 먹이 물고기 수있는 사람을 가르치고,거야 ' 일생 동안 그를 먹일거야.

Jonno, GHC의 오류 메시지가 당신을 도울 수있는 방법과 "undefined drop in"방법을 배우는 것이 좋습니다 (지금 당장 집중 해 보겠습니다). - _) :

ghci> let numbers = [[519432,525806],[632382,518061]] 
ghci> -- so far so good.. 
ghci> let prob99 = maximum $ map ((fst)^(snd)) numbers 

<Bam! Some type error> 

ghci> -- ok, what could have gone wrong? 
ghci> -- I am pretty sure that this part is fine: 
ghci> let prob99 = maximum $ map undefined numbers 
ghci> -- yes, it is fine 
ghci> -- so the culprit must be in the "((fst)^(snd))" part 
ghci> let f = ((fst)^(snd)) 

<Bam! Some type error> 

ghci> -- whoa, so this function never makes sense, not just where I used it.. 
ghci> -- is it doing what I think it is doing? lets get rid of those braces 
ghci> let f = fst^snd 

<Bam! Same type error> 

ghci> -- yeah I got my syntax right alright 
ghci> -- well, can I exponent fst? 
ghci> let f = fst^undefined 

No instance for (Num ((a, b) -> a)) 
    arising from a use of '^' at <interactive>:1:8-22 
Possible fix: add an instance declaration for (Num ((a, b) -> a)) 
In the expression: fst^undefined 
In the definition of 'f': f = fst^undefined 

ghci> -- duh, fst is not a Num 
ghci> -- this is what I wanted: 
ghci> let f x = fst x^snd x 
ghci> -- now lets try it 
ghci> let prob99 = maximum $ map f numbers 

<Bam! Some type error> 

ghci> -- still does not work 
ghci> -- but at least f makes some sense now 
ghci> :t f 

f :: (Num a, Integral b) => (a, b) -> a 

ghci> -- lets find an example input for it 
ghci> head numbers 

[519432,525806] 

ghci> :t head numbers 

head numbers :: [Integer] 

ghci> -- oh, so it is a list of two integers and not a tuple! 
ghci> let f [a, b] = a^b 
ghci> let prob99 = maximum $ map f numbers 
ghci> -- no error? 
ghci> -- finally I got the types right!