How to resolve the algorithm Rep-string step by step in the Haskell programming language
How to resolve the algorithm Rep-string step by step in the Haskell programming language
Table of Contents
Problem Statement
Given a series of ones and zeroes in a string, define a repeated string or rep-string as a string which is created by repeating a substring of the first N characters of the string truncated on the right to the length of the input string, and in which the substring appears repeated at least twice in the original. For example, the string 10011001100 is a rep-string as the leftmost four characters of 1001 are repeated three times and truncated on the right to give the original string. Note that the requirement for having the repeat occur two or more times means that the repeating unit is never longer than half the length of the input string.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm Rep-string step by step in the Haskell programming language
1. Overview:
This code deals with "rep strings" in Haskell, which are strings that can be constructed by repeating a shorter string. It includes two main functions: repstring
and repCycles
.
2. repstring
Function:
- Purpose: Determines if a given string is a rep string and returns its repeated substring if it is. Otherwise, returns
Nothing
. - Implementation:
- Checks that the string is not empty or has only one character.
- Validates that the string contains only '0's and '1's.
- Tries to find the longest substring that, when repeated, matches the original string. This is done by checking all possible substrings of lengths up to half the original string's length.
- If a valid repeated substring is found, it returns the substring. Otherwise, returns
Nothing
.
3. repCycles
Function:
- Purpose: Finds all cycles in a string that repeat to form the original string.
- Implementation:
- Generates all possible substrings up to half the string's length.
- Checks if each substring, when repeated in a cycle, matches the original string.
- Returns a list of all valid cycles.
4. main
Functions:
- The two
main
functions provide test cases for therepstring
andrepCycles
functions, respectively. They print the results to the console.
5. Helper Functions:
subrepeat
: Creates a repeated string using a substring and returns the substring.sndValid
: Checks if the repeated string matches the original string.compLength
: Compares the lengths of two strings.fTable
: A generic function that formats a table of results, used for printing test cases.
Source code in the haskell programming language
import Data.List (inits, maximumBy)
import Data.Maybe (fromMaybe)
repstring :: String -> Maybe String
-- empty strings are not rep strings
repstring [] = Nothing
-- strings with only one character are not rep strings
repstring [_] = Nothing
repstring xs
| any (`notElem` "01") xs = Nothing
| otherwise = longest xs
where
-- length of the original string
lxs = length xs
-- half that length
lq2 = lxs `quot` 2
-- make a string of same length using repetitions of a part
-- of the original string, and also return the substring used
subrepeat x = (x, take lxs $ concat $ repeat x)
-- check if a repeated string matches the original string
sndValid (_, ys) = ys == xs
-- make all possible strings out of repetitions of parts of
-- the original string, which have max. length lq2
possible = map subrepeat . take lq2 . tail . inits
-- filter only valid possibilities, and return the substrings
-- used for building them
valid = map fst . filter sndValid . possible
-- see which string is longer
compLength a b = compare (length a) (length b)
-- get the longest substring that, repeated, builds a string
-- that matches the original string
longest ys = case valid ys of
[] -> Nothing
zs -> Just $ maximumBy compLength zs
main :: IO ()
main =
mapM_ processIO examples
where
examples =
[ "1001110011",
"1110111011",
"0010010010",
"1010101010",
"1111111111",
"0100101101",
"0100100",
"101",
"11",
"00",
"1"
]
process = fromMaybe "Not a rep string" . repstring
processIO xs = do
putStr (xs <> ": ")
putStrLn $ process xs
import Data.Bool (bool)
import Data.List (inits, intercalate, transpose)
------------------------ REP-CYCLES ----------------------
repCycles :: String -> [String]
repCycles cs =
filter
((cs ==) . take n . cycle)
((tail . inits) $ take (quot n 2) cs)
where
n = length cs
--------------------------- TEST -------------------------
main :: IO ()
main =
putStrLn $
fTable
"Longest cycles:\n"
id
((flip bool "n/a" . last) <*> null)
repCycles
[ "1001110011",
"1110111011",
"0010010010",
"1010101010",
"1111111111",
"0100101101",
"0100100",
"101",
"11",
"00",
"1"
]
------------------------- GENERIC ------------------------
fTable ::
String ->
(a -> String) ->
(b -> String) ->
(a -> b) ->
[a] ->
String
fTable s xShow fxShow f xs =
let rjust n c = drop . length <*> (replicate n c <>)
w = maximum (length . xShow <$> xs)
in unlines $
s :
fmap
( ((<>) . rjust w ' ' . xShow)
<*> ((" -> " <>) . fxShow . f)
)
xs
You may also check:How to resolve the algorithm First perfect square in base n with n unique digits step by step in the REXX programming language
You may also check:How to resolve the algorithm Colour pinstripe/Display step by step in the C++ programming language
You may also check:How to resolve the algorithm Sum of a series step by step in the BASIC programming language
You may also check:How to resolve the algorithm Convex hull step by step in the FreeBASIC programming language
You may also check:How to resolve the algorithm Jump anywhere step by step in the 8086 Assembly programming language