7807


CodeEvalのSimpleSortingの解法に関する質問です。  
<https://www.codeeval.com/open_challenges/91/>

以下のコードを実行すると、Float型のソートがうまく行きません。  
(-10.000, -1.000, -2.000) -> (-1.000, -2.000, -10.000)

なぜなのか、ヒントを教えてください。

[code]

    (ns simple-sorting.core
      (:use [clojure.string :only [split join]])
      (:gen-class))
    
    (defn splt-num [s]
      (split s #" "))
    
    (defn str->num [coll]
      (map read-string coll))
    
    (defn num->float3 [coll]
      (vec (map #(format "%.3f" %1) coll)))
    
    (with-open [rdr (clojure.java.io/reader (first *command-line-args*))]
      (doseq [line (remove empty? (line-seq rdr))]
        (def nums (splt-num line))
        (def nss (str->num nums))
        (def f3 (num->float3 nss))
        (println (join " " (sort f3)))))
    
[/code]


CC BY-SA 3.0
2015-03-11T21:34:09.880
7804
2015-03-11T23:35:02.487
8623
question
clojure
Clojureのsortシンボルに関して


`num->float3`で数値を文字列にしてしまってからソートしていることが原因です。文字列としてのソートだと、うまくいく場合もありますが、`["-10.000"
"-1.000" "-2.000"]` -> `["-1.000" "-10.000" "-2.000"]`のようにうまくいかない場合もあります。  
文字列への変換とソートの順序を逆にするといいでしょう。

[code]

    (with-open [rdr (clojure.java.io/reader (first *command-line-args*))]
      (doseq [line (remove empty? (line-seq rdr))]
        (let [nums (-> line splt-num str->num sort)]
          (println (join " " nums)))))
    
[/code]

なお、Clojureでは`def`で定義された変数は、関数定義やletの中であっても常に名前空間のトップレベルに定義されてしまうので、上のようにletを使うなどしてローカル変数にする方がよりよいスタイルとされています。


CC BY-SA 3.0
2015-03-11T23:35:02.487
7807
2015-03-11T23:35:02.487
496
7804
answer