How to resolve the algorithm Factorial base numbers indexing permutations of a collection step by step in the Haskell programming language
How to resolve the algorithm Factorial base numbers indexing permutations of a collection step by step in the Haskell programming language
Table of Contents
Problem Statement
You need a random arrangement of a deck of cards, you are sick of lame ways of doing this. This task is a super-cool way of doing this using factorial base numbers. The first 25 factorial base numbers in increasing order are: 0.0.0, 0.0.1, 0.1.0, 0.1.1, 0.2.0, 0.2.1, 1.0.0, 1.0.1, 1.1.0, 1.1.1,1.2.0, 1.2.1, 2.0.0, 2.0.1, 2.1.0, 2.1.1, 2.2.0, 2.2.1, 3.0.0, 3.0.1, 3.1.0, 3.1.1, 3.2.0, 3.2.1, 1.0.0.0 Observe that the least significant digit is base 2 the next base 3, in general an n-digit factorial base number has digits n..1 in base n+1..2. I want to produce a 1 to 1 mapping between these numbers and permutations:- The following psudo-code will do this: Starting with m=0 and Ω, an array of elements to be permutated, for each digit g starting with the most significant digit in the factorial base number. If g is greater than zero, rotate the elements from m to m+g in Ω (see example) Increment m and repeat the first step using the next most significant digit until the factorial base number is exhausted. For example: using the factorial base number 2.0.1 and Ω = 0 1 2 3 where place 0 in both is the most significant (left-most) digit/element. Step 1: m=0 g=2; Rotate places 0 through 2. 0 1 2 3 becomes 2 0 1 3 Step 2: m=1 g=0; No action. Step 3: m=2 g=1; Rotate places 2 through 3. 2 0 1 3 becomes 2 0 3 1 Let me work 2.0.1 and 0123 The task:
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Factorial base numbers indexing permutations of a collection step by step in the Haskell programming language
The provided Haskell source code defines data types and functions for working with factoradic numbers and crate permutations. Factoradic numbers are a unique representation of integers based on prime factorizations, while crate permutations represent the ordering of items in a particular layout.
1. Data Types:
- Fact: A newtype that represents a factoradic number as a list of integers.
2. Constructor Functions:
-
fact: Constructs a Fact value from a list of integers.
-
toFact: Converts an integer to a Fact value.
-
fromFact: Converts a Fact value back to an integer.
3. Instance Definition:
- Show: Defines a custom show instance for Fact, which displays it as a string in dot-separated form.
4. Helper Functions:
-
toPermutation: Converts a Fact value into a list of integers representing a crate permutation.
-
permute: Applies a given permutation to a list of elements.
5. Main Functions:
-
task1: Displays factoradic representations and corresponding crate permutations for integers from 0 to 23.
-
task2: Demonstrates the usage of the defined functions with specific factoradic numbers and crate permutations.
-
randomFactDigits: Generates a list of random integers based on a given seed.
Explanation of Factoradic Numbers:
Factoradic numbers are a way to represent integers using a unique sequence of prime factors. Each digit in a factoradic number represents the exponent of a prime factor in the integer's prime factorization. For example, the factoradic number Fact [3, 2, 1]
represents the integer 3^3 * 2^2 * 1^1 = 72
.
Explanation of Crate Permutations:
Crate permutations model the arrangement of items in a particular layout, such as a deck of cards. Each permutation is a list of integers representing the original position of each item in the rearranged order. For instance, the permutation [3, 1, 2]
would move the third item to the first position, the first item to the third position, and the second item to the second position in the original order.
Usage:
The code demonstrates the usage of the defined functions by converting integers to factoradic numbers, generating random factoradic numbers, and applying crate permutations to rearrange items in a specific order. It displays the results as strings representing factoradic numbers and crate permutations.
Source code in the haskell programming language
import Data.List (unfoldr, intercalate)
newtype Fact = Fact [Int]
-- smart constructor
fact :: [Int] -> Fact
fact = Fact . zipWith min [0..] . reverse
instance Show Fact where
show (Fact ds) = intercalate "." $ show <$> reverse ds
toFact :: Integer -> Fact
toFact 0 = Fact [0]
toFact n = Fact $ unfoldr f (1, n)
where
f (b, 0) = Nothing
f (b, n) = let (q, r) = n `divMod` b
in Just (fromIntegral r, (b+1, q))
fromFact :: Fact -> Integer
fromFact (Fact ds) = foldr f 0 $ zip [1..] ds
where
f (b, d) r = r * b + fromIntegral d
toPermutation :: Fact -> [Int]
toPermutation (Fact ds) = go (reverse ds) [0.. length ds - 1]
where
go [] p = p
go (d:ds) p = case splitAt (fromIntegral d) p of
(a,x:b) -> x : go ds (a++b)
(a,[]) -> a
permute :: [a] -> [Int] -> [a]
permute s p = case splitAt (length s - length p) s of
(s1,s2) -> s1 ++ map (s2 !!) p
task1 = do
putStrLn "number\tfactoradic\tpermutation"
mapM_ display [0..23]
where
display n =
let f = toFact n
p = permute "0123" (toPermutation f)
in putStrLn $ show n ++ "\t" ++ show f ++ "\t\t(" ++ p ++ ")"
randomFactDigits seed = zipWith mod (random seed) [1..]
where
random = iterate $ \x -> (x * 1103515245 + 12345) `mod` (2^31-1)
task2 = do
putStrLn "-- First example --"
let n1 = toFact 61988771037597375208735783409763169805823569176280269403732950003152
let crate1 = permute crate $ toPermutation n1
putStrLn $ "Factoradic number:\n" ++ show n1
putStrLn $ "Corresponding crate permutation:\n" ++ unwords crate1
putStrLn "\n-- Second example --"
let n2 = toFact 80576939285541005152259046665383499297948014296200417968998877609223
let crate2 = permute crate $ toPermutation n2
putStrLn $ "Factoradic number:\n" ++ show n2
putStrLn $ "Corresponding crate permutation:\n" ++ unwords crate2
putStrLn "\n-- Random example --"
let n3 = Fact $ take 52 $ randomFactDigits 42
let crate3 = permute crate $ toPermutation n3
putStrLn $ "Factoradic number:\n" ++ show n3
putStrLn $ "Decimal representation of n:\n" ++ show (fromFact n3)
putStrLn $ "Corresponding crate permutation:\n" ++ unwords crate3
where
crate = words "A♠ K♠ Q♠ J♠ 10♠ 9♠ 8♠ 7♠ 6♠ 5♠ 4♠ 3♠ 2♠\
\ A♥ K♥ Q♥ J♥ 10♥ 9♥ 8♥ 7♥ 6♥ 5♥ 4♥ 3♥ 2♥\
\ A♦ K♦ Q♦ J♦ 10♦ 9♦ 8♦ 7♦ 6♦ 5♦ 4♦ 3♦ 2♦\
\ A♣ K♣ Q♣ J♣ 10♣ 9♣ 8♣ 7♣ 6♣ 5♣ 4♣ 3♣ 2♣"
You may also check:How to resolve the algorithm Number reversal game step by step in the HicEst programming language
You may also check:How to resolve the algorithm Gamma function step by step in the Maxima programming language
You may also check:How to resolve the algorithm Associative array/Creation step by step in the PicoLisp programming language
You may also check:How to resolve the algorithm Increment a numerical string step by step in the LSL programming language
You may also check:How to resolve the algorithm Deepcopy step by step in the PARI/GP programming language