How to resolve the algorithm Factorial base numbers indexing permutations of a collection step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

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