more documentation/generic string functions
This commit is contained in:
parent
6e40f3d3c2
commit
b936dda857
@ -242,8 +242,8 @@ instructionConcat accessor state =
|
|||||||
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
||||||
-- takes the top item of the primitive stack and prepends it to the first vector in
|
-- takes the top item of the primitive stack and prepends it to the first vector in
|
||||||
-- the vector stack if there is one.
|
-- the vector stack if there is one.
|
||||||
instructionConj :: Lens' State [a] -> Lens' State [[a]] -> State -> State
|
instructionVectorConj :: Lens' State [a] -> Lens' State [[a]] -> State -> State
|
||||||
instructionConj primAccessor vectorAccessor state =
|
instructionVectorConj primAccessor vectorAccessor state =
|
||||||
case (uncons (view primAccessor state), uncons (view vectorAccessor state)) of
|
case (uncons (view primAccessor state), uncons (view vectorAccessor state)) of
|
||||||
(Just (p1,ps), Just (v1,vs)) -> state & primAccessor .~ ps & vectorAccessor .~ ((p1 : v1) : vs)
|
(Just (p1,ps), Just (v1,vs)) -> state & primAccessor .~ ps & vectorAccessor .~ ((p1 : v1) : vs)
|
||||||
_ -> state
|
_ -> state
|
||||||
@ -251,20 +251,27 @@ instructionConj primAccessor vectorAccessor state =
|
|||||||
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
||||||
-- takes the top item of the primitive stack and appends it to the first vector in
|
-- takes the top item of the primitive stack and appends it to the first vector in
|
||||||
-- the vector stack if there is one.
|
-- the vector stack if there is one.
|
||||||
instructionConjEnd :: Lens' State [a] -> Lens' State [[a]] -> State -> State
|
instructionVectorConjEnd :: Lens' State [a] -> Lens' State [[a]] -> State -> State
|
||||||
instructionConjEnd primAccessor vectorAccessor state =
|
instructionVectorConjEnd primAccessor vectorAccessor state =
|
||||||
case (uncons (view primAccessor state), uncons (view vectorAccessor state)) of
|
case (uncons (view primAccessor state), uncons (view vectorAccessor state)) of
|
||||||
(Just (p1,ps), Just (v1,vs)) -> state & primAccessor .~ ps & vectorAccessor .~ ((v1 <> [p1]) : vs)
|
(Just (p1,ps), Just (v1,vs)) -> state & primAccessor .~ ps & vectorAccessor .~ ((v1 <> [p1]) : vs)
|
||||||
_ -> state
|
_ -> state
|
||||||
|
|
||||||
-- |Takes the first N items from the first vector on the top of a vector stack and
|
-- |Takes the first N items from the first vector on the top of a vector stack and
|
||||||
-- pushes the result to said vector stack.
|
-- pushes the result to said vector stack.
|
||||||
instructionTakeN :: Lens' State [[a]] -> State -> State
|
instructionVectorTakeN :: Lens' State [[a]] -> State -> State
|
||||||
instructionTakeN accessor state@(State {_int = i1 : is}) =
|
instructionVectorTakeN accessor state@(State {_int = i1 : is}) =
|
||||||
case uncons (view accessor state) of
|
case uncons (view accessor state) of
|
||||||
Just (v1, vs) -> state{_int = is} & accessor .~ (take (absNum i1 v1) v1 : vs)
|
Just (v1, vs) -> state{_int = is} & accessor .~ (take (absNum i1 v1) v1 : vs)
|
||||||
_ -> state
|
_ -> state
|
||||||
instructionTakeN _ state = state
|
instructionVectorTakeN _ state = state
|
||||||
|
|
||||||
|
instructionVectorTakeRN :: Lens' State [[a]] -> State -> State
|
||||||
|
instructionVectorTakeRN accessor state@(State {_int = i1 : is}) =
|
||||||
|
case uncons (view accessor state) of
|
||||||
|
Just (v1, vs) -> state{_int = is} & accessor .~ (takeR (absNum i1 v1) v1 : vs)
|
||||||
|
_ -> state
|
||||||
|
instructionVectorTakeRN _ state = state
|
||||||
|
|
||||||
-- |Takes the sublist of the top vector based on a passed lens. Check out the
|
-- |Takes the sublist of the top vector based on a passed lens. Check out the
|
||||||
-- subList documentation for information on how this works.
|
-- subList documentation for information on how this works.
|
||||||
@ -341,21 +348,38 @@ instructionVectorFromNthPrim _ state = state
|
|||||||
|
|
||||||
-- |Takes the top vector, removes the first item of said vector, and pushes the result back to top
|
-- |Takes the top vector, removes the first item of said vector, and pushes the result back to top
|
||||||
-- of the stack, based on a lens.
|
-- of the stack, based on a lens.
|
||||||
instructionRest :: Lens' State [[a]] -> State -> State
|
instructionVectorRest :: Lens' State [[a]] -> State -> State
|
||||||
instructionRest accessor state =
|
instructionVectorRest accessor state =
|
||||||
case uncons (view accessor state) of
|
case uncons (view accessor state) of
|
||||||
Just (v1, vs) -> state & accessor .~ (drop 1 v1 : vs)
|
Just (v1, vs) -> state & accessor .~ (drop 1 v1 : vs)
|
||||||
_ -> state
|
_ -> state
|
||||||
|
|
||||||
-- |Takes the top vector, removes the last item of said vector, and pushes the result back to top
|
-- |Takes the top vector, removes the last item of said vector, and pushes the result back to top
|
||||||
-- of the stack, based on a lens.
|
-- of the stack, based on a vector lens.
|
||||||
instructionButLast :: Lens' State [[a]] -> State -> State
|
instructionVectorButLast :: Lens' State [[a]] -> State -> State
|
||||||
instructionButLast accessor state =
|
instructionVectorButLast accessor state =
|
||||||
case uncons (view accessor state) of
|
case uncons (view accessor state) of
|
||||||
Just (v1, vs) -> state & accessor .~ (safeInit v1 : vs)
|
Just (v1, vs) -> state & accessor .~ (safeInit v1 : vs)
|
||||||
_ -> state
|
_ -> state
|
||||||
|
|
||||||
-- |Takes the top vector, pushes the length of that vector to the int stack, based on a lens.
|
-- |Based on a vector lens, drops the first N items from the top vector.
|
||||||
|
-- Pushes the result back to the vector stack. N is pulled from the top
|
||||||
|
-- of the int stack.
|
||||||
|
instructionVectorDrop :: Lens' State [[a]] -> State -> State
|
||||||
|
instructionVectorDrop accessor state@(State {_int = i1 : is}) =
|
||||||
|
case uncons (view accessor state{_int = is}) of
|
||||||
|
Just (v1, vs) -> state{_int = is} & accessor .~ (drop (absNum i1 v1) v1 : vs)
|
||||||
|
_ -> state
|
||||||
|
instructionVectorDrop _ state = state
|
||||||
|
|
||||||
|
instructionVectorDropR :: Lens' State [[a]] -> State -> State
|
||||||
|
instructionVectorDropR accessor state@(State {_int = i1 : is}) =
|
||||||
|
case uncons (view accessor state{_int = is}) of
|
||||||
|
Just (v1, vs) -> state{_int = is} & accessor .~ (dropR (absNum i1 v1) v1 : vs)
|
||||||
|
_ -> state
|
||||||
|
instructionVectorDropR _ state = state
|
||||||
|
|
||||||
|
-- |Takes the top vector, pushes the length of that vector to the int stack, based on a vector lens.
|
||||||
instructionLength :: Lens' State [[a]] -> State -> State
|
instructionLength :: Lens' State [[a]] -> State -> State
|
||||||
instructionLength accessor state@(State {_int = is}) =
|
instructionLength accessor state@(State {_int = is}) =
|
||||||
case uncons (view accessor state) of
|
case uncons (view accessor state) of
|
||||||
@ -479,15 +503,23 @@ instructionVectorSplitOnVector accessor state =
|
|||||||
_ -> state
|
_ -> state
|
||||||
|
|
||||||
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
||||||
-- replaces all occurrences inside of the top vector from the vector stack with two values from
|
-- replaces Maybe Int occurrences inside of the top vector from the vector stack with two values from
|
||||||
-- the primitive stack. The top of the primitive stack is the old value to be replaced. The second item
|
-- the primitive stack. The top of the primitive stack is the old value to be replaced. The second item
|
||||||
-- in the primitive stack is the new value to replace the old one.
|
-- in the primitive stack is the new value to replace the old one. Nothing replaces all occurrences.
|
||||||
instructionVectorReplace :: Eq a => Lens' State [a] -> Lens' State [[a]] -> Maybe Int -> State -> State
|
instructionVectorReplace :: Eq a => Lens' State [a] -> Lens' State [[a]] -> Maybe Int -> State -> State
|
||||||
instructionVectorReplace primAccessor vectorAccessor amt state =
|
instructionVectorReplace primAccessor vectorAccessor amt state =
|
||||||
case (uncons (view vectorAccessor state), uncons (view primAccessor state)) of
|
case (uncons (view vectorAccessor state), uncons (view primAccessor state)) of
|
||||||
(Just (v1, vs), Just (p1, p2 : ps)) -> state & vectorAccessor .~ (replace v1 [p1] [p2] amt: vs) & primAccessor .~ ps
|
(Just (v1, vs), Just (p1, p2 : ps)) -> state & vectorAccessor .~ (replace v1 [p1] [p2] amt: vs) & primAccessor .~ ps
|
||||||
_ -> state
|
_ -> state
|
||||||
|
|
||||||
|
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
||||||
|
-- replaces N occurrences inside of the top vector from the vector stack with two values from
|
||||||
|
-- the primitive stack. The top of the primitive stack is the old value to be replaced. The second item
|
||||||
|
-- in the primitive stack is the new value to replace the old one. N is pulled from the top of the int stack.
|
||||||
|
instructionVectorReplaceN :: Eq a => Lens' State [a] -> Lens' State [[a]] -> State -> State
|
||||||
|
instructionVectorReplaceN primAccessor vectorAccessor state@(State {_int = i1 : is}) = instructionVectorReplace primAccessor vectorAccessor (Just i1) state{_int = is}
|
||||||
|
instructionVectorReplaceN _ _ state = state
|
||||||
|
|
||||||
-- |Based on a vector lens and the top three vectors on said stack.
|
-- |Based on a vector lens and the top three vectors on said stack.
|
||||||
-- Inside of the first vector, replaces the number of instances specified
|
-- Inside of the first vector, replaces the number of instances specified
|
||||||
-- by the Maybe Int parameter of the second vector with the third vector.
|
-- by the Maybe Int parameter of the second vector with the third vector.
|
||||||
@ -508,12 +540,20 @@ instructionVectorReplaceVectorN _ state = state
|
|||||||
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
||||||
-- Removes all occurrences inside of the top vector from the vector stack where the top
|
-- Removes all occurrences inside of the top vector from the vector stack where the top
|
||||||
-- item from the primitive stack equals a primitive inside of the vector stack.
|
-- item from the primitive stack equals a primitive inside of the vector stack.
|
||||||
instructionVectorRemove :: Eq a => Lens' State [a] -> Lens' State [[a]] -> State -> State
|
instructionVectorRemove :: Eq a => Lens' State [a] -> Lens' State [[a]] -> Maybe Int -> State -> State
|
||||||
instructionVectorRemove primAccessor vectorAccessor state =
|
instructionVectorRemove primAccessor vectorAccessor amt state =
|
||||||
case (uncons (view vectorAccessor state), uncons (view primAccessor state)) of
|
case (uncons (view vectorAccessor state), uncons (view primAccessor state)) of
|
||||||
(Just (v1, vs), Just (p1, ps)) -> state & vectorAccessor .~ (replace v1 [p1] [] Nothing : vs) & primAccessor .~ ps
|
(Just (v1, vs), Just (p1, ps)) -> state & vectorAccessor .~ (replace v1 [p1] [] amt: vs) & primAccessor .~ ps
|
||||||
_ -> state
|
_ -> state
|
||||||
|
|
||||||
|
-- |Based on two lenses, one of a primitive type and the next of a vector type,
|
||||||
|
-- Removes N occurrences inside of the top vector from the vector stack where the top
|
||||||
|
-- item from the primitive stack equals a primitive inside of the vector stack. N is pulled
|
||||||
|
-- from the top of the int stack.
|
||||||
|
instructionVectorRemoveN :: Eq a => Lens' State [a] -> Lens' State [[a]] -> State -> State
|
||||||
|
instructionVectorRemoveN primAccessor vectorAccessor state@(State {_int = i1 : is}) = instructionVectorRemove primAccessor vectorAccessor (Just i1) state{_int = is}
|
||||||
|
instructionVectorRemoveN _ _ state = state
|
||||||
|
|
||||||
-- |Based on a vector lens and the two vectors on top of said stack.
|
-- |Based on a vector lens and the two vectors on top of said stack.
|
||||||
-- Inside of the first vector, removes the number of instances specified
|
-- Inside of the first vector, removes the number of instances specified
|
||||||
-- by the Maybe Int parameter of the second vector. Nothing removes all instances.
|
-- by the Maybe Int parameter of the second vector. Nothing removes all instances.
|
||||||
|
@ -2,7 +2,6 @@ module HushGP.Instructions.StringInstructions where
|
|||||||
|
|
||||||
import HushGP.State
|
import HushGP.State
|
||||||
import HushGP.Instructions.GenericInstructions
|
import HushGP.Instructions.GenericInstructions
|
||||||
import Data.List.Split
|
|
||||||
import Control.Lens
|
import Control.Lens
|
||||||
|
|
||||||
-- |Utility String: Whitespack characters.
|
-- |Utility String: Whitespack characters.
|
||||||
@ -139,74 +138,112 @@ instructionStringContainsChar = instructionVectorContains char string
|
|||||||
instructionStringIndexOfChar :: State -> State
|
instructionStringIndexOfChar :: State -> State
|
||||||
instructionStringIndexOfChar = instructionVectorIndexOf char string
|
instructionStringIndexOfChar = instructionVectorIndexOf char string
|
||||||
|
|
||||||
-- |@TODO
|
-- |Takes the top string from the string stack and the top
|
||||||
|
-- char from the char stack. Splits the top string based on
|
||||||
|
-- the top char and pushes the result to the string stack.
|
||||||
instructionStringSplitOnChar :: State -> State
|
instructionStringSplitOnChar :: State -> State
|
||||||
instructionStringSplitOnChar = instructionVectorSplitOn char string
|
instructionStringSplitOnChar = instructionVectorSplitOn char string
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the two top char from the char stack.
|
||||||
|
-- Replaces the first instance of the top char with the second char.
|
||||||
instructionStringReplaceFirstChar :: State -> State
|
instructionStringReplaceFirstChar :: State -> State
|
||||||
instructionStringReplaceFirstChar = instructionVectorReplace char string (Just 1)
|
instructionStringReplaceFirstChar = instructionVectorReplace char string (Just 1)
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the two top char from the char stack.
|
||||||
|
-- Replaces N instances of the top char with the second char. N is determined by the
|
||||||
|
-- top int on the int stack.
|
||||||
instructionStringReplaceNChar :: State -> State
|
instructionStringReplaceNChar :: State -> State
|
||||||
instructionStringReplaceNChar state@(State {_string = s1 : ss, _char = c1 : c2 : cs, _int = i1 : is}) = state{_string = replace s1 [c1] [c2] (Just i1) : ss, _char = cs, _int = is}
|
instructionStringReplaceNChar = instructionVectorReplaceN char string
|
||||||
instructionStringReplaceNChar state = state
|
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the two top char from the char stack.
|
||||||
|
-- Replaces all instances of the top char with the second char.
|
||||||
instructionStringReplaceAllChar :: State -> State
|
instructionStringReplaceAllChar :: State -> State
|
||||||
instructionStringReplaceAllChar = instructionVectorReplace char string Nothing
|
instructionStringReplaceAllChar = instructionVectorReplace char string Nothing
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the top char from the char stack.
|
||||||
|
-- Removes the first instance of the top char with the second char.
|
||||||
instructionStringRemoveFirstChar :: State -> State
|
instructionStringRemoveFirstChar :: State -> State
|
||||||
instructionStringRemoveFirstChar state@(State {_string = s1 : ss, _char = c1 : cs}) = state {_string = replace s1 [c1] "" (Just 1) : ss, _char = cs}
|
instructionStringRemoveFirstChar = instructionVectorRemove char string (Just 1)
|
||||||
instructionStringRemoveFirstChar state = state
|
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the top char from the char stack.
|
||||||
|
-- Removes N instances of the top char with the second char. N is pulled from the top
|
||||||
|
-- of the int stack.
|
||||||
instructionStringRemoveNChar :: State -> State
|
instructionStringRemoveNChar :: State -> State
|
||||||
instructionStringRemoveNChar state@(State {_string = s1 : ss, _char = c1 : cs, _int = i1 : is}) = state{_string = replace s1 [c1] "" (Just i1) : ss, _char = cs, _int = is}
|
instructionStringRemoveNChar = instructionVectorRemoveN char string
|
||||||
instructionStringRemoveNChar state = state
|
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the top char from the char stack.
|
||||||
|
-- Removes all instances of the top char with the second char.
|
||||||
instructionStringRemoveAllChar :: State -> State
|
instructionStringRemoveAllChar :: State -> State
|
||||||
instructionStringRemoveAllChar = instructionVectorRemove char string
|
instructionStringRemoveAllChar = instructionVectorRemove char string Nothing
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the top char from the char stack.
|
||||||
|
-- Counts the amount of occurrences of the top char inside of the top string. Pushes
|
||||||
|
-- this result to the int stack.
|
||||||
instructionStringOccurrencesOfChar :: State -> State
|
instructionStringOccurrencesOfChar :: State -> State
|
||||||
instructionStringOccurrencesOfChar = instructionVectorOccurrencesOf char string
|
instructionStringOccurrencesOfChar = instructionVectorOccurrencesOf char string
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and reverses it. Pushes the reversed string
|
||||||
|
-- to the top of the stack.
|
||||||
instructionStringReverse :: State -> State
|
instructionStringReverse :: State -> State
|
||||||
instructionStringReverse = instructionReverse string
|
instructionStringReverse = instructionReverse string
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack, takes the first N chars from the top string,
|
||||||
|
-- and pushes the result to the string stack. N is pulled from the top of the int stack.
|
||||||
instructionStringHead :: State -> State
|
instructionStringHead :: State -> State
|
||||||
instructionStringHead = instructionTakeN string
|
instructionStringHead = instructionVectorTakeN string
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack, takes the last N chars from the top string,
|
||||||
|
-- and pushes the result to the string stack. N is pulled from the top of the int stack.
|
||||||
instructionStringTail :: State -> State
|
instructionStringTail :: State -> State
|
||||||
instructionStringTail state@(State {_string = s1 : ss, _int = i1 : is}) = state{_string = takeR (absNum i1 s1) s1 : ss, _int = is}
|
instructionStringTail = instructionVectorTakeRN string
|
||||||
instructionStringTail state = state
|
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the top char from the char stack.
|
||||||
|
-- Prepends the top char to the top string. Pushes the result to the string stack.
|
||||||
|
instructionStringPrependChar :: State -> State
|
||||||
|
instructionStringPrependChar = instructionVectorConj char string
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and the top char from the char stack.
|
||||||
|
-- Appends the top char to the top string. Pushes the result to the string stack.
|
||||||
instructionStringAppendChar :: State -> State
|
instructionStringAppendChar :: State -> State
|
||||||
instructionStringAppendChar = instructionConj char string
|
instructionStringAppendChar = instructionVectorConjEnd char string
|
||||||
|
|
||||||
instructionStringConjEndChar :: State -> State
|
|
||||||
instructionStringConjEndChar = instructionConjEnd char string
|
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and removes the first char
|
||||||
|
-- from said string. Pushes the result to the string stack.
|
||||||
instructionStringRest :: State -> State
|
instructionStringRest :: State -> State
|
||||||
instructionStringRest = instructionRest string
|
instructionStringRest = instructionVectorRest string
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and removes the last char
|
||||||
|
-- from said string. Pushes the result to the string stack.
|
||||||
instructionStringButLast :: State -> State
|
instructionStringButLast :: State -> State
|
||||||
instructionStringButLast = instructionButLast string
|
instructionStringButLast = instructionVectorButLast string
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and drops the first N characters
|
||||||
|
-- from said string. Pushes the result to the string stack. N is pulled from the top
|
||||||
|
-- of the int stack.
|
||||||
instructionStringDrop :: State -> State
|
instructionStringDrop :: State -> State
|
||||||
instructionStringDrop state@(State {_string = s1 : ss, _int = i1 : is}) = state{_string = drop (absNum i1 s1) s1 : ss, _int = is}
|
instructionStringDrop = instructionVectorDrop string
|
||||||
instructionStringDrop state = state
|
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and drops the last N characters
|
||||||
|
-- from said string. Pushes the result to the string stack. N is pulled from the top
|
||||||
|
-- of the int stack.
|
||||||
instructionStringButLastN :: State -> State
|
instructionStringButLastN :: State -> State
|
||||||
instructionStringButLastN state@(State {_string = s1 : ss, _int = i1 : is}) = state{_string = dropR (absNum i1 s1) s1 : ss, _int = is}
|
instructionStringButLastN = instructionVectorDropR string
|
||||||
instructionStringButLastN state = state
|
|
||||||
|
|
||||||
|
-- |Takes the top string from the string stack and calculates the length. The length
|
||||||
|
-- is then pushed to the int stack.
|
||||||
instructionStringLength :: State -> State
|
instructionStringLength :: State -> State
|
||||||
instructionStringLength = instructionLength string
|
instructionStringLength = instructionLength string
|
||||||
|
|
||||||
|
-- |Makes an empty string and pushes it to the top of the string stack.
|
||||||
instructionStringMakeEmpty :: State -> State
|
instructionStringMakeEmpty :: State -> State
|
||||||
instructionStringMakeEmpty = instructionVectorMakeEmpty string
|
instructionStringMakeEmpty = instructionVectorMakeEmpty string
|
||||||
|
|
||||||
|
-- |Checks to see if the top string is empty on the string stack.
|
||||||
|
-- Pushes True to the bool stack if empty. Pushes False if not.
|
||||||
instructionStringIsEmptyString :: State -> State
|
instructionStringIsEmptyString :: State -> State
|
||||||
instructionStringIsEmptyString state@(State {_string = s1 : ss, _bool = bs}) = state{_string = ss, _bool = null s1 : bs}
|
instructionStringIsEmptyString = instructionVectorIsEmpty string
|
||||||
instructionStringIsEmptyString state = state
|
|
||||||
|
|
||||||
|
-- TODO: Make this generic
|
||||||
instructionStringRemoveNth :: State -> State
|
instructionStringRemoveNth :: State -> State
|
||||||
instructionStringRemoveNth state@(State {_string = s1 : ss, _int = i1 : is}) = state{_string = deleteAt (absNum i1 s1) s1 : ss, _int = is}
|
instructionStringRemoveNth state@(State {_string = s1 : ss, _int = i1 : is}) = state{_string = deleteAt (absNum i1 s1) s1 : ss, _int = is}
|
||||||
instructionStringRemoveNth state = state
|
instructionStringRemoveNth state = state
|
||||||
|
Loading…
x
Reference in New Issue
Block a user