Word wheel: Difference between revisions

Content added Content deleted
(Added Wren)
(→‎{{header|JavaScript}}: Added a local file access version for macOS)
Line 206: Line 206:
s <- readFile "unixdict.txt"
s <- readFile "unixdict.txt"
mapM_ putStrLn $ gridWords ["NDE", "OKG", "ELW"] (lines s)</lang>
mapM_ putStrLn $ gridWords ["NDE", "OKG", "ELW"] (lines s)</lang>
{{Out}}
<pre>eke
elk
keel
keen
keg
ken
keno
knee
kneel
knew
know
knowledge
kong
leek
week
wok
woke</pre>

=={{header|JavaScript}}==
A version using local access to the dictionary, through the the macOS JavaScript for Automation API.
{{Works with|JXA}}
<lang JavaScript>(() => {
'use strict';

// main :: IO ()
const main = () =>
console.log(unlines(
gridWords(['NDE', 'OKG', 'ELW'])(
lines(readFile('unixdict.txt'))
)
));

// gridWords :: [String] -> [String] -> [String]
const gridWords = grid =>
lexemes => {
const
wheel = sort(toLower(concat(grid))),
wSet = new Set(wheel),
mid = wheel[4];
return lexemes.filter(w => {
const cs = chars(w);
return 2 < cs.length && cs.every(
c => wSet.has(c)
) && elem('k')(cs) && (
wheelFit(wheel, cs)
);
});
};

// wheelFit :: [Char] -> [Char] -> Bool
const wheelFit = (wheel, word) => {
const go = (ws, cs) =>
0 === cs.length ? (
true
) : 0 === ws.length ? (
false
) : ws[0] === cs[0] ? (
go(ws.slice(1), cs.slice(1))
) : go(ws.slice(1), cs);
return go(wheel, sort(word));
};

// ----------------- GENERIC FUNCTIONS -----------------

// chars :: String -> [Char]
const chars = s =>
s.split('');

// concat :: [[a]] -> [a]
// concat :: [String] -> String
const concat = xs => (
ys => 0 < ys.length ? (
ys.every(Array.isArray) ? (
[]
) : ''
).concat(...ys) : ys
)(list(xs));

// elem :: Eq a => a -> [a] -> Bool
const elem = x =>
// True if xs contains an instance of x.
xs => xs.some(y => x === y);

// lines :: String -> [String]
const lines = s =>
// A list of strings derived from a single
// newline-delimited string.
0 < s.length ? (
s.split(/[\r\n]/)
) : [];

// list :: StringOrArrayLike b => b -> [a]
const list = xs =>
// xs itself, if it is an Array,
// or an Array derived from xs.
Array.isArray(xs) ? (
xs
) : Array.from(xs || []);

// readFile :: FilePath -> IO String
const readFile = fp => {
// The contents of a text file at the
// path file fp.
const
e = $(),
ns = $.NSString
.stringWithContentsOfFileEncodingError(
$(fp).stringByStandardizingPath,
$.NSUTF8StringEncoding,
e
);
return ObjC.unwrap(
ns.isNil() ? (
e.localizedDescription
) : ns
);
};

// sort :: Ord a => [a] -> [a]
const sort = xs => list(xs).slice()
.sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));

// toLower :: String -> String
const toLower = s =>
// Lower-case version of string.
s.toLocaleLowerCase();

// unlines :: [String] -> String
const unlines = xs =>
// A single string formed by the intercalation
// of a list of strings with the newline character.
xs.join('\n');

// MAIN ---
return main();
})();</lang>
{{Out}}
{{Out}}
<pre>eke
<pre>eke