September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
1
Task/Rep-string/00META.yaml
Normal file
1
Task/Rep-string/00META.yaml
Normal file
|
|
@ -0,0 +1 @@
|
|||
--- {}
|
||||
18
Task/Rep-string/C/rep-string-2.c
Normal file
18
Task/Rep-string/C/rep-string-2.c
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// strstr : Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
|
||||
// size_t is an unsigned integer typ
|
||||
// lokks for the shortest substring
|
||||
int repstr(char *str)
|
||||
{
|
||||
if (!str) return 0; // if empty input
|
||||
|
||||
size_t sl = 1;
|
||||
size_t sl_max = strlen(str) ;
|
||||
|
||||
while (sl < sl_max) {
|
||||
if (strstr(str, str + sl) == str) // How it works ???? It checks the whole string str
|
||||
return sl;
|
||||
++sl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,28 +1,22 @@
|
|||
import Data.List (inits, intercalate, transpose)
|
||||
import Control.Applicative (liftA2)
|
||||
import Data.Bool (bool)
|
||||
|
||||
-- REP-CYCLES -----------------------------------------------------------------
|
||||
-- REP-CYCLES ---------------------------------------------
|
||||
repCycles :: String -> [String]
|
||||
repCycles cs =
|
||||
let n = length cs
|
||||
in filter ((cs ==) . take n . cycle) (tail $ inits (take (quot n 2) cs))
|
||||
|
||||
cycleReport :: String -> [String]
|
||||
cycleReport xs =
|
||||
let reps = repCycles xs
|
||||
in [ xs
|
||||
, if not (null reps)
|
||||
then last reps
|
||||
else "(n/a)"
|
||||
]
|
||||
|
||||
-- TEST -----------------------------------------------------------------------
|
||||
-- TEST ---------------------------------------------------
|
||||
main :: IO ()
|
||||
main = do
|
||||
putStrLn "Longest cycles:\n"
|
||||
main =
|
||||
putStrLn $
|
||||
unlines $
|
||||
table " -> " $
|
||||
cycleReport <$>
|
||||
fTable
|
||||
"Longest cycles:\n"
|
||||
id
|
||||
((flip bool "n/a" . last) <*> null)
|
||||
repCycles
|
||||
[ "1001110011"
|
||||
, "1110111011"
|
||||
, "0010010010"
|
||||
|
|
@ -36,13 +30,10 @@ main = do
|
|||
, "1"
|
||||
]
|
||||
|
||||
-- GENERIC --------------------------------------------------------------------
|
||||
table :: String -> [[String]] -> [String]
|
||||
table delim rows =
|
||||
intercalate delim <$>
|
||||
transpose
|
||||
((\col ->
|
||||
let width = (length $ maximum col)
|
||||
justifyLeft n c s = take n (s ++ replicate n c)
|
||||
in justifyLeft width ' ' <$> col) <$>
|
||||
transpose rows)
|
||||
-- GENERIC ------------------------------------------------
|
||||
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
|
||||
fTable s xShow fxShow f xs =
|
||||
let w = maximum (length . xShow <$> xs)
|
||||
rjust n c = liftA2 drop length (replicate n c ++)
|
||||
in unlines $
|
||||
s : fmap (((++) . rjust w ' ' . xShow) <*> ((" -> " ++) . fxShow . f)) xs
|
||||
|
|
|
|||
|
|
@ -1,105 +1,145 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// REP-CYCLES -------------------------------------------------------------
|
||||
const main = () => {
|
||||
|
||||
// repCycles :: String -> [String]
|
||||
const repCycles = xs => {
|
||||
const n = xs.length;
|
||||
return filter(
|
||||
cs => xs === takeCycle(n, cs),
|
||||
map(concat, tail(inits(take(quot(n, 2), xs))))
|
||||
);
|
||||
// REP-CYCLES -------------------------------------
|
||||
|
||||
// repCycles :: String -> [String]
|
||||
const repCycles = s => {
|
||||
const n = s.length;
|
||||
return filter(
|
||||
x => s === take(n, cycle(x)).join(''),
|
||||
tail(inits(take(quot(n, 2), s)))
|
||||
);
|
||||
};
|
||||
|
||||
// TEST -------------------------------------------
|
||||
console.log(fTable(
|
||||
'Longest cycles:\n',
|
||||
str,
|
||||
xs => 0 < xs.length ? concat(last(xs)) : '(none)',
|
||||
repCycles,
|
||||
[
|
||||
'1001110011',
|
||||
'1110111011',
|
||||
'0010010010',
|
||||
'1010101010',
|
||||
'1111111111',
|
||||
'0100101101',
|
||||
'0100100',
|
||||
'101',
|
||||
'11',
|
||||
'00',
|
||||
'1'
|
||||
]
|
||||
));
|
||||
};
|
||||
|
||||
// cycleReport :: String -> [String]
|
||||
const cycleReport = xs => {
|
||||
const reps = repCycles(xs);
|
||||
return [xs, isNull(reps) ? '(n/a)' : last(reps)];
|
||||
};
|
||||
// GENERIC FUNCTIONS ----------------------------------
|
||||
|
||||
|
||||
// GENERIC ----------------------------------------------------------------
|
||||
|
||||
// compose :: (b -> c) -> (a -> b) -> (a -> c)
|
||||
const compose = (f, g) => x => f(g(x));
|
||||
|
||||
// concat :: [[a]] -> [a] | [String] -> String
|
||||
const concat = xs => {
|
||||
if (xs.length > 0) {
|
||||
const unit = typeof xs[0] === 'string' ? '' : [];
|
||||
// concat :: [[a]] -> [a]
|
||||
// concat :: [String] -> String
|
||||
const concat = xs =>
|
||||
0 < xs.length ? (() => {
|
||||
const unit = 'string' !== typeof xs[0] ? (
|
||||
[]
|
||||
) : '';
|
||||
return unit.concat.apply(unit, xs);
|
||||
} else return [];
|
||||
};
|
||||
})() : [];
|
||||
|
||||
// cons :: a -> [a] -> [a]
|
||||
const cons = (x, xs) => [x].concat(xs);
|
||||
|
||||
// curry :: ((a, b) -> c) -> a -> b -> c
|
||||
const curry = f => a => b => f(a, b);
|
||||
// cycle :: [a] -> Generator [a]
|
||||
function* cycle(xs) {
|
||||
const lng = xs.length;
|
||||
let i = 0;
|
||||
while (true) {
|
||||
yield(xs[i])
|
||||
i = (1 + i) % lng;
|
||||
}
|
||||
}
|
||||
|
||||
// filter :: (a -> Bool) -> [a] -> [a]
|
||||
const filter = (f, xs) => xs.filter(f);
|
||||
|
||||
// fTable :: String -> (a -> String) ->
|
||||
// (b -> String) -> (a -> b) -> [a] -> String
|
||||
const fTable = (s, xShow, fxShow, f, xs) => {
|
||||
// Heading -> x display function ->
|
||||
// fx display function ->
|
||||
// f -> values -> tabular string
|
||||
const
|
||||
ys = xs.map(xShow),
|
||||
w = Math.max(...ys.map(length));
|
||||
return s + '\n' + zipWith(
|
||||
(a, b) => a.padStart(w, ' ') + ' -> ' + b,
|
||||
ys,
|
||||
xs.map(x => fxShow(f(x)))
|
||||
).join('\n');
|
||||
};
|
||||
|
||||
// inits([1, 2, 3]) -> [[], [1], [1, 2], [1, 2, 3]
|
||||
// inits('abc') -> ["", "a", "ab", "abc"]
|
||||
|
||||
// inits :: [a] -> [[a]]
|
||||
// inits :: String -> [String]
|
||||
const inits = xs => [
|
||||
[]
|
||||
]
|
||||
.concat((typeof xs === 'string' ? xs.split('') : xs)
|
||||
.map((_, i, lst) => lst.slice(0, i + 1)));
|
||||
|
||||
// intercalate :: String -> [a] -> String
|
||||
const intercalate = (s, xs) => xs.join(s);
|
||||
.concat(('string' === typeof xs ? xs.split('') : xs)
|
||||
.map((_, i, lst) => lst.slice(0, 1 + i)));
|
||||
|
||||
// last :: [a] -> a
|
||||
const last = xs => xs.length ? xs.slice(-1)[0] : undefined;
|
||||
const last = xs =>
|
||||
0 < xs.length ? xs.slice(-1)[0] : undefined;
|
||||
|
||||
// map :: (a -> b) -> [a] -> [b]
|
||||
const map = (f, xs) => xs.map(f);
|
||||
// Returns Infinity over objects without finite length.
|
||||
// This enables zip and zipWith to choose the shorter
|
||||
// argument when one is non-finite, like cycle, repeat etc
|
||||
|
||||
// isNull :: [a] -> Bool
|
||||
const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;
|
||||
// length :: [a] -> Int
|
||||
const length = xs =>
|
||||
(Array.isArray(xs) || 'string' === typeof xs) ? (
|
||||
xs.length
|
||||
) : Infinity;
|
||||
|
||||
// Integral a => a -> a -> a
|
||||
// quot :: Int -> Int -> Int
|
||||
const quot = (n, m) => Math.floor(n / m);
|
||||
|
||||
// replicate :: Int -> a -> [a]
|
||||
const replicate = (n, a) => {
|
||||
let v = [a],
|
||||
o = [];
|
||||
if (n < 1) return o;
|
||||
while (n > 1) {
|
||||
if (n & 1) o = o.concat(v);
|
||||
n >>= 1;
|
||||
v = v.concat(v);
|
||||
}
|
||||
return o.concat(v);
|
||||
};
|
||||
// str :: a -> String
|
||||
const str = x => x.toString();
|
||||
|
||||
// tail :: [a] -> [a]
|
||||
const tail = xs => xs.length ? xs.slice(1) : undefined;
|
||||
const tail = xs => 0 < xs.length ? xs.slice(1) : [];
|
||||
|
||||
// take :: Int -> [a] -> [a]
|
||||
const take = (n, xs) => xs.slice(0, n);
|
||||
|
||||
// First n members of an infinite cycle of xs
|
||||
// takeCycle :: Int -> [a] -> [a]
|
||||
const takeCycle = (n, xs) => {
|
||||
const lng = xs.length;
|
||||
return concat((lng >= n ? xs : replicate(Math.ceil(n / lng), xs)))
|
||||
.slice(0, n);
|
||||
};
|
||||
// take :: Int -> String -> String
|
||||
const take = (n, xs) =>
|
||||
'GeneratorFunction' !== xs.constructor.constructor.name ? (
|
||||
xs.slice(0, n)
|
||||
) : [].concat.apply([], Array.from({
|
||||
length: n
|
||||
}, () => {
|
||||
const x = xs.next();
|
||||
return x.done ? [] : [x.value];
|
||||
}));
|
||||
|
||||
// unlines :: [String] -> String
|
||||
const unlines = xs => xs.join('\n');
|
||||
|
||||
// Use of `take` and `length` here allows zipping with non-finite lists
|
||||
// i.e. generators like cycle, repeat, iterate.
|
||||
|
||||
// TEST -------------------------------------------------------------------
|
||||
const samples = ["1001110011", "1110111011", "0010010010", "1010101010",
|
||||
"1111111111", "0100101101", "0100100", "101", "11", "00", "1"
|
||||
];
|
||||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
const zipWith = (f, xs, ys) => {
|
||||
const
|
||||
lng = Math.min(length(xs), length(ys)),
|
||||
as = take(lng, xs),
|
||||
bs = take(lng, ys);
|
||||
return Array.from({
|
||||
length: lng
|
||||
}, (_, i) => f(as[i], bs[i], i));
|
||||
};
|
||||
|
||||
return unlines(cons('Longest cycle:\n',
|
||||
map(compose(curry(intercalate)(' -> '), cycleReport), samples)));
|
||||
// MAIN ---
|
||||
return main();
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,25 +1,97 @@
|
|||
import re
|
||||
'''Rep-strings'''
|
||||
|
||||
matchstr = """\
|
||||
1001110011
|
||||
1110111011
|
||||
0010010010
|
||||
1010101010
|
||||
1111111111
|
||||
0100101101
|
||||
0100100
|
||||
101
|
||||
11
|
||||
00
|
||||
1"""
|
||||
from itertools import (accumulate, chain, cycle, islice)
|
||||
|
||||
def _checker(matchobj):
|
||||
g0, (g1, g2, g3, g4) = matchobj.group(0), matchobj.groups()
|
||||
if not g4 and g1 and g1.startswith(g3):
|
||||
return '%r repeats %r' % (g0, g1)
|
||||
return '%r is not a rep-string' % (g0,)
|
||||
|
||||
def checkit(txt):
|
||||
print(re.sub(r'(.+)(\1+)(.*)|(.*)', _checker, txt))
|
||||
# repCycles :: String -> [String]
|
||||
def repCycles(s):
|
||||
'''Repeated sequences of characters in s.'''
|
||||
n = len(s)
|
||||
cs = list(s)
|
||||
|
||||
checkit(matchstr)
|
||||
return [
|
||||
x for x in
|
||||
tail(inits(take(n // 2)(s)))
|
||||
if cs == take(n)(cycle(x))
|
||||
]
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Tests - longest cycle (if any) in each string.'''
|
||||
print(
|
||||
fTable('Longest cycles:\n')(repr)(
|
||||
lambda xs: ''.join(xs[-1]) if xs else '(none)'
|
||||
)(repCycles)([
|
||||
'1001110011',
|
||||
'1110111011',
|
||||
'0010010010',
|
||||
'1010101010',
|
||||
'1111111111',
|
||||
'0100101101',
|
||||
'0100100',
|
||||
'101',
|
||||
'11',
|
||||
'00',
|
||||
'1',
|
||||
])
|
||||
)
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
# inits :: [a] -> [[a]]
|
||||
def inits(xs):
|
||||
'''all initial segments of xs, shortest first.'''
|
||||
return accumulate(chain([[]], xs), lambda a, x: a + [x])
|
||||
|
||||
|
||||
# tail :: [a] -> [a]
|
||||
# tail :: Gen [a] -> [a]
|
||||
def tail(xs):
|
||||
'''The elements following the head of a
|
||||
(non-empty) list or generator stream.'''
|
||||
if isinstance(xs, list):
|
||||
return xs[1:]
|
||||
else:
|
||||
list(islice(xs, 1)) # First item dropped.
|
||||
return xs
|
||||
|
||||
|
||||
# take :: Int -> [a] -> [a]
|
||||
# take :: Int -> String -> String
|
||||
def take(n):
|
||||
'''The prefix of xs of length n,
|
||||
or xs itself if n > length xs.'''
|
||||
return lambda xs: (
|
||||
xs[0:n]
|
||||
if isinstance(xs, (list, tuple))
|
||||
else list(islice(xs, n))
|
||||
)
|
||||
|
||||
|
||||
# OUTPUT FORMATTING ---------------------------------------
|
||||
|
||||
# fTable :: String -> (a -> String) ->
|
||||
# (b -> String) -> (a -> b) -> [a] -> String
|
||||
def fTable(s):
|
||||
'''Heading -> x display function ->
|
||||
fx display function ->
|
||||
f -> value list -> tabular string.
|
||||
'''
|
||||
def go(xShow, fxShow, f, xs):
|
||||
ys = [xShow(x) for x in xs]
|
||||
w = max(map(len, ys))
|
||||
return s + '\n' + '\n'.join(map(
|
||||
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
|
||||
xs, ys
|
||||
))
|
||||
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
|
||||
xShow, fxShow, f, xs
|
||||
)
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
|||
25
Task/Rep-string/Python/rep-string-4.py
Normal file
25
Task/Rep-string/Python/rep-string-4.py
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import re
|
||||
|
||||
matchstr = """\
|
||||
1001110011
|
||||
1110111011
|
||||
0010010010
|
||||
1010101010
|
||||
1111111111
|
||||
0100101101
|
||||
0100100
|
||||
101
|
||||
11
|
||||
00
|
||||
1"""
|
||||
|
||||
def _checker(matchobj):
|
||||
g0, (g1, g2, g3, g4) = matchobj.group(0), matchobj.groups()
|
||||
if not g4 and g1 and g1.startswith(g3):
|
||||
return '%r repeats %r' % (g0, g1)
|
||||
return '%r is not a rep-string' % (g0,)
|
||||
|
||||
def checkit(txt):
|
||||
print(re.sub(r'(.+)(\1+)(.*)|(.*)', _checker, txt))
|
||||
|
||||
checkit(matchstr)
|
||||
26
Task/Rep-string/Swift/rep-string.swift
Normal file
26
Task/Rep-string/Swift/rep-string.swift
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import Foundation
|
||||
|
||||
func repString(_ input: String) -> [String] {
|
||||
return (1..<(1 + input.count / 2)).compactMap({x -> String? in
|
||||
let i = input.index(input.startIndex, offsetBy: x)
|
||||
return input.hasPrefix(input[i...]) ? String(input.prefix(x)) : nil
|
||||
})
|
||||
}
|
||||
|
||||
let testCases = """
|
||||
1001110011
|
||||
1110111011
|
||||
0010010010
|
||||
1010101010
|
||||
1111111111
|
||||
0100101101
|
||||
0100100
|
||||
101
|
||||
11
|
||||
00
|
||||
1
|
||||
""".components(separatedBy: "\n")
|
||||
|
||||
for testCase in testCases {
|
||||
print("\(testCase) has reps: \(repString(testCase))")
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue