Freitag, 8. Juni 2012

Eigenes Tastaturlayout in Linux

Ich habe auf meinen relativ frisch installierten XUbunutu ein Tastaturlayout erstellt, welches die deutsche Tastatur als Basis besitzt, nur dass die Umlaute durch eckige und geschweifte Klammern ersetzt worden ist. Statt dem ö kommt nun [ bzw. mit Shift { und bei ä ] bzw. }. Statt dem ü habe ích auf dieser Taste das @ und den \. Dieses Tastaturschema nutze ich im Prinzip nur wenn ich programmiere, da ich dort keine Umlaute benötige. Notfalls sind die Umlaute aber immer noch über Alt+die jeweilige Taste verfügbar.
Hier eine kurze Zusammenfassung wie das zustatten geht. Am besten das deutsche Tastaturlayout kopieren. Dieses ist zu finden unter /usr/share/X11/xkb/symbols. Dann alles löschen bis auf die erste Konfiguration:
default
xkb_symbols "basic" {
  // der ganze Kram dazwischen
};

Nun können die einzelnen Tasten individualisiert werden, so wie ich das getan habe:
key <AD11> { [ at, backslash, udiaeresis, Udiaeresis ] };
key <AC10> { [ braceleft, bracketleft, odiaeresis, Odiaeresis ] };
key <AC11> { [ braceright, bracketright, adiaeresis, Adiaeresis ] };

Damit das neue Tastaturlayout erkannt werden kann, muss noch in der /usr/share/X11/xkb/rules/evdev.xml im XML-Tag <layoutList> ein neuer Eintrag erfolgen:
<layout>
  <configItem>
    <name>furi</name> <!-- Der Dateiname des Layouts -->
    <shortDescription>DE-Mit Klammern</shortDescription> <!-- Text im Menü -->
    <description>DE-Mit Klammern statt Umlauten</description> 
    <languageList><iso639Id>ger</iso639Id></languageList>
  </configItem>
</layout>

Mittwoch, 6. Juni 2012

Primfaktorzerlegung in Clojure

Habe mal eben schnell (auf Druck einer Person die gerade neben mir sitzt) das Coding Kata der Primfaktorzerlegung in Clojure implementiert. Hier die Lösung:
(defn prime [x] 
  (loop [counter 2
         number x 
         result '()] 
    (if (= 0 (mod number counter)) 
      (recur counter (/ number counter) (conj result counter)) 
      (if (= 1 number) 
        result 
        (recur (inc counter) number result))))) 
Ggf. folgenden noch weitere Lösungen ;-)

Reverse Polish Notation in Clojure - Version 2

Ein weiterer Kollege von mir hat ebenfalls in Clojure eine Lösung für die RPN geschrieben (zu finden hier). Nicht zu verwechseln mit der Scala Lösung von letztem mal (auch hier noch mal der Link ;-)). Ich habe mich auch nochmal dran gesetzt, um weitere Lösungsmöglichkeiten auszuprobieren. Hier ist eine davon. Diese Lösung erstellt eine unendliche Sequnce der einzelen Schritte, in der die RPN aufgelöst wird, dar. Einfach mal selber testen. Denkt bitte daran, die Sequence ist unendlich groß. Also immer nur einen Teil rausholen (zum Beispiel mit range, take oder nth).
(defn calc-next-step [input]
  (if (= 1 (count input)) input
    (loop [[x y] input
           [op & rest-input] (nthnext input 2)
           output ''()]
      (if (number? op)
        (recur [y op] rest-input (concat output (list x)))
        (concat output `(~(op x y)) rest-input )))))

(defn rpn-seq [input]
  (iterate (fn [n] (calc-next-step n)) input))
Der Output kann folgendermaßen aussehen. Ich habe aus Lesbarkeitsgründen die Ausgabe formatiert, und die Clojure-Operatoren durch Zeichen ersetzt, die man dann auch lesen kann ;-). Ansonsten würde der Multiplikator folgendermaßen aussehen:
#<core$_STAR_ clojure.core$_STAR_@3e2f1b1a>

Java toString halt ;-)
Hier die formatierte Ausgabe

(take 5 (rpn-seq (calc-next-step [12 2 3 + 2 * 5 / -])))
((12 5 2 * 5 / -)
(12 10 5 / -)
(12 2 -)
(10)
(10))
Mir ist gerade später aufgefallen, dass der innere Aufruf unnötig ist. Der kann natürlich weggelassen werden ;-). Dann sieht das alles so aus:
(take 5 (rpn-seq [12 2 3 + 2 * 5 / -]))
((12 2 3 + 2 * 5 / -)
(12 5 2 * 5 / -)
(12 10 5 / -)
(12 2 -)
(10))

Reverse Polish Notation in Clojure

Nachdem ein Kollege von mir mal die Reverse Polish Notation (zu deutsch: Umgekehrte Polnische Notation) in Scala implementiert hatte (Link zum Blogeintrag), wollte ich die selbe Aufgabenstellung in Clojure l?sen. Der erste Versuch sah ungefähr so aus:
(ns rpn.core
  (:use [clojure.contrib.string :only (split)]))

(def *operations* {"+" +
                   "-" -
                   "*" *
                   "/" /})

(defn parse-strings [list]
  (map (fn [x] (if (re-find #"^\\d+$" x)
                 (Double/parseDouble x)
                 (*operations* x)))
       list))

(defn rpn [x]
  (let [y (parse-strings (split #"\\s" x))]
    (loop [stack ''()
           rest-of-input y]
      (if (and (= 1 (count stack)) (empty? rest-of-input))
        (first stack)
        (let [next-value (first rest-of-input)]
          (if (number? next-value)
            (recur (conj stack next-value)
                   (rest rest-of-input))
            (recur (conj (nthnext stack 2)
                         (next-value (nth stack 1) (nth stack 0)))
                   (rest rest-of-input))))))))
Da ich länger nichts mehr in Clojure getan hatte, brauchte diese Lösung erstmal seine Zeit und zudem finde ich persönlich diese Lösung irgendwie nicht schön. Aufgrund dessen habe ich mich nochmals dran gesetzt und versucht eine andere Lösung zu finden. Heraus kam das hier:
(ns rpn.core
  (:use [clojure.contrib.string :only (split)]))

(def *operations* {"+" +
                   "-" -
                   "*" *
                   "/" /})

(defn parse-strings [list]
  (map (fn [x] (if (re-find #"^\\d+$" x)
                 (Double/parseDouble x)
                 (*operations* x)))
       list))

(defn rpn [input]
  (reduce (fn [stack op]
            (if (number? op)
              (conj stack op)
              (let [[r l & rest-of-stack] (reverse stack)]
                (conj rest-of-stack (op l r)))))
          []
          (parse-strings (split #"\\s" input))))