def base_to10_u(base, nums): def ufunc(acc_idx_rst): (acc, idx, rst) = acc_idx_rst if [] == rst: return None addon = rst[-1] * (base ** idx) return (acc + addon, (acc + addon, idx + 1, rst[:-1])) return util.head_or(0, unfold_right_i(ufunc, (0, 0, nums)))
def split_at_u(num, lst): def ufunc(wss_zss_ndx): ((wss, zss), ndx) = wss_zss_ndx if [] == zss or num <= ndx: return None return ((wss + [zss[0]], zss[1:]), ((wss + [zss[0]], zss[1:]), ndx + 1)) return util.head_or(([], lst), unfold_right_i(ufunc, (([], lst), 0)))
def unzip_u(ziplst): def ufunc(acc_rst): (acc, rst) = acc_rst if [] == rst: return None return ([acc[0] + (rst[0][0],), acc[1] + (rst[0][1],)], ([acc[0] + (rst[0][0],), acc[1] + (rst[0][1],)], rst[1:])) return util.head_or([(), ()], unfold_right_i(ufunc, ([(), ()], ziplst)))
def anyall_u(pred, lst): func = lambda acc, e: (acc[0] or pred(e), acc[1] and pred(e)) def ufunc(acc_rst): (acc, rst) = acc_rst if [] == rst: return None return (func(acc, rst[0]), (func(acc, rst[0]), rst[1:])) return util.head_or((False, True), unfold_right_i(ufunc, ((False, True), lst)))
def nth_u(idx, lst): def gen_func(el, acc, ndx): return el if idx == ndx else acc def ufunc(acc_ndx_rst): (acc, ndx, rst) = acc_ndx_rst if [] == rst: return None return (gen_func(rst[0], acc, ndx), (gen_func(rst[0], acc, ndx), ndx + 1, rst[1:])) return util.head_or(None, unfold_right_i(ufunc, (None, 0, lst)))
def index_find_u(data, lst, idx=0): def gen_func(el, idx_fnd, ndx): return (ndx, el) if -1 == idx_fnd[0] and data == el else idx_fnd def ufunc(acc_ndx_rst): (acc, ndx, rst) = acc_ndx_rst if [] == rst: return None return (gen_func(rst[0], acc, ndx), (gen_func(rst[0], acc, ndx), ndx + 1, rst[1:])) return util.head_or(-1, unfold_right_i(ufunc, ((-1, None), 0, lst)))
def lcm_u(nums): import fractions if [] == nums: return 0 def ufunc(acc_rst): (acc, rst) = acc_rst if [] == rst: return None cur = acc * int(rst[0] / fractions.gcd(acc, rst[0])) return (cur, (cur, rst[1:])) return util.head_or(nums[0], unfold_right_i(ufunc, (nums[0], nums[1:])))
def interleave_u(xss, yss): len_short = len(xss) if len(xss) < len(yss) else len(yss) init = xss[len_short:] + yss[len_short:] def ufunc(acc_wss_rst): (acc, wss, rst) = acc_wss_rst if [] == rst: return None return ([wss[-1], rst[0]] + acc, ([wss[-1], rst[0]] + acc, wss[:-1], rst[1:])) return util.head_or(init, unfold_right_i(ufunc, (init, xss[:len_short], list(reversed(yss[:len_short])))))
def is_ordered_u(xss, key_func=None, reverse=False): if None == key_func: key_func = lambda x: x _flip_le = _flip_func(operator.le, reverse) #if 1 2 > len(xss): return True def ufunc(acc_rst): (acc, rst) = acc_rst if 2 > len(rst): return None return (acc and _flip_le(rst[0], rst[1]), (acc and _flip_le(rst[0], rst[1]), rst[1:])) return util.head_or(True, unfold_right_i(ufunc, (True, xss)))
def partition_u(pred, lst): def gen_func(el, lst0_lst1): (lst0, lst1) = lst0_lst1 return (lst0 + [el], lst1) if pred(el) else (lst0, lst1 + [el]) def ufunc(wss_zss_rst): ((wss, zss), rst) = wss_zss_rst if [] == rst: return None return (gen_func(rst[0], (wss, zss)), (gen_func(rst[0], (wss, zss)), rst[1:])) return util.head_or(([], []), unfold_right_i(ufunc, (([], []), lst)))
def minmax_u(lst): if [] == lst: raise Exception('empty list') def gen_func(el, lo_hi): (lo, hi) = lo_hi return (el, hi) if lo > el else (lo, el) if hi < el else (lo, hi) def ufunc(lo_hi_rst): ((lo, hi), rst) = lo_hi_rst if [] == rst: return None return (gen_func(rst[0], (lo, hi)), (gen_func(rst[0], (lo, hi)), rst[1:])) return util.head_or((lst[0], lst[0]), unfold_right_i(ufunc, ((lst[0], lst[0]), lst[1:])))
def expt_u(base, num): def ufunc(acc_cnt): if 1 > acc_cnt[1]: return None return (acc_cnt[0] * base, (acc_cnt[0] * base, acc_cnt[1] - 1)) return util.head_or(0.0, unfold_right_i(ufunc, (1, num)))
def concat_u(nlsts): def ufunc(acc_rst): (acc, rst) = acc_rst return None if [] == rst else (rst[0] + acc, (rst[0] + acc, rst[1:])) return util.head_or([], unfold_right_i(ufunc, ([], list(reversed(nlsts)))))
def numseq_math_u(op, hi, lo): init = 0 if op in [operator.add, operator.sub] else 1 def ufunc(acc_cur): (acc, cur) = acc_cur return None if hi < cur else (op(acc, cur), (op(acc, cur), cur + 1)) return util.head_or(init, unfold_right_i(ufunc, (init, lo)))
def append_u(xss, yss): def ufunc(acc_rst): (acc, rst) = acc_rst if [] == rst: return None return (acc + [rst[0]], (acc + [rst[0]], rst[1:])) return util.head_or(xss[:], unfold_right_i(ufunc, (xss[:], yss)))
def fib_u(num): def ufunc(s0_s1_cnt): (s0, s1, cnt) = s0_s1_cnt return None if 0 > cnt else (s0, (s1, s0 + s1, cnt - 1)) return util.head_or(0, unfold_right_i(ufunc, (0, 1, num)))
def length_u(lst): def ufunc(cnt_rst): if [] == cnt_rst[1]: return None return (cnt_rst[0] + 1, (cnt_rst[0] + 1, cnt_rst[1][1:])) return util.head_or(0, unfold_right_i(ufunc, (0, lst)))