Sistem Handicap PPCG

35

Seperti yang kita semua tahu, meta yang dipenuhi dengan keluhan tentang mencetak kode-golf antara bahasa (ya, setiap kata adalah link terpisah, dan ini mungkin hanya puncak gunung es).

Dengan kecemburuan yang begitu besar terhadap mereka yang benar-benar peduli untuk melihat dokumentasi Pyth, saya pikir akan menyenangkan untuk memiliki sedikit lebih banyak tantangan yang membangun, sesuai dengan sebuah situs web yang berspesialisasi dalam tantangan kode.


Tantangannya agak langsung. Sebagai input , kami memiliki nama bahasa dan jumlah byte . Anda dapat menjadikannya sebagai input fungsi, stdinatau metode input default bahasa Anda.

Sebagai output , kami memiliki jumlah byte yang diperbaiki , yaitu skor Anda dengan handicap yang diterapkan. Masing-masing, output harus menjadi output fungsi, stdoutatau metode output default bahasa Anda. Output akan dibulatkan menjadi bilangan bulat, karena kami menyukai tiebreak.

Menggunakan kueri yang paling jelek, diretas bersama ( tautan - jangan ragu untuk membersihkannya), saya telah berhasil membuat dataset (zip dengan .xslx, .ods, dan .csv) yang berisi snapshot dari semua jawaban untuk pertanyaan . Anda dapat menggunakan file ini (dan menganggap itu akan tersedia untuk program anda, misalnya, itu di folder yang sama) atau mengkonversi file ini ke format konvensional lain ( .xls, .mat, .savdll - tetapi hanya mungkin berisi data asli!). Nama harus tetap QueryResults.extdengan extekstensi pilihan.


Sekarang untuk spesifik. Untuk setiap bahasa, ada parameter Boilerplate Bdan Verbosity V. Bersama-sama, mereka dapat digunakan untuk membuat model linear bahasa. Membiarkan nmenjadi jumlah byte aktual, dan cmenjadi skor yang dikoreksi. Dengan menggunakan model sederhana n=Vc+B, kami mendapatkan skor terkoreksi:

    n-B
c = ---
     V

Cukup sederhana, bukan? Sekarang, untuk menentukan Vdan B. Seperti yang Anda harapkan, kita akan melakukan beberapa regresi linier, atau lebih tepatnya, regresi linear tertimbang kuadrat. Saya tidak akan menjelaskan detailnya - jika Anda tidak yakin bagaimana melakukannya, Wikipedia adalah teman Anda , atau jika Anda beruntung, dokumentasi bahasa Anda.

Data akan sebagai berikut. Setiap titik data akan menjadi jumlah byte ndan bytecount rata-rata pertanyaan c. Untuk memperhitungkan suara, poin akan ditimbang, dengan jumlah suara ditambah satu (untuk memperhitungkan 0 suara), sebut saja itu v. Jawaban dengan suara negatif harus dibuang. Secara sederhana, jawaban dengan 1 suara harus dihitung sama dengan dua jawaban dengan 0 suara.

Data ini kemudian dimasukkan ke dalam model tersebut n=Vc+Bmenggunakan regresi linier tertimbang.


Misalnya , diberikan data untuk bahasa yang diberikan

n1=20, c1=8.2, v1=1
n2=25, c2=10.3, v2=2
n3=15, c3=5.7, v3=5

Sekarang, kami menyusun matriks dan vektor yang relevan A, ydan W, dengan parameter kami di vektor

  [1 c1]    [n1]    [1 0 0]  x=[B]
A=[1 c2]  y=[n2]  W=[0 2 0],   [V]
  [1 c3]    [n3]    [0 0 5]

kita memecahkan persamaan matriks (dengan 'menunjukkan transpos)

A'WAx=A'Wy

untuk x(dan akibatnya, kita mendapatkan parameter Bdan kita V).


Skor Anda akan menjadi output dari program Anda, ketika diberi nama bahasa Anda sendiri dan bytecount. Jadi ya, saat ini bahkan pengguna Java dan C ++ dapat menang!

PERINGATAN: Permintaan menghasilkan dataset dengan banyak baris tidak valid karena orang-orang menggunakan format header 'keren' dan orang-orang menandai pertanyaan mereka sebagai . Unduhan yang saya berikan menghilangkan sebagian besar outlier. JANGAN gunakan CSV yang disediakan dengan kueri.

Selamat coding!

Sanchises
sumber
3
s / mencari dokumentasi Pyth / hati-hati mempelajari dua ada potongan dokumentasi Jelly
lirtosiast
Kueri Anda tampaknya tidak membedakan antara Perl 5 dan Perl 6. Yang mirip dengan tidak membedakan C ++ dari Haskell.
Brad Gilbert b2gills
@ BradGilbertb2gills Saya tahu - ia melakukan banyak hal aneh, sebagian besar karena orang-orang menjadi gila dengan format. Jangan ragu untuk memperbaikinya, tetapi saat ini, itu merupakan pertukaran antara kurangnya penomoran versi dan bahasa yang disebut C++ <s>6 bytes</s>. Selain itu, saya tidak pernah melakukan T-SQL sebelum hari ini dan saya sudah terkesan dengan diri saya bahwa saya berhasil mengekstrak bytecount.
Sanchises
Bisakah kita menghapus outlier, yaitu bahasa apa saja dengan hanya satu entri (biasanya nama bahasa salah) atau yang memiliki> 10.000 byte?
Robert Fraser
@RobertFraser Saya pikir itu akan terlalu banyak untuk satu tantangan. Saya akan memperbaiki file data, lihat edit.
Sanchises

Jawaban:

21

Mathematica, 244.719 (245 bytes)

f[l_,n_]:=x/.Solve[d=Rest@Import@"QueryResults.csv";LinearModelFit[#.#2/Tr@#&@@{#~Max~-1&/@#4+1,#3}&@@Thread@#&/@{#,#~Cases~{_,l,__}}&/@d~GroupBy~Last/@#[[;;,1,5]],x,x,Weights->Tr/@#[[;;,;;,4]]]&[d~Cases~{_,l,_,v_/;v>=0,_}~GatherBy~Last]@x==n,x]

Kasus cobaan

f["mathematica", n]   (* { .820033 (n + 53.4263) } *)
f["mathematica", 245] (* { 244.719 } *)

Bagaimana dengan bahasa lain?

f["c++", n]           (* { .821181 (n - 79.5437) } *)
f["java", n]          (* { .717579 (n - 56.0858) } *)
f["cjam", n]          (* { 2.21357 (n + 2.73772) } *)
f["pyth", n]          (* { 4.52194 (n - 8.82806) } *)

Model alternatif :log(c)=log((n-B)/V)

Salah satu fitur penting dari golf kode (dan mungkin masalah pengkodean lainnya) adalah bahwa distribusi panjang program cenderung menjadi distribusi eksponensial (berbeda dengan distribusi seragam). Karenanya model log(n)=log(Vc+B)jauh lebih mungkin untuk menyeimbangkan pengaruh antara titik-titik dengan besar cdan kecil c.

Seperti yang dapat kita lihat dalam grafik di bawah ini, distribusi titik cocok untuk pemasangan dalam skala logaritmik.


Hasil model baru

Language       V       B

Python       1.365   -19.4    
Javascript   1.002     1.6
Ruby         0.724     1.7
Perl         1.177   -32.7
C            1.105     1.5
Haskell      1.454   -24.5
Mathematica  1.319   -39.7
PHP          1.799   -62.0
Java         1.642     4.4
C#           1.407     4.5

CJam         0.608   -12.5
Pyth         0.519   -11.4
Golfscript   0.766   -18.0
J            0.863   -21.4
APL          0.744   -17.7
K            0.933   -23.3
Retina       1.322   -37.9
MATL         0.762   -13.3
Jelly        0.965   -23.8

Kami telah menemukan dua bahasa yang luar biasa - Ruby with V=0.724dan Retina with V=1.322, dan kriteria untuk menjadi bahasa golf yang populer - memiliki pelat ketel negatif yang besar.

njpipeorgan
sumber
@sanchises Sejauh ini sangat bagus, kecuali bahwa Anda menggunakan tanda titik koma sebagai pembatas di csv.
njpipeorgan
Itu Microsoft Excel untuk Anda. Ternyata menabung sebagai csv terlalu sulit untuk itu.
Sanchises
Jadi ternyata CJam memiliki panjang boilerplate negatif. Menarik.
PurkkaKoodari
@ Pietu1998 Model linear tidak begitu akurat, saya pikir.
njpipeorgan
@ Pietu1998 Tidak sepenuhnya mengejutkan, karena bahasa golf umumnya mengambil input implisit dan dapat mengembalikan output implisit. Perhatikan bahwa "Panjang pelat ketel" didefinisikan rata-rata, bukan bahasa tanpa ketelingan yang ideal. Saya benar-benar terkejut dengan betapa baiknya model sederhana ini tampaknya dilakukan ketika melirik hasil ini.
Sanchises
3

Python3, 765,19 (765) byte

Mungkin ada ruang untuk bermain golf di sini. Membutuhkan numpy untuk hal-hal matriks. Dibaca dari stdin, diformat sebagai berikut: [lang] [bytes / n]. Berhenti ketika Anda mengirim q.

import numpy as n,csv
L={};Q={};X={};D=n.dot;f=open('QueryResults.csv',encoding="utf8");R=csv.reader(f);f.readline();Z=list.append;M=n.matrix
for r in R:
 if r[1] not in L:L[r[1]]=[]
 if r[4] not in Q:Q[r[4]]=[]
 Z(L[r[1]],r);Z(Q[r[4]],r)
for l in L:
 b=[];a=[];v=[];t=[]
 for r in L[l]:
  if int(r[3])>-1:
   Z(b,int(r[2]));o=[]
   for q in Q[r[4]]:Z(o,int(q[2]))
   Z(a,sum(o)/len(o));Z(v,int(r[3])+1)
 for k in a:Z(t,[1,k])
 if len(t)<1:continue
 A=M(t);T=A.transpose();W=n.diag(v);y=M(b).reshape((len(b),1));e=D(D(T,W),A)
 if n.linalg.det(e)==0:continue
 i=n.linalg.inv(e);X[l]=D(i,D(D(T,W),y))
p=input()
while(p!="q"):
 S=p.split()
 if S[1]=='n':print("(n-("+str(X[S[0]].item(0))+"))/"+str(X[S[0]].item(1)))
 else:print(str((int(S[1])-X[S[0]].item(0))/X[S[0]].item(1)))
 p=input()

Hasil

Saya mungkin telah melakukan sesuatu yang salah di beberapa titik; Saya mendapatkan hasil yang berbeda dari jawaban Mathematica:

python3 808 -> 765.19
python3 n   -> (n-(32.41))/1.01

c++ n        -> (n-(71.86))/1.17
cjam n       -> (n-(-14.09))/0.51
java n       -> (n-(18.08))/1.64
pyth n       -> (n-(1.42))/0.28
jelly n      -> (n-(-4.88))/0.34
golfscript n -> (n-(-0.31))/0.44
Yodle
sumber