aboutsummaryrefslogtreecommitdiff
path: root/challenge-101/tyler-wardhaugh/python/ch-1.py
diff options
context:
space:
mode:
authorTyler Wardhaugh <tyler.wardhaugh@gmail.com>2021-02-25 10:47:22 -0800
committerTyler Wardhaugh <tyler.wardhaugh@gmail.com>2021-02-25 14:11:04 -0800
commit7ee7cb632f67d902f69df08aa3df56224a68dacd (patch)
treeee0f93e57adf66b063c385e115c6f897a27364ff /challenge-101/tyler-wardhaugh/python/ch-1.py
parent1b4ace0cc2d0c7dce94718b0e61a30bddd575867 (diff)
downloadperlweeklychallenge-club-7ee7cb632f67d902f69df08aa3df56224a68dacd.tar.gz
perlweeklychallenge-club-7ee7cb632f67d902f69df08aa3df56224a68dacd.tar.bz2
perlweeklychallenge-club-7ee7cb632f67d902f69df08aa3df56224a68dacd.zip
Ch101 (Python): Tasks 1 & 2
Diffstat (limited to 'challenge-101/tyler-wardhaugh/python/ch-1.py')
-rwxr-xr-xchallenge-101/tyler-wardhaugh/python/ch-1.py74
1 files changed, 74 insertions, 0 deletions
diff --git a/challenge-101/tyler-wardhaugh/python/ch-1.py b/challenge-101/tyler-wardhaugh/python/ch-1.py
new file mode 100755
index 0000000000..963f7ef319
--- /dev/null
+++ b/challenge-101/tyler-wardhaugh/python/ch-1.py
@@ -0,0 +1,74 @@
+#!/usr/bin/env python3
+"""Challenge 101, Task 1"""
+
+import sys
+
+
+DEFAULT_INPUT = [1, 2, 3, 4]
+
+
+def print_matrix(mat, colsep=' '):
+ """Pretty print a matrix (list of lists)"""
+ strs = [[str(x) for x in row] for row in mat]
+ lens = [max(len(x) for x in col) for col in zip(*strs)]
+ fmt = colsep.join(f'{{:{x}}}' for x in lens)
+ tbl = (fmt.format(*row) for row in strs)
+
+ for row in tbl:
+ print(row)
+
+
+def get_min_size(coll_len):
+ """Determine the minimum shape necessary for a matrix to hold len items."""
+ f = lambda x: abs(x - coll_len // x)
+ candidates = {x: f(x) for x in range(1, 1+coll_len) if coll_len % x == 0}
+
+ rows = min(candidates, key=candidates.get)
+ cols = coll_len // rows
+ return rows, cols
+
+
+def rotate_matrix(mat):
+ """Rotate the matrix counterclockwise"""
+ rotated_mat = [list(x) for x in zip(*mat)]
+ rotated_mat.reverse()
+ return rotated_mat
+
+
+
+def _pack(coll, m, n):
+ """Recursively pack an incoming coll into an m x n spiral matrix. This is a
+ helper function for pack_spiral, not meant to be called directly."""
+ if m == 1:
+ yield [coll]
+ elif n == 1:
+ yield from ([x] for x in reversed(coll))
+ else:
+ result = rotate_matrix(list(_pack(coll[n:], n, m-1))) + [coll[:n]]
+ yield from result
+
+
+def pack_spiral(coll):
+ """Return coll as a packed spiral matrix."""
+ m, n = get_min_size(len(coll))
+ spiral = list(_pack(coll, m, n))
+ return spiral
+
+
+def main(args=None):
+ """Run the task"""
+ if args is None:
+ args = sys.argv[1:]
+
+ coll = None
+ if args:
+ import json
+ coll = json.loads(args[0])
+ else:
+ coll = DEFAULT_INPUT
+
+ print_matrix(pack_spiral(coll))
+
+
+if __name__ == '__main__':
+ sys.exit(main())