Если компилятор реализовал то, что вы хотели добросовестно, тогда он привязал регистр CPU для длины вашей программы. Это вряд ли практично.
Помните, что register
является только рекомендательным.
Распечатывает прогноз погоды через Yahoo! Погода .
(ns weather
(:use (clojure [xml :only [parse]] [zip :only [xml-zip]])
(clojure.contrib duck-streams str-utils pprint)
(clojure.contrib.zip-filter xml)))
(defn fetch-xml [uri]
(xml-zip
(parse
(org.xml.sax.InputSource.
(java.io.StringReader.
(slurp* (java.net.URI. (re-gsub #"\s+" "+" (str uri)))))))))
(defn yahoo-weather
([loc-code] (yahoo-weather loc-code "c"))
([loc-code unit]
(let [rss (fetch-xml (str "http://weather.yahooapis.com/forecastrss?p=" loc-code "&u=" unit))]
(if (= (text (xml1-> rss :channel :item :title)) "City not found")
"City not found. Go to http://weather.yahoo.com/, search for your city, and look in the URL for the location code."
(let [[units loc wind atm ast] (map #(xml1-> rss :channel (keyword (str "yweather:" %)))
["units" "location" "wind" "atmosphere" "astronomy"])
conditions (xml1-> rss :channel :item :yweather:condition)
date (re-find #"\d+:\d+.*" (xml1-> rss :channel :item :pubDate text))
fors (xml-> rss :channel :item :yweather:forecast)]
(cl-format true
"Weather for ~a, ~a (~a)
Temperature: ~a\u00B0 ~a
Wind Chill: ~a\u00B0 ~a, ~a ~a
Conditions: ~a
Humidity: ~a%
Barometer: ~a ~a
Sunrise/Sunset: ~a / ~a
Forecast:
~{ ~{~a: ~a. Hi ~2d, Lo ~2d.~}~^~%~}
"
(attr loc :city) (attr loc :region) date
(attr conditions :temp) (attr units :temperature)
(attr wind :chill) (attr units :temperature) (attr wind :speed) (attr units :speed)
(attr conditions :text)
(attr atm :humidity)
(attr atm :pressure) (attr units :pressure)
(attr ast :sunrise) (attr ast :sunset)
(map #(list (attr % :day)
(attr % :text)
(attr % :high)
(attr % :low))
fors)))))))
Например:
user> (weather/yahoo-weather "CAXX0328")
Weather for North Vancouver, (10:00 am PDT)
Temperature: 14° C
Wind Chill: 14° C, 8.05 kph
Conditions: Light Rain Shower
Humidity: 88%
Barometer: 1018 mb
Sunrise/Sunset: 6:01 am / 8:32 pm
Forecast:
Thu: Few Showers. Hi 18, Lo 12.
Fri: AM Showers. Hi 19, Lo 12.
nil
99 бутылок пива
(defn bottles [n & [capitalize]]
(str (if (> n 0) n (if capitalize "No more" "no more"))
" bottle" (if (= 1 n) "" "s") " of beer" ))
(defn bot-wall [n & cap] (str (bottles n cap) " on the wall"))
(defn sing
; Default is 99 times.
([] (sing 99))
([stock]
(doseq [i (range stock -1 -1)]
(printf "%s, %s.\n%s.\n\n"
(bot-wall i true) (bottles i)
(apply str
(if (> i 0)
["Take one down and pass it around, " (bot-wall (dec i))]
["Go to the store and buy some more, " (bot-wall stock)]
))))))
(sing)
Clojure, вероятно, имеет степенную функцию, но я был очень взволнован, когда понял это:
(defn pow [base exp] (reduce * (replicate exp base)))
Ну, этот код действительно предназначен для меня и больше ни для кого. Я бросил это вместе через двадцать минут на днях для курса по марковским процессам. Я конечно нашел это полезным. Я использовал это, чтобы убедить профессора в том, что мой теоретический анализ проблемы был правильным. Честно говоря, классная штука (я думаю!) На самом деле - только первая функция, sample
. Я использую подобную функцию во многих своих проектах, и каким-то образом, спеша взломав это, я наткнулся на свое лучшее решение.
(defn sample
"Samples once a discrete random distribution defined by
a vector. E.g., (sample [0.25 0.2 0.1 0.45]) should output
'0' 25% of the time, '1' 20% of the time, etc."
[p]
(let [r (rand)]
(count (take-while #(< % r) (reductions + p)))))
(defn transition
"Given a transition matrix and a history vector, returns
the history with an additional time step added."
[m h]
(conj h (sample (nth m (last h)))))
(defn process-gen
"Takes a transition probability matrix, initial state
probabilities, and a function.
The initial state probs should take the form [p .. q].
The function should accept the full process history
and return true if the process should stop.
Returns a function of no arguments that returns a full
simulated history of the process."
[m i f]
(fn [] (loop [h [(sample i)]] (if (f h) h (recur (transition m h))))))
(defn transition2
"Given a transition matrix and the current state, returns
a sampled state for the next time step."
[m s]
(sample (nth m s)))
(defn lazy-process
"Takes a transition probability matrix, initial state
probabilities, and a function.
The initial state probs should take the form [p .. q].
Returns a function which, when run, produces an infinite
lazy list sampling the process."
[m i]
(fn [] f
([] (f (sample initial)))
([s] (let [i (transition2 m s)]
(cons i (lazy-seq (f i)))))))
Удаление комментариев:
(defn sample [p]
(let [r (rand)]
(count (take-while #(< % r) (reductions + p)))))
(defn transition [m h]
(conj h (sample (nth m (last h)))))
(defn process-gen [m i f]
(fn [] (loop [h [(sample i)]] (if (f h) h (recur (transition m h))))))
(defn transition2 [m s]
(sample (nth m s)))
(defn lazy-process-gen [m i]
(fn [] f
([] (f (sample initial)))
([s] (let [i (transition2 m s)]
(cons i (lazy-seq (f i)))))))
Пример использования:
user=>(def squirrel-matrix [[0.8797 0.0212 0.0981 0.0010]
[0.0382 0.8002 0.0273 0.1343]
[0.0527 0.0041 0.8802 0.0630]
[0.0008 0.0143 0.0527 0.9322]])
user=>(def my-process (process-gen squirrel-matrix [1 0 0 0] #(and (> (count %) 1) (= 0 (last %)))))
user=> (/ (reduce + (map (comp dec count) (repeatedly 1000000 my-process))) 1000000.)
5.820319
user=> (let [hs (reduce + (filter #(> % 1) (map (comp dec count) (repeatedly 1000000 my-process))))] (/ (reduce + hs)) (count hs)))
5002699/120880 ; ~41.386
Эти два числа отвечают, через довольно чрезмерное моделирование, двум различным интерпретациям вопроса здесь .
Я должен признаться, что немного почистил свой код для всех вас. В тот день, когда я написал это, я обнаружил, что Clojure разрешил Unicode в именах символов. Возможно, я изменил немного из-за изменения языка. ;-) Итак ... эти первые три функции на самом деле выглядят так в моем файле!
(Λ σ [p] (let [r (rand)] (|| (take-while #(< % r) (∮ + p)))))
(Λ Δ [Ξ ξ] (⊞ ξ (σ (§ Ξ (last ξ)))))
(Λ Π [Ξ i ω] (λ [] (⟳ [ξ [(σ i)]] (⇒ (ω ξ) ξ (⟲ (Δ Ξ ξ))))))
Сам по себе не особо полезен, но идея похожа на JSON в Javascript - вы можете перемещать структуры данных Clojure в файловую систему и из нее. Взято из Практическая база данных Common Lisp , пример:
(ns storage (:import (java.io File PushbackReader FileReader FileWriter)))
(defn load-data
"Loads data from the given file."
[filepath]
(do
;; the let block creates the file if it doesn't exist
;; reader throws an exception if there's no parsable data struct
(let [file (new File filepath)]
(if (not (.exists file))
(do
(.createNewFile file)
(doto (new FileWriter filepath) (.write "{}") .close))))
(read (new PushbackReader (new FileReader filepath)))))
(defn dump-data
"Exports data structure to a file."
[filepath data]
(doto (new FileWriter filepath) (.write (str data)) .close))
Пример использования:
user=> (dump-data "test.dat" {:a [1 2 3] :b "hello" :c true})
#<FileWriter java.io.FileWriter@186df0f>
user=> (load-data "test.dat")
{:a [1 2 3], :b "hello", :c true}
Определенно лучше, чем написание собственного (сложного) механизма сохранения для вашей программы. Я уверен, что чтение чисто из строки возможно, просто изменив некоторые программы чтения, предоставляемые через Java.
Создает эскиз из изображения. Изображение может быть локальным файлом, удаленным URL-адресом или чем-то еще, что javax.imageio.ImageIO
может прочитать (спасибо, Java!). Вывод может быть в любом формате изображения javax.imageio.ImageIO
может записывать.
(use '(clojure.contrib java-utils)) (defn make-thumbnail "Given an input image (File, URL, InputStream, ImageInputStream), output a smaller, scaled copy of the image to the given filename. The output format is derived from the output filename if possible. Width should be given in pixels." ([image out-filename width] (if-let [format (re-find #"\.(\w+)$" out-filename)] (make-thumbnail image out-filename width (nth format 1)) (throw (Exception. "Can't determine output file format based on filename.")))) ([image out-filename width format] (let [img (javax.imageio.ImageIO/read image) imgtype (java.awt.image.BufferedImage/TYPE_INT_RGB) width (min (.getWidth img) width) height (* (/ width (.getWidth img)) (.getHeight img)) simg (java.awt.image.BufferedImage. width height imgtype) g (.createGraphics simg)] (.drawImage g img 0 0 width height nil) (.dispose g) (javax.imageio.ImageIO/write simg format (as-file out-filename)))))
Создать эскиз JPG из локального PNG:
(make-thumbnail (java.io.File. "some-image.png") "thumb.jpg" 150)
Создать эскиз GIF из удаленного JPG:
(make-thumbnail (java.net.URL. "http://blog.stackoverflow.com/wp-content/uploads/justice-league-small.jpg") "small.gif" 250)
При написании приложений Swing элементы JMenuBar всегда раздражают. Благодаря dorun / map это намного проще:
(let [menus
[
{:name "File" :mnemonic \F
:items
[
{:name "Open" :mnemonic \O :fn file-open}
:separator
{:name "Exit" :mnemonic \x :fn file-exit}
]
}
{:name "Help" :mnemonic \H
:items
[
:separator
{:name "About..." :mnemonic \A :fn help-about}
]
}
]
menu-fns
(into
{}
(mapcat
(fn [menu]
(map
(fn [item] [(:name item) (:fn item)])
(:items menu)))
menus))
ui-frame
(proxy [JFrame ActionListener] ["UI Frame"]
(actionPerformed
[event]
(let [command (.getActionCommand event)
menu-fn (get menu-fns command)]
;; Handle menu commands
(if menu-fn
(apply menu-fn [this]))
))
)
]
(defn new-menu [listener]
(let [menubar (JMenuBar.)]
(dorun
(map
(fn [x]
(let [menu (JMenu. (:name x))]
(.setMnemonic menu (int (:mnemonic x)))
(.add menubar menu)
(dorun
(map
(fn [item]
(if (= :separator item)
(.addSeparator menu)
(let [menu-item
(if (:mnemonic item)
(JMenuItem. (:name item) (int (:mnemonic item)))
(JMenuItem. (:name item)))]
(.addActionListener menu-item listener)
(.add menu menu-item))))
(:items x)))))
menus))
menubar))
Прямо сейчас мне не нужны подменю, но для их получения достаточно просто изменить новое-меню
. Также добавление значков, активного / неактивного состояния и т. Д. - это просто дополнительные поля в меню
.
Самая полезная вещь, которую я написал для себя на Clojure, - это почти тривиальная функция:
(defn tally-map
" Create a map where the keys are all of the unique elements in the input
sequence and the values represent the number of times those elements
occur. Note that the keys may not be formatted as conventional Clojure
keys, i.e. a colon preceding a symbol."
[aseq]
(apply merge-with + (map (fn [x] {x 1}) aseq)))
Я использую ее все время в работе делаю. Очень полезно для гистограмм.
Брайан Карпер любезно предложил следующую улучшенную форму функции:
(defn tally-map [coll]
(reduce (fn [h n]
(assoc h n (inc (or (h n) 0))))
{} coll))