Riduzione dei numeri


10

L'input è un array di (almeno 3, massimo 20) numeri interi diversi. Ogni numero intero è maggiore di -1000 e minore di 1000.

Il tuo compito è ridurre i numeri "mappandoli linearmente" da 0.0a 1.0. Ciò significa che il numero più piccolo nell'array verrà mappato su 0,0, il più grande su 1,0.

Ottieni l'array come parametro (all'interno di una funzione) o argomenti stdin / program (puoi scegliere). Stampa il risultato nel formato double1;double2;double3;.... L'output deve avere lo stesso ordine dell'input .

Se lo si desidera, è possibile arrotondare l'output a 2 cifre dopo il punto decimale. Ci deve essere almeno 1 cifra dopo il punto decimale.

L' uso di funzioni integrate (funzioni che riducono i numeri per te, come i matematici Rescale) non è consentito .

Esempi:

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

(L'ultimo output è arrotondato, altrimenti sarebbe 0.0;0.0125;0.25;1.0)


2
Quindi anche noi scriviamo una funzione il risultato deve essere stampato? (Invece di restituire un corrispondente array di doppi.)
Martin Ender,

@ MartinBüttner Sì, devono essere stampati. Le funzioni integrate non sono consentite.
CommonGuy

"Non è consentito l'uso di funzioni integrate (come matematic Rescale)." - è troppo vago. Quali funzioni non sono consentite? Solo quelli che risolvono il problema completo (che sarebbe una scappatoia standard) lo sono?
John Dvorak,

Aspetta, quindi, l'input può essere un argomento di funzione, ma l'output deve essere sullo schermo ???
John Dvorak,

1
@Dennis Il formato deve corrispondere a quello mostrato nella domanda. Ciò significa che i numeri sono separati da punti e virgola.
CommonGuy

Risposte:


5

CJam, 18 byte

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

Si noti che l' interprete online rappresenta erroneamente 0dcome 0invece di 0.0.

Esempio di esecuzione

$ 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

Come funziona

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, ';'))        ";

La mia reazione a questo, come fonte CJam: Wtf? spiegazione necessaria ...
edc65,

2
Bel modo di ottenere min e max usando l'indice di array invece di spuntare e poi scambiare cose
Ottimizzatore

Probabilmente è il mio modo di parlare a freddo, ma perché lo fai due volte? Un array ordinato non dovrebbe rimanere ordinato se viene sottratta una costante da ciascun elemento?
Ingo Bürk,

@ IngoBürk La matrice ordinata non sopravvive all'accesso alla matrice, credo. Questo ha senso, perché il risultato finale non deve essere ordinato.
Martin Ender,

@ MartinBüttner D'oh. Ovviamente. Dobbiamo conservare l'ordine per il risultato. Grazie!
Ingo Bürk,

4

JavaScript, ES6, 81 byte

Grazie a @ edc65 per il toFixedtrucco

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

Eseguilo nell'ultima console di Firefox.

Questo crea una funzione fche puoi invocare come

F([5,-20,30])

1) perché eval (prompt) quando è consentita una funzione? 2) Deve essere presente almeno 1 cifra dopo il punto decimale. 3) non è necessario memorizzare M, solo d = Mm
edc65

Aggiornato. Tuttavia, ottenere almeno 1 cifra dopo il decimale è difficile
Ottimizzatore

If you want, you can round the output to 2 digits after the decimal pointquesto è il modo più semplice secondo me
edc65

@ edc65 Ma non c'è modo per convertire 1al 1.0tranne che per quello che ho fatto.
Ottimizzatore

No. Posso suggerire?
edc65,

4

Python 2, 72 68 63 56 55

Ovviamente non così conciso come le altre risposte, ma comunque:

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

Esecuzione di esempio:

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

Vecchio (68 caratteri, scritto in Python 3):

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

È possibile salvare un altro carattere definendo m=min(x).
FryAmTheEggman,

4

CJam, 24 23 byte

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

L'input è come:

[5 -20 30]

Provalo online qui Nota che il compilatore online stampa solo Double 0come 0. Esegui nell'interprete Java che stampa correttamente.

Come funziona:

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, è un'idea molto migliore per ottenere il minimo e il massimo.
Martin Ender,

Questo stampa 0;0.5;1invece di 0.0;0.5;1.0.
CommonGuy

@Manu - Sì, sto cercando di risolverlo. E quasi tutte le risposte fanno solo questo.
Ottimizzatore

2
Non hai bisogno della correzione. L'interprete Java rappresenta il doppio 0 come 0.0.
Dennis,

3

C # 92

In esecuzione all'interno di LinqPad

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

Produzione

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

3

APL (15)

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

(o, senza treni, anche 15 caratteri :)

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

Questo legge l'argomento dalla tastiera e stampa il risultato sullo schermo.

Spiegazione:

  • : leggi una riga dalla tastiera e valutala
  • +-⌊/: sottrae l'elemento più basso nella matrice da tutti gli elementi nella matrice
  • +÷⌈/: divide ogni elemento nella matrice per l'elemento più alto della matrice
  • 2⍕: formato con due cifre decimali

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

Dovrebbe aggiungere il conteggio dei byte ...
Ottimizzatore

Che è solo 24 byte.
Ottimizzatore

2
@Optimizer: se non diversamente indicato nella domanda, ogni risposta viene valutata utilizzando la codifica che produce il conteggio di byte più piccolo. C'è una tabella codici APL che rappresenta ogni carattere APL di un byte.
Dennis,

Correggimi se sto facendo qualcosa di sbagliato qui, ma per impostazione predefinita, il codice-golf è conteggiato in byte e mothereff.in/byte-counter#%282%E2%8D%95+%C3%B7%E2%8C%88/ … La pagina indica i suoi 24 byte. Ho dimenticato qualcosa ?
Ottimizzatore

1
L'output deve essere separato da punti e virgola, non da spazi.
CommonGuy

3

Pyth , 18 anni

Ora con una formattazione corretta!

j\;mc-dhSQ-eSQhSQQ

Test:

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

Spiegazione:

(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))

L'output non è formattato correttamente.
CommonGuy

@Manu Mi dispiace, l'ho risolto.
isaacg,

Creare la tua lingua, che cambi nel tempo, non allunga leggermente le regole? Ovviamente puoi semplicemente aggiungere una nuova funzionalità per ridurre il programma?
Chris Jefferson,

3
@ChrisJefferson Uso sempre la versione più recente della lingua che è emersa prima che il problema fosse richiesto. Dal momento che è tutto indirizzato a Github, si può verificare che non aggiungerò nulla dopo la pubblicazione del problema. Questa è la regola CG.SE standard: la lingua deve essere più vecchia della domanda e io la rispondo.
isaacg,

2

Ottava 25

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

Presuppone che l'input sia presente le poiché si tratta di una shell interattiva, il risultato viene stampato automaticamente (è consentito?)


2
Octave / Matlab deve inputcomunque ottenere l'input dell'utente e imitare STDIN. Puoi anche scrivere una funzione. Inoltre, questo stampa il risultato nel formato corretto?
Martin Ender,

E no, solo il ritorno e la stampa della shell in genere non conta. Golfscript e simili sono diversi perché la lingua specifica che la pila viene stampata alla fine. Ma questo non è il caso, ad esempio, di Javascript. E non penso nemmeno per Matlab / Octave.
Ingo Bürk,

2

APL, 31 caratteri / 55 byte

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

Vecchio codice senza cifre dopo il punto decimale:

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

Prendi il minimo del vettore, prendi la differenza tra il massimo e il minimo del vettore, sottrai il minimo da ciascun elemento e dividi per la differenza tra min e max.

Codice modificato per stampare due cifre dopo il punto decimale:


2

CJam, 30 29 byte

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

Si aspetta l'input su STDIN come [5 -20 30].

Provalo qui.(Verrà stampato un numero intero 0e 1senza virgola decimale, ma l'interprete Java stampa 0.0e 1.0.)

A causa di un bug che non posso accorciare {e>}*a:e> anche se questo dovrebbe essere possibile secondo le specifiche (che permetterebbe di risparmiare 4 byte se applicato a entrambi min e max).

Spiegazione leggermente obsoleta: (verrà modificata in seguito)

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

Alla fine del programma, il contenuto dello stack viene stampato per impostazione predefinita.

Sono sicuro che c'è un modo per salvare il rimpasto della metà dello stack, ma non sono ancora a mio agio con CJam.


Questo stampa 0;0.5;1invece di 0.0;0.5;1.0.
CommonGuy

@Manu Vedi il commento di Dennis sulla risposta di Optimizer. Funziona bene nell'interprete Java.
Martin Ender,

2

Xojo, 179 byte

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 byte

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

La formattazione consuma molti byte a causa 0e 1per impostazione predefinita vengono tagliati per non visualizzare nulla oltre la parte intera.


1

Clojure 63

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

Non segue abbastanza le regole, poiché restituisce frazioni anziché doppie. Se ciò non è accettabile, aggiungere 7 byte

Ungolfed:

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

Callable in questo modo:

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

Produzione: (1/2 0 1)


1

Ruby, 49

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

Spiegazione:

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) FORMATO DI USCITA IMPROPRIO

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

ingresso

1 2 3

produzione

0 .5 1

0

Perl - 60

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

0

Java 7, 149 byte

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

Codice non testato e test:

Provalo qui.

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

Produzione:

[0.5, 0.0, 1.0]
[0.0, 0.25, 0.5, 0.75, 1.0]
[0.0, 0.0125, 0.25, 1.0]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.