fork download
  1. from itertools import*
  2. E=enumerate
  3. L=len
  4. U=lambda x:{L(x)-i:a for i,a in E(x,1)}
  5. V=eval
  6. def G(v,r=[]):
  7. if[]==v:yield r;return
  8. for k in product(*([[-1,0,1]]*L(v[0]))):N=[a+b for a,b in zip(v[0],k)];yield from G(v[1:],r+[[[-1]+N[1:]],[N]][N[0]!=0])
  9. def P(p):
  10. if[]==p:return{0:1}
  11. s=U(p[0])
  12. for e in p[1:]:
  13. n={}
  14. for i,a in E(e,1):
  15. for A in s:n[j]=n.get(j:=A+L(e)-i,0)+s[A]*a
  16. s=n
  17. return s
  18. def f(n,d):
  19. S,D,M={*map(str,d)},[],{}
  20. for i in S:Y=d.count(V(i));D+=[(i,Y)]+[(i,1)]*(Y>1==L(S));M[i]=max(Y,M.get(i,0))
  21. N=U(n);q,O=[[(a,b,t:=P([V(i)for J,K in[(j,M[j])for j in{*M}-{a}]+[(a,M[a]-b)]*(M[a]>b)for i in[J]*K]),[1]+[0]*(max(N)-max(t)))for a,b in D]],[]
  22. while q:
  23. a=q.pop(0);O+=a,;r={}
  24. for *_,p,o in a:
  25. for A,B in P([[*p.values()],o]).items():r[A]=r.get(A,0)+B
  26. if r==N:return[[i[-1],[V(i[0])]*int(i[1])]for i in a]
  27. for i in G([j[-1]for j in a]):v=[(A,B,C,z)for(A,B,C,_),z in zip(a,i)];q+=-~-(v in O)*[v]
  28.  
  29. print(f([1,4], [[1,3], [1,2]]))
  30. print(f([1,4], [[1,3], [1,3]]))
  31. print(f([2,-1,4], [[1,0], [1,0,4]]))
Success #stdin #stdout 0.08s 14152KB
stdin
Standard input is empty
stdout
[[[2], [[1, 2]]], [[-1], [[1, 3]]]]
[[[-1, -2], [[1, 3], [1, 3]]], [[2], [[1, 3]]]]
[[[1], [[1, 0]]], [[1, -1], [[1, 0, 4]]]]