Tipo de meta: obtenga la más larga de las respuestas más cortas

14

Su tarea, si la acepta, es escribir un programa que ayude a comprender mi propuesta sobre meta calculando al ganador de una competencia de . Por supuesto, las respuestas a esta pregunta se tratarán como propuestas, por lo que su programa (si es correcto) puede calcular si su respuesta se convertirá en la respuesta aceptada.

Reglas

  • El programa lee un archivo con varias líneas del siguiente formato (ver ejemplo a continuación): [Idioma] TAB [NumberOfCharacters] TAB [LinkToAnswer]
  • El nombre del archivo se pasa como argumento a su programa o el archivo se redirige a la entrada estándar de su programa. Es su elección, mencione el método al dar la respuesta
  • Se espera que el formato de entrada sea correcto. No hay necesidad de manejo de errores.
  • El número de caracteres es positivo. Su programa debe manejar longitudes de hasta 65535. 64k debería ser suficiente para todos :-)
  • El programa genera esas líneas en la salida estándar que cumplen con la idea de la meta propuesta, es decir
    • gana el código más corto de un lenguaje de programación particular (fase de reducción)
    • gana el código más largo entre todos los lenguajes de programación (fase de clasificación)
    • en caso de empate, se imprimirán todas las respuestas con la misma longitud
  • El orden de salida no es importante
  • Aunque el código más largo gana, esto no es . Su código debe ser lo más corto posible para su lenguaje de programación.
  • Las respuestas sobre lenguajes de programación que rara vez no intentan acortar el código merecen un voto negativo, porque intentan evitar la intención de este tipo de preguntas. Si solo hay una respuesta para un lenguaje de programación específico, se consideraría un candidato ganador, por lo que podría comenzar a soplar su código.

Ejemplo de archivo de entrada (separado por pestañas individuales si hubiera algún problema con el formato):

GolfScript  34  http://short.url/answer/ags
GolfScript  42  http://short.url/answer/gsq
C#  210 http://short.url/answer/cs2
Java    208 http://short.url/answer/jav
C#  208 http://short.url/answer/poi
J   23  http://short.url/answer/jsh
Ruby    67  http://short.url/answer/rub
C#  208 http://short.url/answer/yac
GolfScript  210 http://short.url/answer/210

Salida esperada (el orden no es importante):

C#  208 http://short.url/answer/poi
C#  208 http://short.url/answer/yac
Java    208 http://short.url/answer/jav

Actualizar

