Etant donné un vecteur de dimension avec des entrées réelles, pour une permutation la plus proche de par rapport à la -Distance.
Détails
- S'il est plus commode, vous pouvez utiliser les permutations de à la place. S'il y a plusieurs permutations les plus proches, vous pouvez sortir n'importe laquelle ou alternativement toutes.
- La distance entre deux vecteurs est définie comme
- Si vous le souhaitez, vous pouvez supposer que l'entrée se compose uniquement d'entiers.
Exemples
[0.5 1] -> [1 2], [2 1]
c*[1 1 ... 1] -> any permutation
[1 4 2 6 2] -> [1 4 3 5 2], [1 4 2 5 3]
[1 3 5 4 1] -> [2 3 5 4 1], [1 3 5 4 2]
[7 7 3 2 5 6 4 2] -> [8 7 3 2 5 6 4 1], [8 7 3 1 5 6 4 2], [7 8 3 2 5 6 4 1], [7 8 3 1 5 6 4 2]
[-2 4 5 7 -1 9 3] -> [1 4 5 6 2 7 3], [2 4 5 6 1 7 3], [1 4 5 7 2 6 3], [2 4 5 7 1 6 3]
[0 4 2 10 -1 10 5] -> [1 4 2 6 3 7 5], [1 4 3 6 2 7 5], [2 4 3 6 1 7 5], [3 4 2 6 1 7 5], [1 4 2 7 3 6 5], [1 4 3 7 2 6 5], [2 4 3 7 1 6 5], [3 4 2 7 1 6 5]
Script octave pour générer plus d'exemples.
v
seront supérieurs à0
? Ou, du moins, non0
?v
peuvent être des entiers. (Ajout de quelques exemples supplémentaires.)[1.6 2]
c'est un cas de test important (l'algorithme gourmand / le tri lexicographique donne la mauvaise réponse).Réponses:
Python 2 , 60 octets
Essayez-le en ligne!
Utilise l'indexation zéro.
Un algorithme rapide avec une idée simple. Si nous avons besoin au lieu de permuter la liste d'entrée pour le rendre aussi proche(1,2,...,n) que possible, nous devrions trier, comme le prouve ci - dessous. Puisque nous sommes à la place permutant (1,2,...,n) , on choisit la permutation que de commander la même manière que la liste d'entrée, comme dans mon défi Imiter un ordre (sauf l'entrée peut avoir des répétitions). (Edit: miles a souligné ce défi plus identique , où Dennis a la même réponse .)
Note that the only property of(1,2,...,n) that we used is that it's sorted, so the same algorithm would work to permute any given list to minimize its distance to any fixed list.
In the code, the only purpose of
z=zip(l,range(len(l)))
is to make the input elements distinct, that is to avoid ties, while keeping the same comparisons between unequal elements. If the input we guaranteed to have no repeats, we could remove this and just havelambda l:map(sorted(l).index,l)
.la source
05AB1E, 7 bytes
Try it online!
Explanation
la source
Perl 6, 44 bytes
Try it online!
Anonymous codeblock that returns the first minimum permutation with 0 indexing.
Explanation:
I think I might also be able to get rid of the
.sum
and sort by just the list of absolute values, but I'm not sure this is actually corret, though it passes my current test cases.la source
[0.6 1]
(assuming we're 0-indexed), where if you optimize for the first value you get[1,0]
for a score of 1.4, but if you optimize for the whole vector the 1 is more valuable in the second position for a score of 0.6.Jelly, 8 bytes
Try it online!
la source
Jelly, 5 bytes
A monadic Link accepting a list of numbers which yields a list of integers.
Try it online! Or see the test-suite.
How?
N.B.
L
(length of) would work in place ofJ
sinceœ?
given an integer,n
, on the right would implicitly make the range[1..n]
to work with, butJ
is explicit.la source
Ruby,
6360 bytesTry it online!
There's a math trick here that could be helpful in other answers too--instead of minimizing the sum of the absolute values of the differences, we maximize the sum of the products. Why does that work?
Minimizing the sum of
(x-y) squared
isn't equivalent to minimizing the sum of|x-y|
, but it will always give a valid answer, it just prioritizes reducing large differences over small ones whereas the actual challenge is indifferent between the two.But
(x-y)*(x-y)
=x*x+y*y-2*x*y
. Since the square terms will always show up somewhere in the sum for any permutation, they don't affect the result, so we can simplify to-2*x*y
. The2
factors out, so we can simplify to-x*y
. Then if we change minimizing to maximizing, we can simplify tox*y
.Intuitively, this is similar to observing that if you're trying to maximize square footage using a set of horizontal walls and a set of vertical ones, you're best off pairing walls that are close in size to each other to create rooms that are as close to square as possible.
3*3 + 4*4 = 25
, while3*4 + 4*3 = 24
.Edit: Saved three bytes by generating and evaluating a format string instead of using zip and sum.
la source
Gaia, 13 bytes
Try it online!
la source
JavaScript (ES6), 61 bytes
Based on xnor's insight.
Try it online!
Commented
JavaScript (ES6),
130128 bytesThere
must bedefinitely is a more direct way...0-indexed.
Try it online! (with 1-indexed output)
How?
The helper functiong computes all permutations of (0,...,n−1) , where n is the implicit length of the input array a[] .
For each permutationp , we compute:
We eventually return the permutation that leads to the smallestk .
la source
Wolfram Language (Mathematica), 14 bytes
Try it online!
Based on xnor's insight.
la source
Python 2,
149126112 bytes-23 bytes thanks to Mr. Xcoder
-14 bytes thanks to xnor
Try it online!
Uses permutations of (0 ... n-1).
la source
functools
anymore.reduce
is usually overkill, especially here where you're adding stuff. I think you can just dosum(abs(p-q)for p,q in zip(x,a))
.w/o any permutation package
Python 3, 238 bytes
Try it online!
la source
Wolfram Language (Mathematica), 57 bytes
Try it online!
la source
Japt
-g
, 12 bytesTry it
For 0-indexed, replace the first 2 bytes with
m,
to map the array to its indices instead.la source
J,
258 bytesTry it online!
Much shorter answer based xnor's brilliant idea.
original answer
J, 25 bytes
Try it online!
la source