Trova una sequenza di scambi massimamente redditizia in base a una tabella dei tassi di cambio.
Ad esempio, considera le valute A riary (la tua valuta di casa), B aht, C edi e D enar in cui il tasso da uno all'altro (dopo che è stato riscosso qualsiasi tasso di transazione) è dato dalla voce (riga, colonna) in la tabella dei tassi di cambio di seguito:
TO
A B C D
A 0.9999 1.719828 4.509549 0.709929
F B 0.579942 0.9999 2.619738 0.409959
R
O C 0.219978 0.379962 0.9999 0.149985
M
D 1.39986 2.429757 6.409359 0.9999
Ovviamente scambiare A con A non è una grande idea in quanto questa scrivania ti farà felice pagare per non aver fatto nulla.
Meno ovviamente, ma vero con questa tabella, lo scambio di A con qualsiasi altra valuta e quindi il cambio di nuovo è un creatore di perdite:
via B: 1.719828 × 0.579942 = 0.997400489976
via C: 4.509549 × 0.219978 = 0.992001569922
via D: 0.709929 × 1.39986 = 0.99380120994
Tuttavia, lo scambio da A a D, quindi da D a B, quindi da B a A , ha un profitto (dato il capitale sufficiente per non soccombere agli arrotondamenti):
0.709929 × 2.429757 × 0.579942 = 1.0003738278192194
Si potrebbe prendere ripetutamente questo "pranzo libero" mentre esiste l'occasione.
Ma qui esiste una catena ancora più allettante, vale a dire da A a D, quindi da D a C, quindi da C a B e infine da B a A :
0.709929 × 6.409359 × 0.379962 × 0.579942 = 1.0026612752037345
Dettagli della sfida
Dato un tavolo tasso di cambio in qualsiasi formato ragionevole, che fissa il significato della casa-valuta (ad esempio 1 ° fila e 1 ° colonna sono sempre la casa-valuta)
(o dato un tale tabella e un indice di casa-valuta)
trovare un * sequenza di arbitraggio massima degli scambi che iniziano e finiscono con la valuta di casa come indici nell'elenco delle valute senza ripetere l'uso di qualsiasi scambio (cioè uno scambio Y-> X può seguire uno X-> Y, ma un X-> Y non può segui una X-> Y).
Se non esiste tale opportunità redditizia, si ottiene un elenco vuoto o qualche altro risultato non confondibile con un'opportunità identificata.
- ad es. per l'esempio sopra ( A-> D, D-> C, C-> B, B-> A ):
- usando l'indicizzazione 0 si potrebbe restituire
[[0,3],[3,2],[2,1],[1,0]]
o[0,3,2,1,0]
- utilizzando l'indicizzazione 1 si potrebbe restituire
[[1,4],[4,3],[3,2],[2,1]]
o[1,4,3,2,1]
Altri formati vanno bene purché non vi siano ambiguità.
- Una cosa a cui fare attenzione è che è possibile che la migliore opportunità sia una singola transazione da casa-> casa (una scrivania sciocca). Se decidi di escludere l'indice della valuta domestica da entrambe le estremità dell'opzione flat sopra (ovvero [3,2,1]
o [4,3,2]
) e un elenco vuoto per "nessuna opportunità", assicurati che anche home-> home non sia un elenco vuoto.
* Se si verificano più opportunità valide ugualmente redditizie, restituire una di esse, alcune o tutte.
L'algoritmo Bellman-Ford è un modo per avvicinarsi a questo, ma probabilmente non è il più adatto per il golf.
Casi test
Gli input mostrati sono nella disposizione usata nell'esempio, ei risultati mostrati usano l'indicizzazione 0 per elencare gli indici to-currency (quando esiste un'opportunità la valuta domestica è solo alla fine del trailing; nessuna opportunità è un elenco vuoto).
[[0.999900, 1.719828, 4.509549, 0.709929],
[0.579942, 0.999900, 2.619738, 0.409959],
[0.219978, 0.379962, 0.999900, 0.149985],
[1.399860, 2.429757, 6.409359, 0.999900]] -> [3, 2, 1, 0]
[[0.9999, 1.5645, 0.9048, 1.0929],
[0.6382, 0.9999, 0.5790, 0.6998],
[1.1051, 1.7269, 0.9999, 1.2087],
[0.9131, 1.4288, 0.8262, 0.9999]] -> [1, 2, 0]
[[0.9999, 1.4288, 0.8262, 0.9131],
[0.6998, 0.9999, 0.5790, 0.6382],
[1.2087, 1.7269, 0.9999, 1.1051],
[1.0929, 1.5645, 0.9048, 0.9999]] -> [1, 2, 3, 1, 0]
[[1.002662, 1.719828, 4.509549, 0.709929],
[0.579942, 0.999900, 2.619738, 0.409959],
[0.219978, 0.379962, 0.999900, 0.149985],
[1.399860, 2.429757, 6.409359, 0.999900]] -> [3, 2, 1, 0, 0]
[[1.002662, 1.719828, 4.509549, 0.709929],
[0.579942, 1.002604, 2.619738, 0.409959],
[0.219978, 0.379962, 1.003000, 0.149985],
[1.399860, 2.429757, 6.409359, 1.002244]] -> [3, 3, 2, 2, 1, 1, 0, 0]
[[0.9999, 1.4288, 0.8262, 0.9131],
[0.6998, 0.9999, 0.5790, 0.6382],
[1.2087, 1.7269, 1.0001, 1.1051],
[1.0929, 1.4974, 0.9048, 0.9999]] -> [1, 2, 2, 0]
[[0.9999, 1.3262, 0.7262, 0.9131],
[0.6998, 0.9999, 0.5490, 0.6382],
[1.2087, 1.7269, 0.9999, 1.2051],
[1.0929, 1.5645, 0.9048, 0.9999]] -> [3, 2, 3, 1, 0]
[[0.9999, 1.5645, 0.9048, 0.5790],
[0.6382, 0.9999, 0.5790, 0.3585],
[1.1051, 1.7269, 0.9999, 0.6391],
[1.7271, 2.6992, 1.5645, 0.9999]] -> [1, 2, 0] and/or [3, 2, 0]
[[0.9999, 1.2645, 0.7048, 0.3790],
[0.4382, 0.9999, 0.3790, 0.1585],
[1.0001, 1.5269, 1.0001, 0.4391],
[1.5271, 2.4992, 1.3645, 0.9999]] -> []
[[0.9999, 1.2645, 0.7048, 0.3790],
[0.4382, 0.9999, 0.3790, 0.1585],
[0.9999, 1.5269, 1.4190, 0.4391],
[1.5271, 2.4992, 1.3645, 0.9999]] -> [2, 2, 0]
Questo è il code-golf, quindi vince la soluzione più breve in byte, ma anche la competizione dovrebbe essere fatta all'interno della lingua, quindi non lasciare che le lingue di code-golf ti scoraggino a presentare il tuo preferito!