Skor pertandingan Olimpiade [ditutup]


9

Tantangannya adalah untuk menulis program kode golf yang, diberikan n bilangan real positif dari 0 hingga 10 (format xy, y hanya dapat 0 atau 5: 0, 0,5, 1, 1,5, 2, 2,5 ... 9,5 dan 10), buang nilai-nilai terendah dan tertinggi (hanya satu, meskipun mereka diulang) dan menunjukkan rata-rata sisanya, dalam format xy (y dapat 0 atau 5, dibulatkan ke terdekat), mirip dengan beberapa penilaian Olimpiade.

Contoh: Input -> Output

6 -> 6

6.5, 9 -> 8

9, 7, 8 -> 8

6, 5, 7, 8, 9 -> 7

5, 6.5, 9, 8, 7 -> 7

6.5, 6.5, 9.5, 8, 7 -> 7

5, 6.5, 7.5, 8.5, 9.5 -> 7.5

Catatan: Jika inputnya hanya dua angka, jangan dibuang, cukup rata-rata saja. Jika input adalah satu angka, outputnya sama.

Mengklarifikasi aturan pembulatan (maaf, sedikit bingung):

x.01 hingga x.25 bulat ke x.0

x.26 hingga x.75 hingga x.5

x.76 hingga x.99 untuk x + 1.0


2
Bagaimana contoh kedua (6.5, 9 => 8) valid? Jika Anda membuang tinggi dan rendah, tidak ada nilai yang tersisa untuk rata-rata?
Jeff Zeitlin

2
Selamat datang di Code Golf SE!
AdmBorkBork

6
Saya menyarankan agar kami tidak menangani masukan yang tidak valid, Olimpiade akan memiliki jumlah hakim yang lebih besar dari dua untuk acara seperti itu. (Menyelam menghilangkan empat ekstremitas dari tujuh misalnya)
Jonathan Allan

7
Contoh Anda 6.5, 9tidak setuju dengan spesifikasi Anda yang menunjukkan bahwa x.75 membulatkan ke x.5.
Nick Kennedy

7
Sampai pembulatan diurutkan saya memilih untuk menutup.
Nick Kennedy

Jawaban:


5

Jelly , 12 byte

ṢṖḊȯµÆmḤær0H

Cobalah online!

    µ           Take
Ṣ               the input sorted,
 Ṗ              without its last
  Ḋ             or first element,
   ȯ            or the unchanged input if that's empty,
     Æm         then calculate the mean,
       Ḥ        double it,
        ær      round it to the nearest multiple of
          0     10^-0 (= 1),
           H    and halve it.

Versi yang putaran turun separuh, sesuai dengan spesifikasi dengan mengorbankan test case kedua:

Jelly , 12 byte

ṢṖḊȯµÆmḤ_.ĊH

Cobalah online!

Metode pembulatan di sini lebih dekat dengan Jonathan Allan's:

Ḥ        Double,
 _       subtract
  .      one half,
   Ċ     round up,
    H    and halve.

Kebetulan secara tidak sengaja mematuhi pembaruan ke spec
Unrelated String

@NickKennedy Jika saya tidak membulatkan , kasing menghasilkan 6,8, yang harus dibulatkan menjadi 7 sesuai dengan spesifikasi sejak 6,75 <6,8 ≤ 7.
String Tidak Terkait

1
maaf satu dua banyak 7s. Maksud saya[1,10,6,7,7,7]
Nick Kennedy

1
Oh, ya, itu salah.
String Tidak Terkait

4

Retina , 86 byte

\.5
__
\d+
*4*__
O`_+
_+ (.+) _+
$1
O`.
^ *
$.&*__:
(_+):(\1{4})*(\1\1)?_*
$#2$#3*$(.5

Cobalah online! Tautan termasuk kasus uji. Penjelasan:

\.5
__
\d+
*4*__

