Ziemlich hohe Werte

23

Aufgabe

Berechnen Sie aus einer eingegebenen Liste von Ganzzahlen x 1 … x n eine Liste von Rängen r 1 … r n (eine Permutation von {1… n} ), sodass x r 1  ≤ x r 2  ≤… ≤ x r n . Ersetzen Sie dann für jedes x i seinen Rang durch das arithmetische Mittel der Ränge aller Werte in x , die gleich x i sind . (Das heißt, wenn es einen Gleichstand zwischen gleichen Werten in x gibt , verteilen Sie die Ränge unter allen fair neu.) Geben Sie die modifizierte Liste der Ränge r ' n aus 1 … r' aus. .

(Für Statistikfreaks: Eine solche Rangfolge von Beobachtungen wird im Mann-Whitney- U- Test (Methode zwei, Schritt 1) ​​verwendet.)

Beispiel

Bei einer Eingabeliste [3, -6, 3, 3, 14, 3] wäre die erste Rangliste [2, 1, 3, 4, 6, 5] , wodurch die Liste in [-6, 3, 3, 3, 3, 14] . Dann werden die Ränge für alle 3 s in der Eingabeliste auf (2 + 3 + 4 + 5) ÷ 4 = 3,5 ausgeglichen . Die endgültige Ausgabe ist [3.5, 1, 3.5, 3.5, 6, 3.5] .

Testfälle

[4, 1, 4] -> [2.5, 1.0, 2.5]
[5, 14, 14, 14, 14, 5, 14] -> [1.5, 5.0, 5.0, 5.0, 5.0, 1.5, 5.0]
[9, 9, -5, -5, 13, -5, 13, 9, 9, 13] -> [5.5, 5.5, 2.0, 2.0, 9.0, 2.0, 9.0, 5.5, 5.5, 9.0]
[13, 16, 2, -5, -5, -5, 13, 16, -5, -5] -> [7.5, 9.5, 6.0, 3.0, 3.0, 3.0, 7.5, 9.5, 3.0, 3.0]

Regeln

Das ist , also gewinnt der kürzeste Code in Bytes.

Lynn
quelle

Antworten:

6

Pyth, 12

m+l<#dQ.OS/Q

Test Suite

Für jeden Wert berechnet dies das arithmetische Mittel von [1..frequency]und addiert die Anzahl der Werte, die kleiner als der aktuelle sind.

Dies funktioniert, weil wir für jeden Wert Folgendes berechnen würden:

(1 / frequency) * sum (i = 1..frequency) i + count_less

was wir vereinfachen können:

(1 / frequency) * [ frequency * (frequency + 1) / 2 + count_less * frequency ]

und nochmal zu:

(frequency + 1) / 2 + count_less

In Pyth war es jedoch Golfspieler, den ersten Summanden mit dem eingebauten Mittelwert zu berechnen, anstatt mit dieser anderen Formel.

FryAmTheEggman
quelle
4

Python 2, 51 Bytes

lambda l:[-~sum(1+cmp(y,x)for x in l)/2.for y in l]

Für jedes Element ygibt der cmpAusdruck 2 Punkte für jedes kleinere xund 1 Punkt für jedes gleiche an x. Diese Summe wird durch Addition von 1 und Halbierung in den richtigen Bereich skaliert. Das 2.wird benötigt, um eine Ganzzahldivision zu vermeiden.

Python 3, 52 Bytes

Python 3 fehlt cmp, erfordert einen Booleschen Ausdruck (+2 Byte), hat aber eine Float-Division (-1 Byte).

lambda l:[-~sum((y>x)+(y>=x)for x in l)/2for y in l]
xnor
quelle
3

MATL , 14 Bytes

7#utG&S&S2XQw)

Probieren Sie es online! Oder überprüfen Sie alle Testfälle (leicht geänderte Version des Codes; jedes Ergebnis steht in einer anderen Zeile).

      % Implicit input. Example: [5 14 14 14 14 5 14]
