Desafio Meta Golf

22

Nesse desafio, você precisa resolvê-lo.

O concurso acabou! Verifique o final da pergunta

Especificações:

  1. Escreva o menor código (qualquer idioma *).
  2. A pontuação de uma resposta é a soma de:
    • Comprimento do código sem espaço em branco .
    • Número de respostas usando o mesmo idioma ao quadrado.
    • Tamanho do nome do maior idioma do concurso menos o tamanho do seu idioma.
    • Votos negativos menos Votos positivos (também conhecido como total negativo de menos)
  3. Escreva a posição dos usuários e a pontuação.
  4. Cada usuário pode escrever apenas uma resposta.
  5. A pontuação mais baixa vence.

Teste:

Portanto, no final do concurso, uma possível entrada poderia ser (STDIN):

As colunas são: Nome de usuário, Idioma, Comprimento do código (sem espaço em branco) e TotalVotes

UserA Python 100 1
UserB Perl 30 2
UserC Java 500 3
UserD Brainfuck 499 4
UserE Perl 29 5

Se o seu nome de usuário tiver espaços como "Meu nome de usuário", ele se tornará "Meu nome de usuário", portanto a entrada sempre terá exatamente 4 colunas .

A saída será (STDOUT):

1 UserE 33
2 UserB 37
3 UserA 103
4 UserD 496
5 UserC 503

Explicação:

User  P  N^2  L   V
 A   100  1   3  -1
 B    30  4   5  -2
 C   500  1   5  -3
 D   499  1   0  -4
 E    29  4   5  -5

Brainfuck é o maior nome com 9 caracteres ( 9 - 9 = 0).

Perl e Java possuem 4 caracteres ( 9 - 4 = 5).

Python possui 6 caracteres ( 9 - 6 = 3).

Perl tem 2 entradas para que cada um ganhe 4 pontos extras.


Sobre idiomas:

O nome do idioma deve conter apenas letras em inglês (ou seja, [A-Za-z]) e aquelas que não se encaixam devem ser "traduzidas" para outra coisa.

No final do concurso, todos os idiomas devem ter sua representação (você pode propor melhores representações)

Exemplos:

Python3      -> Python
Ruby1.9      -> Ruby
Shell Script -> Shell
C++          -> Cpp
C#           -> CSharp
><>          -> Fish

Prazo: 20 de agosto de 2011 00:00 UTC

No final do concurso, o vencedor deve usar seu programa para encontrar o vencedor. É permitido aos não vencedores usarem seus programas para encontrar o vencedor e pedir que ele use seu programa para encontrar o vencedor. :)

O vencedor (veja acima) recebe a resposta aceita!

* A linguagem Whitespace tem a vantagem injusta de poder introduzir complexidade ilimitada sem penalizar a contagem de caracteres. As respostas escritas em espaço em branco podem estar no concurso, mas não podem vencer.

Se você pode fazer a lógica do seu programa em espaços em branco , também não pode vencer. Esse é um tópico subjetivo, mas se o seu programa pode aumentar consideravelmente em tamanho sem ser penalizado, ele cai nessa condição.


Entrada final

Ordem alfabética dos nomes (em 20 de agosto de 2011 UTC 00:00)

boothby Sage 41 9
Harpyon Python 203 4
JBernardo Python 184 7
JoeyAdams PostgreSQL 225 6
jpjacobs AWK 269 4
Lowjacker Ruby 146 2
PeterTaylor Golfscript 82 4
rmackenzie CommonLisp 542 2
shesek Javascript 243 3
userunknown Scala 252 1

Como as respostas da minha e do boothby não estão autorizadas a vencer, o vencedor deve se proclamar o vencedor editando esta pergunta e publicando a saída final abaixo.

Saída final

1 boothby 39
2 PeterTaylor 79
3 Lowjacker 151
4 JBernardo 185
5 Harpyon 207
6 JoeyAdams 220
7 shesek 241
8 userunknown 257
9 jpjacobs 273
10 rmackenzie 541
JBernardo
fonte
8
Isso significa que uma solução no Whitespace vencerá automaticamente?
Joey Adams
1
De onde vêm as informações sobre outras respostas? Nossos programas devem se conectar ao StackExchange e extrair as respostas para esta pergunta?
23611 Justin Morgan
1
@ Justin No final do concurso, farei a entrada do programa real com as respostas. Eu dei o formato
JBernardo 18/07/11
1
@Harpyon <> <ti dexif I! SknahT
JBernardo
1
Devemos ordenar a saída por pontuações? Se sim, o que devemos fazer em caso de empate?
Boothby

Respostas:

11

Golfscript, 83 caracteres (82 sem contar o espaço em branco)

n/{},{' ':s/}%.{1=}%\{~~\~\-\.`{=}+4$\,,.*\,-+2${,}%$)\;+[\]}%$\;.,,]zip{~)s@~s@n}%

Explicação:

# Split the string containing all the input on newlines
n/
# Remove empty lines
{},
# Split each line on spaces (storing the space character in variable s)
{' ':s/}%
# We now have an array of arrays of words. Duplicate it, filter the copy to contain
# only the second word of each array, and reorder with the array of second words first
.{1=}%\
# Map each line
{
    # Unpack the array ["user" "lang" "length" "votes"] and evaluate the integers
    ~~\~\
    # Subtract votes from length and bring "lang" to the top
    -\
    # Create a function to match the string "lang"
    .`{=}+
    # Stack is currently [array of langs] "user" (length-votes) "lang" {"lang"=}
    # Duplicate the array of langs and apply the match function as a filter
    4$\,
    # Get the length of the array of matches and square it
    ,.*
    # Stack is [array of langs] "user" (length-votes) "lang" (num with lang)^2
    # Bring the "lang" to the top, get its length, subtract and add
    \,-+
    # Stack is [array of langs] "user" (score-length of longest lang)
    # Get an array of length of language names and sort it
    2${,}%$
    # Drop it apart from the largest value, and add that to the score
    )\;+
    # Package the "user" score from the top of the stack as [score "user"]
    [\]
}%
# Sort. Since each element is a [score "user"] value, this will sort by score.
$
# Discard the [array of langs].
\;
# Stack is an array of [score "user"] arrays. Get its length and create an array of the
# same length which counts from 0.
.,,
# Group and zip, so we go from [[score0 "user0"] ... [scoren "usern"]] [0 ... n] to
# [[[score0 "user0"] 0] ... [[scoren "usern"] n]]
]zip
# Map each [[scorei "useri"] i]
{
    # Expand, increment i (so we count from 1 rather than 0), add a space
    ~)s
    # Bring the [scorei "useri"] to the top, unpack, add a space
    @~s
    # Bring the scorei to the top, add a newline
    @n
}%
# We now have an array [[1 " " "userA" " " scoreA "\n"] ... [n " " "userZ" " " scoreZ "\n"]
# so Golfscript's standard output formatting does the rest
Peter Taylor
fonte
Isso é muito puro, eu deveria dar uma olhada em GolfScript ... Eu não tenho nenhuma idéia de como isso é analisado em algo significativo
shesek
3
@shesek, adicionou uma versão fortemente comentada
Peter Taylor
uau, muito legal! obrigado :-)
shesek
15

Sábio: 48 42 41 sem espaço em branco (60246 bytes no total)

Só para ser um idiota:

s = '   '
for c in '<lots of whitespace>'.split(s):
    s+=chr(len(c))
exec s

Observe que a primeira linha deve ser equivalente a s='\t', mas o bloco de código SE converte a guia em 4 espaços.

O espaço em branco descompacta para:

exec preparse("""
import sys
instances = {}
maxlen = 0
inputs = [line.split() for line in sys.stdin.readlines()]
for i in [0..len(inputs)-1]:
    user, language, length, votes = inputs[i]
    if language in instances:
        instances[language]+=1
    else:
        instances[language]=1
    if len(language) > maxlen:
        maxlen = len(language)

scoresheet = []
for i in [0..len(inputs)-1]:
    user, language, length, votes = inputs[i]
    length = int(length)
    votes = int(votes)
    score = length + (maxlen - len(language)) + instances[language]*instances[language] - votes
    scoresheet.append((score,user))

scoresheet.sort(reverse=False)
for user, score in scoresheet:
    print user, score""")

Observe que meu uso de [0..len(inputs)-1] garante que este não seja um script Python, pois o Sage é um superpython *. Infelizmente, o executivo recorre ao Python ... então eu tenho que prepará-lo.

edit 1: dividir abas, não novas linhas - o que eu estava pensando? edit 2: facilitou o código aos olhos e reciclou a aba de divisão, empurrando outra 'nova linha' para o espaço em branco

* ok, não exatamente: nós quebramos xor

boothby
fonte
10

Python, 184

É por isso que amo espaços.

import          sys
x = sys.stdin.read(
    ).split()
z = x [  1 : : 4  ]
for i , ( j , k
) in enumerate (
      sorted (
       zip (
        [
      int(i)
    - int(j) +
  z.count(k) ** 2
+ max(map(len, z)) -
      len(k)
  for i, j, k in
       zip (
    x[2 : : 4],
    x[3 : : 4],
         z
         )
         ],
     x[ : : 4]
         )
         ),
         1
         ):
   print i, k, j

É muito mais legível!

JBernardo
fonte
3
isso deveria ser algum tipo de arte ascii imaginando alguma coisa? se sim, como deve ser?
Enone
@ oenone você me diz.
JBernardo 17/08/11
2
parece que ele deveria, mas eu não posso reconhecer nada
Enone
1
@oneone nem eu ...
JBernardo
7

PostgreSQL - 225 caracteres não espaciais

242 → 225: Subconsultas substituídas por cláusulas de janelas .

\set QUIET 1
\t
\a
\f ' '
CREATE TEMPORARY TABLE t (u TEXT, l TEXT, c INT, v INT);
\copy t FROM PSTDIN WITH DELIMITER ' ';
SELECT row_number() OVER (ORDER BY score), *
    FROM (SELECT u,
                 c
                 + count(*) OVER (PARTITION BY l)^2
                 + max(length(l)) OVER ()
                 - length(l)
                 - v AS score
                 FROM t) AS q

testado em 9.2devel

Uso e saída:

$ psql -f meta.sql < meta.in
1 UserE 33
2 UserB 37
3 UserA 103
4 UserD 496
5 UserC 503
Joey Adams
fonte
4

Python 2 - 210 203 caracteres não espaciais

import sys
e=enumerate
n=len
l=[x.split()for x in sys.stdin.readlines()]
for i,(x,y)in e(sorted((int(x[2])-int(x[3])+n(list(y for y in l if y[1]==x[1]))**2+max(n(x[1])for x in l)-n(x[1]),i)for i, x in e(l))):print i+1,l[y][0],x

Uso e saída:

$ cat meta.txt | python meta.py
1 UserE 33
2 UserB 37
3 UserA 103
4 UserD 496
5 UserC 503

fonte
você só poderia usar x.split()(que também irá remover \n)
JBernardo
@JBernardo Cheers! Salvou 7 caracteres.
Você pode abandonar o .readlines () no sys.stdin .... para qualquer duração razoável de entrada, a chamada de função não fará diferença e custará alguns caracteres. Só descobri isso em outro golfe e pensei em compartilhar.
arrdem
4

AWK, 277 269 ​​caracteres não espaciais

Usado inpara cortar 8 caracteres.

Versão espaçada e versão comentada:

{
        # read in user strings
        u[NR]=$0
        # count number of times language has been used
        l[$2]+=1
}

END{
        # get maximum language length
        M=0
        X=NR
        for (g in l){
                f=length(g)
                if(f>M)
                        M=f
        }
        # get score for user i
        for(i in u){
                split(u[i],c)
                s[i]=c[3]+l[c[2]]^2+M-length(c[2])-c[4]
        }
        # sort scores and users
        for(i=2;i<=X;++i){
                for(j=i;s[j-1]>s[j];--j){
                        t=s[j]
                        x=u[j]
                        s[j]=s[j-1]
                        u[j]=u[j-1]
                        s[j-1]=t
                        u[j-1]=x
                }
        }
        # output
        for(i=1;i<=X;++i){
                split(u[i],c)
                print i,c[1],s[i]
        }
}

uso:

awk -f meta.awk data.txt
jpjacobs
fonte
usado sed '/#/ d' meta.awk|sed ':a;$!N;s/\n//;ta;s/\s//g;'|wc -cpara contar caracteres.
Jpjacobs
3

Ruby, 146 caracteres + 4 espaços

b=$<.map &:split
puts b.map{|u,l,c,v|[b.map{|_,n|n.size}.max-l.size+b.count{|_,n|n==l}**2+eval(c+?-+v),u]}.sort.map.with_index{|(s,u),i|[i+1,u,s]*' '}
Lowjacker
fonte
3

JavaScript, 243 caracteres

for(g=0,H="length",i=J.split("\n"),p=[],l={};i[H]&&p.push(a=i.pop().split(" "));)
    X=a[1],X[H]>g&&(g=X[H]),l[X]=l[X]+1||1
for(i=-1;m=p[++i];)p[i]=[m[0],+m[2]+Math.pow(l[m[1]],2)+(g-m[1][H])-m[3]]
p.sort(function(a,b){return a[1]<b[1]?-1:1}).join("\n")

Mais do que a maioria das outras soluções ... mas o melhor que eu poderia criar em JavaScript.

Uso

A entrada deve estar em uma variável J. Por exemplo, abra um console e escreva:

J="UserA Python 100 1\nUserB Perl 30 2\nUserC Java 500 3\nUserD Brainfuck 499 4\nUserE Perl 29 5";
for(g=0,H="length",i=J.split("\n"),p=[],l={};i[H]&&p.push(a=i.pop().split(" "));)
    X=a[1],X[H]>g&&(g=X[H]),l[X]=l[X]+1||1
for(i=-1;m=p[++i];)p[i]=[m[0],+m[2]+Math.pow(l[m[1]],2)+(g-m[1][H])-m[3]]
p.sort(function(a,b){return a[1]<b[1]?-1:1}).join("\n")

CoffeScript, 177 caracteres

Sobre a mesma lógica, no CoffeScript:

g=0;H="length";l={};([A,+C+Math.pow(l[B],2)+(g-B[H])-D] for [A,B,C,D] in for a in J.split "\n" then [_,X]=a=a.split " ";X[H]>g&&g=X[H];l[X]=l[X]+1||1;a).sort((a,b)->`a[1]<b[1]?-1:1`).join "\n"
shesek
fonte
Eu gosto de como você abrevia o lengthatributo usando uma variável e subscritos.
Joey Adams
3

Lisp comum - 546

(quando garoto de golfe consolida parênteses, sem contar espaços)

;;;; This is an answer to Code-Golf question
;;;; 3203/meta-golf-challenge
;;;; By using Common Lisp I plan to have the longest
;;;; Language-name while I cannot hope to have the
;;;; lowest character count due to Lisp's
;;;; linguistic tradition I can avoid the 16 or 25-pt
;;;; penalty atached to being the 4th or 5th PY
;;;; based answer.

(defun f (i)
 (loop for e in y do
  (if (eq i (nth 0 e))
   (return (nth 1 e))
  )
 )
)

(setf x
 (loop for l = (read-line () () () ())
  while l collect (loop for i = 0 then (1+ j)
                   as j = (position #\Space l :start i)
                   collect (subseq l i j) while j)
 )
)

(setf y
 (loop for a in x collect
  (list
   (+
    (read-from-string (nth 2 a))
    (expt (reduce #'+ (loop for b in x collect (if (string= (nth 1 a) (nth 1 b)) 1 0) ) ) 2 )
    (+ 5 (- (reduce #'min (loop for b in x collect (length (nth 1 b)))) (length (nth 1 a))))
    (* -1 (read-from-string (nth 3 a)))
   )
   (car a)
  )
 )
)

(setf g
 (sort (loop for c in y collect (nth 0 c)) #'<)
)

(loop for i = 0 then (1+ i) while (< i (length g)) do
 (setf a (nth i g))
 (format t "~A ~A ~A~%" (1+ i) (f a) a)
)

Fortemente jogado, minha solução comum de lisonjas era e é a mais longa do jogo. Então decidi trapacear um pouco, escrevendo um gerenciador de inicialização significativamente mais curto e afirmando isso como meu envio.(Considero que a submissão de @ Boothby é um precedente a favor desse comportamento)

Agradecimentos importantes a Peter Taylor por sua ajuda para extrair todos os caracteres do bootstrapper.

BASH - 35

wget -q goo.gl/R4R54
cat -|clisp l.lsp

Uso : cat ./test0 | bash ./btstrp.sh

Joey Adams apontou que essa não é uma solução justa, porque eu posso "aumentar arbitrariamente a complexidade da sua solução sem um aumento correspondente no tamanho do código", um ponto que não está claramente expresso nas especificações.

arrdem
fonte
1
Um loop for não seria mais curto que o até?
Peter Taylor
não tenho certeza ... mas encontrou um tempo mais curto!
arrdem
1
Além disso, se você especificar a variável a ser lida, não precisará usar $REPLY. Tente while read x;do a=$x"\n"$a;done. E você deve poder remover os espaços após os |na última linha. Em outra nota, não tenho certeza de que usar um endereço IP interno seja muito útil: ele não funcionará para mais ninguém.
22611 Peter Peter Taylor
Ou até mesmowget -q http://url/l.lsp ;cat - |clisp l.lsp
Peter Taylor
Ok, você me perdeu no gato #:
arrdem
2

Scala 269 ​​266 252 sem espaços em branco e novas linhas.

val b = io.Source.stdin.getLines.toList.map (_.split (" "))
b.map (a => {
  val l = b.filter (_(1) .equals ( a(1))).size
  a(0) -> (a (2).toInt + l * l + (b.map (x => x(1).length).max - a(1).length) - a(3).toInt)
}).sortBy (_._2).zipWithIndex .map (m => m._2 + " " + m._1._1 + " "+ m._1._2).mkString ("\n")

Invocação:

cat user.lst | scala -i metagolf.scala

atualizações:

  • simplificado (l => l.foo) -> (_.foo)
  • invocação
  • Gareths sugerem stdin

minha solução:

* 0 boothby 39
1 PeterTaylor 79
2 Lowjacker 151
* 3 JBernardo 185
4 Harpyon 207
5 JoeyAdams 220
6 shesek 241
7 userunknown 257
8 jpjacobs 273
9 rmackenzie 541

*) fora de competição

Usuário desconhecido
fonte
Você pode usar em stdinvez de fromFile(System.in).
21711 Gareth
1
Obrigado. Agora preciso de 179 votos positivos e teria vencido o desafio - ceteris paribus.
usuário desconhecido
Sem problemas. Hmm ... não tenho certeza há tráfego suficiente para que você obtenha 179 upvotes ...
Gareth