O Sistema de Handicap PPCG

35

Como todos sabemos, meta está transbordando com queixas sobre marcando código-golfe entre línguas (sim, cada palavra é um link independente, e estas podem ser apenas a ponta do iceberg).

Com tanto ciúme daqueles que realmente se preocuparam em procurar a documentação do Pyth, achei que seria bom ter um desafio um pouco mais construtivo, condizente com um site especializado em desafios de código.


O desafio é bastante direto. Como entrada , temos o nome do idioma e contagem de bytes . Você pode usá-las como entradas de função stdinou como método de entrada padrão de idiomas.

Como resultado , temos uma contagem de bytes corrigida , ou seja, sua pontuação com o handicap aplicado. Respectivamente, a saída deve ser a saída da função stdoutou o método de saída padrão do seu idioma. A saída será arredondada para números inteiros, porque amamos desempatadores.

Usando o mais feio, cortado junto consulta ( ligação - sinta-se livre para limpá-lo), eu consegui criar um conjunto de dados (ZIP com .xslx, .ods e .csv) que contém um instantâneo de todas as respostas para perguntas . Você pode usar este arquivo (e assumir que ele esteja disponível para o seu programa, por exemplo, é na mesma pasta) ou converter esse arquivo para outro formato convencional ( .xls, .mat, .savetc - mas ele só pode conter os dados originais!). O nome deve permanecer QueryResults.extcom exta extensão de escolha.


Agora, para os detalhes. Para cada idioma, há um parâmetro Boilerplate Be Verbosity V. Juntos, eles podem ser usados ​​para criar um modelo linear da linguagem. Vamos nser o número real de bytes, e cser a pontuação corrigida. Usando um modelo simples n=Vc+B, obtemos a pontuação corrigida:

    n-B
c = ---
     V

Simples o suficiente, certo? Agora, para determinar Ve B. Como você pode esperar, faremos uma regressão linear ou, mais precisamente, uma regressão linear ponderada em mínimos quadrados. Não vou explicar os detalhes sobre isso - se você não tiver certeza de como fazer isso, a Wikipedia é sua amiga ou, se tiver sorte, a documentação do seu idioma.

Os dados serão os seguintes. Cada ponto de dados será a contagem de bytes ne a contagem média de bytes da pergunta c. Para contabilizar os votos, os pontos serão ponderados, pelo número de votos mais um (para contabilizar 0 votos), vamos chamar assim v. Respostas com votos negativos devem ser descartadas. Em termos simples, uma resposta com 1 voto deve contar o mesmo que duas respostas com 0 votos.

Esses dados são então ajustados ao modelo acima mencionado n=Vc+Busando regressão linear ponderada.


Por exemplo , dados os dados para um determinado idioma

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

Agora, nós compor as matrizes e vetores relevantes A, ye W, com os nossos parâmetros no vector

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

resolvemos a equação da matriz (com 'denotar a transposição)

A'WAx=A'Wy

para x(e consequentemente, obtemos nosso Be Vparâmetro).


Sua pontuação será a saída do seu programa, quando for indicado o seu próprio nome de idioma e o número da conta. Então, sim, desta vez até usuários de Java e C ++ podem ganhar!

AVISO: A consulta gera um conjunto de dados com muitas linhas inválidas devido a pessoas que usam formatação de cabeçalho 'cool' e pessoas que marcam suas perguntas de como . O download que forneci removeu a maioria dos outliers. NÃO use o CSV fornecido com a consulta.

Feliz codificação!

Sanchises
fonte
3
s / procurar a documentação Pyth / estudar cuidadosamente as duas existentes pedaços de documentação Jelly
lirtosiast
Sua consulta não parece distinguir entre Perl 5 e Perl 6. O que é semelhante a não distinguir C ++ de Haskell.
Brad Gilbert b2gills
@ BradGilbertb2gills eu sei - ele faz um monte de coisas peculiares, principalmente devido a pessoas enlouquecendo com a formatação. Sinta-se à vontade para aprimorá-lo, mas, no momento, é uma troca entre a falta de numeração de versão e os idiomas chamados C++ <s>6 bytes</s>. Além disso, nunca fiz T-SQL antes de hoje e já estou impressionado comigo mesmo por conseguir extrair o número de bytes.
Sanchises
Podemos remover valores discrepantes, ou seja, qualquer idioma com apenas uma entrada (geralmente nomes de idioma incorretos) ou com mais de 10.000 bytes?
Robert Fraser
@RobertFraser Eu pensei que seria demais para um único desafio. Vou consertar o arquivo de dados, veja editar.
Sanchises

Respostas:

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]

Caso de teste

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

E outras línguas?

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

Modelo alternativo :log(c)=log((n-B)/V)

Uma característica notável do código de golfe (e provavelmente outros problemas de codificação) é que a distribuição dos comprimentos dos programas tende a ser distribuição exponencial (em contraste com a distribuição uniforme). Portanto, log(n)=log(Vc+B)é muito mais provável que o modelo equilibre as influências entre pontos com grandes ce pequenos c.

Como podemos ver nos gráficos abaixo, a distribuição de pontos é adequada para o ajuste em escala logarítmica.


Resultados do novo modelo

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

Encontramos duas linguagens excepcionais - Ruby com V=0.724e Retina com V=1.322, e um critério de ser uma linguagem popular de golfe - com uma grande clichê negativa.

njpipeorgan
fonte
@sanchises Até agora tudo bem, exceto que você usa ponto e vírgula como delimitadores em csv.
Njpipeorgan
Esse é o Microsoft Excel para você. Aparentemente, salvar como CSV é muito difícil para isso.
Sanchises
Então, aparentemente, o CJam tem um comprimento padrão negativo. Interessante.
PurkkaKoodari
@ Pietu1998 O modelo linear não é tão preciso, eu acho.
Njpipeorgan
@ Pietu1998 Não é de todo surpreendente, uma vez que os idiomas de golfe geralmente recebem entradas implícitas e podem retornar saídas implícitas. Observe que o "comprimento da placa padrão" é definido com base na média, e não na linguagem ideal para placas sem caldeira. Na verdade, estou positivamente surpreso com o desempenho desse modelo simples ao olhar para esses resultados.
Sanchises
3

Python3, 765,19 (765) bytes

Provavelmente algum espaço para jogar golfe aqui. Requer numpy para o material da matriz. Lê do stdin, formatado da seguinte forma: [lang] [bytes / n]. Para quando você envia 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()

Resultados

Eu poderia ter feito algo errado em algum momento; Eu obtenho resultados diferentes da resposta do 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
fonte