September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,8 +1,8 @@
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.
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.
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.
;Task:

View file

@ -0,0 +1,240 @@
-- REP-CYCLES ----------------------------------------------------------------
-- repCycles :: String -> [String]
on repCycles(xs)
set n to length of xs
script isCycle
on |λ|(cs)
xs = takeCycle(n, cs)
end |λ|
end script
filter(isCycle, tail(inits(take(quot(n, 2), xs))))
end repCycles
-- cycleReport :: String -> [String]
on cycleReport(xs)
set reps to repCycles(xs)
if isNull(reps) then
{xs, "(n/a)"}
else
{xs, |last|(reps)}
end if
end cycleReport
-- TEST ----------------------------------------------------------------------
on run
set samples to {"1001110011", "1110111011", "0010010010", ¬
"1010101010", "1111111111", "0100101101", "0100100", ¬
"101", "11", "00", "1"}
unlines(cons("Longest cycle:" & linefeed, ¬
map(curry(intercalate)'s |λ|(" -> "), ¬
map(cycleReport, samples))))
end run
-- GENERIC FUNCTIONS ---------------------------------------------------------
-- concat :: [[a]] -> [a] | [String] -> String
on concat(xs)
if length of xs > 0 and class of (item 1 of xs) is string then
set acc to ""
else
set acc to {}
end if
repeat with i from 1 to length of xs
set acc to acc & item i of xs
end repeat
acc
end concat
-- cons :: a -> [a] -> [a]
on cons(x, xs)
{x} & xs
end cons
-- curry :: (Script|Handler) -> Script
on curry(f)
script
on |λ|(a)
script
on |λ|(b)
|λ|(a, b) of mReturn(f)
end |λ|
end script
end |λ|
end script
end curry
-- filter :: (a -> Bool) -> [a] -> [a]
on filter(f, xs)
tell mReturn(f)
set lst to {}
set lng to length of xs
repeat with i from 1 to lng
set v to item i of xs
if |λ|(v, i, xs) then set end of lst to v
end repeat
return lst
end tell
end filter
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
-- inits :: [a] -> [[a]]
-- inits :: String -> [String]
on inits(xs)
script elemInit
on |λ|(_, i, xs)
items 1 thru i of xs
end |λ|
end script
script charInit
on |λ|(_, i, xs)
text 1 thru i of xs
end |λ|
end script
if class of xs is string then
{""} & map(charInit, xs)
else
{{}} & map(elemInit, xs)
end if
end inits
-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate
-- last :: [a] -> a
on |last|(xs)
if length of xs > 0 then
item -1 of xs
else
missing value
end if
end |last|
-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
tell mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to |λ|(item i of xs, i, xs)
end repeat
return lst
end tell
end map
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- isNull :: [a] -> Bool
on isNull(xs)
xs = {}
end isNull
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- quot :: Integral a => a -> a -> a
on quot(n, m)
n div m
end quot
-- replicate :: Int -> a -> [a]
on replicate(n, a)
set out to {}
if n < 1 then return out
set dbl to {a}
repeat while (n > 1)
if (n mod 2) > 0 then set out to out & dbl
set n to (n div 2)
set dbl to (dbl & dbl)
end repeat
return out & dbl
end replicate
-- tail :: [a] -> [a]
on tail(xs)
if length of xs > 1 then
items 2 thru -1 of xs
else
{}
end if
end tail
-- take :: Int -> [a] -> [a]
on take(n, xs)
if class of xs is string then
if n > 0 then
text 1 thru min(n, length of xs) of xs
else
""
end if
else
if n > 0 then
items 1 thru min(n, length of xs) of xs
else
{}
end if
end if
end take
-- takeCycle :: Int -> [a] -> [a]
on takeCycle(n, xs)
set lng to length of xs
if lng n then
set cycle to xs
else
set cycle to concat(replicate((n div lng) + 1, xs))
end if
if class of xs is string then
items 1 thru n of cycle as string
else
items 1 thru n of cycle
end if
end takeCycle
-- unlines :: [String] -> String
on unlines(xs)
intercalate(linefeed, xs)
end unlines

View file

@ -0,0 +1,48 @@
import Data.List (inits, intercalate, transpose)
-- 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 -----------------------------------------------------------------------
main :: IO ()
main = do
putStrLn "Longest cycles:\n"
putStrLn $
unlines $
table " -> " $
cycleReport <$>
[ "1001110011"
, "1110111011"
, "0010010010"
, "1010101010"
, "1111111111"
, "0100101101"
, "0100100"
, "101"
, "11"
, "00"
, "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)

View file

@ -0,0 +1,105 @@
(() => {
'use strict';
// REP-CYCLES -------------------------------------------------------------
// 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))))
);
};
// cycleReport :: String -> [String]
const cycleReport = xs => {
const reps = repCycles(xs);
return [xs, isNull(reps) ? '(n/a)' : last(reps)];
};
// 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' ? '' : [];
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);
// filter :: (a -> Bool) -> [a] -> [a]
const filter = (f, xs) => xs.filter(f);
// 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);
// last :: [a] -> a
const last = xs => xs.length ? xs.slice(-1)[0] : undefined;
// map :: (a -> b) -> [a] -> [b]
const map = (f, xs) => xs.map(f);
// isNull :: [a] -> Bool
const isNull = xs => (xs instanceof Array) ? xs.length < 1 : undefined;
// Integral a => a -> a -> a
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);
};
// tail :: [a] -> [a]
const tail = xs => xs.length ? xs.slice(1) : undefined;
// 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);
};
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
// TEST -------------------------------------------------------------------
const samples = ["1001110011", "1110111011", "0010010010", "1010101010",
"1111111111", "0100101101", "0100100", "101", "11", "00", "1"
];
return unlines(cons('Longest cycle:\n',
map(compose(curry(intercalate)(' -> '), cycleReport), samples)));
})();

View file

@ -0,0 +1,37 @@
// version 1.0.6
fun repString(s: String): MutableList<String> {
val reps = mutableListOf<String>()
if (s.length < 2) return reps
for (c in s) if (c != '0' && c != '1') throw IllegalArgumentException("Not a binary string")
for (len in 1..s.length / 2) {
val t = s.take(len)
val n = s.length / len
val r = s.length % len
val u = t.repeat(n) + t.take(r)
if (u == s) reps.add(t)
}
return reps
}
fun main(args: Array<String>) {
val strings = listOf(
"1001110011",
"1110111011",
"0010010010",
"1010101010",
"1111111111",
"0100101101",
"0100100",
"101",
"11",
"00",
"1"
)
println("The (longest) rep-strings are:\n")
for (s in strings) {
val reps = repString(s)
val size = reps.size
println("${s.padStart(10)} -> ${if (size > 0) reps[size - 1] else "Not a rep-string"}")
}
}

View file

@ -0,0 +1,38 @@
function list_reps(string r)
sequence replist = {}
integer n = length(r)
for m=1 to floor(n/2) do
string s = r[1..m]
if join(repeat(s,floor(n/m)+1),"")[1..n]=r then
replist = append(replist,s)
end if
end for
return replist
end function
constant tests = {"1001110011",
"1110111011",
"0010010010",
"1010101010",
"1111111111",
"0100101101",
"0100100",
"101",
"11",
"00",
"1"}
for i=1 to length(tests) do
printf(1,"%s\n",{tests[i]})
sequence replist = list_reps(tests[i])
if length(replist)=0 then
printf(1,"not a rep-string.\n")
else
for j=1 to length(replist) do
string rj = replist[j],
pad = repeat(' ',length(rj))
printf(1,"%s%s\n",{pad,rj})
end for
end if
printf(1,"\n")
end for

View file

@ -2,7 +2,7 @@ a$="1001110011"+#CRLF$+"1110111011"+#CRLF$+"0010010010"+#CRLF$+"1010101010"+#CRL
"0100101101"+#CRLF$+"0100100" +#CRLF$+"101" +#CRLF$+"11" +#CRLF$+"00" +#CRLF$+
"1" +#CRLF$
Define.i : OpenConsole()
OpenConsole()
Procedure isRepStr(s1$,s2$)
If Int(Len(s1$)/Len(s2$))>=2 : ProcedureReturn isRepStr(s1$,s2$+s2$) : EndIf

View file

@ -0,0 +1,7 @@
fcn repString(s){
foreach n in ([s.len()/2+1..1,-1]){
Walker.cycle(s[0,n]).pump(s.len(),String) :
if(_==s and n*2<=s.len()) return(n);
}
return(False)
}

View file

@ -0,0 +1,6 @@
fcn repString(s){
foreach n in ([s.len()/2..0,-1]){
if(s.matches(s[n,*] + "*") and n*2<=s.len()) return(n);
}
return(False)
}

View file

@ -0,0 +1,7 @@
words:=("1001110011 1110111011 0010010010 1010101010 "
"1111111111 0100101101 0100100 101 11 00 1").split(" ");
foreach w in (words){
if(not n:=repString2(w)) "No repeat in ".println(w);
else [0..*,n].tweak('wrap(z){ if(s:=w[z,n]) s else Void.Stop })
.walk().concat(" ").println();
}