Last active
September 5, 2017 19:29
-
-
Save pataprogramming/06a3d8ea82365b1ccdce5418fac121ca to your computer and use it in GitHub Desktop.
PhillyDev Slack #daily_programmer 2017-09-05 - Testing word alphabetization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns daily.ordering | |
;; Include [org.clojure/core.match "0.3.0-alpha5"] in project deps | |
(:require [clojure.core.match :refer [match]] | |
[clojure.string :as string]) | |
(:import java.text.Normalizer)) | |
(defn ordered? | |
([coll] | |
(ordered? compare coll)) | |
([^java.util.Comparator cmp coll] | |
(every? #(<= (apply cmp %) 0) (partition 2 1 (seq coll))))) | |
(def ascending? ordered?) | |
(def descending? (partial ordered? (comp - compare))) | |
(defn ordering [coll] | |
(if-let [s (seq coll)] | |
(match [(ascending? s) (descending? s)] | |
[false false] :unordered | |
[false true] :descending | |
[true false] :ascending | |
[true true] :both) | |
:empty)) | |
;; Taken from github.com/expez/superstring | |
(defn strip-accents | |
"Strip all accents (diacritical marks) from s. | |
Et ça sera sa moitié => Et ca sera sa moitie" | |
^String [^String s] | |
{:pre [(string? s)] | |
:post [(string? %)]} | |
(-> s | |
(Normalizer/normalize java.text.Normalizer$Form/NFD) | |
(.replaceAll "\\p{InCombiningDiacriticalMarks}+" ""))) | |
(defn strip-apostrophes [^String s] | |
(.replaceAll s "'" "")) | |
(defn normalize-word [s] | |
"If s is a word, translate it to a form consisting of only the unaccented, | |
lower-case version of its letters, with all acccents and apostrophes removed; | |
if s contains spaces or any characters than cannot be identified as letters, | |
returns nil." | |
(some->> s | |
strip-accents | |
strip-apostrophes | |
string/lower-case | |
(re-matches #"[a-z]+"))) | |
(defn categorize [s] | |
(if (normalize-word s) | |
(ordering s) | |
:not-a-simple-word)) | |
(defn describe [s] | |
(str "'" s "' " | |
(if-let [n (normalize-word s)] | |
(case (ordering n) | |
:ascending "is in alphabetical order" | |
:descending "is in reverse alphabetical order" | |
:both "is in both alphabetical and reverse alphabetical order" | |
"is not in alphabetical order") | |
"is not a word composed of the letters 'a' to 'z'."))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment