Schrumpfende Zahlen


10

Die Eingabe ist ein Array von (mindestens 3, maximal 20) verschiedenen Ganzzahlen. Jede Ganzzahl ist größer als -1000 und kleiner als 1000.

Ihre Aufgabe ist es, die Zahlen zu verkleinern, indem Sie sie linear von 0.0bis zuordnen 1.0. Dies bedeutet, dass die kleinste Zahl im Array auf 0,0 abgebildet wird, die größte auf 1,0.

Sie erhalten das Array als Parameter (innerhalb einer Funktion) oder als stdin / program-Argumente (Sie können wählen). Drucken Sie das Ergebnis im Format aus double1;double2;double3;.... Die Ausgabe muss dieselbe Reihenfolge wie die Eingabe haben .

Wenn Sie möchten, können Sie die Ausgabe auf 2 Nachkommastellen runden. Nach dem Dezimalpunkt muss mindestens eine Ziffer stehen.

Die Verwendung von integrierten Funktionen (Funktionen, die die Zahlen für Sie verkleinern, z. B. Mathematik Rescale) ist nicht zulässig .

Beispiele:

Input              Output
[5,-20,30]         0.5;0.0;1.0
[1,2,3,4,5]        0.0;0.25;0.5;0.75;1.0
[0,5,100,400]      0.0;0.01;0.25;1.0

(Die letzte Ausgabe ist gerundet, sonst wäre es 0.0;0.0125;0.25;1.0)


2
Also, selbst wenn wir eine Funktion schreiben, muss das Ergebnis gedruckt werden? (Im Gegensatz zur Rückgabe eines entsprechenden Doppel-Arrays.)
Martin Ender

@ MartinBüttner Ja, sie müssen gedruckt werden. Eingebaute Funktionen sind nicht zulässig.
CommonGuy

"Die Verwendung von integrierten Funktionen (wie mathematicas Rescale) ist nicht zulässig." - Das ist zu vage. Welche Funktionen sind nicht erlaubt? Nur diejenigen, die das gesamte Problem lösen (was eine Standardlücke wäre), sind?
John Dvorak

Warten Sie, also kann die Eingabe ein Funktionsargument sein, aber die Ausgabe muss auf dem Bildschirm sein ???
John Dvorak

1
@Dennis Das Format muss mit dem in der Frage gezeigten übereinstimmen. Dies bedeutet, dass die Zahlen durch Semikolons getrennt sind.
CommonGuy

Antworten:


5

CJam, 18 Bytes

q~_$0=f-_$W=df/';*

Beachten Sie, dass der Online-Interpreter fälschlicherweise 0dals 0anstelle von darstellt 0.0.

Beispiellauf

$ cjam shrink.cjam <<< '[5 -20 30]'; echo
0.5;0.0;1.0
$ cjam shrink.cjam <<< '[1 2 3 4 5]'; echo
0.0;0.25;0.5;0.75;1.0
$ cjam shrink.cjam <<< '[0 5 100 400]'; echo
0.0;0.0125;0.25;1.0

Wie es funktioniert

q~                    " P := eval(input())         ";
  _$0=                " S := sorted(P)[0]          ";
      f-              " Q := { X - S : X ∊ P }     ";
        _$W=d         " D := double(sorted(Q)[-1]) ";
             f/       " R := { X / D : X ∊ Q }     ";
               ';*    " print(join(R, ';'))        ";

Meine Reaktion darauf als CJam-Quelle: Wtf? Erklärung erforderlich ...
edc65

2
Gute Möglichkeit, Min und Max mithilfe des Array-Index zu erhalten, anstatt zu knallen und dann Dinge auszutauschen
Optimizer

Es ist wahrscheinlich meine Erkältung, aber warum sortierst du zweimal? Sollte ein sortiertes Array nicht sortiert bleiben, wenn von jedem Element eine Konstante abgezogen wird?
Ingo Bürk

@ IngoBürk Das sortierte Array überlebt den Array-Zugriff nicht, denke ich. Was Sinn macht, weil das Endergebnis nicht sortiert werden darf.
Martin Ender

@ MartinBüttner D'oh. Natürlich. Wir müssen die Ordnung für das Ergebnis behalten. Vielen Dank!
Ingo Bürk

4

JavaScript, ES6, 81 Bytes

Danke an @ edc65 für den toFixedTrick

F=a=>a.map(v=>((v-n)/d).toFixed(2),n=Math.min(...a),d=Math.max(...a)-n).join(';')

Führen Sie es in der neuesten Firefox-Konsole aus.

Dadurch wird eine Funktion erstellt, fdie Sie gerne aufrufen können

