Skip to content

Instantly share code, notes, and snippets.

@tnguven
Created April 5, 2022 12:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tnguven/fdd3021631f00eb1ffa61e02da7f2d77 to your computer and use it in GitHub Desktop.
Save tnguven/fdd3021631f00eb1ffa61e02da7f2d77 to your computer and use it in GitHub Desktop.
Currency conversion algorithm with Depth First Search algorithm
const currencies = [
['USD', 'EUR', 0.89],
['EUR', 'CHF', 1.03],
['CAD', 'USD', 0.79],
['GBP', 'USD', 1.34],
['AUD', 'HKF', 5.68],
['GBP', 'CAD', 1.7],
['JPY', 'CAD', 0.011],
['GBP', 'JPY', 154.28],
] as [CurrencyType, CurrencyType, number][];
type CurrencyType = 'USD' | 'EUR' | 'CHF' | 'CAD' | 'GBP' | 'AUD' | 'JPY';
function convert(val: number, from: CurrencyType, to: CurrencyType) {
if (from === to) return val;
const res = currencies.reduce((result, currency) => {
if (currency.includes(from) && currency.includes(to)) {
const [f, , r] = currency;
if (f === from) {
result = val * r;
} else {
result = val / r;
}
}
return result;
}, 0);
if (res) return res;
const currencyNames = currencies.reduce((acc, [f, t]) => {
acc.add(f);
acc.add(t);
return acc;
}, new Set<CurrencyType>());
const graphList = new Map();
const addNode = (currency: CurrencyType) => {
graphList.set(currency, []);
};
const addEdge = (origin: CurrencyType, destination: CurrencyType) => {
graphList.get(origin).push(destination);
graphList.get(destination).push(origin);
};
currencyNames.forEach(addNode);
currencies.forEach(([f, t]) => addEdge(f, t));
function findPath(
start: CurrencyType,
visited = new Set<CurrencyType>()
): CurrencyType[] | undefined {
visited.add(start);
const destinations = graphList.get(start);
const indexOfFinalDest = destinations.findIndex((currency: CurrencyType) => currency === to);
if (indexOfFinalDest !== -1) {
return [...visited, destinations[indexOfFinalDest]];
}
for (const destination of destinations) {
if (destination === to) {
return [...visited];
}
if (!visited.has(destination)) {
return findPath(destination, visited);
}
}
return undefined;
}
const conversionPath = findPath(from);
if (!conversionPath) return null;
const { result } = conversionPath.reduce(
(acc, path) => {
if (acc.query.length < 2) {
acc.query.push(path);
}
if (acc.query.length === 2) {
acc.result = convert(acc.result, acc.query[0], acc.query[1]) as number;
acc.query.shift();
}
return acc;
},
{ result: val, query: [] } as { result: number; query: CurrencyType[] }
);
return result;
}
const JPY = convert(20, 'EUR', 'JPY');
console.log({ JPY }); // 2585.9505...
const GBP = convert(20, 'EUR', 'GBP');
console.log({ GBP }); // 16.77008...
const EUR = convert(10, 'USD', 'EUR');
console.log({ EUR }); // 8.9
const AUD = convert(5, 'JPY', 'AUD');
console.log({ AUD }); // null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment