Kurczące się liczby

10

Dane wejściowe to tablica (co najmniej 3, maksymalnie 20) różnych liczb całkowitych. Każda liczba całkowita jest większa niż -1000 i mniejsza niż 1000.

Twoim zadaniem jest zmniejszanie liczb poprzez „liniowe mapowanie” ich od 0.0do 1.0. Oznacza to, że najmniejsza liczba w tablicy zostanie zmapowana na 0,0, największa na 1,0.

Dostajesz tablicę jako parametr (wewnątrz funkcji) lub argumenty stdin / program (możesz wybrać). Wydrukuj wynik w formacie double1;double2;double3;.... Dane wyjściowe muszą mieć tę samą kolejność co dane wejściowe .

Jeśli chcesz, możesz zaokrąglić wynik do 2 cyfr po przecinku. Musi być co najmniej 1 cyfra po przecinku.

Wykorzystanie wbudowanych funkcji (funkcje, które skala dół numerów dla Ciebie, takich jak Mathematica Rescale) jest niedozwolone .

Przykłady:

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

(Ostatni wynik jest zaokrąglany, w przeciwnym razie byłby 0.0;0.0125;0.25;1.0)

CommonGuy
źródło
2
Więc nawet gdy piszemy funkcję, wynik musi zostać wydrukowany? (W przeciwieństwie do zwracania odpowiedniej tablicy podwójnych.)
Martin Ender
@ MartinBüttner Tak, muszą zostać wydrukowane. Wbudowane funkcje są niedozwolone.
CommonGuy
„korzystanie z wbudowanych funkcji (takich jak przeskalowanie matematyki) jest niedozwolone”. - to jest zbyt niejasne. Jakie funkcje są niedozwolone? Są tylko ci, którzy rozwiązują pełny problem (który byłby standardową luką)?
John Dvorak
Zaczekaj, więc dane wejściowe mogą być argumentem funkcji, ale dane wyjściowe muszą być wyświetlane na ekranie?
John Dvorak
1
@Dennis Format musi odpowiadać formatowi pokazanemu w pytaniu. Oznacza to, że liczby są oddzielone średnikami.
CommonGuy,

Odpowiedzi:

5

CJam, 18 bajtów

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

Zauważ, że tłumacz online błędnie przedstawia 0djako 0zamiast 0.0.

Przykładowy przebieg

$ 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

Jak to działa

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, ';'))        ";
Dennis
źródło
Moja reakcja na to, jako źródło CJam: Wtf? potrzebne wyjaśnienie ...
edc65
2
Fajny sposób na uzyskanie min. I maks. Przy użyciu indeksu tablicy zamiast wyskakiwania, a następnie zamiany elementów
Optimizer
To chyba moja zimna mowa, ale dlaczego sortujesz dwa razy? Czy posortowana tablica nie powinna pozostać posortowana, jeśli od każdego elementu zostanie odjęta stała?
Ingo Bürk
@ IngoBürk Posortowana tablica, jak sądzę, nie przetrwa dostępu do tablicy. To ma sens, ponieważ ostatecznego wyniku nie można sortować.
Martin Ender
@ MartinBüttner D'oh. Oczywiście. Musimy zachować porządek dla wyniku. Dzięki!
Ingo Bürk
4

JavaScript, ES6, 81 bajtów

Dzięki @ edc65 za toFixedlewę

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

Uruchom go w najnowszej konsoli Firefox.

To tworzy funkcję, fktórą możesz wywołać jak

F([5,-20,30])
Optymalizator
źródło
1) dlaczego eval (pytanie), kiedy funkcja jest dozwolona? 2) Po przecinku musi być co najmniej 1 cyfra. 3) nie trzeba przechowywać M, po prostu d = Mm
edc65
Zaktualizowano Chociaż uzyskanie co najmniej 1 cyfry po przecinku jest trudne
Optimizer
If you want, you can round the output to 2 digits after the decimal pointtak mi się wydaje
edc65
@ edc65 Ale nie ma sposobu, aby przekształcić 1się 1.0z wyjątkiem tego, co zrobiłem.
Optymalizator
Nie. Czy mogę podpowiedzieć?
edc65
4

Python 2, 72 68 63 56 55

Oczywiście nie tak zwięzłe jak inne odpowiedzi, ale w każdym razie:

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

Przykładowy przebieg:

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

Stare (68 znaków, napisane w języku Python 3):

x=eval(input())
y=sorted(x)
print([(i-y[0])/(y[-1]-y[0])for i in x])
monopole
źródło
Możesz zapisać jeszcze jeden znak, definiując m=min(x).
FryAmTheEggman
4

CJam, 24 23 bajty

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

Dane wejściowe powinny wyglądać tak:

[5 -20 30]

Wypróbuj online tutaj. Pamiętaj, że kompilator online drukuje tylko Double 0jako 0. Uruchom interpreter Java, który drukuje poprawnie.

Jak to działa:

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";
Optymalizator
źródło
1
Ach, to znacznie lepszy pomysł, aby uzyskać minimum i maksimum.
Martin Ender
To drukuje 0;0.5;1zamiast 0.0;0.5;1.0.
CommonGuy
@Manu - Tak, próbuję to naprawić. I prawie wszystkie odpowiedzi robią to tylko.
Optymalizator
2
Nie potrzebujesz poprawki. Interpretator Java reprezentuje Double 0 jako 0.0.
Dennis
3

C # 92

Działa w LinqPad

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

Testuj w 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();}

Wynik

IEnumerable<String> (3 items)
0,50 
0,00 
1,00 
edc65
źródło
3

APL (15)

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

(lub, bez pociągów, także 15 znaków :)

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

