Menyusut angka


10

Input adalah larik (setidaknya 3, maksimum 20) bilangan bulat yang berbeda. Setiap bilangan bulat lebih besar dari -1000 dan lebih kecil dari 1000.

Tugas Anda adalah mengecilkan angka dengan "memetakan secara linear" dari 0.0menjadi 1.0. Ini berarti angka terkecil dalam array akan dipetakan ke 0,0, terbesar ke 1,0.

Anda mendapatkan array sebagai parameter (di dalam fungsi) atau argumen stdin / program (Anda dapat memilih). Cetak hasilnya dalam format double1;double2;double3;.... Output harus memiliki urutan yang sama dengan input .

Jika mau, Anda dapat membulatkan output menjadi 2 digit setelah titik desimal. Harus ada minimal 1 digit setelah titik desimal.

The penggunaan fungsi built-in (yang skala bawah angka-angka untuk Anda fungsi, seperti Mathematica Rescale) adalah batasan .

Contoh:

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

(Output terakhir dibulatkan, jika tidak maka 0.0;0.0125;0.25;1.0)


2
Jadi, meskipun kita menulis fungsi, hasilnya harus dicetak? (Berbeda dengan mengembalikan array ganda yang sesuai.)
Martin Ender

@ MartinBüttner Ya, mereka harus dicetak. Fungsi bawaan tidak diizinkan.
CommonGuy

"Penggunaan fungsi bawaan (seperti Mathematicas Rescale) tidak diizinkan." - itu terlalu kabur. Fungsi apa yang tidak diizinkan? Hanya mereka yang memecahkan masalah penuh (yang akan menjadi celah standar)?
John Dvorak

Tunggu, jadi, inputnya bisa berupa argumen fungsi, tapi outputnya harus ke layar ???
John Dvorak

1
@ Dennis Format harus sesuai dengan yang ditunjukkan dalam pertanyaan. Ini berarti angkanya dipisahkan oleh titik koma.
CommonGuy

Jawaban:


5

CJam, 18 byte

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

Perhatikan bahwa penerjemah online secara keliru menyatakan 0dsebagai 0alih-alih 0.0.

Contoh dijalankan

$ 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

Bagaimana itu bekerja

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

Reaksi saya terhadap ini, sebagai sumber CJam: Wtf? diperlukan penjelasan ...
edc65

2
Cara yang bagus untuk mendapatkan min dan maks menggunakan indeks array alih-alih muncul dan bertukar hal-hal di sekitar
Pengoptimal

Mungkin bicara dingin saya, tetapi mengapa Anda menyortir dua kali? Tidakkah seharusnya array yang disortir tetap disortir jika konstanta dikurangi dari setiap elemen?
Ingo Bürk

@ IngoBürk Array yang diurutkan tidak bertahan dari akses array, saya pikir. Yang masuk akal, karena hasil akhirnya tidak boleh disortir.
Martin Ender

@ MartinBüttner D'oh. Tentu saja. Kita perlu mempertahankan pesanan untuk hasilnya. Terima kasih!
Ingo Bürk

4

JavaScript, ES6, 81 byte

Terima kasih kepada @ edc65 untuk toFixedtriknya

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

Jalankan di Konsol Firefox terbaru.

Ini menciptakan fungsi fyang bisa Anda panggil

F([5,-20,30])

1) mengapa eval (prompt) ketika suatu fungsi diizinkan? 2) Harus ada minimal 1 digit setelah titik desimal. 3) tidak perlu menyimpan M, cukup d = Mm
edc65

Diperbarui. Meskipun demikian, mendapatkan setidaknya 1 digit setelah desimal sulit
Pengoptimal

If you want, you can round the output to 2 digits after the decimal pointitulah cara yang lebih sederhana menurut saya
edc65

@ edc65 Tapi tidak ada cara untuk mengkonversi 1ke 1.0kecuali untuk apa yang saya lakukan.
Pengoptimal

Nggak. Bolehkah saya memberi petunjuk?
edc65

4

Python 2, 72 68 63 56 55

Jelas tidak sepadat jawaban lain, tapi bagaimanapun:

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

Contoh dijalankan:

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

Lama (68 karakter, ditulis dengan Python 3):

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

Anda dapat menyimpan satu char lagi dengan mendefinisikan m=min(x).
FryAmTheEggman

4

CJam, 24 23 byte

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

Masukan menjadi seperti:

[5 -20 30]

Cobalah online di sini Perhatikan bahwa compiler cetak secara online Double 0sebagai 0saja. Jalankan di interpreter java yang mencetak dengan benar.

Bagaimana itu bekerja:

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, itu ide yang jauh lebih baik untuk mendapatkan minimum dan maksimum.
Martin Ender

Ini mencetak 0;0.5;1bukannya 0.0;0.5;1.0.
CommonGuy

@ Manu - Ya, mencoba memperbaikinya. Dan hampir semua jawaban hanya melakukan ini.
Pengoptimal

2
Anda tidak perlu memperbaikinya. Java interpreter mewakili Double 0 as 0.0.
Dennis

3

C # 92

Berjalan di dalam LinqPad

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

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

Keluaran

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

3

APL (15)

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

