Solve a Holy Knight's tour: Difference between revisions

Content added Content deleted
(→‎JS ES6: Replaced startPosn function with a more generic (and slight better typed) charColRow function)
Line 1,726: Line 1,726:
const problems = [
const problems = [
[
[
" 000 " //
" 000 " //
, " 0 00 " //
, " 0 00 " //
, " 0000000" //
, " 0000000" //
Line 1,736: Line 1,736:
],
],
[
[
"-----1-0-----" //
"-----1-0-----" //
, "-----0-0-----" //
, "-----0-0-----" //
, "----00000----" //
, "----00000----" //
Line 1,769: Line 1,769:
return unit.concat.apply(unit, xs);
return unit.concat.apply(unit, xs);
})() : [];
})() : [];

// charColRow :: Char -> [String] -> Maybe (Int, Int)
const charColRow = (c, rows) =>
foldr((a, xs, iRow) =>
a.nothing ? (() => {
const mbiCol = elemIndex(c, xs);
return mbiCol.nothing ? mbiCol : {
just: [mbiCol.just, iRow],
nothing: false
};
})() : a, {
nothing: true
}, rows);


// 2 or more arguments
// 2 or more arguments
Line 1,782: Line 1,795:
// elem :: Eq a => a -> [a] -> Bool
// elem :: Eq a => a -> [a] -> Bool
const elem = (x, xs) => xs.indexOf(x) !== -1;
const elem = (x, xs) => xs.indexOf(x) !== -1;

// elemIndex :: Eq a => a -> [a] -> Maybe Int
const elemIndex = (x, xs) => {
const i = xs.indexOf(x);
return {
nothing: i === -1,
just: i
};
};


// enumFromTo :: Int -> Int -> [Int]
// enumFromTo :: Int -> Int -> [Int]
Line 1,807: Line 1,829:
// foldl :: (b -> a -> b) -> b -> [a] -> b
// foldl :: (b -> a -> b) -> b -> [a] -> b
const foldl = (f, a, xs) => xs.reduce(f, a);
const foldl = (f, a, xs) => xs.reduce(f, a);

// foldr (a -> b -> b) -> b -> [a] -> b
const foldr = (f, a, xs) => xs.reduceRight(f, a);


// groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
// groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
Line 1,898: Line 1,923:
return v;
return v;
};
};

// zip :: [a] -> [b] -> [(a,b)]
const zip = (xs, ys) =>
xs.slice(0, Math.min(xs.length, ys.length))
.map((x, i) => [x, ys[i]]);


// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
Line 1,932: Line 1,962:
const hash = ([col, row]) => col.toString() + '.' + row.toString();
const hash = ([col, row]) => col.toString() + '.' + row.toString();



// startPosn :: [String] -> Maybe (Int, Int)
const startPosn = rows => {
const mb = findIndex(s => s.indexOf('1') !== -1, rows);
return mb.nothing ? {
nothing: true
} : (() => {
const iRow = mb.just;
return [
findIndex(s => s === '1', rows[iRow])
.just, iRow
];
})();
};


// Start node, and degree-sorted cache of moves from each node
// Start node, and degree-sorted cache of moves from each node
Line 1,958: Line 1,976:
);
);
return {
return {
start: hash(startPosn(boardLines)),
start: hash(charColRow('1', boardLines)
.just),
boardWidth: boardLines.length > 0 ? boardLines[0].length : 0,
boardWidth: boardLines.length > 0 ? boardLines[0].length : 0,
stepCount: steps.length,
stepCount: steps.length,