Какова самая полезная вещь, которую Вы сделали меньше чем в 50 строках Clojure?

Если компилятор реализовал то, что вы хотели добросовестно, тогда он привязал регистр CPU для длины вашей программы. Это вряд ли практично.

Помните, что register является только рекомендательным.

25
задан anon 11 August 2009 в 16:42
поделиться

8 ответов

Распечатывает прогноз погоды через 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
15
ответ дан 28 November 2019 в 20:49
поделиться

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)

http://99-bottles-of-beer.net/language-clojure-1996.html

6
ответ дан 3 revs, 2 users 73% 15 October 2019 в 16:01
поделиться

Clojure, вероятно, имеет степенную функцию, но я был очень взволнован, когда понял это:

(defn pow [base exp] (reduce * (replicate exp base)))
4
ответ дан Ronald 15 October 2019 в 16:01
поделиться

Ну, этот код действительно предназначен для меня и больше ни для кого. Я бросил это вместе через двадцать минут на днях для курса по марковским процессам. Я конечно нашел это полезным. Я использовал это, чтобы убедить профессора в том, что мой теоретический анализ проблемы был правильным. Честно говоря, классная штука (я думаю!) На самом деле - только первая функция, 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)]] (⇒ (ω ξ) ξ (⟲ (Δ Ξ ξ))))))
1
ответ дан galdre 15 October 2019 в 16:01
поделиться

Сам по себе не особо полезен, но идея похожа на 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.

9
ответ дан 28 November 2019 в 20:49
поделиться

Создает эскиз из изображения. Изображение может быть локальным файлом, удаленным 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)
6
ответ дан 28 November 2019 в 20:49
поделиться

При написании приложений 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))

Прямо сейчас мне не нужны подменю, но для их получения достаточно просто изменить новое-меню . Также добавление значков, активного / неактивного состояния и т. Д. - это просто дополнительные поля в меню .

2
ответ дан 28 November 2019 в 20:49
поделиться

Самая полезная вещь, которую я написал для себя на 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))
6
ответ дан 28 November 2019 в 20:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: