Вид мета: отримайте найдовший із найкоротших відповідей


14

Ваше завдання - якщо ви приймаєте це - написати програму, яка допоможе зрозуміти мою пропозицію щодо мета шляхом підрахунку переможця змагань, . Звичайно, відповіді на це питання будуть розглядатися як запропоновано, тому ваша програма (якщо вона правильна) зможе розрахувати, чи стане ваша відповідь прийнятою відповіддю.

Правила

  • Програма читає файл із кількома рядками наступного формату (див. Приклад нижче): [Мова] TAB [NumberOfCharacters] TAB [LinkToAnswer]
  • Ім'я файлу передається як аргумент вашій програмі або файл перенаправляється на стандартний вхід вашої програми. Це ваш вибір, будь ласка, зазначте метод, коли даєте відповідь
  • Очікується, що формат введення правильний. Немає необхідності в обробці помилок.
  • Кількість символів додатна. Ваша програма повинна обробляти довжину до 65535. 64 к. Має вистачити на всіх :-)
  • Програма виводить ті рядки на стандартному виході, які відповідають ідеї мета-пропозиції, тобто
    • виграє найкоротший код певної мови програмування (фаза скорочення)
    • виграє найдовший код серед усіх мов програмування (фаза сортування)
    • у разі жеребкування всі відповіді з однаковою довжиною надрукуються
  • Порядок виводу не важливий
  • Хоча виграє найдовший код, це не . Ваш код повинен бути якомога коротшим для вашої мови програмування.
  • Відповіді на рідкісні мови програмування, які не намагаються скоротити код, заслуговують скорочення, оскільки вони намагаються обійти наміри подібного роду питань. Якщо є лише одна відповідь на певну мову програмування, вона вважатиметься кандидатом-переможцем, тож ви можете почати демонструвати її код.

Приклад вхідного файлу (відокремлений окремими вкладками, якщо має бути проблема з форматуванням):

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

Очікуваний вихід (порядок не важливий):

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

Оновлення

Деякі програми покладаються на те, що існує єдиний максимум (наприклад, програма символів C # 210). Отриманий з реальності, хтось також може написати програму GolfScript з 210 символами. Вихід залишився б колишнім. Я додав такий GolfScript у вхід.

Оновлення 2

Як було запропоновано, я переназначив (як і раніше код-гольф), а кінцевий термін - 2014-03-06 (це схоже на довільну дату, але я повернуся до Німеччини з поїздки тоді).

Кінцеві результати

Я вирішив проголосувати наступним чином:

  • У відповідях, де кількість символів не може бути підтверджено, отримайте коментар для пояснення кількості.
  • Відповіді, які легко зменшити, отримують коментар, пропозицію щодо редагування та переходять до результату із меншим значенням підрахунку. (Сподіваюся, я це бачив заздалегідь).
  • Відповіді, які не складаються, отримують зворотну оцінку. (Досить важке завдання, як виявляється).
  • Відповіді, які не займаються гольфом, отримують знижку (як це вже описано в правилах).
  • Відповіді, які дають очікуваний вихід, отримують репутацію. Через деякі відповіді, які працюють не так, як очікувалося, я використовую 4 різні вхідні файли та перевіряю очікуваний результат.

Нарешті, переможець визначається, надаючи таблицю кваліфікованих відповідей як вхід до моєї довідкової програми (плюс подвійну перевірку результату вручну). Якщо моя власна відповідь була б виграшною, я виключив би її зі списку. У випадку кількох переможців, мені доведеться вибрати лише одного. Тому деякі бонуси можна заробити:

  • відповіді, які приймають більше введення, ніж очікувалося (наприклад, поза визначеними діапазонами)
  • відповіді, в яких використовується розумна ідея зробити її короткою

Я зробив знімок відповідей 6 березня 2014 року, 19:45 UTC + 1. Аналіз триває. Перевірити всі відповіді важче, ніж очікувалося ...


Не слід наразі це тегувати код-виклик ? Також коли закінчується термін?
TheConstructor

2
Alt-name для цього - Code-Blackjack
VoronoiPotato

Відповіді:


2

Ява - 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);}}

Програма читатиметься від 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. Програма буде читати рядок за рядком до тих пір, поки не буде включено виняток (або ArrayIndexOutOfBoundsExceptionколи зустрічається порожній рядок, або NoSuchElementExceptionякщо введення закінчується без закінчення нового рядка) Кожен прочитаний рядок додається до TreeMap m, що можна було б визначити як TreeMap<String, TreeMap<Long, TreeMap<String,String[]>>>(зліва направо: мова, розмір коду, URL, введення).
  2. Тоді будується результат TreeSet<Long, TreeSet<String, String[]>> n(зліва направо: розмір коду, URL, введення), де вміст усіх мов firstEntry()агрегується.
  3. lastEntry()із зведеного TreeMapмістить наш результат - нам потрібно лише роздрукувати його.

Спробуйте на ideone.com (переключив останні два рядки введення, щоб показати, що всі рядки прочитані)


Довелося додати змінну для зберігання BufferedReader -.-
TheConstructor

1
Можливо, Java перемагає цього разу, оскільки у нього немає ключового слова var ...
Thomas Weller

@ThomasW. щойно зрозумів, що я залишив зайве {} всередині версії для гольфу -.-
TheConstructor

Крім того, просто релізоване я використовував Integer. Хоча int коротший, ніж довгий, Integer, безумовно, повинен бути в гольф до Long -.-
TheConstructor

2

Perl, 195 байт

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

