Open gamous opened 2 years ago
Assemble a one-line base conversion function using the Y combinator.
from functools import reduce
chr_num_map=lambda x:x-87 if x>96 else x-55 if x>64 else x-48
out_num_map=lambda x:chr(x+48 if x<10 else x+87)
chr_raw_map=lambda x:x
out_raw_map=lambda x:chr(x)
out_base64_map=lambda x:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[x]
chr_base64_map=lambda x:b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".index(x)
def base_convert(data,in_base,out_base,chr_map=chr_num_map,ord_map=out_num_map):
num=reduce(lambda r,x:r*in_base+x,map(lambda c:(chr_map)(ord(c)),data)) #foldl
format_num=lambda r,n:(r if len(r)>0 else[0]) if n==0 else format_num([n%out_base]+r,n//out_base) #unfold
return "".join(map(ord_map, format_num([],num))) #render
def base64_encode(data):
return base_convert(data,256,64,chr_raw_map,out_base64_map)
def base64_decode(data):
return base_convert(data,64,256,chr_base64_map,out_raw_map)
print(base64_decode("Z2Ftb3Vz"))
#y-conbinator version
fp_base=lambda data,in_base,out_base:"".join(map(lambda x:chr(x+48 if x<10 else x+87),\
(lambda f:(lambda self:lambda r,n: f(self(self),r,n))(lambda self:lambda r,n: f(self(self),r,n)))\
(lambda self,r,n:(r if len(r)>0 else[0]) if n==0 else self([n%out_base]+r,n//out_base))\
([],reduce(lambda r,x:r*in_base+x,map(lambda c:(lambda x:x-87 if x>96 else x-55 if x>64 else x-48)(ord(c)),data)))))
print(fp_base("a",16,10))
Build recursive tools from scratch.