2010-05-23 4 views
3

모두, Clojure의 Euler Project에서 어제 작업을 시작했는데 알아 내지 못하는 해결책 중 하나에 문제가 있습니다. 나는 이런 식으로 그것을 실행하려고Clojure 함수의 문제점

(defn find-max-palindrom-in-range [beg end] 
    (reduce max 
      (loop [n beg result []] 
      (if (>= n end) 
       result 
       (recur (inc n) 
        (concat result 
          (filter #(is-palindrom? %) 
            (map #(* n %) (range beg end))))))))) 

:

(find-max-palindrom-in-range 100 1000) 

을 나는이 예외 얻을 : 나는 가정

java.lang.Integer cannot be cast to clojure.lang.IFn 
    [Thrown class java.lang.ClassCastException] 

가에 있음을 의미를

나는이 기능이 어떤 곳에서는 Integer를 함수로 평가하려고합니다. 그러나 나는이 곳을 찾아 무엇보다 저를 난처하게하는 것은 단순히 이런 식으로 평가하면 모든 것이 작동하지 수 (상수 매개 변수 난 그냥 함수 정의를 제거했습니다 교체)

(reduce max 
      (loop [n 100 result []] 
      (if (>= n 1000) 
       result 
       (recur (inc n) 
        (concat result 
          (filter #(is-palindrom? %) 
            (map #(* n %) (range 100 1000)))))))) 

사전에 도움을 주셔서 감사 드리며 미안하지만 바보 같은 실수로 귀찮게 생각합니다. Btw 나는 Clojure 1.1과 ELPA의 최신 SLIME을 사용하고있다.

편집 : 여기 코드는 is-palindrom입니까?. 숫자의 텍스트 속성으로 구현했습니다. 숫자가 아닌.

(defn is-palindrom? [n] 
    (loop [num (String/valueOf n)] 
    (cond (not (= (first num) (last num))) false 
      (<= (.length num) 1) true 
      :else (recur (.substring num 1 (dec (.length num))))))) 
+1

나는 문제가'입니다 - 회문 생각? 당신의'찾기-MAX-회문 -에 - range'을 나는'없는-회문을 구현할 때 나를 위해 작동?' – Jonas

+0

이후'기능 is-palindrom의 코드를 추가 했습니까? 질문에. –

+0

Clojure에서'is-palindom? '의 더 좋은 이름은'palindrome?'입니다. –

답변

6

이 코드는 내 REPL (1.1)에서 작동합니다. 나는 그것을 당신의 것으로 다시 붙여 넣고 다시 시도 할 것을 제안합니다 - 아마 당신은 단순히 뭔가 잘못 입력 했습니까?

이렇게 말하면 코드를 더 간단하고 분명하게 수정하는 기회로 사용할 수 있습니다. 일부 낮은 교수형 과일 (당신이 당신의 논리가 이미 써와 나는 그것을해야하지 생각하지만 그것은 당신의 프로젝트 오일러 재미로 데려 갈 수 있다고 생각하면 읽지 않는다) :

  1. 당신은 필요가 없습니다 익명 함수로 is-palindrome?을 랩핑하여 filter으로 전달하십시오. 대신 (filter is-palindrome? ...)으로 작성하십시오.

  2. loopis-palindrome?은 꽤 복잡합니다. 또한 특별히 효율적이지는 않습니다 (firstlast). 문자열에서 seq을 먼저 추출한 다음 last을 모두 통과해야합니다. (require '[clojure.contrib.str-utils2 :as str])은 더 간단하고 빠르며 (= num (str/reverse num))을 사용합니다. 그것은 게으른 서열, 당신은 게으름이 개 많은 수준을 쌓아 경우이 오일러의 맥락에서 중요하지 않습니다 (날려 버릴 수 생성 -이 방법으로 concat를 사용하여 내가 효율성을 언급 한 이후

  3. 은, 조금 위험하다 4, 그러나 그것을 명심하는 것이 좋다). 벡터를 오른쪽으로 확장해야한다면 into을 선호합니다.

  4. 더 단순하게하기 위해, 주어진 시퀀스를 필터링하여 회문 만 남기고 별도의 함수를 사용하여 두 세 자리 숫자의 모든 제품을 반환하는 방법을 생각해 볼 수 있습니다. 후자는 예를 들어,

    (for [f (range 100 1000) 
         s (range 100 1000) 
         :when (<= f s)] ; avoid duplication of effort 
        (* f s)) 
    
+0

+1에서 위대한 제안입니다. 나는 Clojure와 함수형 프로그래밍에 익숙하지 않기 때문에 스타일이 좋지 않다는 것을 알고있다. 코드를 개선하는 데 유용한 팁을 듣는 것이 좋습니다. REPL에서 여러 번 코드를 시도했지만 간단히 작동하지 않는다고했습니다. 그리고 기본적으로 그 안에 내 코드에서 아무것도 없기 때문에 나는 스택 추적에서 머리와 꼬리를 만들 수 없습니다 ... –

+0

정말 이상합니다. :-(내가 말하고 싶지만 신선한 REPL로 한번 더 시도해보십시오. 작동하지 않으면 사용중인 코드와 어딘가에 스택 추적을 붙여 넣을 수 있고 여기에 링크를 게시 할 수 있습니까? 내 열등한 혀짤배기 프로세스를 죽이고 시작 –

+0

이 다시 난 아직도 원래의 문제가 무엇인지 의아해하고 있습니다.이 문제를 해결,하지만 난 도움을 주셔서 감사합니다. 그 듣고 해피 –