Karena Retina tidak dapat dengan mudah menangani bilangan pecahan atau nol, setiap bilangan diwakili dalam unary dengan 1 lebih dari 4 kali nilainya. Karena .5itu memperluas ke 2 _s, sedangkan *4*_berlaku untuk bagian bilangan bulat, dan final _suffixed.

O`_+

Urutkan angka ke dalam urutan.

_+ (.+) _+
$1

Jika setidaknya ada tiga angka, buang yang pertama (terkecil) dan terakhir (terbesar).

O`.

Urutkan spasi ke awal, sehingga juga menjumlahkan angka.

^ *
$.&*__:

Hitung jumlah spasi dan tambahkan _dan pemisah. Ini kemudian mewakili angka yang harus kita bagi.

(_+):(\1{4})*(\1\1)?_*
$#2$#3*$(.5

Membagi jumlah dengan jumlah angka, memungkinkan untuk fakta bahwa kami bekerja dalam kelipatan 4 kali dari angka asli, sehingga bagian bilangan bulat dan desimal dapat langsung diekstraksi. Ini adalah divisi pemotongan, tetapi untungnya karena kami menambahkan ekstra _untuk setiap angka, hasilnya secara efektif mencakup 0,25 tambahan, sehingga memberi kami pembulatan yang kami inginkan.


3

EDIT: Jawaban ini sejak itu menjadi tidak valid. Itu valid sekitar setengah menit setelah diposting.

Jelly , 10 byte

ṢḊṖȯƊÆmḤḞH

Cobalah online!


tampaknya menghasilkan hasil yang salah untuk [6.5,9].
String Tidak Terkait

1
@UnrelatedString Pada saat saya memposting ini, itu adalah output yang benar. Sepertinya OP telah mengubah aturan sekarang.
Erik the Outgolfer

1
Ya, saya membuat kekacauan, maaf :(
JuanCa

1
Sesuai komentar saya di bawah posting Arnauld, saya pada dasarnya memiliki algoritma ini juga, jadi, setelah mendapatkan klarifikasi tentang aturan, saya telah memposting milik saya :)
Jonathan Allan

1
@ JonathanAllan Yang sama dengan Unrelated String's. : P
Erik the Outgolfer

3

J , 36 35 byte

[:(1r4<.@+&.+:+/%#)}:@}.^:(2<#)@/:~

Cobalah online!

Meminjam trik dobel / lantai / separuh untuk pembulatan menjadi 0,5 penambahan dari String Tidak Terkait.



3

JavaScript (V8) , 213 211 189 176 byte

Sunting: -2 byte karena saya berakhir dengan ;\n}ketika saya hanya bisa mengakhiri dengan }, kesalahan konyol.

Sunting 2: -22 byte lebih banyak dengan membaca tentang kiat-kiat golf JS umum. Saya berhasil mengeluarkan tanda kurung dari terary saya yang bersarang dalam rfungsi pembulatan, dan menggunakan operasi matematika bitwise untuk menghindari penggunaan Math.floordanMath.ceil

Sunting 3: -13 byte karena saya bisa mengganti a.lengthfungsi pintas hanya dengan panggilan langsung ke a.lengthuntuk menyimpan 4 byte. Saya juga memindahkan fungsi g () langsung ke pernyataan kembali, karena itu hanya digunakan sekali, yang menghapus sisa byte.

a=>{s=i=>a.splice(i,1)
e=_=>a.reduce((t,i)=>t+=i)/a.length
r=n=>(m=n%1,m<0.75?m>0.25?~~(n)+0.5:~~(n):n%1?-~n:n)
return a.length>2?r((a.sort((x,y)=>x-y),s(0),s(-1),e())):r(e())}

Cobalah online!

Saya yakin ini dapat ditingkatkan karena saya cukup baru, tapi itu menyenangkan untuk menyelesaikan yang satu ini. Saya percaya hal-hal utama yang dapat diperbaiki adalah logika pembulatan / metode saya, dan fakta bahwa fungsi utama menggunakan fungsi tubuh ( { }dan return).