Algunos programas se basan en el hecho de que hay un solo máximo (como el programa de caracteres C # 210). Derivado de la realidad, alguien también puede escribir un programa GolfScript con 210 caracteres. El resultado sería el mismo. He agregado un GolfScript a la entrada.

Actualización 2

Como sugerí, volví a etiquetar (todavía en código de golf también) y la fecha límite es 2014-03-06 (que parece una fecha arbitraria, pero volveré a Alemania después de viajar).

Resultados finales

Decidí votar de la siguiente manera:

  • Las respuestas en las que no se puede confirmar el número de caracteres reciben un comentario para explicar el recuento.
  • Las respuestas que se pueden reducir fácilmente obtienen un comentario, una sugerencia de edición y van al resultado con el valor de conteo más bajo. (Espero haberlo visto de antemano).
  • Las respuestas que no se compilan obtienen un voto negativo. (Resulta que es una tarea difícil).
  • Las respuestas que no son de golf reciben un voto negativo (como ya se describe en las reglas).
  • Las respuestas que producen el resultado esperado obtienen un voto positivo. Debido a algunas respuestas que no funcionan como se esperaba, utilizo 4 archivos de entrada diferentes y compruebo el resultado esperado.

Finalmente, el ganador se determina al proporcionar la tabla de respuestas de calificación como entrada para mi programa de referencia (además de verificar el resultado manualmente). Si mi propia respuesta fuera la ganadora, la excluiría de la lista. En caso de varios ganadores, tendría que elegir solo uno. Por lo tanto, se pueden ganar algunos bonos:

  • respuestas que aceptan más información de la esperada (por ejemplo, fuera de los rangos definidos)
  • respuestas que usan una idea inteligente de hacerlo corto

Tomé una instantánea de las respuestas el 6 de marzo de 2014, 19:45 UTC + 1. El análisis está en curso. Comprobar todas las respuestas es más difícil de lo esperado ...

Thomas Weller
fuente
¿No debería esto ser etiquetado como desafío de código por ahora? También cuando es la fecha límite?
TheConstructor
2
El nombre
alternativo

Respuestas:

2

Java - 556

import java.util.*;class G{public static void main(String[]x){TreeMap<?,TreeMap>m=new TreeMap();try{Scanner s=new Scanner(System.in);for(;;){String[]a=s.nextLine().split("\t");a(new Long(a[1]),a(a[0],m)).put(a[2],a);}}catch(Exception e){}TreeMap<?,Map<?,String[]>>n=new TreeMap();for(TreeMap o:m.values())a(o.firstEntry().getKey(),n).putAll((Map)o.firstEntry().getValue());for(String[]o:n.lastEntry().getValue().values())System.out.println(o[0]+"\t"+o[1]+"\t"+o[2]);}static<T>Map a(T t,Map m){if(m.get(t)==null)m.put(t,new TreeMap());return(Map)m.get(t);}}

El programa leerá de STDIN.

import java.util.Map;
import java.util.Scanner;
import java.util.TreeMap;

class G {
    public static void main(String[] x) {
        TreeMap<?, TreeMap> m = new TreeMap();
        try {
            Scanner s = new Scanner(System.in);
            for (; ; ) {
                String[] a = s.nextLine().split("\t");
                a(new Long(a[1]), a(a[0], m)).put(a[2], a);
            }
        } catch (Exception e) {
        }
        TreeMap<?, Map<?, String[]>> n = new TreeMap();
        for (TreeMap o : m.values())
            a(o.firstEntry().getKey(), n).putAll((Map) o.firstEntry().getValue());
        for (String[] o : n.lastEntry().getValue().values())
            System.out.println(o[0] + "\t" + o[1] + "\t" + o[2]);
    }

    static <T> Map a(T t, Map m) {
        if (m.get(t) == null)
            m.put(t, new TreeMap());
        return (Map) m.get(t);
    }
}
  1. El programa leerá línea por línea hasta que ocurra una excepción (ya sea ArrayIndexOutOfBoundsExceptioncuando se encuentre una línea en blanco o NoSuchElementExceptionsi la entrada finaliza sin una nueva línea final). Cada línea leída se agrega a TreeMap m, que podría haberse definido como TreeMap<String, TreeMap<Long, TreeMap<String,String[]>>>(de izquierda a derecha: idioma, tamaño de código, URL, entrada).
  2. Luego, se genera un resultado TreeSet<Long, TreeSet<String, String[]>> n(de izquierda a derecha: tamaño de código, URL, entrada) donde firstEntry()se agregan los contenidos de cada idioma .
  3. lastEntry()del agregado TreeMapcontiene nuestro resultado; solo necesitamos imprimirlo.

Pruebe ideone.com (cambió las últimas dos líneas de entrada para mostrar que todas las líneas se leen)

El constructor
fuente
Tuve que agregar una variable para almacenar BufferedReader -.-
TheConstructor
1
Tal vez Java gane esta vez, porque no tiene una palabra clave var ...
Thomas Weller
@ThomasW. acabo de darme cuenta de que dejé algunos {} innecesarios dentro de la versión de golf -.-
TheConstructor
También relaté que estaba usando Integer. Si bien int es más corto que largo, Integer debería jugar golf a Long -.-
TheConstructor
2

Perl, 195 bytes

while(<>){/(\S+)\t(\d+)\t(.+)/;push@{$a{$1}},$3if$2==$l{$1};$l{$1}=$2,$a{$1}=[$3]if $2<($l{$1}//65536)}$m=(sort{$b<=>$a}values%l)[0];map{$l=$_;map{print"$l\t$m\t$_\n"if$l{$l}==$m}@{$a{$l}}}keys%l

Se espera la entrada en STDIN, el resultado se escribe en STDOUT:

C#      208     http://short.url/answer/poi
C#      208     http://short.url/answer/yac
Java    208     http://short.url/answer/jav

Versión sin golf

#!/usr/bin/env perl
use strict;
$^W=1;

# hash %language remembers the minimum count for a language
# %language: <language> => <minimum count>
my %language;
# hash %array remembers the URLs for the minimum count of the language
# %array: <language> => [<url>, <url>, ....]
my %array;

while(<>){
    # parse input line (no error checking)
    /(\S+)\t(\d+)\t(.+)/;
    my ($lang, $count, $url) = ($1, $2, $3);
    # add URL, if the count is the current minimum for the language
    if ($count == ($language{$lang}//0)) {
    # better, but longer version:
    # if (defined $language{$lang} and $count == $language{$lang}) {
        push @{$array{$lang}}, $url;
    }
    # create a new entry for the language, if there is a new minimum
    if ($count < ($language{$lang}//65536)) {
    # better, but longer version:
    # if (not defined $language{$lang} or $count < $language{$lang}) {
        $language{$lang} = $count;
        $array{$lang} = [$url];   
    }
}

# Sort the minimal values in numerical descending order and
# get the first entry as maximum.
my $maximum = (sort { $b <=> $a } values %language)[0];

# Loop over all URLs of minimal answers for the language,
# but print only the entries for the languages with the largest
# minima.
foreach my $lang (keys %language) {
    foreach my $url (@{$array{$lang}}) {
        if ($language{$lang} == $maximum) {
            print "$lang\t$maximum\t$url\n";
        }
    }
}
__END__
Heiko Oberdiek
fuente
Heiko, como señaló @grovesNL, algunos programas podrían basarse en el hecho de que existe un máximo único. Tal vez pueda verificar si su programa se ve afectado. Simplemente agregue una GolfScript 210 http://short.url/answer/210línea a la entrada y vea si la salida sigue siendo la misma. En realidad, creo que el tuyo no se ve afectado, porque estás usando [0] para el máximo, pero no tengo Perl disponible en este momento para intentarlo.
Thomas Weller
@ThomasW .: No se ve afectado. He agregado la línea y la salida sigue siendo la misma. Después de la primera parte que lee el archivo, la estructura de datos %l/ %languagecontiene los idiomas y sus valores mínimos. La estructura de datos %a/ %arraycontiene solo esos pares de idiomas / URL, cuyo valor es el mínimo para este idioma. Luego, los valores mínimos se ordenan en orden descendente y el primero se usa como máximo global y como condición de filtro para %a/ %array.
Heiko Oberdiek
2

Python 378 377 372

import sys
d=__import__("collections").defaultdict(list)
o={}
x=int
n="\n"
for i,l,u in[a.split()for a in sys.stdin.read().strip().split(n)]:d[i]+=[(l,u)]
for e,b in d.items():o[e]=[i for i in b if i[0]==str(min([x(i[0])for i in b]))]
print("".join(n.join("\t".join([u,s[0],s[1]])for s in y if x(s[0])==max(x(i[0][0])for i in o.values()))+n for u,y in o.items()).strip())

Entrada en el stdin:

C:\Users\gcq\Documents\python>type m.txt | python test.py
C#      208     http://short.url/answer/poi
C#      208     http://short.url/answer/yac
Java    208     http://short.url/answer/jav

Y esto es lo que tenía antes de comenzar a comprimirlo, a 551 caracteres:

from collections import defaultdict
import sys
d = defaultdict(list)

for language, length, url in [a.split() for a in sys.stdin.read().strip().split("\n")]:
    d[language].append((length, url))

o = {}
for language, data in d.items():
    winval = data[0][0]
    for i in data:
        if int(i[0]) < int(winval):
            winval = i[0]
    o[language] = [i for i in data if i[0] == winval]

maxlen = max(int(i[0][0]) for i in o.values())

for language, dataa in o.items():
    for data in dataa:
        if int(data[0]) == maxlen:
            print("\t".join([language, data[0], data[1]]))
gcq
fuente
1

C # - 628

Aquí hay una alternativa más larga que usa DataTable:

using Microsoft.VisualBasic.FileIO;namespace System{using T=Data.DataTable;using R=Data.DataRow;using V=Data.DataView;using C=Data.DataColumn;class p{static void Main(string[] a){var I=typeof(Int32);T t=new T();t.Columns.AddRange(new[]{new C("a"),new C("b",I),new C("c"),new C("d",I)});var f=new TextFieldParser(a[0]);f.SetDelimiters("\t");while(!f.EndOfData){var r=t.NewRow();r.ItemArray=f.ReadFields();t.Rows.Add(r);}foreach(R r in t.Rows){r[3]=t.Compute("min(b)","a='"+r[0]+"'");}V v=new V(t);T s=v.ToTable();foreach(R r in s.Select("b='"+t.Compute("max(d)","")+"'")){Console.WriteLine(String.Join("\t",r[0],r[1],r[2]));}}}}

Originalmente pensé que podría haber obtenido una ligera reducción de código al usar max / min con DataTable, pero DataTabledesafortunadamente los tipos necesarios para construir (filas / columnas / vista) agregan mucha longitud. Soy nuevo en el código de golf, por lo que tal vez alguien podría reducirlo aún más. Sigue siendo un desafío divertido.

grovesNL
fuente
1

dg - 286 281 260 251 218 bytes

import '/sys'
d=dict!
for(a,b,c)in(map str.split$(sys.stdin.read!).splitlines!)=>d!!a=(d.get a list!)+(list'(int b,c))
for(i,l)in(d.items!)=>for(s,u)in l=>s==(max$map(i->fst$min i)d.values!)=>print$i+' '+(str s)+' '+u

Ejemplo:

$ cat langs.txt | dg langs.dg 
C# 208 http://short.url/answer/poi
C# 208 http://short.url/answer/yac
Java 208 http://short.url/answer/jav

Versión sin golf :

import '/sys'

s = sys.stdin.read!
d = dict!
# convert the string into a list of tuples (name, score, url)
u = map str.split $ s.splitlines!
# add all the values to the dict (converting the score to an integer)
for (a, b, c) in u =>
  d!!a = (d.get a list!) + (list' (int b, c))
# computes the maximum value amongst the mins
m = max $ map (i -> fst $ min i) d.values!
for (i, l) in (d.items!) =>
  for (s, u) in l =>
    # if the score equals the maximum then print all the line
    s == m => print $ i + ' ' + (str s) + ' ' + u  # actually here .format()
                                                   # would be better

Q: ¿Qué diablos es dg?
R: Un lenguaje de programación que compila a bytecode CPython, al igual que Scala compila a JVM. Eso esencialmente significa que dg es una sintaxis alternativa para Python 3. También le permite usar todas las bibliotecas existentes.

Más información aquí (¡incluso un tutorial!): Https://pyos.github.io/dg

rubik
fuente
Si pongo eso en un archivo, solo tiene 217 bytes (terminaciones de línea de Linux)
Thomas Weller
@ThomasW. ¡Extraño! Usando cat langs.dg | wc -cconsigo 218!
rubik
¿Quizás nueva línea final versus ninguna nueva línea final?
TheConstructor
@TheConstructor podría ser, aunque no debería guardarlo con una nueva línea oO
rubik
1

Rebol - 314

d: map[]foreach r read/lines to-file system/script/args[r: split r tab p: take r r/1: to-integer r/1 r/2: reduce[r/2]either none? d/:p[repend d[p r]][case[d/:p/1 > r/1[d/:p: r]d/:p/1 = r/1[append d/:p/2 r/2]]]]l: 0 foreach[k v]d[l: max l v/1]foreach[k v]d[if l = v/1[foreach n v/2[print rejoin[k tab v/1 tab n]]]]

sin golf

d: map []

foreach r read/lines to-file system/script/args [
    r: split r tab
    p: take r
    r/1: to-integer r/1
    r/2: reduce [r/2]
    either none? d/:p [repend d [p r]] [
        case [
            d/:p/1 > r/1 [d/:p: r]
            d/:p/1 = r/1 [append d/:p/2 r/2]
        ]
    ]
]

l: 0 foreach [k v] d [l: max l v/1]
foreach [k v] d [
    if l = v/1 [
        foreach n v/2 [print rejoin [k tab v/1 tab n]]
    ]
]

Ejemplo de uso:

$ rebol script.reb data.txt
C#    208   http://short.url/answer/poi
C#    208   http://short.url/answer/yac
Java  208   http://short.url/answer/jav
draegtun
fuente
0

C # - 515

Espera un nombre de archivo como argumento

using System.Collections.Generic;namespace N{using S=SortedList<int,T>;class T:List<string>{static void Main(string[]a){var d=new Dictionary<string,S>();int n,m=0;T w=new T();foreach(var l in System.IO.File.ReadAllLines(a[0])){var p=(a=l.Split('\t'))[0];n=int.Parse(a[1]);if(!d.ContainsKey(p))d.Add(p,new S());if(!d[p].ContainsKey(n))d[p].Add(n,new T());d[p][n].Add(l);}foreach(var e in d){n=e.Value.Keys[0];if(n==m)w.AddRange(e.Value[n]);if(n>m)w=e.Value[m=n];}foreach(var e in w)System.Console.WriteLine(e);}}}

Primero diseñé mi programa C # para que fuera sencillo, porque quería tener una especie de programa de referencia. Pero luego decidí también saltar al concurso y jugar golf. Esta es una de las versiones anteriores del código + algunos comentarios:

// N: namespace
// P: Program
// S: type definition: sorted dictionary
// a: arguments
// d: data container
// r: lines read from text file
// l: single line from r
// t: tabbed part of l after splitting
// p: programming language name
// n: character count
// m: maximum character count
// w: list of winners
// e: entry in data container
// c: winner candidate
using System.Collections.Generic;
namespace N
{
    using S = SortedList<int, P>;
    public class P : List<string>
    {
        public static void Main(string[] a)
        {
            var r = System.IO.File.ReadAllLines(a[0]);
            // Make it a data structure
            var d = new Dictionary<string, S>();
            foreach (var l in r)
            {
                var t = l.Split('\t');
                var p = t[0];
                var n = int.Parse(t[1]);
                if (!d.ContainsKey(p)) d.Add(p, new S());
                if (!d[p].ContainsKey(n)) d[p].Add(n, new P());
                d[p][n].Add(l);
            }
            // Get the maximum values
            var m = 0;
            P w = null;
            foreach (var e in d)
            {
                foreach (var s in e.Value.Keys)
                {
                    if (s > m)
                    {
                        w = e.Value[s];
                        m = s;
                    }
                    else if (s == m)
                    {
                        w.AddRange(e.Value[s]);
                    }
                    break; // Break here to get the shortest solution per language
                }
            }
            // Print everything on console
            foreach (var e in w)
            {
                System.Console.WriteLine(e);
            }
        }
    }
}
Thomas Weller
fuente
Parece que el tamaño del archivo 515 en mi disco incluye una marca de orden de bytes. Copiar / pegar desde aquí es de solo 512 bytes.
Thomas Weller
0

C # - 460 359

Después de darme cuenta de lo voluminosa DataTableque era mi solución, creé el siguiente ejemplo usando Linq. Utiliza la misma metodología que mi solución anterior.

Golfed

namespace System{using Linq;using IO;class p{static void Main(string[]i){var l=(from f in File.ReadAllLines(i[0])let s=f.Split('\t')select new Tuple<string,int,string>(s[0],Convert.ToInt16(s[1]),f)).ToList();foreach(var f in l.Where(a=>a.Item2==l.Where(b=>b.Item1==l.Single(c=>c.Item2==l.Max(d=>d.Item2)).Item1).Min(e=>e.Item2)))Console.WriteLine(f.Item3);}}}

Sin golf

namespace System
{
    using Linq;
    using IO;
    class p
    {
        static void Main(string[]i)
        {
            var l=(from f in File.ReadAllLines(i[0])
                   let s=f.Split('\t')
                   select new Tuple<string, int, string>(s[0],Convert.ToInt16(s[1]),f)).ToList();
            foreach(var f in l.
                Where(a=>a.Item2==l.
                    Where(b=>b.Item1==l.
                        Single(c=>c.Item2==l.
                            Max(d=>d.Item2)).Item1).
                                Min(e=>e.Item2)))
            Console.WriteLine(f.Item3);
        }
    }
}

Todavía soy bastante nuevo en Linq, así que estoy casi seguro de que esas expresiones se pueden reducir aún más.

De su pregunta, no está claro si hay una única solución de longitud máxima. Para mis respuestas, he usado la suposición de que hay un único punto máximo (es decir, si también hubo un máximo de GolfScript de 210, puede fallar en función del registro máximo único devuelto). La solución de Heiko tendría el mismo problema. Para solucionar esto, tendríamos que agregar otro paso que contuviera una lista de máximos vinculados para verificar los mínimos para cada idioma.

grovesNL
fuente
1
Me parece que podría guardar f como Item3 (en lugar de s [2]) y luego escribir f.Item3 en la Consola sin la necesidad de recombinar Item1 e Item2.
Thomas Weller
Gracias por la aclaración de los requisitos. Derivado de la realidad, diría que podría suceder que alguien (sin experiencia, obviamente) escriba un GolfScript con 210 caracteres.
Thomas Weller
1
Si convierte el primer bucle foreach a LINQ, se vuelve aún más corto:namespace System{using Linq;using IO;class p{static void Main(string[]i){var l=(from f in File.ReadAllLines(i[0])let s=f.Split('\t') select new Tuple<string, int, string>(s[0],Convert.ToInt16(s[1]),f)).ToList();foreach(var f in l.Where(a=>a.Item2==l.Where(b=>b.Item1==l.Single(c=>c.Item2==l.Max(d=>d.Item2)).Item1).Min(e=>e.Item2)))Console.WriteLine(f.Item3);}}}
Thomas Weller
@ThomasW .: Buena idea para la división. Gracias por la conversión del bucle foreach, había pensado en agregarla originalmente, pero no sabía que podía usar let de esa manera.
grovesNL
Creo que empiezo a entender lo que su consulta no :) y también fallar por la entrada simple como esto: Golfscript 100 ..., C# 1 ..., C# 200 .... Probablemente esto necesite un poco de retrabajo
Thomas Weller
0

C ++ - 535

Solo generará las respuestas vinculadas para la posición más larga después de seleccionar solo las respuestas más cortas de cada idioma como posibles ganadores.

#include<fstream>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(){

    string s;
    vector<string>l;
    vector<int>v;
    vector<string>u;
    cin>>s;

    ifstream i(s.c_str());

    do{
        int n;
        i>>s;
        if(i.eof())break;
        l.push_back(s);
        i>>n;
        v.push_back(n);
        i>>s;
        u.push_back(s);
    }while(1);

    for(int i=0;i<l.size();i++){
        for(int j=0;j<l.size();j++){
            if(l[j]==l[i]){
                if(v[i]>v[j])l[i]="";
                else if(v[i]<v[j])l[j]="";
            }
        }
    }
    int n=0;
    for(int i=0;i<v.size();i++)
        if(n<v[i]&l[i]!="")n=v[i];

    for(int i=0;i<v.size();i++)
        if(v[i]==n)cout<<l[i]<<'\t'<<v[i]<<'\t'<<u[i]<<endl;
}

Golfizado (no tan ilegible como algunos idiomas):

#include<fstream>
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main(){string s;vector<string>l;vector<int>v;vector<string>u;cin>>s;ifstream i(s.c_str());do{int n;i>>s;if(i.eof())break;l.push_back(s);i>>n;v.push_back(n);i>>s;u.push_back(s);}while(1);for(int i=0;i<l.size();i++)for(int j=0;j<l.size();j++)if(l[j]==l[i]){if(v[i]>v[j])l[i]="";else if(v[i]<v[j])l[j]="";}int n=0;for(int i=0;i<v.size();i++)if(n<v[i]&l[i]!="")n=v[i];for(int i=0;i<v.size();i++)if(v[i]==n)cout<<l[i]<<'\t'<<v[i]<<'\t'<<u[i]<<endl;}

fuente
¿Ha verificado su salida con la salida esperada? Con 8 líneas de entrada, dará solo 3 líneas como salida. Su programa parece dar salida a todo.
Thomas Weller
@ThomasW. Oh, entendí mal esa parte. Lo eliminaré por ahora.
@ThomasW. ¿Esto se ve bien?
Si pongo eso en un archivo, obtengo 540 bytes, no 535. ¿Podría verificar la longitud, por favor?
Thomas Weller
Tiene 535 caracteres. Los dos estamos en lo correcto. Puedo cambiarlo si quieres.