2017-06-15 1 views
0

Ich versuche, folgende code ausführen.Clojure Code, Basteln mit: Haupt

Im Folgenden sind die Schritte, die ich nahm:

$ lein new app latinsq 

ich dann geändert project.clj wie folgt:

(defproject latinsq "0.1.0-SNAPSHOT" 
    :description "FIXME: write description" 
    :url "http://example.com/FIXME" 
    :license {:name "Eclipse Public License" 
      :url "http://www.eclipse.org/legal/epl-v10.html"} 
    :dependencies [[org.clojure/clojure "1.8.0"]] 
    :main latinsq.core 
    :target-path "target/%s" 
    :profiles {:uberjar {:aot :all}}) 

und /latinsq/src/latinsq/core.clj

(ns latinsq.core 
    (:use [clojure.set :only (difference)])) 


(defn replace-at 
    "in string s, replaces character at index p with c" 
    [s p c] 
    (str 
    (.substring s 0 p) 
    c 
    (.substring s (inc p)))) 

; memoized function to save time on sqrt calls 
(def sqrt (memoize (fn [x] (Math/sqrt x)))) 


(defn candidates 
    "assuming that the position pos is empty in sq, return those values that it might be" 
    [pos sq] 

    (let [sq-size (int (sqrt (count sq)))] 

        ; set difference between... 
    (difference 
        ; ...all the possible values... 
    (set (map #(first (str %)) (range 1 (inc sq-size)))) 

        ; ...and the set of... 
    (into #{} 
     (concat 
        ; ...those in the same column... 
     (map #(get sq %) 
     (range (rem pos sq-size) 
      (count sq) 
      sq-size)) 
        ; ...and those in the same row. 
     (map #(get sq %) 
     (map #(+ % (- pos (rem pos sq-size))) 
       (range 0 sq-size)))))))) 




(defn latinsq 
    "encode your partial-square as a string like 1--1 
    this fn returns a lazy sequence of all solutions" 
    [sq] 
        ; Find the first empty square 
    (let [empty-pos (.indexOf sq "-")] 

        ; if none, we don't need to do anything 
    (if (= -1 empty-pos) 
     (list sq) 

        ; else make a lazy sequence of... 
     (lazy-seq 
        ; ...the concatenation of all the results of... 
     (apply concat 
        ; ...using "map" to recurse, filling in the empty 
        ; square with... 
      (map #(latinsq (replace-at sq empty-pos %)) 

        ; ...each possible value in turn 
      (candidates empty-pos sq))))))) 




;; So, now some examples 

(time 
(latinsq "123------")) 
;; "Elapsed time: 0.045368 msecs" 
;; ("123231312" "123312231") 

(time 
(latinsq "12---31--------4")) 
;; "Elapsed time: 0.068511 msecs" 
;; ("1243431224313124" "1243431234212134") 


;; A bit harder, an empty 5x5 grid 
;; has 161280 solutions according to 
;; http://mathworld.wolfram.com/LatinSquare.html 
(time 
(count (latinsq "-------------------------"))) 
;; "Elapsed time: 36980.759177 msecs" <--- a bit slow 
;; 161280 


;; Having made sure that our function returns a lazy seq 
;; the whole result can be treated lazily, so to find just one 
;; solution to the 5x5 grid: 
(time 
(first (latinsq "-------------------------"))) 
;; "Elapsed time: 0.985559 msecs"  <--- not slow 
;; "1234521453345124523153124" 

;; first 3 of 5524751496156892842531225600 solutions for a 9x9 grid 
(time 
(take 3 (latinsq "---------------------------------------------------------------------------------"))) 
;; "Elapsed time: 0.075874 msecs" 
;; ("123456789214365897341278956432189675567891234658917342789523461896742513975634128" 
;; "123456789214365897341278956432189675567891234658917342789523461975634128896742513" 
;; "123456789214365897341278956432189675567891234658917342789524163896743521975632418") 

Ich erhalte den folgenden Fehler:

Exception in thread "main" java.lang.Exception: Cannot find anything to run for: latinsq.core, compiling:(/tmp/form-init4810859530587029884.clj:1:73) 
     at clojure.lang.Compiler.load(Compiler.java:7391) 
     at clojure.lang.Compiler.loadFile(Compiler.java:7317) 
     at clojure.main$load_script.invokeStatic(main.clj:275) 
     at clojure.main$init_opt.invokeStatic(main.clj:277) 
     at clojure.main$init_opt.invoke(main.clj:277) 
     at clojure.main$initialize.invokeStatic(main.clj:308) 
     at clojure.main$null_opt.invokeStatic(main.clj:342) 
     at clojure.main$null_opt.invoke(main.clj:339) 
     at clojure.main$main.invokeStatic(main.clj:421) 
     at clojure.main$main.doInvoke(main.clj:384) 
     at clojure.lang.RestFn.invoke(RestFn.java:421) 
     at clojure.lang.Var.invoke(Var.java:383) 
     at clojure.lang.AFn.applyToHelper(AFn.java:156) 
     at clojure.lang.Var.applyTo(Var.java:700) 
     at clojure.main.main(main.java:37) 
Caused by: java.lang.Exception: Cannot find anything to run for: latinsq.core 
     at user$eval5.invokeStatic(form-init4810859530587029884.clj:1) 
     at user$eval5.invoke(form-init4810859530587029884.clj:1) 
     at clojure.lang.Compiler.eval(Compiler.java:6927) 
     at clojure.lang.Compiler.eval(Compiler.java:6917) 
     at clojure.lang.Compiler.load(Compiler.java:7379) 
     ... 14 more 

Aus der Forschung, die ich getan habe, wird das Problem durch den Namen auf: main verursacht. Ich habe ein paar Mal daran herumgebastelt und ich konnte das nicht zur Arbeit bringen. Liegt das daran, dass "latinsq" zu oft im Verzeichnisbaum angezeigt wird? Oder, ich verstehe das Ausführen des Codes nicht richtig.

Alternativ kann, wenn ich es endlich zu laufen bekommen, die einzige Ausgabe ist:

"Elapsed time: 0.468492 msecs" 
"Elapsed time: 0.0796 msecs" 

Antwort

1

Sie haben vergessen -main Funktion zu definieren - diese wird automatisch generiert von Leiningen in Kern-Namespace. Sie haben auch nicht angegeben, wie Sie versuchen, die Anwendung auszuführen, aber ich nehme an, dass Sie einfach lein run aufrufen. Solange Sie Ihrem Namensraum die Funktion -main hinzufügen, sollte es funktionieren. Ich empfehle auch, die Funktionsaufrufe latinsq in eine andere Funktion zu wickeln, um zu vermeiden, sie zu bewerten, wenn Namespace geladen wird.

Btw. dies ist die volle Leistung, die ich bekam (unmodifiziert -main von Leiningen erzeugt: ein. lein run "Elapsed time: 0.183692 msecs" "Elapsed time: 0.055872 msecs" "Elapsed time: 68742.261628 msecs" "Elapsed time: 1.361745 msecs" "Elapsed time: 0.045366 msecs" Hello, World!

+0

Dies führt mich zu zwei Fragen Die erste, wie kann ich/wo verwende ich die -main ich es an verschiedenen Orten platziert. versuchen, einen Zusammenhang zu bekommen, zweitens, sollte es nicht eine Art von String-Ausgabe geben? Die String-Ausgabe ist, was ich am meisten interessiert bin. – emka

+0

Auch ich habe nur lein run. – emka

+0

@ emka 1. Als Ich sagte, die '-main'-Funktion wird automatisch im 'core'-Namespace generiert, es sieht so aus: https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L205 2. Ich bin mir nicht sicher, was Sie mit "String-Ausgabe" meinen, aber wenn Sie Ausgabe auf Komma erhalten möchten Zeile muss nur in die Standardausgabe geschrieben werden (vermutlich mit 'println' Funktion) –