7#u   % Replace each value by a unique, integer label. Example: [1; 2; 2; 2; 2; 1; 2]
t     % Duplicate
G&S   % Push input again. Sort and get indices of the sorting. Example: [1 6 2 3 4 5 7]
&S    % Sort and get the indices, again. This gives the ranks. Example: [1 3 4 5 6 2 7]
2XQ   % Compute mean of ranks for equal values of the integer label. Example: [1.5; 5]
w     % Swap top two elements in stack
)     % Index the means with the integer labels. Example: [1.5; 5; 5; 5; 5; 1.5; 5]
      % Implicit display
Luis Mendo
quelle
3

R 17 12 Bytes

Übernimmt die Eingabe von STDIN-Ausgängen an STDOUT. Wenn der Ausgang flexibel ist, können wir den abwerfen cat().

rank(scan())

Ziemlich einfach, verwendet den eingebauten Rang, der standardmäßig als Mittelwert für einen Tie Breaker verwendet wird.

In Benutzung:

> rank(scan())
1: 5 14 14 14 14 5 14
8: 
Read 7 items
[1] 1.5 5.0 5.0 5.0 5.0 1.5 5.0
> rank(scan())
1: 3 -6 3 3 14 3
7: 
Read 6 items
[1] 3.5 1.0 3.5 3.5 6.0 3.5
> 
MickyT
quelle
Sie können die fallen lassen cat(), wenn es nach mir geht. Ich weiß jedoch nicht, wie der Konsens in der Community lautet.
Lynn
@Lynn Danke werde ich. Ich kann es immer zurücklegen.
MickyT
2

J, 18 Bytes

1-:@+1+/"1@:+*@-/~

Basiert auf Dennis ' Lösung nach der Methode von xnor .

Die Verwendung eines einfachen Ansatzes erfordert für mich 24 Bytes .

(i.~~.){](+/%#)/.1+/:@/:

Verwendung

   f =: 1-:@+1+/"1@:+*@-/~
   f 3 _6 3 3 14 3
3.5 1 3.5 3.5 6 3.5
   f 4 1 4
2.5 1 2.5
   f 5 14 14 14 14 5 14
1.5 5 5 5 5 1.5 5
   f 9 9 _5 _5 13 _5 13 9 9 13
5.5 5.5 2 2 9 2 9 5.5 5.5 9
   f 13 16 2 _5 _5 _5 13 16 _5 _5
7.5 9.5 6 3 3 3 7.5 9.5 3 3
Meilen
quelle
1

Eigentlich 18 Bytes

;╗`╝╜"╛-su"£MΣu½`M

Probieren Sie es online!

Dies ist im Wesentlichen ein Hafen von Python-Lösung xnor .

Erläuterung:

;╗`╝╜"╛-su"£MΣu½`M
;╗                  push a copy of input to reg0
  `             `M  for x in input:
   ╝                  push x to reg1
    ╜                 push input from reg0
     "    "£M         for y in input:
      ╛                 push x from reg0
       -s               cmp(y,x) (sgn(y-x))
         u              add 1
             Σu½      sum, add 1, half
Mego
quelle
1

APL, 17 Zeichen

(y+.×⍋X)÷+/y←∘.=⍨X

Angenommen, die Liste ist in gespeichert X .

Erläuterung:

Beachten Sie, dass APL Ausdrücke von rechts nach links auswertet. Dann:

  • ∘.=⍨X= X∘.=XWo ∘.=wird das äußere Produkt =als dyadische Funktion verwendet ? (Wo Sie normalerweise multiplizieren würden. So kann das mathematische äußere Produkt als geschrieben werden ∘.×.)
  • Die resultierende Matrix wird in gespeichert yund ydirekt gefaltet +, um einen Vektor der Anzahl gleicher Objekte für jeden Rang zu erhalten (nennen wir es z←+/y).
  • ⍋X liefert die Ränge von X
  • y+.×⍋X gibt das innere Produkt unserer Matrix y mit diesem Vektor an.
  • Das Ergebnis wird (komponentenweise) durch geteilt z.
user2070206
quelle
0

JavaScript (ES6), 49 48 Bytes

a=>a.map(n=>a.reduce((r,m)=>r+(n>m)+(n>=m),1)/2)

Bearbeiten: 1 Byte durch Neuformulierung des Ausdrucks gespeichert, sodass er jetzt wie die Antwort von @ xnor auf Python 3 aussieht.

Neil
quelle