You are given several data sources that each map routing numbers to bank names. Different sources may disagree, and the same source may even contain inconsistent records for the same routing number. You are also given a bank alias dictionary. Resolve each routing number using weighted voting across sources. First normalize bank names using the alias dictionary, trimming spaces and ignoring case. Inside a single source, if a routing number appears multiple times with equivalent names, that source casts one vote for that bank. If a single source contains conflicting banks for the same routing number, that source casts no vote for that routing number. Across sources, add up the source weights for each candidate bank. Return the bank with the highest total weight. If there is a tie for highest weight, or if no valid source votes remain for a routing number that appeared in the input, return 'AMBIGUOUS'.
Examples
Input: ([[('111', ' Bank of America '), ('111', 'boa')], [('111', 'Bank of America')]], [2, 1], {'boa': 'Bank of America'})
Expected Output: {'111': 'Bank of America'}
Explanation: In the first source, both names normalize to Bank of America, so that source casts one vote worth 2. The second source adds another vote worth 1. Bank of America wins with total weight 3.
Input: ([[('222', 'Chase'), ('222', ' JP Morgan Chase ')], [('222', 'Wells Fargo')], [('222', ' chase ')]], [3, 4, 2], {'jp morgan chase': 'Chase'})
Expected Output: {'222': 'Chase'}
Explanation: Source 1 contributes 3 to Chase because both records are equivalent after alias normalization. Source 2 contributes 4 to Wells Fargo. Source 3 contributes 2 to Chase. Final totals: Chase 5, Wells Fargo 4.
Input: ([[('333', 'Citi')], [('333', 'Wells Fargo')]], [3, 3], {})
Expected Output: {'333': 'AMBIGUOUS'}
Explanation: Citi and Wells Fargo both receive total weight 3, so the routing number is ambiguous.
Input: ([[('444', 'Alpha Bank'), ('444', 'Beta Bank')], [('444', ' alpha bank '), ('444', 'Beta Bank')]], [5, 1], {})
Expected Output: {'444': 'AMBIGUOUS'}
Explanation: Each source has conflicting normalized banks for routing 444, so neither source casts a valid vote. Since the routing number appeared but no valid votes remain, the result is AMBIGUOUS.
Input: ([[('001', ' First Bank '), ('002', 'Second Bank'), ('002', 'second bank')], [], [('001', 'first bank'), ('003', 'Third Bank'), ('003', 'Third Bank')]], [1, 5, 2], {})
Expected Output: {'001': 'First Bank', '002': 'Second Bank', '003': 'Third Bank'}
Explanation: Routing 001 gets one vote from source 1 and one from source 3 for the same normalized bank. Routing 002 appears twice in source 1 with equivalent names, so that source casts one vote. Routing 003 appears twice in source 3 with the same bank, which still counts as one vote.
Input: ([], [], {})
Expected Output: {}
Explanation: No routing numbers appear in the input, so the result is an empty dictionary.