"""Owned positive-axis broadcasting shape and explicit source-index mapper, no NumPy."""
from itertools import product
import math,json
def valid(s):
    if any(type(x)is not int or x<=0 for x in s):raise ValueError('positive integer axes only in this subset')
def shape(a,b):
    valid(a);valid(b);n=max(len(a),len(b));aa=(1,)*(n-len(a))+a;bb=(1,)*(n-len(b))+b
    out=[]
    for x,y in zip(aa,bb):
        if x!=y and x!=1 and y!=1:raise ValueError('incompatible right-aligned axes')
        out.append(max(x,y))
    return tuple(out)
def source_index(out_index,s):return tuple(0 if n==1 else i for i,n in zip(out_index[len(out_index)-len(s):],s)) if s else ()
def add(a_shape,a_values,b_shape,b_values):
    s=shape(a_shape,b_shape)
    if len(a_values)!=math.prod(a_shape) or len(b_values)!=math.prod(b_shape):raise ValueError('flat value count mismatch')
    if math.prod(s)>256:raise ValueError('own demonstration output cap')
    def flat(idx,dims):
        k=0
        for i,n in zip(idx,dims):k=k*n+i
        return k
    rows=[]
    for idx in product(*(range(n) for n in s)):
        ai=source_index(idx,a_shape);bi=source_index(idx,b_shape);av=a_values[flat(ai,a_shape)];bv=b_values[flat(bi,b_shape)]
        rows.append({'output_index':idx,'a_index':ai,'b_index':bi,'a':av,'b':bv,'sum':av+bv})
    return {'output_shape':s,'elements':rows}
def demo():
    multi=add((2,1,3),[0,1,2,100,101,102],(1,4,1),[0,100,200,300])
    selected=next(r for r in multi['elements'] if r['output_index']==(1,2,2))
    assert multi['output_shape']==(2,4,3) and selected['a_index']==(1,0,2) and selected['b_index']==(0,2,0) and selected['sum']==302
    missing=add((3,),[1,2,3],(2,1),[10,20]);assert [r['sum'] for r in missing['elements']]==[11,12,13,21,22,23]
    scalar=add((),[5],(2,),[1,2]);assert [r['sum'] for r in scalar['elements']]==[6,7]
    rejected=[]
    for name,a,b in [('axis_mismatch',(2,3),(2,)),('zero_axis_outside_own_subset',(0,3),(1,3)),('boolean_axis',(True,3),(3,))]:
        try:shape(a,b)
        except ValueError:rejected.append(name)
        else:raise AssertionError(name)
    return {'multi_axis_addition':multi,'missing_leading_axis_addition':missing,'scalar_addition':scalar,'selected_multi_axis_row':selected,'rejected_cases':rejected,'NumPy_memory_or_matrix_multiplication_executed':False}
if __name__=='__main__':print(json.dumps(demo(),indent=2))
