Erik Wognsen avatar Erik Wognsen committed 2f13d13

Added Haskell version of charfreq

Comments (0)

Files changed (1)

+
+-- Erik Ramsgaard Wognsen, 2011
+-- This work is placed in the public domain.
+
+import Data.Char
+import Data.List (elemIndices, sortBy, intercalate)
+import Data.Function (on)
+import qualified Data.Set as Set
+import Text.Printf (printf)
+
+main = interact charfreq
+
+barGraphWidth = 60
+maxNumCharsToShow = 100
+
+homeKeysColemak = "arstneio"
+homeKeysDvorak = "aoeuhtns"
+-- homeKeysQwerty = "asdfjkl;:"
+homeKeysQwerty = "asdfjklæ"  -- Danish
+
+charfreq input =
+    let
+        text = filter (not . isSpace) $ map toLower input
+    in
+        if
+            null text
+        then
+            "Not enough input to analyze.\n"
+        else
+            let
+                totalCount = length text
+                unique = Set.toList $ Set.fromList $ text
+                charCountPairs = [(char, length $ elemIndices char text) | char <- unique]
+                charCountPairsSorted = reverse $ sortBy (compare `on` snd) charCountPairs
+                maxCount = snd $ head charCountPairsSorted
+                charCountPairsRanked = zip [1..] charCountPairsSorted
+                formattedRows = map (formatRow maxCount totalCount barGraphWidth) charCountPairsRanked
+            in
+                unlines $ take maxNumCharsToShow formattedRows
+
+formatRow :: Int ->   Int ->     Int ->        (Int,  (Char, Int))   -> String
+formatRow    maxCount totalCount barGraphWidth (rank, (char, count)) =
+    let
+        barSize = barGraphWidth * count `div` maxCount
+        percentage = (fromIntegral count) / (fromIntegral totalCount) * 100 :: Float
+    in
+        intercalate "   "
+            [ printf "%6d" rank
+            , [char]
+            , if elem char homeKeysQwerty  then "Q" else " "
+            , if elem char homeKeysDvorak  then "D" else " "
+            , if elem char homeKeysColemak then "C" else " "
+            , printf "%6d" count
+            , printf "%5.2f" percentage ++ "%"
+            , replicate barSize '#'
+            ]
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.