Challenge:
Two input files are given The first contains |N| ratios in the form of two labels and a ratio:
- USD, GBP, 0.69
- Meter, Yard, 1.09
- YEN, EUR, 0.0077
- GBP, YEN, 167.75
- Horsepower, Watt, 745.7
Each line A, B, C means that C is a conversion factor from A to B. In other words, multiply by C to go from A to B, and 1 A is worth C B's.
Example: USD, GBP, 0.69 means that 1 USD = 0.69 GBP, so multiplying by 0.69 converts an amount from USD to GBP.
And the expected output is a file with the query and the ratio value filled in.
- USD, EUR, 0.89
- Yard, Meter, 0.91
Write a program that reads both input files and produces the expected output
USD-EUR can be found by multiplying 0.69*167*0.0077=0.89 (Approx)
My Approach: These inputs can be represented as a weighted bi-directional graph
0.69 167 0.0077
USD------->GBP------->YEN------->EUR
<------ <------- <-------
1.449 0.0059 129.87
If we represent this format the problem reduces to finding shortest path between two nodes which can be done using Dijkstra. Instead of writing graph code from scratch i found a library from https://pypi.org/project/Dijkstar/ which reduced my code to
>>> from dijkstar import Graph,find_path
>>> graph=Graph()
>>> graph.add_edge('USD','GBP',{'cost':0.69})
>>> graph.add_edge('GBP','YEN',{'cost':167})
>>> graph.add_edge('YEN','EUR',{'cost':0.0077})
>>> graph.add_edge('EUR','YEN',{'cost':129.87})
>>> graph.add_edge('YEN','GBP',{'cost':0.0059})
>>> graph.add_edge('GBP','USD',{'cost':1.449})
>>> cost_func=lambda u,v,e,prev_e:e['cost']
>>> t=find_path(graph,'USD','EUR',cost_func=cost_func)
>>> print(t.costs)
[0.69,167,0.0077]
>>> from functools import reduce
>>> ans=reduce(lambda x, y: x*y, t.costs)
>>> print(round(ans,2))
0.89
I think the time complexity should be O(|V|+|E|).
Can I optimize this further? Is there a better or another way to solve this problem ?