(atau, tanpa kereta, juga 15 karakter :)

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

Ini membaca argumen dari keyboard dan mencetak hasilnya ke layar.

Penjelasan:

  • : membaca baris dari keyboard dan mengevaluasinya
  • +-⌊/: kurangi item terendah dalam array dari semua item dalam array
  • +÷⌈/: bagi setiap item dalam array dengan item tertinggi array
  • 2⍕: format dengan dua tempat desimal

Uji:

      (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

Harus menambahkan jumlah byte ...
Pengoptimal

Yang hanya 24 byte.
Pengoptimal

2
@Optimizer: Kecuali jika pertanyaan menyatakan sebaliknya, setiap jawaban diberi skor menggunakan pengodean yang menghasilkan jumlah byte terkecil. Ada codepage APL yang mewakili setiap karakter APL dengan satu byte.
Dennis

Perbaiki saya jika saya melakukan sesuatu yang salah di sini, tetapi secara default, kode-golf dihitung dalam bytes dan mothereff.in/byte-counter#%282%E2%8D%95+%C3%B7%E2%8C%88/ ... halaman mengatakan 24 byte. Apakah saya melewatkan sesuatu?
Pengoptimal

1
Output harus dipisahkan dengan titik koma, bukan spasi.
CommonGuy

3

Pyth , 18

Sekarang dengan pemformatan yang benar!

j\;mc-dhSQ-eSQhSQQ

Uji:

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

Penjelasan:

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

Output tidak diformat dengan benar.
CommonGuy

@ Manu Maaf tentang itu, saya sudah memperbaikinya.
isaacg

Tidak menciptakan bahasa Anda sendiri, yang Anda ubah seiring waktu, sedikit memperluas aturan? Anda jelas dapat menambahkan fitur baru untuk membuat program lebih pendek?
Chris Jefferson

3
@ ChrisJefferson Saya selalu menggunakan versi terbaru dari bahasa yang keluar sebelum masalah diajukan. Karena semuanya didorong ke Github, dapat diverifikasi bahwa saya tidak menambahkan apa pun setelah masalah diposting. Itu aturan standar CG.SE - bahasa harus lebih tua dari pertanyaan, dan saya mematuhinya.
isaacg

2

Oktaf 25

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

Asumsikan input dalam ldan karena ini shell interaktif hasilnya dicetak secara otomatis (apakah ini diizinkan?)


2
Octave / Matlab memang harus inputmendapatkan input pengguna dan meniru STDIN. Anda juga dapat menulis suatu fungsi. Juga, apakah ini mencetak hasilnya dalam format yang benar?
Martin Ender

Dan tidak, hanya mengembalikan dan mencetak shell biasanya tidak masuk hitungan. Golfscript dan sejenisnya berbeda karena bahasa menetapkan bahwa tumpukan dicetak pada akhirnya. Tapi ini tidak berlaku untuk, misalnya, Javascript. Dan saya juga tidak berpikir untuk Matlab / Oktaf.
Ingo Bürk

2

APL, 31 karakter / 55 byte

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

Kode lama tanpa digit setelah titik desimal:

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

Ambil minimum vektor, ambil perbedaan antara maksimum dan minimum vektor, kurangi minimum dari setiap elemen dan bagi dengan perbedaan antara min dan maks.

Kode yang diedit untuk mencetak dua digit setelah titik desimal:


2

CJam, 30 29 byte

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

Mengharapkan input pada suka STDIN [5 -20 30].

Uji di sini. (Ini akan mencetak bilangan bulat 0dan 1tanpa titik desimal, tetapi penerjemah Java mencetak 0.0dan 1.0.)

Karena bug saya tidak dapat mempersingkat {e>}*ke :e>meskipun yang harus mungkin sesuai spec (yang akan menghemat 4 byte bila diterapkan untuk kedua min dan max).

Penjelasan sedikit kedaluwarsa: (akan diubah kemudian)

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

Di akhir program, isi tumpukan dicetak secara default.

Saya yakin ada cara untuk menghemat setengah dari reshuffle tumpukan, tapi saya belum nyaman dengan CJam.


Ini mencetak 0;0.5;1bukannya 0.0;0.5;1.0.
CommonGuy

@Manu Lihat komentar Dennis tentang jawaban Pengoptimal. Ini berfungsi dengan baik di interpreter 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=";")    

Memformat memakan banyak byte karena 0dan 1secara default dipangkas untuk tidak menampilkan apa pun yang melewati bagian integer.


1

Clojure 63

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

Tidak cukup mengikuti aturan, karena mengembalikan fraksi bukannya ganda. Jika itu tidak dapat diterima, tambahkan 7 byte

Tidak Disatukan:

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

Callable seperti ini:

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

Keluaran: (1/2 0 1)


1

Ruby, 49

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

Penjelasan:

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) FORMAT OUTPUT IMPROPER

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

memasukkan

1 2 3

keluaran

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

Tidak digabungkan & kode uji:

Coba di sini.

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

Keluaran:

[0.5, 0.0, 1.0]
[0.0, 0.25, 0.5, 0.75, 1.0]
[0.0, 0.0125, 0.25, 1.0]
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.