Odczytuje argument z klawiatury i drukuje wynik na ekranie.

Wyjaśnienie:

  • : przeczytaj wiersz z klawiatury i oceń go
  • +-⌊/: odejmij najniższy element w tablicy od wszystkich elementów w tablicy
  • +÷⌈/: podziel każdy element w tablicy przez najwyższy element w tablicy
  • 2⍕: format z dwoma miejscami po przecinku

Test:

      (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
marinus
źródło
Należy dodać liczbę bajtów ...
Optymalizator
To jest tylko 24 bajty.
Optymalizator
2
@Optimizer: O ile pytanie nie stanowi inaczej, każda odpowiedź jest punktowana przy użyciu kodowania, które daje najmniejszą liczbę bajtów. Istnieje strona kodowa APL, która reprezentuje każdy znak APL jednym bajtem.
Dennis
Popraw mnie, jeśli robię coś źle tutaj, ale domyślnie code-golf jest liczony w bajtach i mothereff.in/byte-counter#%282%E2%8D%95+%C3%B7%E2%8C%88/ … Strona podaje 24 bajty. Przegapiłem coś ?
Optymalizator
1
Wyjście musi być oddzielone średnikami, a nie spacjami.
CommonGuy
3

Pyth , 18 lat

Teraz z poprawnym formatowaniem!

j\;mc-dhSQ-eSQhSQQ

Test:

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

Wyjaśnienie:

(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))
isaacg
źródło
Dane wyjściowe nie są poprawnie sformatowane.
CommonGuy
@Manu Przepraszamy za to, naprawiłem to.
isaacg
Czy nie tworzysz własnego języka, który zmieniasz w miarę upływu czasu, nieco rozszerzając zasady? Możesz oczywiście dodać nową funkcję, aby skrócić program?
Chris Jefferson
3
@ChrisJefferson Zawsze używam najnowszej wersji języka, który pojawił się przed zgłoszeniem problemu. Ponieważ wszystko jest przekazywane do Github, można zweryfikować, że nic nie dodam po opublikowaniu problemu. To standardowa reguła CG.SE - język musi być starszy od pytania i ja go przestrzegam.
isaacg
2

Oktawa 25

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

Zakłada, że ​​dane wejściowe są wprowadzone, la ponieważ jest to powłoka interaktywna, wynik jest drukowany automatycznie (czy jest to dozwolone?)

Gryf
źródło
2
Octave / Matlab musi inputjednak uzyskać dane od użytkowników i naśladować STDIN. Możesz także napisać funkcję. Ponadto, czy ten wynik drukuje w prawidłowym formacie?
Martin Ender
I nie, po prostu powrót i wydrukowanie powłoki zasadniczo się nie liczy. Golfscript i tym podobne są różne, ponieważ język określa, że stos jest drukowany na końcu. Ale nie dotyczy to np. Javascript. I nie myślę też o Matlabie / Octave.
Ingo Bürk
2

APL, 31 znaków / 55 bajtów

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

Stary kod bez cyfr po przecinku:

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

Weź minimum wektora, weź różnicę między maksimum i minimum wektora, odejmij minimum od każdego elementu i podziel przez różnicę między min i maks.

Zmodyfikowany kod, aby wydrukować dwie cyfry po przecinku:

Shujal
źródło
2

CJam, 30 29 bajtów

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

Oczekuje danych wejściowych na STDIN jak [5 -20 30].

Sprawdź to tutaj. (Spowoduje to wydrukowanie liczby całkowitej0 i 1bez kropki dziesiętnej, ale interpreter Java drukuje 0.0i 1.0.)

Spowodowany błędu nie można skrócić {e>}*do :e>choć powinno to być możliwe, jak na spec (który uratuje 4 bajty, gdy stosuje się zarówno do min i max).

Nieco przestarzałe wyjaśnienie: (zmieni się później)

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";

Na końcu programu zawartość stosu jest drukowana domyślnie.

Jestem pewien, że istnieje sposób na zaoszczędzenie połowy przetasowania stosu, ale nie jestem jeszcze tak zadowolony z CJam.

Martin Ender
źródło
To drukuje 0;0.5;1zamiast 0.0;0.5;1.0.
CommonGuy
@Manu Zobacz komentarz Dennisa do odpowiedzi Optimizera. Działa dobrze w interpreter Java.
Martin Ender
2

Xojo, 179 bajtów

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,";")
srebrnik
źródło
2

R, 60 bajtów

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

Formatowanie zjada wiele bajtów, ponieważ 0i 1domyślnie są przycinane, aby nie wyświetlały niczego poza częścią całkowitą.

Billywob
źródło
1

Clojure 63

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

Nie do końca przestrzega zasad, ponieważ zwraca ułamki zamiast podwójnych. Jeśli to nie do przyjęcia, dodaj 7 bajtów

Nie golfowany:

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

Można wywołać w ten sposób:

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

Wynik: (1/2 0 1)

ratownik
źródło
1

Ruby, 49

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

Wyjaśnienie:

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
histocrat
źródło
0

Q (31) NIEPRAWIDŁOWY FORMAT WYJŚCIA

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

Wejście

1 2 3

wynik

0 .5 1
protista
źródło
0

Perl - 60

my@a=sort@ARGV;print map{($_-$a[0])/($a[-1]-$a[0])." "}@ARGV
KSFT
źródło
0

Java 7, 149 bajtów

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;}

Kod niepoznany i testowy:

Wypróbuj tutaj.

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 })));
  }
}

Wynik:

[0.5, 0.0, 1.0]
[0.0, 0.25, 0.5, 0.75, 1.0]
[0.0, 0.0125, 0.25, 1.0]
Kevin Cruijssen
źródło