Вхід очікується в STDIN, результат записується в STDOUT:

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

Безгольова версія

#!/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__

Як зазначав @grovesNL, Хайко, деякі програми можуть покладатися на те, що існує єдиний максимум. Можливо, ви можете перевірити, чи впливає ваша програма. Просто додайте GolfScript 210 http://short.url/answer/210рядок до вхідного сигналу і подивіться, чи не залишиться результат таким же. Насправді я думаю, що на вас це не впливає, тому що ви використовуєте [0] максимум, але на даний момент у мене немає Perl, щоб спробувати.
Томас Веллер

@ThomasW. Це не впливає. Я додав рядок і вихід залишається тим самим. Після першої частини, яка читає файл, структура даних %l/ %languageмістить мови та їх мінімальні значення. Структура даних %a/ %arrayмістить лише ті мовні / URL-адреси, значення яких є мінімальними для цієї мови. Потім мінімальні значення сортуються у порядку зменшення, а перше використовується як глобальний максимум та як фільтр для %a/ %array.
Хайко Обердік

2

Пітон 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())

Введення на 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

І ось що я мав перед тим, як почати його стискати, на 551 символі:

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]]))

1

C # - 628

Ось ваша довша альтернатива, яка використовує 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]));}}}}

Спочатку я вважав, що, можливо, я отримав незначне скорочення коду від використання max / min з DataTable, але типи, необхідні для побудови DataTable(рядки / стовпці / перегляд), додають велику довжину, на жаль. Я новачок в коді гольфу, тому, можливо, хтось зможе його ще більше зменшити. Все-таки цікаве завдання.


1

дг - 286 281 260 251 218 байт

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

Приклад:

$ 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

Негольована версія:

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

Питання: Що, до біса, dg?
A: Мова програмування, що компілюється в байт-код CPython, подібно до того, як Scala компілюється в JVM. Це по суті означає, що dg є альтернативним синтаксисом для Python 3. Це дозволяє також використовувати всі існуючі бібліотеки.

Більше інформації тут (навіть підручник!): Https://pyos.github.io/dg


Якщо я поміщую це у файл, він має лише 217 байт (закінчення рядків Linux)
Thomas Weller

@ThomasW. Дивно! Використовуючи cat langs.dg | wc -cя отримую 218!
rubik

Можливо, трейлінг нового рядка проти відсутнього трейлінг нового рядка?
TheConstructor

@TheConstructor це може бути, хоча це не повинно врятувати його новим рядком oO
rubik

1

Ребол - 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]]]]

без гольфу

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]]
    ]
]

Приклад використання:

$ 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

0

C # - 515

Очікує ім'я файлу як аргумент

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

Спочатку я сконструював свою програму C # прямою, тому що хотів мати якусь довідкову програму. Але потім я вирішив також стрибнути на змагання і пограв у нього. Це одна з більш ранніх версій коду + деякі коментарі:

// 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);
            }
        }
    }
}

Здається, розмір файлу 515 на моєму диску містив позначку порядку байтів. Скопіювати / вставити звідси всього 512 байт.
Томас Веллер

0

C # - 460 359

Після розуміння, як громіздкий мій DataTable рішення, я створив наступний приклад, використовуючи Linq. Він використовує ту саму методологію, що і попереднє рішення.

Гольф

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

Безумовно

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

Я все ще досить новачок у Linq, тому я майже впевнений, що вирази можна зменшити ще більше.

З вашого запитання незрозуміло, чи є рішення щодо однієї максимальної довжини. Для моїх відповідей я використав припущення про те, що є одна максимальна точка (тобто, якщо був і GolfScript максимум 210, він може не виходити з огляду на повернення єдиного максимального запису). Рішення Хейко матиме те саме питання. Щоб виправити це, нам доведеться додати ще один крок, який містив список прив’язаних максимумів, щоб перевірити мінімуми для кожної мови.


1
Мені здається, ви можете зберегти f як Item3 (замість s [2]), а потім написати f.Item3 в консоль без необхідності повторно комбінувати Item1 та Item2.
Томас Веллер

Дякуємо за уточнення вимог. Отриманий з реальності, я б сказав, що може статися так, що хтось (недосвідчений, очевидно) пише GolfScript з 210 символами.
Томас Веллер

1
Якщо ви перетворите перший цикл foreach в LINQ, він стає ще коротшим: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.: Гарна ідея для розколу. Дякую за перетворення циклу foreach, я подумав про це, додавши, що спочатку, але я не знав, що можу використати нехай так.
grovesNL

Я думаю , що я починаю розуміти , що ваш запит робить :) , і це також не буде для спрощення введення , як це: Golfscript 100 ..., C# 1 ..., C# 200 .... Це, мабуть, потребує певної переробки
Томас Веллер

0

C ++ - 535

Виводитимуть відповіді, пов'язані для найдовшої позиції, лише після вибору лише найкоротших відповідей кожної мови як потенційних переможців.

#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;
}

Гольф (не такий читабельний, як деякі мови):

#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;}

Ви перевірили ваш вихід із очікуваним результатом? З 8 рядків введення, він повинен дати лише 3 рядки як вихід. Наче ваша програма видає все.
Томас Веллер

@ThomasW. О, я неправильно зрозумів цю частину. Я її зараз видалю.

@ThomasW. Це правильно виглядає?

Якщо я вкладу це у файл, я отримаю 540 байт, а не 535. Чи можете ви двічі перевірити довжину?
Томас Веллер

Це 535 символів. Ми обоє правильні. Я можу це змінити, якщо хочете.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.