Ada satu hal dalam pertanyaan yang tidak konsisten dengan contoh dan saya tidak benar-benar yakin bagaimana menanganinya. Saya menerapkannya agar konsisten dengan contoh, tetapi tidak persis mencerminkan aturan pembulatan yang ditentukan, berikut adalah contoh yang saya temukan tidak konsisten:

6.5, 9 -> 8

Anda mengatakan itu harus 8, meskipun rata-rata adalah 7,75. Dalam aturan pembulatan, Anda mengatakan setidaknya harus 0,76 untuk menjadi +1. Saya memilih untuk mencerminkan contoh alih-alih aturan pembulatan Anda, jadi> = 0,75 untuk menjadi +1, dan <= 0,25 untuk -1, antara 0,25 dan 0,75 (eksklusif) untuk 0,5. Jika spesifikasi pembulatan berubah, kode saya harus dapat beradaptasi tanpa mengubah jumlah byte, dengan hanya mengubah angka dalam fungsi pembulatanr , dan mungkin urutan pernyataan ternary tergantung pada aturan.

Sedikit tidak tahu apa-apa dengan penjelasan (operasi matematika diubah menjadi operasi bitwise dan g () langsung dalam pernyataan kembali)

a => { // a is the input array
    s = i=>a.splice(i, 1); // shortcut to remove index i for 1 element
    e = _=>a.reduce((t, i) => t += i) / a.length; // get array avg
    g = _=>(a.sort((x,y)=>x-y), s(0), s(-1), e()); // what to execute when > 2: sort, remove 1st/last, get avg
    t = n=>Math.floor(n); // Math.floor shortcut

    // apply olympic rounding to number by checking the value of n%1
    r = n=>(m=n%1,m < 0.75 ? (m > 0.25 ? t(n) + 0.5 : t(n)) : Math.ceil(n));

    // if arr length > 2: round g(), otherwise round e()
    return a.length > 2 ? r(g()) : r(e());
}

1
Saya telah mengirim komentar pada pertanyaan tentang perbedaan antara contoh dan spesifikasi.
Nick Kennedy

1
mengapa Anda tidak menggunakan l = a.length dan setiap kali Anda ingin panjang cukup memanggil l, di sini saya tidak tahu mengapa Anda arr menggunakan fungsi di sini
Chau Giang

@chaugiang Itu akan menyimpan nilai, bukan referensi a.length, jadi karena saya menggunakannya sebelum & sesudah operasi yang mengubah array, lakan menjadi tidak valid segera setelah array diubah. LMK jika salah. Ternyata itu benar-benar akan menyelamatkan saya 3 byte sekarang untuk hanya menggantinya dengan a.lengthpanggilan langsung . Ketika saya awalnya menulisnya, saya tidak tahu JS mengizinkan Anda untuk menggunakan angka negatif untuk sambungan, jadi awalnya sambungan kedua saya s(l()-1)bukan hanya s(-1), dan ketika saya memiliki 3 panggilan panjang, disimpan byte untuk memiliki pintasan ini. Sekarang sudah tidak layak lagi. Terima kasih, akan diperbarui!
Matsyir

2

Jelly , 12 byte

ṢṖḊȯ⁸ÆmḤ+.ḞH

Tautan monadik yang menerima daftar angka yang menghasilkan angka.

Cobalah online!

Bagaimana?

ṢṖḊȯ⁸ÆmḤ+.ḞH - Link, list of numbers, X
Ṣ            - sort X
 Ṗ           - remove the right-most
  Ḋ          - remove the left-most
    ⁸        - chain's left argument, X
   ȯ         - logical OR (if we have nothing left use X instead)
     Æm      - arithmetic mean
       Ḥ     - double
         .   - literal half
        +    - add
          Ḟ  - floor
           H - halve

1
@NickKennedy 34/5> 6.75
Jonathan Allan

