System HCP PPCG

35

Jak wszyscy wiemy, meta jest przepełnione ze skargami o zabicie kodu golfa między językami (tak, każde słowo jest link indywidualne, a te mogą być tylko wierzchołkiem góry lodowej).

Mając tak dużo zazdrości wobec tych, którzy rzeczywiście próbowali przejrzeć dokumentację Pyth, pomyślałem, że byłoby miło mieć trochę bardziej konstruktywnego wyzwania, jakim jest strona internetowa specjalizująca się w wyzwaniach kodu.


Wyzwanie jest raczej proste. Jako dane wejściowe mamy nazwę języka i liczbę bajtów . Możesz je traktować jako dane wejściowe funkcji stdinlub domyślną metodę wprowadzania w swoich językach.

Jako wynik mamy poprawioną liczbę bajtów , tj. Twój wynik z zastosowanym handicapem. Odpowiednio, wyjście powinno być wyjściem funkcji stdoutlub domyślną metodą wyjścia twojego języka. Dane wyjściowe zostaną zaokrąglone do liczb całkowitych, ponieważ uwielbiamy tiebreakers.

Korzystając z najbardziej brzydkiego, zhakowanego zapytania ( link - nie krępuj się go wyczyścić), udało mi się stworzyć zestaw danych (zip z .xslx, .ods i .csv), który zawiera migawkę wszystkich odpowiedzi na pytania związane z . Można użyć tego pliku (a zakładamy, że będzie dostępny do programu, na przykład, jest w tym samym folderze) lub przekonwertować ten plik na inny format konwencjonalnej ( .xls, .mat, .savitd - ale może zawierać tylko oryginalne dane!). Nazwa powinna pozostać QueryResults.extz extrozszerzeniem wyboru.


Teraz szczegóły. Dla każdego języka istnieją parametry Boilerplate Bi Verbosity V. Razem można je wykorzystać do stworzenia liniowego modelu języka. Niech nbędzie rzeczywistą liczbą bajtów i cbędzie poprawionym wynikiem. Korzystając z prostego modelu n=Vc+B, otrzymujemy skorygowany wynik:

    n-B
c = ---
     V

Dość proste, prawda? Teraz do ustalenia Vi B. Jak można się spodziewać, przeprowadzimy regresję liniową, a dokładniej regresję liniową ważoną metodą najmniejszych kwadratów. Nie zamierzam wyjaśniać szczegółów na ten temat - jeśli nie jesteś pewien, jak to zrobić, Wikipedia jest twoim przyjacielem , a jeśli masz szczęście, dokumentacją Twojego języka.

Dane będą następujące. Każdy punkt danych będzie liczbą bajtów ni średnią liczbą bajtów pytania c. Aby uwzględnić głosy, punkty będą ważone według liczby głosów plus jeden (w celu uwzględnienia 0 głosów), nazwijmy to v. Odpowiedzi negatywne powinny zostać odrzucone. Mówiąc najprościej, odpowiedź z 1 głosem powinna liczyć się tak samo jak dwie odpowiedzi z 0 głosem.

Dane te są następnie dopasowywane do wyżej wspomnianego modelu n=Vc+Bprzy użyciu ważonej regresji liniowej.


Na przykład , biorąc pod uwagę dane dla danego języka

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

Teraz tworzymy odpowiednie macierze i wektory A, ya Wwraz z naszymi parametrami w wektorze

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

rozwiązujemy równanie macierzowe (z 'oznaczeniem transpozycji)

A'WAx=A'Wy

dla x(i w konsekwencji otrzymujemy nasz Bi Vparametr).


Twój wynik będzie wynikiem twojego programu, jeśli podasz własną nazwę języka i liczbę bajtów. Tak, tym razem nawet użytkownicy Java i C ++ mogą wygrać!

UWAGA: Zapytanie generuje zestaw danych z wielu wierszy z powodu nieprawidłowych osób korzystających z „cool” i formatowaniem ludzi nagłówek znakowaniu ich pytania jak . Pobrane przeze mnie pliki usunęły większość wartości odstających. NIE używaj pliku CSV dostarczonego z zapytaniem.

Miłego kodowania!

Sanchises
źródło
3
s / sprawdź dokumentację Pyth / dokładnie przestudiuj dwa istniejące fragmenty dokumentacji Jelly
lirtosiast
Twoje zapytanie nie rozróżnia Perla 5 i Perla 6. Jest to podobne do nierozróżniania C ++ od Haskell.
Brad Gilbert b2gills
@ BradGilbertb2gills Wiem - robi wiele dziwacznych rzeczy, głównie dlatego, że ludzie oszaleli na punkcie formatowania. Możesz go ulepszyć, ale teraz jest to kompromis między brakiem numeracji wersji a nazywanymi językami C++ <s>6 bytes</s>. Poza tym nigdy wcześniej nie korzystałem z T-SQL i już jestem pod wrażeniem, że udało mi się wyodrębnić bajt.
Sanchises
Czy możemy usunąć wartości odstające, tj. Wszystkie języki zawierające tylko jeden wpis (zwykle niepoprawne nazwy języków) lub te, które mają> 10 000 bajtów?
Robert Fraser
@RobertFraser Myślałem, że byłoby to zbyt wiele jak na jedno wyzwanie. Naprawię plik danych, patrz edycja.
Sanchises

Odpowiedzi:

21

Mathematica, 244,719 (245 bajtów)

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]

Przypadek testowy

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

Co z innymi językami?

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

Alternatywny model :log(c)=log((n-B)/V)

Jedną z godnych uwagi cech kodowego golfa (i prawdopodobnie innych problemów z kodowaniem) jest to, że rozkład długości programów ma tendencję do rozkładu wykładniczego (w przeciwieństwie do rozkładu jednolitego). W związku z tym model log(n)=log(Vc+B)znacznie bardziej równoważy wpływy między punktami z dużymi ci małymi c.

Jak widać na poniższych wykresach, rozkład punktów jest odpowiedni do dopasowania w skali logarytmicznej.


Wyniki nowego modelu

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

Znaleźliśmy dwa wyjątkowe języki - Ruby V=0.724zi Retina V=1.322oraz kryterium bycia popularnym językiem golfa - mające duży ujemny talerz.

njpipeorgan
źródło
@sanchises Do tej pory tak dobrze, z tym wyjątkiem, że używasz średników jako ograniczników w csv.
njpipeorgan
To jest Microsoft Excel dla Ciebie. Najwyraźniej zapisywanie jako csv jest dla niego zbyt trudne.
Sanchises
Najwyraźniej CJam ma ujemną długość płyty kotłowej. Ciekawy.
PurkkaKoodari
@ Pietu1998 Myślę, że model liniowy nie jest tak dokładny.
njpipeorgan
@ Pietu1998 Nie do końca zaskakujące, ponieważ języki gry w golfa zazwyczaj przyjmują dane niejawne i mogą zwracać dane niejawne. Zauważ, że „Długość bojlera” jest zdefiniowana względem średniej, a nie idealnego języka bez bojlera. Jestem naprawdę pozytywnie zaskoczony, jak dobrze ten prosty model wydaje się sprawdzać, patrząc na te wyniki.
Sanchises
3

Python3, 765.19 (765) bajtów

Prawdopodobnie jest tu miejsce na grę w golfa. Wymaga numpy dla macierzy. Odczytuje ze standardowego formatu, sformatowany w następujący sposób: [język] [bajtów / n]. Zatrzymuje się podczas wysyłania 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()

Wyniki

W pewnym momencie mogłem zrobić coś złego; Otrzymuję inne wyniki niż odpowiedź 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
Jodła
źródło