Mind boggling card trick: Difference between revisions
Content deleted Content added
→{{header|Haskell}}: (Some tidying of the threeStack function, refreshed sample output) |
→{{header|Javascript}}: Added a JS version |
||
Line 333: | Line 333: | ||
BBBBBB = Black cards in the black pile |
BBBBBB = Black cards in the black pile |
||
True</pre> |
True</pre> |
||
=={{header|Javascript}}== |
|||
{{trans|Haskell}} |
|||
<lang javascript>(() => { |
|||
'use strict'; |
|||
const main = () => { |
|||
const |
|||
// DEALT |
|||
cards = enumFromTo(1, 52), |
|||
[rs_, bs_, discards] = threeStacks( |
|||
map(n => |
|||
even(n) ? ( |
|||
'R' |
|||
) : 'B', knuthShuffle(cards) |
|||
) |
|||
), |
|||
// SWAPPED |
|||
nSwap = randomRInt(1, min(rs_.length, bs_.length)), |
|||
bs = take(nSwap, rs_).concat(drop(nSwap, bs_)), |
|||
rs = take(nSwap, bs_).concat(drop(nSwap, rs_)), |
|||
// CHECKED |
|||
rrs = filter(c => 'R' === c, rs).join(''), |
|||
bbs = filter(c => 'B' === c, bs).join(''); |
|||
return unlines([ |
|||
'Discarded: ' + discards.join(''), |
|||
'Swapped: ' + nSwap, |
|||
'Red pile: ' + rs, |
|||
'Black pile: ' + bs, |
|||
rrs + ' = Red cards in the red pile', |
|||
bbs + ' = Black cards in the black pile', |
|||
(rrs.length === bbs.length).toString() |
|||
]); |
|||
}; |
|||
// THREE STACKS --------------------------------------- |
|||
// threeStacks :: [Chars] -> ([Chars], [Chars], [Chars]) |
|||
const threeStacks = cards => { |
|||
const go = ([rs, bs, ds], xs) => { |
|||
const lng = xs.length; |
|||
return 0 < lng ? ( |
|||
1 < lng ? (() => { |
|||
const |
|||
rest = drop(2, xs), |
|||
[x, y] = take(2, xs); |
|||
return 'R' === x ? ( |
|||
go([ |
|||
cons(y, rs), bs, cons(x, ds) |
|||
], rest) |
|||
) : go([rs, cons(y, bs), cons(x, ds)], rest) |
|||
})() : [rs, bs, cons(xs[0], ds)] |
|||
) : [rs, bs, ds]; |
|||
}; |
|||
return go([ |
|||
[], |
|||
[], |
|||
[] |
|||
], cards) |
|||
}; |
|||
// SHUFFLE -------------------------------------------- |
|||
// knuthShuffle :: [a] -> [a] |
|||
const knuthShuffle = xs => |
|||
enumFromTo(0, xs.length - 1) |
|||
.reduceRight((a, i) => { |
|||
const iRand = randomRInt(0, i); |
|||
return i !== iRand ? ( |
|||
swapped(i, iRand, a) |
|||
) : a; |
|||
}, xs); |
|||
// swapped :: Int -> Int -> [a] -> [a] |
|||
const swapped = (iFrom, iTo, xs) => |
|||
xs.map( |
|||
(x, i) => iFrom !== i ? ( |
|||
iTo !== i ? ( |
|||
x |
|||
) : xs[iFrom] |
|||
) : xs[iTo] |
|||
); |
|||
// GENERIC FUNCTIONS ---------------------------------- |
|||
// cons :: a -> [a] -> [a] |
|||
const cons = (x, xs) => |
|||
Array.isArray(xs) ? ( |
|||
[x].concat(xs) |
|||
) : (x + xs); |
|||
// drop :: Int -> [a] -> [a] |
|||
// drop :: Int -> String -> String |
|||
const drop = (n, xs) => xs.slice(n); |
|||
// enumFromTo :: Int -> Int -> [Int] |
|||
const enumFromTo = (m, n) => |
|||
m <= n ? iterateUntil( |
|||
x => n <= x, |
|||
x => 1 + x, |
|||
m |
|||
) : []; |
|||
// even :: Int -> Bool |
|||
const even = n => 0 === n % 2; |
|||
// filter :: (a -> Bool) -> [a] -> [a] |
|||
const filter = (f, xs) => xs.filter(f); |
|||
// iterateUntil :: (a -> Bool) -> (a -> a) -> a -> [a] |
|||
const iterateUntil = (p, f, x) => { |
|||
const vs = [x]; |
|||
let h = x; |
|||
while (!p(h))(h = f(h), vs.push(h)); |
|||
return vs; |
|||
}; |
|||
// map :: (a -> b) -> [a] -> [b] |
|||
const map = (f, xs) => xs.map(f); |
|||
// min :: Ord a => a -> a -> a |
|||
const min = (a, b) => b < a ? b : a; |
|||
// randomRInt :: Int -> Int -> Int |
|||
const randomRInt = (low, high) => |
|||
low + Math.floor( |
|||
(Math.random() * ((high - low) + 1)) |
|||
); |
|||
// take :: Int -> [a] -> [a] |
|||
const take = (n, xs) => xs.slice(0, n); |
|||
// unlines :: [String] -> String |
|||
const unlines = xs => xs.join('\n'); |
|||
// MAIN --- |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>Discarded: BRRRBBBRRRRBRRRRBRRRBBBBRR |
|||
Swapped: 5 |
|||
Red pile: R,B,B,R,B,R,R,B,R,R,R,B,B,R,B,B |
|||
Black pile: B,B,B,B,B,R,B,B,R,B |
|||
RRRRRRRR = Red cards in the red pile |
|||
BBBBBBBB = Black cards in the black pile |
|||
true</pre> |
|||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |