Recognize mod-folds
Pyth, 14 bytes
}Qm%M+RdUQy_Sl
Returns True/False
. Try it online: Demonstration or Test Suite
Explanation:
}Qm%M+RdUQy_SlQ implicit Q (=input) at the end
lQ length of input list
S create the list [1, 2, ..., len]
_ reverse => [len, ..., 2, 1]
y generate all subsets (these are all possible mod-folds)
m map each subset d to:
UQ take the range [0, 1, ..., len-1]
+Rd transform each number into a list by prepending it to d
e.g. if mod-fold = [7,3], than it creates:
[[0,7,3], [1,7,3], [2,7,3], [3,7,3], ...]
%M fold each list by the modulo operator
this gives all possible truthy sequences of length len
}Q so checking if Q appears in the list returns True or False
Pyth, 11 bytes
q%M.e+k_tx0
Based on @ferrsum's idea. I actually thought about using the zero-indices for the subset generation, but didn't realize, that all zero-indices has to be the solution already.
Python 3, 239 218 bytes
from itertools import*
lambda z:z in[[eval(''.join([str(l)]+['%'+str(i[::-1][k])for k in range(len(i))]))for l in range(len(z))]for i in(i for j in(combinations(range(1,len(z)+1),i+1)for i in range(len(z)))for i in j)]
An anonymous function that takes input of a list z
and returns True
or False
for Y
and N
.
This uses a method similar to @Jakube 's answer, and although it is essentially a brute force, runs very quickly.
from itertools import* Import everything from the Python module for
iterable generation
lambda z Anonymous function with input list z
combinations(range(1,len(z)+1),i+1) Yield all sorted i+1 length subsets of the range
[1,len(z)]...
...for i in range(len(z)) ...for all possible subset lengths
(i for j in(...)for i in j) Flatten, yielding an iterator containing all possible
mod-fold values as separate lists
...for i in... For all possible mod-fold values...
...for k in range(len(i)) ...for all mod-fold values indices k...
...for l in range(len(z)) ...for all function domain values in [0,len(z)-1]...
[str(l)]+['%'+str(i[::-1][k])...] ...create a list containing each character of the
expression representing the function defined by the
mod-fold values (reversed such that the divisors
decrease in magnitude) applied to the domain value...
eval(''.join(...)) ...concatenate to string and evaluate...
[...] ...and pack all the values for that particular
function as a list
[...] Pack all lists representing all functions into a list
...:z in... If z is in this list, it must be a valid mod-fold, so
return True. Else, return False
Try it on Ideone
Python 2, 69 bytes
f=lambda a,i=0:i/len(a)or a[i]in[a[i-1]+1,i,0][i<=max(a)::2]*f(a,i+1)
Uses True
/False
.
The answer to what characterizes a mod-foldable series turns out to be less interesting than it seems at first. It is a series of the form 0, 1, ..., M - 1, 0, 1, ... x1, 0, 1, ..., x2, ... such that for all i, 0 <= xi < M. Such a sequence can be produced by the mod chain of all the (0-based) indices of the zeroes in the array, excluding the first.