F([5,-20,30])

1) Warum eval (prompt), wenn eine Funktion erlaubt ist? 2) Nach dem Dezimalpunkt muss mindestens eine Ziffer stehen. 3) M muss nicht gespeichert werden, nur d = Mm
edc65

Aktualisiert. Obwohl es schwierig ist, mindestens eine Ziffer nach der Dezimalstelle zu erhalten
Optimizer

If you want, you can round the output to 2 digits after the decimal pointDas ist der einfachere Weg, den ich denke
edc65

@ edc65 Aber es gibt keine Möglichkeit, zu konvertieren 1, 1.0außer was ich getan habe.
Optimierer

Nee. Darf ich andeuten?
edc65

4

Python 2, 72 68 63 56 55

Offensichtlich nicht so prägnant wie andere Antworten, aber trotzdem:

x=input()
m=min(x)
print[(i*1.-m)/(max(x)-m)for i in x]

Probelauf:

[1,100,25,8,0]                  #input
[0.01, 1.0, 0.25, 0.08, 0.0]    #output

Alt (68 Zeichen, geschrieben in Python 3):

x=eval(input())
y=sorted(x)
print([(i-y[0])/(y[-1]-y[0])for i in x])

Sie können ein weiteres Zeichen speichern, indem Sie es definieren m=min(x).
FryAmTheEggman

4

CJam, 24 23 Bytes

