Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Subanagram Generator in Elm
rm subanagram.js; elm-make SubanagramGenerator.elm --output subanagram.js
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Subanagram Generator</title>
<script type="text/javascript" src="subanagram.js"></script>
</head>
<body>
</body>
<script>
Elm.SubanagramGenerator.fullscreen();
</script>
</html>
port module SubanagramGenerator exposing (..)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Html.App as App
import String exposing (toLower, toList)
import Ni2Dictionary
import Char exposing (isLower)
import Dict exposing (Dict)
import Exts.Dict exposing (frequency)
-- model
type alias Model =
{ word : String
, input : String
, subanagrams : List String
}
initModel : Model
initModel =
{ word = ""
, input = ""
, subanagrams = []
}
-- update
type Msg
= GetSubanagrams
| Input String
getCharacterFrequencies : String -> Dict Char Int
getCharacterFrequencies givenWord =
toLower givenWord
|> toList
|> List.filter isLower
|> frequency
checkBank : Dict Char Int -> Char -> Int
checkBank bank letter =
let
value = Dict.get letter bank
in
case value of
Just value -> value
Nothing -> 0
compareWords : String -> String -> Bool
compareWords parent child =
let
parentDict = getCharacterFrequencies parent
childDict = getCharacterFrequencies child
parentVals = List.map (\x -> checkBank parentDict x) (Dict.keys childDict)
childVals = Dict.values childDict
in
List.all (\n -> n == True) (List.map2 (>=) parentVals childVals)
filterWordsByLength : Int -> List String -> List String
filterWordsByLength n words =
List.filter (\w -> String.length w == n) words
determineMaximumLength : String -> Int
determineMaximumLength wordInput =
(String.filter Char.isLower wordInput |> String.length)
+ (String.filter Char.isUpper wordInput |> String.length)
update : Msg -> Model -> Model
update msg model =
case msg of
Input s ->
{ model
| input = s
}
GetSubanagrams ->
{ model
| word = model.input
, subanagrams = (List.filter (\w -> compareWords model.input w) Ni2Dictionary.words)
}
-- view
displayWordsSubset n words =
let
wordsToDisplay = filterWordsByLength n words
in
if wordsToDisplay /= [] then
div []
[ text ((toString <| List.length wordsToDisplay) ++ " " ++ (toString n) ++ "-letter words:")
, ul [] (List.map (\w -> li [] [ text w ]) wordsToDisplay)
]
else
span [] []
view : Model -> Html Msg
view model =
div []
[
-- h3 [] [ text ("Get Subanagrams: " ++ (toString model.word)) ]
input
[ type' "text"
, placeholder "Enter a string"
, onInput Input
, value model.input
]
[]
, button
[ type' "button"
, onClick GetSubanagrams
]
[ text "Get Subanagrams" ]
-- , p [] [ text (toString model) ]
, div [] (List.map (\n -> displayWordsSubset n model.subanagrams) [1..(determineMaximumLength model.input)])
, br [] []
, if model.subanagrams /= [] then
text ((toString <| List.length model.subanagrams) ++ " words in the word '" ++ model.input ++ "'.")
else
text ""
]
main : Program Never
main =
App.beginnerProgram
{ model = initModel
, update = update
, view = view
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment