El sistema de discapacidad PPCG

35

Como todos sabemos, el meta está repleto de quejas sobre la puntuación del golf de código entre idiomas (sí, cada palabra es un enlace separado, y esto puede ser solo la punta del iceberg).

Con tantos celos hacia aquellos que realmente se molestaron en buscar la documentación de Pyth, pensé que sería bueno tener un poco más de un desafío constructivo, acorde con un sitio web que se especializa en desafíos de código.


El desafío es bastante sencillo. Como entrada , tenemos el nombre del idioma y el recuento de bytes . Puede tomarlos como entradas de función stdino como método de entrada predeterminado de sus idiomas.

Como resultado , tenemos un recuento de bytes corregido , es decir, su puntaje con la desventaja aplicada. Respectivamente, la salida debe ser la salida de la función stdouto el método de salida predeterminado de su idioma. La salida se redondeará a enteros, porque nos encantan los desempates.

Usando el más feo, cortado junto consulta ( enlace - no dude en para limpiarlo), he conseguido crear un conjunto de datos (ZIP con .xslx, .ods y .csv) que contiene una instantánea de todas las respuestas a preguntas . Puede usar el archivo (y asumir que esté disponible para su programa, por ejemplo, está en la misma carpeta) o convertir este archivo a otro formato convencional ( .xls, .mat, .savetc - pero sólo puede contener los datos originales!). El nombre debe permanecer QueryResults.extcon extla extensión de elección.


Ahora para los detalles. Para cada idioma, hay una Boilerplate By Vparámetros de verbosidad . Juntos, se pueden usar para crear un modelo lineal del lenguaje. Sea nel número real de bytes y csea ​​la puntuación corregida. Usando un modelo simple n=Vc+B, obtenemos la puntuación corregida:

    n-B
c = ---
     V

Bastante simple, ¿verdad? Ahora, para determinar Vy B. Como es de esperar, haremos una regresión lineal, o más precisa, una regresión lineal ponderada de mínimos cuadrados. No voy a explicar los detalles sobre eso: si no está seguro de cómo hacerlo, Wikipedia es su amigo , o si tiene suerte, la documentación de su idioma.

Los datos serán los siguientes. Cada punto de datos será el recuento de bytes ny el recuento de bytes promedio de la pregunta c. Para dar cuenta de los votos, los puntos se ponderarán, por su número de votos más uno (para dar cuenta de 0 votos), llamemos a eso v. Las respuestas con votos negativos deben descartarse. En términos simples, una respuesta con 1 voto debe contar lo mismo que dos respuestas con 0 votos.

Luego, estos datos se ajustan al modelo antes mencionado n=Vc+Bmediante regresión lineal ponderada.


Por ejemplo , dados los datos para un idioma dado

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

Ahora, componemos las matrices y vectores pertinentes A, yy W, con nuestros parámetros en el 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 la ecuación matricial (con 'denotar la transposición)

A'WAx=A'Wy

para x(y en consecuencia, obtenemos nuestro By Vparámetro).


Su puntaje será el resultado de su programa, cuando se le dé su propio nombre de idioma y número de bytes. Entonces, sí, ¡esta vez incluso los usuarios de Java y C ++ pueden ganar!

ADVERTENCIA: La consulta genera un conjunto de datos con muchas filas no válidas debido a que las personas usan un formato de encabezado "genial" y etiquetan sus preguntas de como . La descarga que proporcioné ha eliminado la mayoría de los valores atípicos. NO use el CSV proporcionado con la consulta.

¡Feliz codificación!

Sanchises
fuente
3
s / busque la documentación de Pyth / estudie cuidadosamente las dos piezas existentes de documentación de Jelly
lirtosiast
Su consulta no parece distinguir entre Perl 5 y Perl 6. Lo que es similar a no distinguir C ++ de Haskell.
Brad Gilbert b2gills
@ BradGilbertb2gills Lo sé: hace muchas cosas extrañas, principalmente debido a que la gente se vuelve loca con el formateo. Siéntase libre de mejorarlo, pero en este momento, es una compensación entre la falta de numeración de versiones y los idiomas llamados C++ <s>6 bytes</s>. Además, nunca hice ningún T-SQL antes de hoy y ya estoy impresionado conmigo mismo de que logré extraer el bytecount.
Sanchises
¿Podemos eliminar los valores atípicos, es decir, cualquier idioma con una sola entrada (generalmente nombres de idioma incorrectos) o los que tienen> 10,000 bytes?
Robert Fraser
@RobertFraser Pensé que sería demasiado para un solo desafío. Arreglaré el archivo de datos, ver edición.
Sanchises

Respuestas:

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 prueba

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

¿Qué hay de otros idiomas?

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)

Una característica notable del golf de código (y probablemente otros problemas de codificación) es que la distribución de las longitudes de los programas tiende a ser distribución exponencial (en contraste con la distribución uniforme). Por lo tanto, log(n)=log(Vc+B)es mucho más probable que el modelo equilibre las influencias entre puntos con grandes cy pequeños c.

Como podemos ver en los gráficos a continuación, la distribución de puntos es adecuada para ajustarse en escala logarítmica.


Resultados del nuevo 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

Hemos encontrado dos idiomas excepcionales: Ruby with V=0.724y Retina with V=1.322, y un criterio de ser un lenguaje de golf popular, que tiene una gran repetitiva negativa.

njpipeorgan
fuente
@sanchises Hasta ahora todo bien, excepto que usas punto y coma como delimitadores csv.
njpipeorgan
Eso es Microsoft Excel para ti. Aparentemente guardar como csv es demasiado difícil para ello.
Sanchises
Aparentemente, CJam tiene una longitud de placa repetitiva negativa. Interesante.
PurkkaKoodari
@ Pietu1998 El modelo lineal no es tan preciso, creo.
njpipeorgan
@ Pietu1998 No es del todo sorprendente, ya que los lenguajes de golf generalmente toman entradas implícitas y pueden devolver salidas implícitas. Tenga en cuenta que la "longitud de repetitivo" se define con el promedio, no es un lenguaje ideal sin repetitivo. De hecho, estoy positivamente sorprendido por lo bien que parece estar funcionando este modelo simple al mirar estos resultados.
Sanchises
3

Python3, 765.19 (765) bytes

Probablemente hay espacio para jugar golf aquí. Requiere numpy para cosas de matriz. Lecturas de stdin, formateadas de la siguiente manera: [lang] [bytes / n]. Se detiene cuando envía 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

Podría haber hecho algo mal en algún momento; Obtengo resultados diferentes a los de la respuesta de 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
fuente