l~_$)\(:M\;-\Mf-\df/';*

Eingabe sei wie:

[5 -20 30]

Probieren Sie es hier online aus. Beachten Sie, dass der Online-Compiler nur Double 0als druckt 0. Führen Sie den Java-Interpreter aus, der korrekt druckt.

Wie es funktioniert:

l~                      "Evaluate input and convert each element to double";
  _$                    "Copy the array and sort the copied array";
    )                   "Pop the last element out of the array. This is Max";
     \                  "Swap last two stack elements, bring sorted array on top";
      (:M               "Pop the first element of array and store it in M. This is Min";
         \;             "Bring the remaining of sorted array on top and remove it from stack";
           -\           "Subtract Max and Min and bring the original array to top of stack"
             Mf-        "Push min to stack and subtract it from each array element";
                \df/    "Bring (Double)(Max-Min) to top and divide each array element by it";
                   ';*  "Push the character ; to stack and join the array with it";

1
Ah, das ist eine viel bessere Idee, um ein Minimum und ein Maximum zu erreichen.
Martin Ender

Dies druckt 0;0.5;1statt 0.0;0.5;1.0.
CommonGuy

@ Manu - Ja, ich versuche das zu beheben. Und fast alle Antworten tun dies nur.
Optimierer

2
Sie brauchen das Update nicht. Der Java-Interpreter repräsentiert die Double 0 als 0.0.
Dennis

3

C # 92

Wird in LinqPad ausgeführt

void F(int[]a)
{
   double n=a.Min(),d=a.Max()-n;
   a.Select(x=>((x-n)/d).ToString("0.00")).Dump();
}

Test in LinqPad

void Main()
{
    F(new int[]{5,-20,30});
}
void F(int[]a){double n=a.Min(),d=a.Max()-n;a.Select(x=> ((x-n)/d).ToString("0.00")).Dump();}

Ausgabe

IEnumerable<String> (3 items)
0,50 
0,00 
1,00 

3

APL (15)

(2⍕+÷⌈/)(+-⌊/)⎕

(oder ohne Züge auch 15 Zeichen :)

2⍕V÷⌈/V←V-⌊/V←⎕

Dies liest das Argument von der Tastatur und druckt das Ergebnis auf den Bildschirm.

Erläuterung:

  • : Lesen Sie eine Zeile von der Tastatur und werten Sie sie aus
  • +-⌊/: Subtrahieren Sie das niedrigste Element im Array von allen Elementen im Array
  • +÷⌈/: Teilen Sie jedes Element im Array durch das höchste Element des Arrays
  • 2⍕: Format mit zwei Dezimalstellen

Prüfung:

      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
     5 ¯20 30
 0.50 0.00 1.00
      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
      1 2 3 4 5
 0.00 0.25 0.50 0.75 1.00
      (2⍕+÷⌈/)(+-⌊/)⎕
⎕:
      0 5 100 400
 0.00 0.01 0.25 1.00

Sollte die Anzahl der Bytes hinzufügen ...
Optimizer

Welches ist nur 24 Bytes.
Optimierer

2
@Optimizer: Sofern in der Frage nichts anderes angegeben ist, wird jede Antwort mit der Codierung bewertet, die die kleinste Byteanzahl ergibt. Es gibt eine APL-Codepage, die jedes APL-Zeichen um ein Byte darstellt.
Dennis

Korrigieren Sie mich, wenn ich hier etwas falsch mache, aber standardmäßig werden Code-Golf in Bytes und Mothereff gezählt.in / byte-counter#%282%E2%8D%95+%C3%B7%E2%8C%88/ … Seite sagt seine 24 Bytes. Habe ich etwas verpasst ?
Optimierer

1
Die Ausgabe muss durch Semikolons und nicht durch Leerzeichen getrennt werden.
CommonGuy

3

Pyth , 18

Jetzt mit korrekter Formatierung!

j\;mc-dhSQ-eSQhSQQ

Prüfung:

$ pyth -c 'j\;mc-dhSQ-eSQhSQQ' <<< '[0,5,100,400]'
0.0;0.0125;0.25;1.0

Erläuterung:

(implicit)              Q = eval(input())
j\;                     ';'.join(
   m                             map(lambda d:
    c                                         float_div(
     -dhSQ                                              d-sorted(Q)[0],
     -eSQhSQ                                            sorted(Q)[-1]-sorted(Q)[0]),
    Q                                         Q))

Die Ausgabe ist nicht richtig formatiert.
CommonGuy

@Manu Entschuldigung, ich habe es behoben.
isaacg

Erstellt Sie nicht Ihre eigene Sprache, die Sie im Laufe der Zeit ändern, wodurch die Regeln leicht erweitert werden? Sie können natürlich einfach eine neue Funktion hinzufügen, um das Programm zu verkürzen?
Chris Jefferson

3
@ChrisJefferson Ich verwende immer die neueste Version der Sprache, die herauskam, bevor das Problem gestellt wurde. Da alles an Github gesendet wird, kann überprüft werden, dass ich nach dem Veröffentlichen des Problems nichts mehr hinzufüge. Das ist die Standard-CG.SE-Regel - die Sprache muss älter sein als die Frage, und ich halte mich daran.
isaacg

2

Oktave 25

b=min(l);(l-b)/(max(l)-b)

Angenommen, die Eingabe erfolgt lund da es sich um eine interaktive Shell handelt, wird das Ergebnis automatisch gedruckt (ist dies zulässig?)


2
Octave / Matlab muss jedoch inputBenutzereingaben erhalten und STDIN nachahmen. Sie können auch eine Funktion schreiben. Gibt dies auch das Ergebnis im richtigen Format aus?
Martin Ender

Und nein, nur zurückzukehren und die Shell drucken zu lassen, zählt im Allgemeinen nicht. Golfscript und dergleichen sind unterschiedlich, da die Sprache angibt, dass der Stapel am Ende gedruckt wird. Dies ist jedoch beispielsweise bei Javascript nicht der Fall. Und ich denke auch nicht für Matlab / Octave.
Ingo Bürk

2

APL, 31 Zeichen / 55 Bytes

{b←⌊/⍵⋄c←(⌈/⍵)-b⋄{2⍕(⍵-b)÷c}¨⍵}

Alter Code ohne Nachkommastellen:

{b←⌊/⍵⋄c←(⌈/⍵)-b⋄{(⍵-b)÷c}¨⍵}

Nehmen Sie das Minimum des Vektors, nehmen Sie die Differenz zwischen dem Maximum und dem Minimum des Vektors, subtrahieren Sie das Minimum von jedem Element und dividieren Sie durch die Differenz zwischen min und max.

Bearbeiteter Code zum Drucken von zwei Ziffern nach dem Dezimalpunkt:


2

CJam, 30 29 Bytes

l~:d_{e>}*\_{e<}*:Mf-\M-f/';*

Erwartet die Eingabe auf STDIN wie [5 -20 30].

Testen Sie es hier. (Dies gibt eine Ganzzahl 0und 1ohne Dezimalpunkt aus, aber der Java-Interpreter druckt 0.0und 1.0.)

Aufgrund eines Fehlers kann ich nicht verkürzen {e>}*, :e>obwohl dies gemäß der Spezifikation möglich sein sollte (was 4 Bytes sparen würde, wenn es sowohl auf min als auch auf max angewendet wird).

Etwas veraltete Erklärung: (wird später geändert)

l~:d_{e<}*_@_{e>}*@-\@f-\f/';* "Read and eval the input leaving an array of strings on the stack";
l~                             "Read and eval the input leaving an array of strings on the stack";
  :d                           "Convert all elements to double";
    _                          "Duplicate the array";
     {e<}*                     "Wrap the MIN function in a black and fold it onto the array";
          _                    "Duplicate the minimum";
           @                   "Rotate the stack, pulling the array to the top";
            _                  "Duplicate the array";
             {e>}*             "Same as before, now with MAX";
                  @            "Rotate the stack, pulling the minimum to the top";
                   -           "Subtract to give the total range";
                    \          "Swap range and array";
                     @         "Rotate the stack, pulling the other minimum to the top";
                      f-       "Subtract the minimum from each element in the array";
                        \      "Swap range and array";
                         f/    "Divide each element in the array by the range";
                           ';  "Push a semicolon character";
                             * "Riffle the semicolon into the array";

Am Ende des Programms wird der Stapelinhalt standardmäßig gedruckt.

Ich bin mir sicher, dass es eine Möglichkeit gibt, die Hälfte der Stapelumbildung zu sparen, aber ich bin mit CJam noch nicht so zufrieden.


Dies druckt 0;0.5;1statt 0.0;0.5;1.0.
CommonGuy

@Manu Siehe Dennis 'Kommentar zur Antwort des Optimierers. Es funktioniert gut im Java-Interpreter.
Martin Ender

2

Xojo, 179 Bytes

dim x,n as double,k,z as int16,s() as string
n=1e3
x=-n
for each k in a
x=max(x,k)
n=min(n,k)
next
for k=0 to ubound(a)
s.append str((a(k)-n)/(x-n),"0.0#")
next
msgbox join(s,";")

2

R, 60 Bytes

m=min(x<-scan());cat(sprintf("%f",(x-m)/(max(x)-m)),sep=";")    

Durch die Formatierung werden aufgrund von 0und 1standardmäßig viele Bytes verbraucht, sodass nach dem ganzzahligen Teil nichts mehr angezeigt wird.


1

Clojure 63

(fn[v](let[l(apply min v)](map #(/(- % l)(-(apply max v)l))v))) 

Befolgen Sie die Regeln nicht ganz, da es Brüche statt Doppel zurückgibt. Wenn dies nicht akzeptabel ist, fügen Sie 7 Bytes hinzu

Ungolfed:

(fn [values]
    (let [low (apply min values)]
         (map #(/ (- % low)
                  (- (apply max values) low))
              values)))

So aufrufbar:

((fn[v](let[l(apply min v)](map #(/(- % l)(-(apply max v)l))v))) [5 -20 30])

Ausgabe: (1/2 0 1)


1

Ruby, 49

f=->a{$><<a.map{|x|(x-l=a.min).fdiv(a.max-l)}*?;}

Erläuterung:

f=->a{}     # Define a lambda that takes one argument a
$><<        # Print the following to STDOUT
a.map{|x|}  # For each element x
(x-l=a.min) # Find the lowest element of a, assign it to l, and subtract it from x
.fdiv       # Float division (/ truncates)
(a.max - l) # Divide by the maximum minus the minimum
*?;         # Convert the resulting array into a string joined by the ';' character


0

Q (31) IMPROPER OUTPUT FORMAT

{(%/)(x;max x)-min x}(.:)(0::)0

Eingang

1 2 3

Ausgabe

0 .5 1

0

Perl - 60

my@a=sort@ARGV;print map{($_-$a[0])/($a[-1]-$a[0])." "}@ARGV

0

Java 7, 149 Bytes

float[]c(int[]x){int b=1<<31,a=b-1,j=0,l=x.length;for(int i:x){a=i<a?i:a;b=i>b?i:b;}float[]r=new float[l];for(;j<l;r[j]=x[j++]-a)*1f/(b-a);return r;}

Ungolfed & Testcode:

Probieren Sie es hier aus.

import java.util.Arrays;
class M{
  static float[] c(int[] x){
    int b = Integer.MIN_VALUE,
        a = b-1, // In Java, Integer.MIN_VALUE - 1 = Integer.MAX_VALUE (and vice-versa)
        j = 0,
        l = x.length;
    for(int i : x){
      a = i < a ? i : a; // Determine min value of array
      b = i > b ? i : b; // Determine max value of array
    }
    float[] r = new float[l];
    for(; j < l; r[j] = (x[j++] - a) * 1f / (b-a));
    return r;
  }

  public static void main(String[] a){
    System.out.println(Arrays.toString(c(new int[]{ 5, -20, 30 })));
    System.out.println(Arrays.toString(c(new int[]{ 1, 2, 3, 4, 5 })));
    System.out.println(Arrays.toString(c(new int[]{ 0, 5, 100, 400 })));
  }
}

Ausgabe:

[0.5, 0.0, 1.0]
[0.0, 0.25, 0.5, 0.75, 1.0]
[0.0, 0.0125, 0.25, 1.0]
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.