Trouvez une séquence d'échanges extrêmement rentable avec un tableau des taux de change.
À titre d'exemple, considérons les devises A riary (votre devise nationale), B aht, C edi et D enar où le taux de l'un à l'autre (après qu'un taux de transaction a été prélevé) est donné par l'entrée (ligne, colonne) dans le tableau des taux de change ci-dessous:
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
De toute évidence, l'échange de A contre A n'est pas une bonne idée car ce bureau se fera un plaisir de vous facturer pour ne rien faire.
Moins évidemment, mais vrai avec ce tableau, échanger A contre n'importe quelle autre devise, puis échanger à nouveau est un facteur de perte:
via B: 1.719828 × 0.579942 = 0.997400489976
via C: 4.509549 × 0.219978 = 0.992001569922
via D: 0.709929 × 1.39986 = 0.99380120994
Cependant, l'échange de A à D puis de D à B puis de B à A est rentable (avec suffisamment de capital pour ne pas succomber à l'arrondissement):
0.709929 × 2.429757 × 0.579942 = 1.0003738278192194
On pourrait à plusieurs reprises prendre ce "déjeuner gratuit" tant que l'occasion se présente.
Mais une chaîne encore plus séduisante existe ici, à savoir A à D puis D à C puis C à B et enfin B à A :
0.709929 × 6.409359 × 0.379962 × 0.579942 = 1.0026612752037345
Détails du défi
Étant donné un tableau des taux de change dans un format raisonnable qui fixe la signification de la devise nationale (par exemple, la 1ère ligne et la 1ère colonne sont toujours la devise nationale)
(ou étant donné un tel tableau et un indice de la devise nationale),
trouvez un * séquence maximale d'arbitrage des échanges commençant et se terminant avec la devise locale comme indices dans la liste des devises sans répéter l'utilisation d'aucun échange (c'est-à-dire qu'un échange Y-> X peut suivre un échange X-> Y, mais un X-> Y ne peut pas suivre un X-> Y).
S'il n'existe aucune opportunité rentable, indiquez une liste vide ou un autre résultat qui ne peut pas être confondu avec une opportunité identifiée.
- par exemple pour l'exemple ci-dessus ( A-> D, D-> C, C-> B, B-> A ):
- en utilisant l'indexation 0, on pourrait retourner
[[0,3],[3,2],[2,1],[1,0]]
ou[0,3,2,1,0]
- en utilisant 1-indexation on pourrait retourner
[[1,4],[4,3],[3,2],[2,1]]
ou[1,4,3,2,1]
Les autres formats sont corrects tant qu'il n'y a pas d'ambiguïté.
- Une chose à surveiller est qu'il est possible que la meilleure opportunité soit une seule transaction de la maison-> maison (un bureau stupide). Si vous décidez d'exclure l'index de la devise locale des deux extrémités de l'option plate ci-dessus (c'est-à [3,2,1]
- dire ou [4,3,2]
) et une liste vide pour "aucune opportunité", assurez-vous que le home-> home n'est pas également une liste vide.
* S'il existe plusieurs opportunités valables tout aussi rentables, renvoyez-en une, certaines ou la totalité.
L'algorithme Bellman-Ford est une façon d'aborder cela, mais ce n'est probablement pas le mieux adapté au golf.
Cas de test
Les entrées indiquées sont dans l'arrangement utilisé dans l'exemple, et les résultats affichés utilisent l'indexation 0 pour répertorier les indices de devise (lorsqu'une opportunité existe, la devise nationale est uniquement à l'extrémité arrière; aucune opportunité n'est une liste vide).
[[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]
Il s'agit de code-golf, donc la solution la plus courte en octets l'emporte, mais la compétition devrait également se faire en intra-langue, alors ne laissez pas les langues de golf par code vous empêcher de soumettre dans votre langue préférée!