# Fun with linked lists.
from functools import reduce
class Node:
def __init__(self, val=None, next=None):
self.val = val
self.next = next
def __str__(self):
return '#(' + ' '.join(map(str, ltoa(self))) + ')'
def atol(a):
# Array to linked-list.
return reduce(lambda init, x: Node(x, init), reversed(a), None)
def ltoa(l):
# Linked-list to array.
return reducelp(lambda init, x: init + [x.val], l, [])
def reducelp(f, l, init):
while l:
init = f(init, l)
l = l.next
return init
def _append(tail, l):
while l:
tail.next = Node(l.val)
tail = tail.next
l = l.next
return tail
def appendl(ls):
temp = Node()
reducelp(lambda init, x: _append(init, x.val), ls, temp)
return temp.next
def reversel(l):
return reducelp(lambda init, x: Node(x.val, init), l, None)
def mapl(f, l):
return maplp(lambda x: f(x.val), l)
def maplp(f, l):
return reversel(reducelp(lambda init, x: Node(f(x), init), l, None))
def appendmaplp(f, l):
return appendl(maplp(f, l))
def combinationsl(l, k):
if k == 0:
return Node()
return appendmaplp(lambda r: mapl(lambda c: Node(r.val, c),
combinationsl(r.next, k-1)), l)
# Show.
n = 5
l1 = atol(list(range(n)))
l2 = atol(list(range(n, n*2)))
l3 = atol(list(range(n*2, n*3)))
print(l1)
print(ltoa(l1))
print(reversel(l1))
print(mapl(lambda x: x**2, l1))
print(appendl(atol([None, l1, None, None, l2, None, None, l3, None])))
print(appendmaplp(lambda x: Node(x.val), l1))
for k in range(n+1):
print(f'{n} choose {k}')
for x in ltoa(combinationsl(l1, k)):
print(x)
IyBGdW4gd2l0aCBsaW5rZWQgbGlzdHMuCgpmcm9tIGZ1bmN0b29scyBpbXBvcnQgcmVkdWNlCgpjbGFzcyBOb2RlOgogICAgZGVmIF9faW5pdF9fKHNlbGYsIHZhbD1Ob25lLCBuZXh0PU5vbmUpOgogICAgICAgIHNlbGYudmFsID0gdmFsCiAgICAgICAgc2VsZi5uZXh0ID0gbmV4dAoKICAgIGRlZiBfX3N0cl9fKHNlbGYpOgogICAgICAgIHJldHVybiAnIygnICsgJyAnLmpvaW4obWFwKHN0ciwgbHRvYShzZWxmKSkpICsgJyknCgpkZWYgYXRvbChhKToKICAgICMgQXJyYXkgdG8gbGlua2VkLWxpc3QuCiAgICByZXR1cm4gcmVkdWNlKGxhbWJkYSBpbml0LCB4OiBOb2RlKHgsIGluaXQpLCByZXZlcnNlZChhKSwgTm9uZSkKCmRlZiBsdG9hKGwpOgogICAgIyBMaW5rZWQtbGlzdCB0byBhcnJheS4KICAgIHJldHVybiByZWR1Y2VscChsYW1iZGEgaW5pdCwgeDogaW5pdCArIFt4LnZhbF0sIGwsIFtdKQoKZGVmIHJlZHVjZWxwKGYsIGwsIGluaXQpOgogICAgd2hpbGUgbDoKICAgICAgICBpbml0ID0gZihpbml0LCBsKQogICAgICAgIGwgPSBsLm5leHQKICAgIHJldHVybiBpbml0CgpkZWYgX2FwcGVuZCh0YWlsLCBsKToKICAgIHdoaWxlIGw6CiAgICAgICAgdGFpbC5uZXh0ID0gTm9kZShsLnZhbCkKICAgICAgICB0YWlsID0gdGFpbC5uZXh0CiAgICAgICAgbCA9IGwubmV4dAogICAgcmV0dXJuIHRhaWwKCmRlZiBhcHBlbmRsKGxzKToKICAgIHRlbXAgPSBOb2RlKCkKICAgIHJlZHVjZWxwKGxhbWJkYSBpbml0LCB4OiBfYXBwZW5kKGluaXQsIHgudmFsKSwgbHMsIHRlbXApCiAgICByZXR1cm4gdGVtcC5uZXh0CgpkZWYgcmV2ZXJzZWwobCk6CiAgICByZXR1cm4gcmVkdWNlbHAobGFtYmRhIGluaXQsIHg6IE5vZGUoeC52YWwsIGluaXQpLCBsLCBOb25lKQoKZGVmIG1hcGwoZiwgbCk6CiAgICByZXR1cm4gbWFwbHAobGFtYmRhIHg6IGYoeC52YWwpLCBsKQoKZGVmIG1hcGxwKGYsIGwpOgogICAgcmV0dXJuIHJldmVyc2VsKHJlZHVjZWxwKGxhbWJkYSBpbml0LCB4OiBOb2RlKGYoeCksIGluaXQpLCBsLCBOb25lKSkKCmRlZiBhcHBlbmRtYXBscChmLCBsKToKICAgIHJldHVybiBhcHBlbmRsKG1hcGxwKGYsIGwpKQoKZGVmIGNvbWJpbmF0aW9uc2wobCwgayk6CiAgICBpZiBrID09IDA6CiAgICAgICAgcmV0dXJuIE5vZGUoKQogICAgcmV0dXJuIGFwcGVuZG1hcGxwKGxhbWJkYSByOiBtYXBsKGxhbWJkYSBjOiBOb2RlKHIudmFsLCBjKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21iaW5hdGlvbnNsKHIubmV4dCwgay0xKSksIGwpCgojIFNob3cuCgpuID0gNQpsMSA9IGF0b2wobGlzdChyYW5nZShuKSkpCmwyID0gYXRvbChsaXN0KHJhbmdlKG4sIG4qMikpKQpsMyA9IGF0b2wobGlzdChyYW5nZShuKjIsIG4qMykpKQoKcHJpbnQobDEpCnByaW50KGx0b2EobDEpKQpwcmludChyZXZlcnNlbChsMSkpCnByaW50KG1hcGwobGFtYmRhIHg6IHgqKjIsIGwxKSkKcHJpbnQoYXBwZW5kbChhdG9sKFtOb25lLCBsMSwgTm9uZSwgTm9uZSwgbDIsIE5vbmUsIE5vbmUsIGwzLCBOb25lXSkpKQpwcmludChhcHBlbmRtYXBscChsYW1iZGEgeDogTm9kZSh4LnZhbCksIGwxKSkKCmZvciBrIGluIHJhbmdlKG4rMSk6CiAgICBwcmludChmJ3tufSBjaG9vc2Uge2t9JykKICAgIGZvciB4IGluIGx0b2EoY29tYmluYXRpb25zbChsMSwgaykpOgogICAgICAgIHByaW50KHgp