September Morn Update
This commit is contained in:
parent
4e2d22a71d
commit
aac6731f2c
6856 changed files with 141342 additions and 21127 deletions
68
Task/Ordered-Partitions/C-sharp/ordered-partitions.cs
Normal file
68
Task/Ordered-Partitions/C-sharp/ordered-partitions.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public static class OrderedPartitions
|
||||
{
|
||||
public static void Main() {
|
||||
var input = new [] { new[] { 0, 0, 0, 0, 0 }, new[] { 2, 0, 2 }, new[] { 1, 1, 1 } };
|
||||
foreach (int[] sizes in input) {
|
||||
foreach (var partition in Partitions(sizes)) {
|
||||
Console.WriteLine(partition.Select(set => set.Delimit(", ").Encase('{','}')).Delimit(", ").Encase('(', ')'));
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<IEnumerable<int[]>> Partitions(params int[] sizes) {
|
||||
var enumerators = new IEnumerator<int[]>[sizes.Length];
|
||||
var unused = Enumerable.Range(1, sizes.Sum()).ToSortedSet();
|
||||
var arrays = sizes.Select(size => new int[size]).ToArray();
|
||||
|
||||
for (int s = 0; s >= 0; ) {
|
||||
if (s == sizes.Length) {
|
||||
yield return arrays;
|
||||
s--;
|
||||
}
|
||||
if (enumerators[s] == null) {
|
||||
enumerators[s] = Combinations(sizes[s], unused.ToArray()).GetEnumerator();
|
||||
} else {
|
||||
unused.UnionWith(arrays[s]);
|
||||
}
|
||||
if (enumerators[s].MoveNext()) {
|
||||
enumerators[s].Current.CopyTo(arrays[s], 0);
|
||||
unused.ExceptWith(arrays[s]);
|
||||
s++;
|
||||
} else {
|
||||
enumerators[s] = null;
|
||||
s--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<T[]> Combinations<T>(int count, params T[] array) {
|
||||
T[] result = new T[count];
|
||||
foreach (int pattern in BitPatterns(array.Length - count, array.Length)) {
|
||||
for (int b = 1 << (array.Length - 1), i = 0, r = 0; b > 0; b >>= 1, i++) {
|
||||
if ((pattern & b) == 0) result[r++] = array[i];
|
||||
}
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
|
||||
static IEnumerable<int> BitPatterns(int ones, int length) {
|
||||
int initial = (1 << ones) - 1;
|
||||
int blockMask = (1 << length) - 1;
|
||||
for (int v = initial; v >= initial; ) {
|
||||
yield return v;
|
||||
if (v == 0) break;
|
||||
|
||||
int w = (v | (v - 1)) + 1;
|
||||
w |= (((w & -w) / (v & -v)) >> 1) - 1;
|
||||
v = w & blockMask;
|
||||
}
|
||||
}
|
||||
|
||||
static string Delimit<T>(this IEnumerable<T> source, string separator) => string.Join(separator, source);
|
||||
static string Encase(this string s, char start, char end) => start + s + end;
|
||||
}
|
||||
107
Task/Ordered-Partitions/Python/ordered-partitions-3.py
Normal file
107
Task/Ordered-Partitions/Python/ordered-partitions-3.py
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
'''Ordered Partitions'''
|
||||
|
||||
|
||||
# partitions :: [Int] -> [[[Int]]]
|
||||
def partitions(xs):
|
||||
'''Ordered partitions of xs.'''
|
||||
n = sum(xs)
|
||||
|
||||
def go(s, n, ys):
|
||||
return [
|
||||
[l] + r
|
||||
for (l, rest) in choose(s)(n)(ys[0])
|
||||
for r in go(rest, n - ys[0], ys[1:])
|
||||
] if ys else [[]]
|
||||
return go(enumFromTo(1)(n), n, xs)
|
||||
|
||||
|
||||
# choose :: [Int] -> Int -> Int -> [([Int], [Int])]
|
||||
def choose(xs):
|
||||
'''(m items chosen from n items, the rest)'''
|
||||
def go(xs, n, m):
|
||||
f = cons(xs[0])
|
||||
choice = choose(xs[1:])(n - 1)
|
||||
return [([], xs)] if 0 == m else (
|
||||
[(xs, [])] if n == m else (
|
||||
[first(f)(x) for x in choice(m - 1)] +
|
||||
[second(f)(x) for x in choice(m)]
|
||||
)
|
||||
)
|
||||
return lambda n: lambda m: go(xs, n, m)
|
||||
|
||||
|
||||
# TEST ----------------------------------------------------
|
||||
# main :: IO ()
|
||||
def main():
|
||||
'''Tests of the partitions function'''
|
||||
|
||||
f = partitions
|
||||
print(
|
||||
fTable(main.__doc__ + ':')(
|
||||
lambda x: '\n' + f.__name__ + '(' + repr(x) + ')'
|
||||
)(
|
||||
lambda ps: '\n\n' + '\n'.join(
|
||||
' ' + repr(p) for p in ps
|
||||
)
|
||||
)(f)([
|
||||
[2, 0, 2],
|
||||
[1, 1, 1]
|
||||
])
|
||||
)
|
||||
|
||||
|
||||
# DISPLAY -------------------------------------------------
|
||||
|
||||
# fTable :: String -> (a -> String) ->
|
||||
# (b -> String) -> (a -> b) -> [a] -> String
|
||||
def fTable(s):
|
||||
'''Heading -> x display function -> fx display function ->
|
||||
f -> xs -> 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
|
||||
)
|
||||
|
||||
|
||||
# GENERIC -------------------------------------------------
|
||||
|
||||
# cons :: a -> [a] -> [a]
|
||||
def cons(x):
|
||||
'''Construction of a list from x as head,
|
||||
and xs as tail.
|
||||
'''
|
||||
return lambda xs: [x] + xs
|
||||
|
||||
|
||||
# enumFromTo :: (Int, Int) -> [Int]
|
||||
def enumFromTo(m):
|
||||
'''Integer enumeration from m to n.'''
|
||||
return lambda n: list(range(m, 1 + n))
|
||||
|
||||
|
||||
# first :: (a -> b) -> ((a, c) -> (b, c))
|
||||
def first(f):
|
||||
'''A simple function lifted to a function over a tuple,
|
||||
with f applied only the first of two values.
|
||||
'''
|
||||
return lambda xy: (f(xy[0]), xy[1])
|
||||
|
||||
|
||||
# second :: (a -> b) -> ((c, a) -> (c, b))
|
||||
def second(f):
|
||||
'''A simple function lifted to a function over a tuple,
|
||||
with f applied only the second of two values.
|
||||
'''
|
||||
return lambda xy: (xy[0], f(xy[1]))
|
||||
|
||||
|
||||
# MAIN ---
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Loading…
Add table
Add a link
Reference in a new issue