1
Maaf berarti di 1,10,7,7,7,6mana 27/4 = 6,75
Nick Kennedy

1
Tidak, masalahnya adalah pembulatan yang agak tidak konvensional dalam spesifikasi. Sebenarnya jawaban Anda juga salah [1,10,7,6,6,6] (seharusnya 6 bukan 6,5), sementara versi asli @ UnrelatedString mendapatkan yang benar karena Python membulatkan ke titik rata (jadi 12,5 putaran ke 12 ). Seperti yang telah saya tunjukkan dalam komentar pada pertanyaan, salah satu contoh juga melanggar spesifikasi pembulatan. Juga perhatikan bahwa pecahan kekuatan 2 seharusnya tidak menjadi masalah untuk ketidaktepatan floating point karena mereka memiliki representasi biner yang tepat.
Nick Kennedy

1
Saya merasa speknya canggung dan mungkin tidak disengaja. (Untuk apa x.251 dibulatkan ke, dll; apakah batasannya inklusif, eksklusif, atau terserah kita?) ... dan kemudian ada komentar "Saya sadar ini agak membingungkan, mari kita bulatkan ke yang terdekat , tergantung dari platform ". Mungkin kita harus VTC tidak jelas?
Jonathan Allan

1
ya setujui VTC untuk saat ini
Nick Kennedy


2

Cepat , 203 byte

func a(b:[Double])->Void{var r=0.0,h=0.0,l=11.0
b.forEach{(c)in h=c>h ?c:h;l=c<l ?c:l;r+=c}
var d=Double(b.count)
r=d>2 ?(r-h-l)/(d-2.0):r/d
d=Double(Int(r))
r=r-d<=0.25 ?d:r-d<=0.75 ?d+0.5:d+1
print(r)}

Cobalah online!


2

PHP , 110 byte

Sepertinya PHP memiliki beberapa fungsi bawaan yang baik untuk ini. Saya hanya array_sum semuanya, maka jika ada lebih dari dua elemen, kurangi nilai min () dan max () dan bagi dengan 2 kurang dari panjang array.

Untuk pembulatan, saya menggunakan fungsi round () dengan flag PHP_ROUND_HALF_DOWN (yang = 2) dengan menggandakan rata-rata, dan kemudian membaginya dengan 2 sehingga bertambah menjadi 0,5

EDIT: untuk kasus [6,5, 9] saya mengikuti aturan yang dinyatakan bahwa 7,75 putaran menjadi 7,5 dan bukan 8 seperti pada contoh asli yang diberikan.

function s($s){$c=count($s);$t=array_sum($s);if($c>2){$c-=2;$t-=min($s)+max($s);}return round($t/$c*2,0,2)/2;}

Cobalah online!


1
Sudah selesai dilakukan dengan baik! Saya ingin memposting jawaban PHP tetapi aturannya memiliki banyak kekurangan atau perubahan yang baru saja saya berikan! Saya mengubah sedikit kode Anda dan menyimpan 10 byte: Cobalah secara online!
Night2

2

Zsh , 141 136 byte

coba online!   141bytes

setopt FORCE_FLOAT
m=$1 n=$1 a=$#
for x ((t+=x))&&m=$[x>m?x:m]&&n=$[x<n?x:n]
s=$[2*(a>2?(t-m-n)/(a-2):t/a)]
<<<$[(s^0+(s-s^0>.5?1:0))/2]

Solusi mengikuti spesifikasi terbaru. Menyimpan beberapa byte menggunakan implisit ($@).

Kami secara implisit mengulangi argumen dengan for x, dan membangun total berjalan t, dan juga menemukan maksimum, minimum m, n. Jika jumlah argumen alebih besar dari 2, kami membuang mdan ndari rata-rata. sadalah 2x rata-rata yang dihasilkan. Jika mantissa slebih besar dari 0,5, bulatkan s, jika tidak terpotong s^0. Akhirnya, bagi dengan 2 dan output.

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.