Создание таблицы ASCII наиболее часто используемых слов в данном тексте [закрыто]

avatar
ChristopheD
2 июля 2010 в 20:54
36728
59
156

Задача:

Создайте таблицу ASCII наиболее часто используемых слов в данном тексте.

Правила:

  • Принимайте только a-z и A-Z (буквенные символы) как часть слова.
  • Игнорировать корпус (She == she для нашей цели).
  • Игнорируйте следующие слова (я знаю, это произвольно): the, and, of, to, a, i, it, in, or, is
  • Уточнение: учитывая don't: это будет восприниматься как 2 разных «слова» в диапазонах a-z и A-Z: (don и t).

  • При желании (сейчас уже слишком поздно формально изменять спецификации) вы можете удалить все однобуквенные «слова» (это потенциально может привести к сокращение списка игнорирования).

Проанализируйте данный text (прочтите файл, указанный с помощью аргументов командной строки или переданный по конвейеру; предположим, us-ascii) и создайте нам word frequency chart со следующими характеристиками:

  • Отобразите диаграмму (см. Также пример ниже) для 22 наиболее употребительных слов (в порядке убывания частоты).
  • Полоса width представляет количество вхождений (частоту) слова (пропорционально). Добавьте один пробел и выведите слово.
  • Убедитесь, что эти полосы (плюс пробел-слово-пробел) всегда соответствуют : bar + [space] + word + [space] всегда должны быть <= 80 символы убедитесь, что вы учитываете возможные различия в длине полос и слов: например: второе наиболее распространенное слово может быть намного длиннее первого, но не сильно различается по частоте). Увеличьте до ширину полосы в пределах этих ограничений и соответствующим образом масштабируйте полосы (в соответствии с частотами, которые они представляют).

Пример:

Текст для примера можно найти здесь ( Приключения Алисы в стране чудес, Льюис Кэрролл ).

Этот конкретный текст даст следующую диаграмму:

 _________________________________________________________________________
|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|____________________________________________________| alice 
|______________________________________________| was 
|__________________________________________| that 
|___________________________________| as 
|_______________________________| her 
|____________________________| with 
|____________________________| at 
|___________________________| s 
|___________________________| t 
|_________________________| on 
|_________________________| all 
|______________________| this 
|______________________| for 
|______________________| had 
|_____________________| but 
|____________________| be 
|____________________| not 
|___________________| they 
|__________________| so 


Для вашего сведения: это частоты, на которых построена приведенная выше диаграмма:

[('she', 553), ('you', 481), ('said', 462), ('alice', 403), ('was', 358), ('that
', 330), ('as', 274), ('her', 248), ('with', 227), ('at', 227), ('s', 219), ('t'
, 218), ('on', 204), ('all', 200), ('this', 181), ('for', 179), ('had', 178), ('
but', 175), ('be', 167), ('not', 166), ('they', 155), ('so', 152)]

Второй пример (чтобы проверить, реализовали ли вы полную спецификацию): Замените каждое появление you в связанном файле Алиса в стране чудес на superlongstringstring:

 ________________________________________________________________
|________________________________________________________________| she 
|_______________________________________________________| superlongstringstring 
|_____________________________________________________| said 
|______________________________________________| alice 
|________________________________________| was 
|_____________________________________| that 
|______________________________| as 
|___________________________| her 
|_________________________| with 
|_________________________| at 
|________________________| s 
|________________________| t 
|______________________| on 
|_____________________| all 
|___________________| this 
|___________________| for 
|___________________| had 
|__________________| but 
|_________________| be 
|_________________| not 
|________________| they 
|________________| so 

Победитель:

Кратчайшее решение (по количеству символов для каждого языка). Удачи!


Изменить : Таблица, суммирующая результаты на текущий момент (2012-02-15) (первоначально добавлена ​​пользователем Насом Бановым):

Language          Relaxed  Strict
=========         =======  ======
GolfScript          130     143
Perl                        185
Windows PowerShell  148     199
Mathematica                 199
Ruby                185     205
Unix Toolchain      194     228
Python              183     243
Clojure                     282
Scala                       311
Haskell                     333
Awk                         336
R                   298
Javascript          304     354
Groovy              321
Matlab                      404
C#                          422
Smalltalk           386
PHP                 450
F#                          452
TSQL                483     507

Числа представляют длину кратчайшего решения на определенном языке. «Строгое» относится к решению, которое полностью реализует спецификацию (рисует |____| столбцов, закрывает первую полосу сверху строкой ____, учитывает вероятность появления длинных слов с высокой частотой и т. Д.). «Расслабленный» означает, что были приняты некоторые вольности, чтобы сократить время до решения.

Включены только решения, длина которых меньше 500 символов. Список языков отсортирован по длине «строгого» решения. «Unix Toolchain» используется для обозначения различных решений, в которых используется традиционная оболочка * nix плюс сочетание инструментов (таких как grep, tr, sort, uniq, head, perl, awk).

Источник
Brian
2 июля 2010 в 20:57
0

Спецификация: как решить, какого размера делать стержни? Например. я думаю, что все полосы длиной в 1 пробел подойдут к спецификации?

Brian
2 июля 2010 в 20:58
0

Спецификация: я предполагаю, что мы можем предположить, что ни одно слово длиной более 80 символов не будет одним из самых частых (например, все слова имеют разумную длину).

ChristopheD
2 июля 2010 в 20:59
0

@Brian: хорошие моменты, немного отредактирую (надеюсь), чтобы прояснить.

dmckee --- ex-moderator kitten
2 июля 2010 в 21:01
0

@Brian: кажется, что длина самого длинного столбца указана точно, а остальные должны масштабироваться, не так ли?

Brian
2 июля 2010 в 21:04
4

Что ж, «самая длинная полоса» + слово = 80 может не поместиться в 80 столбцов, если второе по частоте слово - гораздо более длинное слово. Я думаю, ищу «максимальное ограничение».

Brian
2 июля 2010 в 21:04
1

Нормализуем ли мы обсадную колонну? «Она» = «она»?

Brian
2 июля 2010 в 21:05
0

Вместо черного списка, например. «игнорировать пунктуацию» (в настоящее время учитываются дефисы, числа и т. д.), можем ли мы просто занести в белый список алфавиты (a-z, A-Z)?

ChristopheD
2 июля 2010 в 21:06
0

@ Брайан, dmckee: это идея да; 1. масштабируйте полосы в соответствии с частотами, которые они представляют) и 2. максимизируйте ширину полосы в пределах ограничения (полоса + пробел + слово + пробел) <= 80. Надеюсь, теперь спецификация стала яснее ...

ChristopheD
2 июля 2010 в 21:09
0

@ Брайан: было бы лучше, я немного обновлю спецификацию

ChristopheD
2 июля 2010 в 21:13
0

@Brian: регистр можно игнорировать: She == she

Frank Farmer
2 июля 2010 в 22:17
2

ИМО делает это, как с точки зрения времени выполнения, так и использования памяти, кажется более интересной задачей, чем количество символов.

indiv
2 июля 2010 в 22:23
81

Рад видеть, что представлены мои любимые слова s и t.

JSBձոգչ
2 июля 2010 в 22:25
1

@ Фрэнк, да, но тогда это был бы не кодовый гольф.

ChristopheD
2 июля 2010 в 22:26
1

@indiv: смешно ;-) (хотя сейчас немного поздно менять спецификацию; уже 3 решения ;-)

Nas Banov
3 июля 2010 в 02:03
0

@ChristopheD: измените его на "не считать слова длиной 1", это позаботится о 's' и 't', а также 'i' и 'a'. Кажется, 15 голосов до сих пор не согласны с тем, что уже слишком поздно

hobbs
3 июля 2010 в 06:40
8

@indiv, @Nas Banov - глупый, слишком простой токенизатор читает "не" как {didn, t} и "she's" как {she, s} :)

Joey
3 июля 2010 в 12:07
0

Что должно произойти с конечным пробелом? В вашем примере выходных данных он есть в каждой строке, однако я прочитал ограничение на длину стержня, как будто оно должно быть включено только для целей расчета. Так следует ли выводить конечный пробел в каждой строке?

ChristopheD
3 июля 2010 в 12:16
0

@Johannes Rössel: не стесняйтесь писать конечный пробел (в большинстве решений их нет), я немного отредактирую вопрос.

ChristopheD
3 июля 2010 в 12:27
0

@indiv, @Nas Banov: обновлены спецификации, чтобы разрешить (необязательно) отбрасывание односимвольных слов.

Nas Banov
3 июля 2010 в 18:10
0

@Johannes Rössel: я думаю, что логически конечное пространство не должно быть включено в вывод, потому что в противном случае следующая новая строка (в позиции 80) приведет к пропуску пустой строки / строки.

Gabe
3 июля 2010 в 19:25
0

Действительно ли в спецификации должно быть сказано «делайте все строчными буквами», или этого достаточно, чтобы «она» и «она» отображались в том же контейнере, как вы сказали Брайану?

ChristopheD
3 июля 2010 в 19:30
0

@Gabe: хороший момент (хотя результаты не должны отличаться), я немного обновлю спецификацию.

Gabe
3 июля 2010 в 19:39
0

Спасибо. Я просто хотел убедиться, что не имеет значения, печатаю ли я «она» или «Она», при условии, что у него есть полоса правильной длины.

ChristopheD
3 июля 2010 в 21:40
0

@LiraNuna: спасибо! Но в следующий раз я позабочусь о том, чтобы мои спецификации были более жесткими и недвусмысленными, прежде чем публиковать ;-)

gnarf
3 июля 2010 в 22:14
0

Вам действительно следует предоставить тестовый пример, который решает проблему с длиной стержня ... Кажется, здесь довольно много ответов, которые не принимают это во внимание ...

ChristopheD
3 июля 2010 в 22:40
0

@gnarf: около часа назад я добавил второй пример вывода (этого будет достаточно?). Мне жаль, что я не предоставил этот образец вывода, когда я разместил вопрос, хотя он уже был сформулирован в спецификации с самого начала. Через несколько дней я сделаю рейтинг ASCII (количество символов - язык - пользователь - реализована полная спецификация). Реализация этого масштабирования bar+word обычно требует около 50/60 дополнительных символов.

gnarf
3 июля 2010 в 23:20
0

@ChrisopheD - извините, пропустил часть sed 's/\byou\b/superlongstring/gI' 11.txt ... :)

Joey
4 июля 2010 в 10:29
0

Хм, забавная викторина: какие реализации правильно обрабатывают "foo_the" во входной строке? Согласно спецификации должно остаться только foo. Однако несколько реализаций разделения на основе регулярных выражений (включая мою) дают foo и the (я собираюсь исправить это, но это также может быть довольно распространенной ошибкой). [И да, здесь масштабирование полосы составляет ровно 50 дополнительных символов ;-)]

Joey
4 июля 2010 в 12:39
0

Хм, я еще раз: что мы можем предположить о вводе (кроме ASCII и ни одного слова не длиннее 75 символов)? Сколько там хотя бы слов? Сколько отдельных слов существует хотя бы?

Gabe
4 июля 2010 в 15:22
0

Вы действительно можете предположить, что слово не может быть длиннее 75 символов? Я бы только предположил, что ни одно слово в топ-22 не будет таким длинным, но вы можете представить строку из звездочек или О.

ChristopheD
4 июля 2010 в 18:44
0

@Johannes Rössel: учитывая забавную викторину: foot_the должны стать двумя отдельными словами (foo и the) в духе четвертого пункта в спецификации. Я знаю, что он не идеален, но спецификации уже на высоте.

ChristopheD
4 июля 2010 в 18:46
0

@Johannes Rössel, Гейб: вы действительно можете с уверенностью предположить, что ни одно слово во вводе не длиннее 75 символов (для этого кода-гольфа) и что существует как минимум 22 разных слова.

kriss
5 июля 2010 в 02:28
0

Где в спецификациях просят написать первую полосу (ту, что без слов). Многие решения реализуют это, чтобы оно выглядело как приведенный образец диаграммы, но, похоже, этого не спрашивают.

Almo
26 апреля 2012 в 20:11
0

Кто-нибудь может сделать это в LOLCODE? Это выглядело бы действительно забавно.

Ответы (59)

avatar
20 июня 2020 в 09:12
1

Python, 320 символов

import sys
i="the and of to a i it in or is".split()
d={}
for j in filter(lambda x:x not in i,sys.stdin.read().lower().split()):d[j]=d.get(j,0)+1
w=sorted(d.items(),key=lambda x:x[1])[:-23:-1]
m=sorted(dict(w).values())[-1]
print" %s\n"%("_"*(76-m)),"\n".join(map(lambda x:("|%s| "+x[0])%("_"*((76-m)*x[1]/w[0][1])),w))
avatar
BalusC
20 июня 2020 в 09:12
2

Java - 991 символ (включая символы новой строки и отступы)

Я взял код @seanizer, исправил ошибку (он пропустил первую строку вывода), внес некоторые улучшения, чтобы сделать код более «мягким».

import java.util.*;
import java.util.regex.*;
import org.apache.commons.io.IOUtils;
public class WF{
 public static void main(String[] a)throws Exception{
  String t=IOUtils.toString(new java.net.URL(a[0]).openStream());
  class W implements Comparable<W> {
   String w;int f=1;W(String W){w=W;}public int compareTo(W o){return o.f-f;}
   String d(float r){char[]c=new char[(int)(f/r)];Arrays.fill(c,'_');return "|"+new String(c)+"| "+w;}
  }
  Map<String,W>M=new HashMap<String,W>();
  Matcher m=Pattern.compile("\\b\\w+\\b").matcher(t.toLowerCase());
  while(m.find()){String w=m.group();W W=M.get(w);if(W==null)M.put(w,new W(w));else W.f++;}
  M.keySet().removeAll(Arrays.asList("the,and,of,to,a,i,it,in,or,is".split(",")));
  List<W>L=new ArrayList<W>(M.values());Collections.sort(L);int l=76-L.get(0).w.length();
  System.out.println(" "+new String(new char[l]).replace('\0','_'));
  for(W w:L.subList(0,22))System.out.println(w.d((float)L.get(0).f/(float)l));
 }
}

Вывод:

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| with
|_____________________________| at
|____________________________| s
|____________________________| t
|__________________________| on
|__________________________| all
|_______________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so

Sean Patrick Floyd
3 июля 2010 в 06:18
1

new String(new char[l]).replace('\0','_') это хороший трюк, чтобы запомнить, спасибо.

avatar
6502
20 июня 2020 в 09:12
7

Общий LISP, 670 символов

Я новичок в LISP, и это попытка использовать хеш-таблицу для подсчета (так что, вероятно, не самый компактный метод).

(flet((r()(let((x(read-char t nil)))(and x(char-downcase x)))))(do((c(
make-hash-table :test 'equal))(w NIL)(x(r)(r))y)((not x)(maphash(lambda
(k v)(if(not(find k '("""the""and""of""to""a""i""it""in""or""is"):test
'equal))(push(cons k v)y)))c)(setf y(sort y #'> :key #'cdr))(setf y
(subseq y 0(min(length y)22)))(let((f(apply #'min(mapcar(lambda(x)(/(-
76.0(length(car x)))(cdr x)))y))))(flet((o(n)(dotimes(i(floor(* n f)))
(write-char #\_))))(write-char #\Space)(o(cdar y))(write-char #\Newline)
(dolist(x y)(write-char #\|)(o(cdr x))(format t "| ~a~%"(car x))))))
(cond((char<= #\a x #\z)(push x w))(t(incf(gethash(concatenate 'string(
reverse w))c 0))(setf w nil)))))

можно запустить, например, с cat alice.txt | clisp -C golf.lisp.

В читаемой форме:

(flet ((r () (let ((x (read-char t nil)))
               (and x (char-downcase x)))))
  (do ((c (make-hash-table :test 'equal))  ; the word count map
       w y                                 ; current word and final word list
       (x (r) (r)))  ; iteration over all chars
       ((not x)

        ; make a list with (word . count) pairs removing stopwords
        (maphash (lambda (k v)
                   (if (not (find k '("" "the" "and" "of" "to"
                                      "a" "i" "it" "in" "or" "is")
                                  :test 'equal))
                       (push (cons k v) y)))
                 c)

        ; sort and truncate the list
        (setf y (sort y #'> :key #'cdr))
        (setf y (subseq y 0 (min (length y) 22)))

        ; find the scaling factor
        (let ((f (apply #'min
                        (mapcar (lambda (x) (/ (- 76.0 (length (car x)))
                                               (cdr x)))
                                y))))
          ; output
          (flet ((outx (n) (dotimes (i (floor (* n f))) (write-char #\_))))
             (write-char #\Space)
             (outx (cdar y))
             (write-char #\Newline)
             (dolist (x y)
               (write-char #\|)
               (outx (cdr x))
               (format t "| ~a~%" (car x))))))

       ; add alphabetic to current word, and bump word counter
       ; on non-alphabetic
       (cond
        ((char<= #\a x #\z)
         (push x w))
        (t
         (incf (gethash (concatenate 'string (reverse w)) c 0))
         (setf w nil)))))
Aaron
5 июля 2010 в 01:55
0

Вы пробовали установить специальный макрос для чтения, чтобы немного уменьшить размер ввода?

6502
5 июля 2010 в 06:18
0

@Aaron на самом деле для меня это было не тривиально, даже просто заставить это работать ... :-) для фактической части игры в гольф я просто использовал однобуквенные переменные, и все. В любом случае, помимо отчасти высокой многословности, присущей CL для этого уровня проблем («concatenate 'string», «setf» или «gethash» - убийцы ... в python они «+», «=», «[]» ) Тем не менее, я чувствовал это намного хуже, чем я ожидал даже на логическом уровне. В некотором смысле у меня есть ощущение, что шепелявость - это нормально, но обычная шепелявость так себе, и это выходит за рамки именования (перечитывание его очень несправедливый комментарий, поскольку мой опыт работы с CL близок к нулю).

Aaron
7 июля 2010 в 16:37
0

правда. Схема сделает игру в гольф немного проще с помощью единого пространства имен. вместо повсеместного добавления строки вы можете (letrec ((a string-append) (b gethash)) ... (a "x" "yz") ...)

avatar
BalusC
20 июня 2020 в 09:12
5

Java - 886 865 756 744 <46979840296> 744 <462998409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469768409840> <469798409840> <469768409840> <469768409840> <469768409840> <469798409840> 752 742 714 680 символов

  • Обновления перед первым 742 : улучшено регулярное выражение, удалены лишние параметризованные типы, удалены лишние пробелы.

  • Обновление 742> 744 символа : исправлен хак с фиксированной длиной. Это зависит только от первого слова, а не от других слов (пока). Найдено несколько мест для сокращения кода (\\s в регулярном выражении заменено на и ArrayList заменено на Vector). Сейчас я ищу короткий способ удалить зависимость ввода-вывода Commons и чтение из stdin.

  • Обновление 744> 752 символа : я удалил зависимость общего доступа. Теперь он читается со стандартного ввода. Вставьте текст в стандартный ввод и нажмите Ctrl+Z, чтобы получить результат.

  • Обновление 752> 742 символа : я удалил public и пробел, сделал имя класса 1 символом вместо 2, и теперь он игнорирует однобуквенные слова.

  • Обновление 742> 714 символов : обновлено в соответствии с комментариями Карла: удалено избыточное присвоение (742> 730), заменено m.containsKey(k) на m.get(k)!=null (730> 728), введена подстрока строки ( 728> 714).

  • Обновление 714> 680 символов : Обновлено в соответствии с комментариями Rotsor: улучшено вычисление размера стержня для удаления ненужного литья и улучшено split() для удаления ненужного replaceAll().


import java.util.*;class F{public static void main(String[]a)throws Exception{StringBuffer b=new StringBuffer();for(int c;(c=System.in.read())>0;b.append((char)c));final Map<String,Integer>m=new HashMap();for(String w:b.toString().toLowerCase().split("(\\b(.|the|and|of|to|i[tns]|or)\\b|\\W)+"))m.put(w,m.get(w)!=null?m.get(w)+1:1);List<String>l=new Vector(m.keySet());Collections.sort(l,new Comparator(){public int compare(Object l,Object r){return m.get(r)-m.get(l);}});int c=76-l.get(0).length();String s=new String(new char[c]).replace('\0','_');System.out.println(" "+s);for(String w:l.subList(0,22))System.out.println("|"+s.substring(0,m.get(w)*c/m.get(l.get(0)))+"| "+w);}}

Более читаемая версия:

import java.util.*;
class F{
 public static void main(String[]a)throws Exception{
  StringBuffer b=new StringBuffer();for(int c;(c=System.in.read())>0;b.append((char)c));
  final Map<String,Integer>m=new HashMap();for(String w:b.toString().toLowerCase().split("(\\b(.|the|and|of|to|i[tns]|or)\\b|\\W)+"))m.put(w,m.get(w)!=null?m.get(w)+1:1);
  List<String>l=new Vector(m.keySet());Collections.sort(l,new Comparator(){public int compare(Object l,Object r){return m.get(r)-m.get(l);}});
  int c=76-l.get(0).length();String s=new String(new char[c]).replace('\0','_');System.out.println(" "+s);
  for(String w:l.subList(0,22))System.out.println("|"+s.substring(0,m.get(w)*c/m.get(l.get(0)))+"| "+w);
 }
}

Вывод:

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| with
|_____________________________| at
|__________________________| on
|__________________________| all
|_______________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so
|___________________| very
|__________________| what

Довольно отстойно, что в Java нет закрытий String#join() и (пока).

Отредактировал Ротсор:

Я внес несколько изменений в ваше решение:

  • Замененный список строкой []
  • Повторно использовал аргумент args вместо объявления моего собственного массива String. Также использовал его как аргумент для .ToArray ()
  • Заменен StringBuffer на String (да, да, ужасная производительность)
  • Сортировка Java заменена сортировкой по выбору с ранней остановкой (нужно найти только первые 22 элемента)
  • Объединение некоторого объявления int в один оператор
  • Реализован алгоритм без мошенничества, обнаруживающий наиболее ограничивающую строку вывода. Реализовал без ФП.
  • Исправлена ​​проблема сбоя программы, когда в тексте было менее 22 различных слов
  • Реализован новый алгоритм чтения ввода, который является быстрым и всего на 9 символов длиннее медленного.

Сокращенный код: 688 711 684 длиной символов:

import java.util.*;class F{public static void main(String[]l)throws Exception{Map<String,Integer>m=new HashMap();String w="";int i=0,k=0,j=8,x,y,g=22;for(;(j=System.in.read())>0;w+=(char)j);for(String W:w.toLowerCase().split("(\\b(.|the|and|of|to|i[tns]|or)\\b|\\W)+"))m.put(W,m.get(W)!=null?m.get(W)+1:1);l=m.keySet().toArray(l);x=l.length;if(x<g)g=x;for(;i<g;++i)for(j=i;++j<x;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}for(;k<g;k++){x=76-l[k].length();y=m.get(l[k]);if(k<1||y*i>x*j){i=x;j=y;}}String s=new String(new char[m.get(l[0])*i/j]).replace('\0','_');System.out.println(" "+s);for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/j)+"| "+w);}}}

Быстрая версия ( 720 693 символов)

import java.util.*;class F{public static void main(String[]l)throws Exception{Map<String,Integer>m=new HashMap();String w="";int i=0,k=0,j=8,x,y,g=22;for(;j>0;){j=System.in.read();if(j>90)j-=32;if(j>64&j<91)w+=(char)j;else{if(!w.matches("^(|.|THE|AND|OF|TO|I[TNS]|OR)$"))m.put(w,m.get(w)!=null?m.get(w)+1:1);w="";}}l=m.keySet().toArray(l);x=l.length;if(x<g)g=x;for(;i<g;++i)for(j=i;++j<x;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}for(;k<g;k++){x=76-l[k].length();y=m.get(l[k]);if(k<1||y*i>x*j){i=x;j=y;}}String s=new String(new char[m.get(l[0])*i/j]).replace('\0','_');System.out.println(" "+s);for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/j)+"| "+w);}}}

Более читаемая версия:

import java.util.*;class F{public static void main(String[]l)throws Exception{
    Map<String,Integer>m=new HashMap();String w="";
    int i=0,k=0,j=8,x,y,g=22;
    for(;j>0;){j=System.in.read();if(j>90)j-=32;if(j>64&j<91)w+=(char)j;else{
        if(!w.matches("^(|.|THE|AND|OF|TO|I[TNS]|OR)$"))m.put(w,m.get(w)!=null?m.get(w)+1:1);w="";
    }}
    l=m.keySet().toArray(l);x=l.length;if(x<g)g=x;
    for(;i<g;++i)for(j=i;++j<x;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}
    for(;k<g;k++){x=76-l[k].length();y=m.get(l[k]);if(k<1||y*i>x*j){i=x;j=y;}}
    String s=new String(new char[m.get(l[0])*i/j]).replace('\0','_');
    System.out.println(" "+s);
    for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/j)+"| "+w);}}
}

Версия без улучшенного поведения: 615 символов:

import java.util.*;class F{public static void main(String[]l)throws Exception{Map<String,Integer>m=new HashMap();String w="";int i=0,k=0,j=8,g=22;for(;j>0;){j=System.in.read();if(j>90)j-=32;if(j>64&j<91)w+=(char)j;else{if(!w.matches("^(|.|THE|AND|OF|TO|I[TNS]|OR)$"))m.put(w,m.get(w)!=null?m.get(w)+1:1);w="";}}l=m.keySet().toArray(l);for(;i<g;++i)for(j=i;++j<l.length;)if(m.get(l[i])<m.get(l[j])){w=l[i];l[i]=l[j];l[j]=w;}i=76-l[0].length();String s=new String(new char[i]).replace('\0','_');System.out.println(" "+s);for(k=0;k<g;k++){w=l[k];System.out.println("|"+s.substring(0,m.get(w)*i/m.get(l[0]))+"| "+w);}}}
Joey
3 июля 2010 в 10:01
0

Не могли бы вы просто использовать полное имя для IOUtils вместо его импорта? Насколько я понимаю, вы все равно используете его только один раз.

Gabe
3 июля 2010 в 10:10
5

Вы как бы обманули, предположив, что самая длинная полоса будет ровно 75 символов. Вы должны убедиться, что ни одна полоса + слово не длиннее 80 символов.

st0le
3 июля 2010 в 12:45
0

Вам не хватает пробела после слова. ;)

Jonathon Faust
3 июля 2010 в 16:49
0

Когда я сокращал свой ответ, я надеялся, что смогу победить представление BalusC. У меня еще осталось 200 персонажей, тьфу! Интересно, как долго это будет без предположения Commons IO & 75 char.

BalusC
3 июля 2010 в 21:23
0

@Gabe и @Jon: я удалил исправление 75 символов, но теперь оно зависит только от 1-го слова. Я также удалил зависимость Commons IO.

Carl
4 июля 2010 в 01:35
0

m.get(w)==null - более короткая проверка, чем m.containsKey(w), и вам фактически не нужно объявлять t - вы можете выгружать его прямо в конструкцию for-each. Я думаю, что было бы короче назначить new String(new char[c]).replace... строке и использовать подстроку во втором вызове, чтобы получить ее фрагмент.

BalusC
4 июля 2010 в 03:12
0

@Carl: спасибо, теперь я вижу в истории обновлений, что вы действительно обновили его, но я полностью его пропустил и переопределил, извините! :)

Michael Myers
4 июля 2010 в 05:08
1

Похоже, вы могли бы сократить количество символов, сделав b String вместо StringBuffer. Я не хочу думать о том, какой будет производительность (тем более, что вы добавляете по одному символу за раз).

BalusC
4 июля 2010 в 05:25
0

@mmyers: Код-гольф - это не только производительность! Вы правы, я слишком привык к StringBuilder / Buffer для такой работы. Обновление ...

BalusC
4 июля 2010 в 05:47
0

@mmyers: Это не сработало, это действительно слишком медленно. Нажатие Ctrl + Z немедленно прервет его. На сбор входных данных в качестве примера ушло около 10 секунд вместо одной секунды.

Gabe
4 июля 2010 в 07:21
0

Какова цель final перед Map? Мне это кажется чуждым.

Landei
4 июля 2010 в 11:21
0

Вот уловка: вместо того, чтобы писать System.out.println (...), определите System x; и напишем позже x.out.println (...)

BalusC
4 июля 2010 в 12:47
0

@Gabe: чтобы к нему можно было получить доступ в анонимном классе Comparator. @Landei: это невозможно в Java.

Gabe
5 июля 2010 в 04:56
0

Можете ли вы сделать m a Map<String,Float>? Я ожидал, что это сэкономит 4 удара.

ealf
5 июля 2010 в 07:11
0

Вы можете сэкономить место, поместив код в инициализатор: enum X {X {{.. здесь находится код ..}}}

BalusC
5 июля 2010 в 16:04
0

@ealf: вам в любом случае понадобится где-нибудь a main() для выполнения кода.

Carl
6 июля 2010 в 12:32
0

Я думаю, есть способ сбрить некоторые символы, выполнив что-то вроде: final Map<String,Integer>m=new HashMap();new BufferedInputReader(new InputStreamReader(System.in)){{for(String w:readLine().toLowerCase().replaceAll("\\b(.|the|and|of|to|i[tns]|or)\\b|\\W"," ").split(" +"))m.put(w,m.get(w)!=null?m.get(w)+1:1);}};

Carl
6 июля 2010 в 12:34
0

хотя это предполагает, что нет слов, разделенных дефисом по строкам, что, похоже, не учитывается в другом месте, поэтому кажется достаточно безопасным предположением.

BalusC
6 июля 2010 в 12:34
0

@Carl: К сожалению, ввод может состоять из нескольких строк. Я уже думал об этом.

Carl
6 июля 2010 в 13:24
0

хм, как насчет того, чтобы вставить while(ready()) перед for?

Rotsor
10 июля 2010 в 22:53
0

Зачем вам здесь столько кастинга? (int)(((float)m.get(w)/m.get(l.get(0)))*c) Вы можете сделать это: m.get(w)*c/m.get(l.get(0)) сохранить 16 символов, которые будут иметь дополнительное преимущество, поскольку они всегда точны и не опасны для FP. Однако l.get (0) обманывает. Это решение не будет работать с примером «сверхдлинной строки».

Rotsor
10 июля 2010 в 22:56
0

Вы можете заменить .replaceAll("\\b(.|the|and|of|to|i[tns]|or)\\b|\\W"," ").split(" +") на .split("(\\b(.|the|and|of|to|i[tns]|or)\\b|\\W)+"), сохранив 18 символов!

Rotsor
10 июля 2010 в 23:00
0

Решение с двумя изменениями выше и StringBuffer, замененным на String, имеет длину всего 641 символ. Никому не требовалось линейное время, поэтому я думаю, что String вместо StringBuffer приемлем.

BalusC
10 июля 2010 в 23:00
0

@Rotsor: Большое спасибо за подсказки :) Скоро я обновлю ответ. И да, я обманываю. Но это требование появилось позже, и это будет еще> 100 дополнительных символов ...

Rotsor
11 июля 2010 в 00:47
0

Я поменял его на версию без накрутки, также исправив ошибку IndexOutOfBoundsException. Приложу к твоему посту. Не стесняйтесь делать с ним все, что захотите.

Rotsor
11 июля 2010 в 01:51
0

Кстати, требование появилось не позже, оно было с самого начала, но просто не было примера, чтобы показать эту ошибку.

avatar
JSBձոգչ
20 июня 2020 в 09:12
25

Perl, 237 229 209 символов

(Снова обновлено, чтобы превзойти версию Ruby с более грязными трюками с гольфом, заменой split/[^a-z/,lc на lc=~/[a-z]+/g и устранением проверки на пустую строку в другом месте. Они были вдохновлены версией Ruby, так что честь к оплате.)

Обновление: теперь с Perl 5.10! Замените print на say и используйте ~~, чтобы избежать map. Это должно быть вызвано в командной строке как perl -E '<one-liner>' alice.txt. Поскольку весь скрипт находится в одной строке, написание его однострочным не должно вызвать затруднений :).

 @s=qw/the and of to a i it in or is/;$c{$_}++foreach grep{!($_~~@s)}map{lc=~/[a-z]+/g}<>;@s=sort{$c{$b}<=>$c{$a}}keys%c;$f=76-length$s[0];say" "."_"x$f;say"|"."_"x($c{$_}/$c{$s[0]}*$f)."| $_ "foreach@s[0..21];

Обратите внимание, что эта версия нормализуется для регистра. Это не укорачивает решение, поскольку удаление ,lc (для нижнего регистра) требует, чтобы вы добавили A-Z к разделенному регулярному выражению, так что это промывка.

Если вы работаете в системе, где перевод строки состоит из одного символа, а не двух, вы можете сократить его еще на два символа, используя буквальный перевод строки вместо \n. Однако я не написал приведенный выше образец таким образом, так как он «яснее» (ха!) Таким образом.


Вот в основном правильное, но далеко не достаточно короткое решение perl:

use strict;
use warnings;

my %short = map { $_ => 1 } qw/the and of to a i it in or is/;
my %count = ();

$count{$_}++ foreach grep { $_ && !$short{$_} } map { split /[^a-zA-Z]/ } (<>);
my @sorted = (sort { $count{$b} <=> $count{$a} } keys %count)[0..21];
my $widest = 76 - (length $sorted[0]);

print " " . ("_" x $widest) . "\n";
foreach (@sorted)
{
    my $width = int(($count{$_} / $count{$sorted[0]}) * $widest);
    print "|" . ("_" x $width) . "| $_ \n";
}

Нижеследующее является максимально коротким, оставаясь при этом относительно читаемым. (392 символа).

%short = map { $_ => 1 } qw/the and of to a i it in or is/;
%count;

$count{$_}++ foreach grep { $_ && !$short{$_} } map { split /[^a-z]/, lc } (<>);
@sorted = (sort { $count{$b} <=> $count{$a} } keys %count)[0..21];
$widest = 76 - (length $sorted[0]);

print " " . "_" x $widest . "\n";
print"|" . "_" x int(($count{$_} / $count{$sorted[0]}) * $widest) . "| $_ \n" foreach @sorted;
JSBձոգչ
2 июля 2010 в 21:35
0

Есть несколько ошибок прямо сейчас; фиксация и укорачивание.

Joey
3 июля 2010 в 10:19
4

Это не касается случая, когда второе слово намного длиннее первого, верно?

Zaid
4 июля 2010 в 18:05
1

Оба foreach могут быть записаны как for. Это на 8 символов меньше. Затем у вас есть grep{!($_~~@s)}map{lc=~/[a-z]+/g}<>, который, я полагаю, можно было бы записать как grep{!(/$_/i~~@s)}<>=~/[a-z]+/g, чтобы опуститься еще на 4. Замените " " на $", и вы потеряете еще 1 ...

mob
5 июля 2010 в 23:45
0

sort{$c{$b}-$c{$a}}... чтобы сохранить еще два. Вы также можете просто передать %c вместо keys %c в функцию sort и сохранить еще четыре.

avatar
Anurag
23 мая 2017 в 12:25
19

Рубин, 215, 216 , 218 , 221 , 224 <701047043433>, 224 <70104601043434> 224 <7010601060104348 237 символы

обновление 1: Ура ! Это связано с решением от JS Bangs. Больше не могу придумать способ вырубить :)

обновление 2: сыграл грязный трюк с гольфом. Изменено each на map, чтобы сохранить 1 символ :)

обновление 3: изменено с File.read на IO.read +2. Array.group_by не очень плодотворно, заменено на reduce +6. Проверка без учета регистра не требуется после нижнего регистра с downcase в регулярном выражении +1. Сортировку по убыванию легко выполнить, отрицая значение +6. Общая экономия +15

обновление 4: [0], а не .first, +3. (@ Shtééf)

обновление 5: развернуть переменную l на месте, +1. Разверните переменную s на месте, +2. (@ Shtééf)

обновление 6: используйте добавление строк вместо интерполяции для первой строки, +2. (@ Штеф)

w=(IO.read($_).downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).reduce(Hash.new 0){|m,o|m[o]+=1;m}.sort_by{|k,v|-v}.take 22;m=76-w[0][0].size;puts' '+'_'*m;w.map{|x,f|puts"|#{'_'*(f*1.0/w[0][1]*m)}| #{x} "}

обновление 7: я прошел через множество шумих, чтобы обнаружить первую итерацию внутри цикла, используя переменные экземпляра. Все, что у меня есть, это +1, хотя, возможно, есть потенциал. Сохраняю предыдущую версию, потому что я считаю, что это черная магия. (@ Shtééf)

(IO.read($_).downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).reduce(Hash.new 0){|m,o|m[o]+=1;m}.sort_by{|k,v|-v}.take(22).map{|x,f|@f||(@f=f;puts' '+'_'*(@m=76-x.size));puts"|#{'_'*(f*1.0/@f*@m)}| #{x} "}

Версия для чтения

string = File.read($_).downcase

words = string.scan(/[a-z]+/i)
allowed_words = words - %w{the and of to a i it in or is}
sorted_words = allowed_words.group_by{ |x| x }.map{ |x,y| [x, y.size] }.sort{ |a,b| b[1] <=> a[1] }.take(22)
highest_frequency = sorted_words.first
highest_frequency_count = highest_frequency[1]
highest_frequency_word = highest_frequency[0]

word_length = highest_frequency_word.size
widest = 76 - word_length

puts " #{'_' * widest}"    
sorted_words.each do |word, freq|
  width = (freq * 1.0 / highest_frequency_count) * widest
  puts "|#{'_' * width}| #{word} "
end

Использовать:

echo "Alice.txt" | ruby -ln GolfedWordFrequencies.rb

Вывод:

 _________________________________________________________________________
|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|_____________________________________________________| alice 
|_______________________________________________| was 
|___________________________________________| that 
|____________________________________| as 
|________________________________| her 
|_____________________________| with 
|_____________________________| at 
|____________________________| s 
|____________________________| t 
|__________________________| on 
|__________________________| all 
|_______________________| this 
|_______________________| for 
|_______________________| had 
|_______________________| but 
|______________________| be 
|_____________________| not 
|____________________| they 
|____________________| so 
rfusca
3 июля 2010 в 03:21
3

Разве "p" не сокращение от "put"? Это могло побрить некоторых.

JSBձոգչ
3 июля 2010 в 04:35
1

Отлично. Однако ваше использование scan дало мне лучшее представление, так что я снова пошел вперед :).

Anurag
3 июля 2010 в 08:56
0

@rfusca, p помещает кавычки вокруг вывода, чтобы он не соответствовал OP.

Anurag
3 июля 2010 в 09:10
0

@JS Похоже, это будет игра в кошки-мышки, пока не появится J :)

Stéphan Kochen
3 июля 2010 в 09:23
0

Вы неправильно посчитали. В обновлении 3 у вас было 224 символа. В любом случае, я вернул вас на 221. :) Этот трюк с уменьшением - это черная магия. : o

Anurag
3 июля 2010 в 09:27
0

@ Shtéf - спасибо :) .. последнее, что мы хотим в code-golf, - это неправильный учет на более высокой стороне .. lol: o)

mP.
3 июля 2010 в 09:56
0

Разве оболочка не используется для "чтения" и передачи файла по каналу?

Anurag
3 июля 2010 в 10:01
0

Вопрос гласит, что ввод может быть передан по конвейеру. Кроме того, мы просто передаем имя файла, а не его содержимое.

Stéphan Kochen
3 июля 2010 в 10:42
0

Хорошо, теперь я полностью с этим покончил. Теперь ты можешь кричать на меня. :) Очень надеюсь, что версия Perl не станет намного короче.

Gabe
3 июля 2010 в 11:36
2

Вам нужно масштабировать полоски так, чтобы самое длинное слово и его полоса умещались на 80 символах. Как предположил Брайан, длинное второе слово нарушит вашу программу.

Joey
3 июля 2010 в 11:44
3

Интересно, почему это все еще набирает голоса. Решение неверное (в общем случае), и здесь уже есть два более коротких решения Ruby.

st0le
3 июля 2010 в 12:37
1

Теперь поправьте меня, если я ошибаюсь, но почему бы вам не использовать регистр без учета регистра REGEXP, который экономит 6-7 байтов, не так ли?

Dogbert
3 июля 2010 в 14:08
0

Как насчет [0..21] вместо .take 22?

avatar
RichardTheKiwi
23 мая 2017 в 11:53
1

Еще одно решение T-SQL, заимствованное из решения Мартина (min76- и т. Д.).

declare @ varchar(max),@w real,@j int;select s=@ into[ ]set @=(select*
from openrowset(bulk'a',single_blob)a)while @>''begin set @=stuff(@,1,
patindex('%[a-z]%',@)-1,'')+'.'set @j=patindex('%[^a-z]%',@)if @j>2insert[ ]
select lower(left(@,@j-1))set @=stuff(@,1,@j,'')end;select top(22)s,count(*)
c into # from[ ]where',the,and,of,to,it,in,or,is,'not like'%,'+s+',%'
group by s order by 2desc;select @w=min((76.-len(s))/c),@=' '+replicate(
'_',max(c)*@w)from #;select @=@+'
|'+replicate('_',c*@w)+'| '+s+' 'from #;print @

Все решение должно состоять из двух строк (объединить первые 7), хотя вы можете вырезать, вставить и запустить его как есть. Всего символов = 507 (считая разрыв строки как 1, если вы сохраняете его в формате Unix и выполняете с использованием SQLCMD)

Допущения:

  1. Нет временной таблицы #
  2. Нет таблицы с именем [ ]
  3. Входные данные находятся в системной папке по умолчанию, например C:\windows\system32\a
  4. В вашем окне запроса активна опция "установить nocount" (предотвращение ложных сообщений о "затронутых строках")

И чтобы перейти к списку решений (<500 знаков), вот "расслабленное" издание с 483 символами (без вертикальных полос / без верхней панели / без конечного пробела после слова)

declare @ varchar(max),@w real,@j int;select s=@ into[ ]set @=(select*
from openrowset(bulk'b',single_blob)a)while @>''begin set @=stuff(@,1,
patindex('%[a-z]%',@)-1,'')+'.'set @j=patindex('%[^a-z]%',@)if @j>2insert[ ]
select lower(left(@,@j-1))set @=stuff(@,1,@j,'')end;select top(22)s,count(*)
c into # from[ ]where',the,and,of,to,it,in,or,is,'not like'%,'+s+',%'
group by s order by 2desc;select @w=min((78.-len(s))/c),@=''from #;select @=@+'
'+replicate('_',c*@w)+' '+s from #;print @

Версия для чтения

declare @ varchar(max), @w real, @j int
select s=@ into[ ] -- shortcut to create table; use defined variable to specify column type
-- openrowset reads an entire file
set @=(select * from openrowset(bulk'a',single_blob) a) -- a bit shorter than naming 'BulkColumn'

while @>'' begin -- loop until input is empty
    set @=stuff(@,1,patindex('%[a-z]%',@)-1,'')+'.' -- remove lead up to first A-Z char *
    set @j=patindex('%[^a-z]%',@) -- find first non A-Z char. The +'.' above makes sure there is one
    if @j>2insert[ ] select lower(left(@,@j-1)) -- insert only words >1 char
    set @=stuff(@,1,@j,'') -- remove word and trailing non A-Z char
end;

select top(22)s,count(*)c
into #
from[ ]
where ',the,and,of,to,it,in,or,is,' not like '%,'+s+',%' -- exclude list
group by s
order by 2desc; -- highest occurence, assume no ties at 22!

-- 80 - 2 vertical bars - 2 spaces = 76
-- @w = weighted frequency
-- this produces a line equal to the length of the max occurence (max(c))
select @w=min((76.-len(s))/c),@=' '+replicate('_',max(c)*@w)
from #;

-- for each word, append it as a new line. note: embedded newline
select @=@+'
|'+replicate('_',c*@w)+'| '+s+' 'from #;
-- note: 22 words in a table should always fit on an 8k page
--       the order of processing should always be the same as the insert-orderby
--       thereby producing the correct output

print @ -- output
avatar
Daniel C. Sobral
23 мая 2017 в 11:46
2

Scala, 327 символов

Это было адаптировано из ответа mkneissl , вдохновленного версией Python, хотя она больше. Я оставляю его здесь на случай, если кто-нибудь сможет сделать его короче.

val f="\\w+\\b(?<!\\bthe|and|of|to|a|i[tns]?|or)".r.findAllIn(io.Source.fromFile("11.txt").mkString.toLowerCase).toSeq
val t=f.toSet[String].map(x=> -f.count(x==)->x).toSeq.sorted take 22
def b(p:Int)="_"*(-p/(for((c,w)<-t)yield-c/(76.0-w.size)).max).toInt
println(" "+b(t(0)._1))
for(p<-t)printf("|%s| %s \n",b(p._1),p._2)
avatar
Joe Zoller
9 ноября 2013 в 22:12
123

LabVIEW 51 узел, 5 структур, 10 диаграмм

Учить слона чечетке никогда не бывает красиво. Я пропущу подсчет символов.

labVIEW code

results

Программа идет слева направо:

labVIEW code explained

JDonner
4 июля 2010 в 05:49
0

Вау, я никогда раньше не видел примера визуального программирования, который выглядел бы полезным! Я думал, что это был своего рода консенсус, что это невозможно или не стоит того.

user216441
4 июля 2010 в 06:18
10

Это не стоит

Joe Z
4 июля 2010 в 06:23
4

LabVIEW очень доволен своей нишей аппаратного контроля и измерения, но действительно ужасен для манипуляций со строками.

Blair Holloway
6 июля 2010 в 01:48
19

Лучший ответ на гольф-код, который я когда-либо видел. +1 за нестандартное мышление!

dmckee --- ex-moderator kitten
6 июля 2010 в 05:52
1

Для нас нужно подсчитать элементы ... учитывается каждый ящик и виджет, которые вам пришлось перетащить на экран.

Joe Z
7 июля 2010 в 00:16
0

@dmckee Хороший звонок. Большинство показателей основано на количестве узлов, поэтому я добавлю это.

dmckee --- ex-moderator kitten
7 июля 2010 в 00:24
0

@Underflow: Достаточно честно. Я не уверен, что это точное сравнение, но это что-то.

Svish
7 июля 2010 в 12:35
1

Можно ли добавить ссылку на более крупную версию этих диаграмм?

Joe Z
8 июля 2010 в 05:33
0

@Svish Переключился на другой хост для изображений. Надеюсь, это поможет.

Carter Pape
30 апреля 2012 в 02:39
0

Моим первым языком программирования был LabView, поэтому у меня мурашки по спине, когда я вижу, что он используется так красиво и с таким большим приемом со стороны сообщества. Очень хорошая работа.

avatar
reso
24 сентября 2013 в 16:39
2

MATLAB 335 404 410 байт 357 байт. <711187116011064099>

Обновленный код теперь содержит 335 символов вместо 404, и, похоже, подходит для обоих примеров.


Исходное сообщение (для кода из 404 символов)

Эта версия немного длиннее, , однако , она будет правильно масштабировать длину полос если есть до смешного длинное слово, так что ни один столбец не превышает 80.

Итак, мой код составляет 357 байт без повторного масштабирования и 410 байтов с повторным масштабированием.

A=textscan(fopen('11.txt'),'%s','delimiter',' 0123456789,.!?-_*^:;=+\\/(){}[]@&#$%~`|"''');
s=lower(A{1});s(cellfun('length', s)<2)=[];s(ismember(s,{'the','and','of','to','it','in','or','is'}))=[];
[w,~,i]=unique(s);N=hist(i,max(i)); [j,k]=sort(N,'descend'); b=k(1:22); n=cellfun('length',w(b));
q=80*N(b)'/N(k(1))+n; q=floor(q*78/max(q)-n); for i=1:22, fprintf('%s| %s\n',repmat('_',1,l(i)),w{k(i)});end

Результаты:

___________________________________________________________________________| she
_________________________________________________________________| you
______________________________________________________________| said
_______________________________________________________| alice
________________________________________________| was
____________________________________________| that
_____________________________________| as
_________________________________| her
______________________________| at
______________________________| with
____________________________| on
___________________________| all
_________________________| this
________________________| for
________________________| had
________________________| but
_______________________| be
_______________________| not
_____________________| they
____________________| so
___________________| very
___________________| what

Например, заменив все вхождения «you» в тексте «Алиса в стране чудес» на «superlongstringofridiculousness», мой код будет правильно масштабировать результаты:

____________________________________________________________________| she
_________________________________________________________| superlongstringstring
________________________________________________________| said
_________________________________________________| alice
____________________________________________| was
________________________________________| that
_________________________________| as
______________________________| her
___________________________| with
___________________________| at
_________________________| on
________________________| all
_____________________| this
_____________________| for
_____________________| had
_____________________| but
____________________| be
____________________| not
__________________| they
__________________| so
_________________| very
_________________| what

Вот обновленный код, написанный немного более разборчиво:

A=textscan(fopen('t'),'%s','delimiter','':'@');
s=lower(A{1});
s(cellfun('length', s)<2|ismember(s,{'the','and','of','to','it','in','or','is'}))=[];
[w,~,i]=unique(s);
N=hist(i,max(i)); 
[j,k]=sort(N,'descend'); 
n=cellfun('length',w(k));
q=80*N(k)'/N(k(1))+n; 
q=floor(q*78/max(q)-n); 
for i=1:22, 
    fprintf('%s| %s\n',repmat('_',1,q(i)),w{k(i)});
end

ChristopheD
3 июля 2010 в 21:01
0

Престижность за полную реализацию спецификации! (Я бы проголосовал за, но на сегодня у меня закончились голоса ...)

Bwmat
3 июля 2010 в 21:57
10

не должна ли полоса «сверхдлинной нити смешности» быть длиннее, чем полоса «сказанного»?

reso
4 июля 2010 в 07:51
0

@Bwmat: ааа !! хороший глаз! Вернуться к доске для рисования...

Amro
30 июля 2010 в 20:57
1

вы можете сэкономить 18 символов, заменив строку разделителя на: char([32:64 91:96 123:126])

reso
23 августа 2010 в 15:43
0

@Amro: эй, спасибо за подсказку, это здорово. Однажды я вернусь и исправлю ошибку, которую испортил Bwmat, и добавлю ее к ней.

Dennis Jaheruddin
24 сентября 2013 в 16:39
0

Исправлена ​​опечатка и немного сокращен код, не учитывалась большая часть логики, просто пытались использовать более короткий синтаксис.

avatar
7 апреля 2012 в 23:23
0

Кв., 194

{t::y;{(-1')t#(.:)[b],'(!:)[b:"|",/:(((_)70*x%(*:)x)#\:"_"),\:"|"];}desc(#:')(=)($)(`$inter\:[(,/)" "vs'" "sv/:"'"vs'a(&)0<(#:')a:(_:')read0 -1!x;52#.Q.an])except`the`and`of`to`a`i`it`in`or`is`}

функция принимает два аргумента: один - файл, содержащий текст, а другой - количество отображаемых строк диаграммы

q){t::y;{(-1')t#(.:)[b],'(!:)[b:"|",/:(((_)70*x%(*:)x)#\:"_"),\:"|"];}desc(#:')(=)($)(`$inter\:[(,/)" "vs'" "sv/:"'"vs'a(&)0<(#:')a:(_:')read0 -1!x;52#.Q.an])except`the`and`of`to`a`i`it`in`or`is`}[`a.txt;20]

вывод

|______________________________________________________________________|she
|____________________________________________________________|you
|__________________________________________________________|said
|___________________________________________________|alice
|_____________________________________________|was
|_________________________________________|that
|__________________________________|as
|_______________________________|her
|_____________________________|with
|____________________________|at
|___________________________|t
|___________________________|s
|_________________________|on
|_________________________|all
|_______________________|this
|______________________|for
|______________________|had
|_____________________|but
|_____________________|be
|_____________________|not
avatar
30 ноября 2011 в 11:49
0

Groovy, 250

Код:

m=[:]
(new URL(args[0]).text.toLowerCase()=~/\w+/).each{it==~/(the|and|of|to|a|i[tns]?|or)/?:(m[it]=1+(m[it]?:0))}
k=m.keySet().sort{a,b->m[b]<=>m[a]}
b={d,c,b->println d+'_'*c+d+' '+b}
b' ',z=77-k[0].size(),''
k[0..21].each{b'|',m[it]*z/m[k[0]],it}

Выполнение:

$ groovy wordcount.groovy http://www.gutenberg.org/files/11/11.txt

Вывод:

 __________________________________________________________________________  
|__________________________________________________________________________| she
|________________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| at
|______________________________| with
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|________________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so

Примечание. это следует расслабленным правилам: длинные строки

avatar
Јοеу
11 июля 2010 в 09:23
20

Windows PowerShell, 199 символов

$x=$input-split'\P{L}'-notmatch'^(the|and|of|to|.?|i[tns]|or)$'|group|sort *
filter f($w){' '+'_'*$w
$x[-1..-22]|%{"|$('_'*($w*$_.Count/$x[-1].Count))| "+$_.Name}}
f(76..1|?{!((f $_)-match'.'*80)})[0]

(Последний разрыв строки не обязателен, но включен здесь для удобства чтения.)

(Текущий код и мои тестовые файлы доступны в моем репозитории SVN. Надеюсь, мои тестовые примеры выявляют наиболее распространенные ошибки (длина полосы, проблемы с сопоставлением регулярных выражений и некоторые другие))

Допущения:

  • US ASCII в качестве входных данных. С Юникодом, наверное, становится странно.
  • Минимум два непрерывных слова в тексте

История

Ослабленная версия (137), поскольку теперь она считается отдельно, очевидно:

($x=$input-split'\P{L}'-notmatch'^(the|and|of|to|.?|i[tns]|or)$'|group|sort *)[-1..-22]|%{"|$('_'*(76*$_.Count/$x[-1].Count))| "+$_.Name}
  • не закрывает первый бар
  • не учитывает длину не первого слова

Вариации длины полосы одного символа по сравнению с другими решениями связаны с тем, что PowerShell использует округление вместо усечения при преобразовании чисел с плавающей запятой в целые числа. Поскольку задача требовала только пропорциональной длины стержня, это должно быть нормально.

По сравнению с другими решениями я применил несколько иной подход к определению максимальной длины полосы, просто попробовав и выбрав наибольшую такую ​​длину, когда ни одна строка не превышает 80 символов.

Объяснение более старой версии можно найти здесь.

ChristopheD
3 июля 2010 в 11:51
0

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

Joey
3 июля 2010 в 11:57
1

@ChristopheD: По моему опыту (Anarchy Golf, некоторые задачи Project Euler и еще несколько задач просто для удовольствия), PowerShell обычно лишь немного хуже Ruby и часто связан или лучше, чем Perl и Python. Однако не может сравниться с GolfScript. Но, насколько я понимаю, это может быть самое короткое решение, которое правильно учитывает длину стержня ;-)

Gabe
3 июля 2010 в 12:02
0

Видимо я был прав. Powershell может работать лучше - намного лучше! Просьба представить расширенную версию с комментариями.

Gabe
3 июля 2010 в 12:20
0

Йоханнес: Вы пробовали -split("\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z]")? Меня устраивает.

Gabe
3 июля 2010 в 12:47
0

Не забудьте интерполировать строку вывода: "|$('_'*($w*$_.count/$x[0].count))| $($_.name) " (или удалить последний пробел, так как это вроде как автоматически). И вы можете использовать -split("(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z])+"), чтобы сэкономить еще несколько, не включая пробелы (или используйте [-2..-23]).

Gabe
3 июля 2010 в 13:10
0

Обратите внимание, что без конечного пробела вам нужно соответствовать .{80}. И вы можете гарантировать, что пробелы всегда будут первыми, например: "\b(?:the|and|of|to|a|i[tns]?|or)\b|[^a-z]()" (пустая группа захвата гарантирует пустое место для каждого слова)

Gabe
3 июля 2010 в 14:25
0

Итак, если у вас есть "$input", вам все еще нужен ()? Кроме того, теперь, когда вы удалили конечный пробел, вы можете сэкономить пару штрихов, не интерполируя имя: "|$('_'*($w*$_.count/$x[0].count))| "+$_.name. Мы еще дойдем до 200!

Gabe
3 июля 2010 в 21:20
0

С удалением .ToString его снова меньше 200!

Joey
3 июля 2010 в 22:35
0

@Gabe: Ура, спасибо. И хороший улов на function по сравнению с filter. Я думал об использовании filter, я просто не думал о том, что фильтры тоже могут принимать аргументы. Для меня это было сравнение между function f($w){...} и filter{$w=$_;...} (поскольку мне определенно нужен цикл в функции, и поэтому я не могу оставить аргумент как $_. Хороший трюк, чтобы запомнить, спасибо :-). Тем не менее, я думаю, что к настоящему времени этот подход был использован почти до смерти. [И я заметил, что мы убили его где-то посередине ... два других моих тестовых случая больше не работают - отладка ...]

Gabe
4 июля 2010 в 15:00
0

Кто-то может возразить, что вы делаете это тоже немного общим, но я не собираюсь жаловаться, так как он все еще ниже 200.

Joey
4 июля 2010 в 15:33
0

@Gabe: Ну, я уже пересмотрел свои предположения относительно хотя бы одного непрерывного слова. Но проблема \b явно противоречила спецификации и работала только для тестового ввода.

avatar
11 июля 2010 в 05:34
1

TCL 554 Strict

foreach w [regexp -all -inline {[a-z]+} [string tolower [read stdin]]] {if {[lsearch {the and of to it in or is a i} $w]>=0} {continue};if {[catch {incr Ws($w)}]} {set Ws($w) 1}}
set T [lrange [lsort -decreasing -stride 2 -index 1 -integer [array get Ws]] 0 43]
foreach {w c} $T {lappend L [string length $w];lappend C $c}
set N [tcl::mathfunc::max {*}$L]
set C [lsort -integer $C]
set M [lindex $C end]
puts " [string repeat _ [expr {int((76-$N) * [lindex $T 1] / $M)}]] "
foreach {w c} $T {puts "|[string repeat _ [expr {int((76-$N) * $c / $M)}]]| $w"}

Или, точнее,

foreach w [regexp -all -inline {[a-z]+} [string tolower [read stdin]]] {
    if {[lsearch {the and of to a i it in or is} $w] >= 0} { continue }
    if {[catch {incr words($w)}]} {
        set words($w) 1
    }
}
set topwords [lrange [lsort -decreasing -stride 2 -index 1 -integer [array get words]] 0 43]
foreach {word count} $topwords {
    lappend lengths [string length $word]
    lappend counts $count
}
set maxlength [lindex [lsort -integer $lengths] end]
set counts [lsort -integer $counts]
set mincount [lindex $counts 0].0
set maxcount [lindex $counts end].0
puts " [string repeat _ [expr {int((76-$maxlength) * [lindex $topwords 1] / $maxcount)}]] "
foreach {word count} $topwords {
    set barlength [expr {int((76-$maxlength) * $count / $maxcount)}]
    puts "|[string repeat _ $barlength]| $word"
}
avatar
Thomas
10 июля 2010 в 06:25
12

Haskell - 366 351 344 3373091031138> 3373091031138>

(Один разрыв строки в main добавлен для удобства чтения, и разрыв строки не требуется в конце последней строки.)

import Data.List
import Data.Char
l=length
t=filter
m=map
f c|isAlpha c=toLower c|0<1=' '
h w=(-l w,head w)
x!(q,w)='|':replicate(minimum$m(q?)x)'_'++"| "++w
q?(g,w)=q*(77-l w)`div`g
b x=m(x!)x
a(l:r)=(' ':t(=='_')l):l:r
main=interact$unlines.a.b.take 22.sort.m h.group.sort
  .t(`notElem`words"the and of to a i it in or is").words.m f

Как это работает, лучше всего увидеть, прочитав аргумент до interact в обратном порядке:

  • map f строчные буквы, все остальное заменяется пробелами.
  • words создает список слов без разделительных пробелов.
  • filter ( notElem words "the and of to a i it in or is") отбрасывает все записи с запрещенными словами.
  • group . sort сортирует слова и группирует идентичные в списки.
  • map h отображает каждый список идентичных слов в кортеж вида (-frequency, word).
  • take 22 . sort сортирует кортежи по убыванию частоты (первая запись кортежа) и сохраняет только первые 22 кортежа.
  • b отображает кортежи в столбцы (см. Ниже).
  • a добавляет перед первой строкой подчеркивания, чтобы завершить самую верхнюю полосу.
  • unlines объединяет все эти строки вместе с символами новой строки.

Сложная задача - получить правильную длину стержня. Я предположил, что только символы подчеркивания учитываются в длине полосы, поэтому || будет полосой нулевой длины. Функция b отображает c x на x, где x - это список гистограмм. Весь список передается в c, так что каждый вызов c может вычислить масштабный коэффициент для себя, вызывая u. Таким образом, я избегаю использования математических или рациональных чисел с плавающей запятой, функции преобразования и импорт которых потребляют много символов.

Обратите внимание на хитрость использования -frequency. Это устраняет необходимость в reverse и sort, поскольку при сортировке (по возрастанию) -frequency слова с наибольшей частотой помещаются первыми. Позже в функции u два значения -frequency умножаются, что отменяет отрицание.

ChristopheD
3 июля 2010 в 19:50
0

Очень хорошая работа (проголосовал бы за, но на сегодня закончились голоса со всеми отличными ответами в этой ветке).

Owen S.
4 июля 2010 в 05:53
0

У меня болят глаза так, что больно даже думать об описании, но я многому научился на Haskell, преобразовав его в разборчивый код. Молодец, сэр. :-)

Thomas
4 июля 2010 в 08:26
0

На самом деле это все еще довольно идиоматичный Haskell, хотя и не очень эффективный. Из-за коротких названий все выглядит намного хуже, чем есть на самом деле.

Owen S.
4 июля 2010 в 08:34
0

@ Томас: Ты можешь повторить это еще раз. :-)

Edward Kmett
5 июля 2010 в 22:25
0

u q (g, w) = q * div (77-l w) g - можно сэкономить 2 символа

Thomas
6 июля 2010 в 07:16
0

@MtnViewMark: Отличная работа! Я не знал, что words отбрасывает пробелы пробелов или что вы можете поместить условия | в одну строку. И я не могу поверить, что ввел туда двухбуквенное имя переменной ...

MtnViewMark
6 июля 2010 в 21:21
1

На самом деле не могу переместить div! Попробуйте - вывод неверный. Причина в том, что выполнение div до * теряет точность.

Thomas
7 июля 2010 в 12:54
0

Ах, упс, неправильно расставил приоритеты. Надо было протестировать перед редактированием: P

Thomas
10 июля 2010 в 10:40
0

@trinithis: Короче, ладно, но теперь я не понимаю, как это работает! Боюсь, вы вышли за рамки моего понимания Haskell. Зачем нужен узор челки? Что вообще означает вопросительный знак?

Thomas Eding
10 июля 2010 в 15:45
0

Это не образец челки: D. Все, что я сделал, это заменил бинарные функции на инфиксные операторы. Я просто решил использовать ? и ! для имен операторов.

avatar
Joshua Weinberg
10 июля 2010 в 06:01
1

Любить больших ... Objective-C ( 1070 931 905 символов)

#define S NSString
#define C countForObject
#define O objectAtIndex
#define U stringWithCString
main(int g,char**b){id c=[NSCountedSet set];S*d=[S stringWithContentsOfFile:[S U:b[1]]];id p=[NSPredicate predicateWithFormat:@"SELF MATCHES[cd]'(the|and|of|to|a|i[tns]?|or)|[^a-z]'"];[d enumerateSubstringsInRange:NSMakeRange(0,[d length])options:NSStringEnumerationByWords usingBlock:^(S*s,NSRange x,NSRange y,BOOL*z){if(![p evaluateWithObject:s])[c addObject:[s lowercaseString]];}];id s=[[c allObjects]sortedArrayUsingComparator:^(id a,id b){return(NSComparisonResult)([c C:b]-[c C:a]);}];g=[c C:[s O:0]];int j=76-[[s O:0]length];char*k=malloc(80);memset(k,'_',80);S*l=[S U:k length:80];printf(" %s\n",[[l substringToIndex:j]cString]),[[s subarrayWithRange:NSMakeRange(0,22)]enumerateObjectsUsingBlock:^(id a,NSUInteger x,BOOL*y){printf("|%s| %s\n",[[l substringToIndex:[c C:a]*j/g]cString],[a cString]);}];}

Перешел на использование большого количества устаревших API, удалено ненужное управление памятью, более агрессивное удаление пробелов

 _________________________________________________________________________
|_________________________________________________________________________| she
|______________________________________________________________| said
|__________________________________________________________| you
|____________________________________________________| alice
|________________________________________________| was
|_______________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| with
|______________________________| at
|___________________________| on
|__________________________| all
|________________________| this
|________________________| for
|________________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| so
|___________________| very
|__________________| what
|_________________| they
dmckee --- ex-moderator kitten
3 июля 2010 в 09:12
1

Обратите внимание, что спецификация требует игнорирования 's, поэтому "не" разбирается как два слова "don" и "s". В эталонной реализации вы увидите, что «s» и «t» представлены в верхних 22 ...

ChristopheD
3 июля 2010 в 11:58
0

Престижность за то, что сделал это в obj-c (не на том языке, который вы часто видите в игре в гольф)!

Joey
3 июля 2010 в 13:38
0

@Christophe: И здесь мы видим именно , почему мы не видим его так часто;)

please delete me
3 июля 2010 в 16:47
0

Попробуйте #define S NSString, #define C countForObject и используйте эти два значения соответствующим образом. Также замените calloc(80,1) на просто malloc(80), так как вы устанавливаете содержимое сразу после этого. Кроме того, повторно используйте параметр a, чтобы сохранить объявление int. Это должно получить меньше 1000 символов ...

Joshua Weinberg
3 июля 2010 в 17:20
0

@brone спасибо за идею, взял их и еще кое-что, что я видел, сейчас намного ниже 1000

kennytm
10 июля 2010 в 05:47
0

Используйте id вместо NSCountedSet* и т. Д.!

Joshua Weinberg
10 июля 2010 в 05:59
0

Черт побери, как я не подумал об этом .... отредактировал, чтобы исправить, 905 :)

avatar
9 июля 2010 в 08:32
1

Решение Lua: 478 символов.

t,u={},{}for l in io.lines()do
for w in l:gmatch("%a+")do
w=w:lower()if not(" the and of to a i it in or is "):find(" "..w.." ")then
t[w]=1+(t[w]or 0)end
end
end
for k,v in next,t do
u[#u+1]={k,v}end
table.sort(u,function(a,b)return a[2]>b[2]end)m,n=u[1][2],math.min(#u,22)for w=80,1,-1 do
s=""for i=1,n do
a,b=u[i][1],w*u[i][2]/m
if b+#a>=78 then s=nil break end
s2=("_"):rep(b)if i==1 then
s=s.." " ..s2.."\n"end
s=s.."|"..s2.."| "..a.."\n"end
if s then print(s)break end end

Версия для чтения:

t,u={},{}
for line in io.lines() do
    for w in line:gmatch("%a+") do
        w = w:lower()
        if not (" the and of to a i it in or is "):find(" "..w.." ") then
            t[w] = 1 + (t[w] or 0)
        end
    end
end
for k, v in pairs(t) do
    u[#u+1]={k, v}
end

table.sort(u, function(a, b)
    return a[2] > b[2]
end)

local max = u[1][2]
local n = math.min(#u, 22)

for w = 80, 1, -1 do
    s=""
    for i = 1, n do
        f = u[i][2]
        word = u[i][1]
        width = w * f / max
        if width + #word >= 78 then
            s=nil
            break
        end
        s2=("_"):rep(width)
        if i==1 then
            s=s.." " .. s2 .."\n"
        end
        s=s.."|" .. s2 .. "| " .. word.."\n"
    end
    if s then
        print(s)
        break
    end
end
avatar
belisarius
9 июля 2010 в 04:11
28

Mathematica ( 297 284 248 244 <

8> Функция 24502 ​​chap)

и проверка закона Ципфа

Смотри, мама ... ни варов, ни рук, .. ни головы

Редактировать 1> определены некоторые сокращения (284 символа)

f[x_, y_] := Flatten[Take[x, All, y]]; 

BarChart[f[{##}, -1], 
         BarOrigin -> Left, 
         ChartLabels -> Placed[f[{##}, 1], After], 
         Axes -> None
] 
& @@
Take[
  SortBy[
     Tally[
       Select[
        StringSplit[ToLowerCase[Import[i]], RegularExpression["\\W+"]], 
       !MemberQ[{"the", "and", "of", "to", "a", "i", "it", "in", "or","is"}, #]&]
     ], 
  Last], 
-22]

Некоторые пояснения

Import[] 
   # Get The File

ToLowerCase []
   # To Lower Case :)

StringSplit[ STRING , RegularExpression["\\W+"]]
   # Split By Words, getting a LIST

Select[ LIST, !MemberQ[{LIST_TO_AVOID}, #]&]
   #  Select from LIST except those words in LIST_TO_AVOID
   #  Note that !MemberQ[{LIST_TO_AVOID}, #]& is a FUNCTION for the test

Tally[LIST]
   # Get the LIST {word,word,..} 
     and produce another  {{word,counter},{word,counter}...}

SortBy[ LIST ,Last]
   # Get the list produced bt tally and sort by counters
     Note that counters are the LAST element of {word,counter}

Take[ LIST ,-22]
   # Once sorted, get the biggest 22 counters

BarChart[f[{##}, -1], ChartLabels -> Placed[f[{##}, 1], After]] &@@ LIST
   # Get the list produced by Take as input and produce a bar chart

f[x_, y_] := Flatten[Take[x, All, y]]
   # Auxiliary to get the list of the first or second element of lists of lists x_
     dependending upon y
   # So f[{##}, -1] is the list of counters
   # and f[{##}, 1] is the list of words (labels for the chart)

Вывод

альтернативный текст http://i49.tinypic.com/2n8mrer.jpg

Mathematica не очень подходит для игры в гольф, и это только из-за длинных описательных имен функций. Такие функции, как "RegularExpression []" или "StringSplit []" заставляют меня рыдать :(.

Проверка закона Ципфа

Закон Ципфа предсказывает, что для текста на естественном языке Log (Rank) vs Log (вхождений) Log (вхождений) <93439> линейный > отношения.

Закон используется при разработке алгоритмов криптографии и сжатия данных. (Но это НЕ "Z" в алгоритме LZW).

В нашем тексте мы можем проверить это с помощью следующего

 f[x_, y_] := Flatten[Take[x, All, y]]; 
 ListLogLogPlot[
     Reverse[f[{##}, -1]], 
     AxesLabel -> {"Log (Rank)", "Log Counter"}, 
     PlotLabel -> "Testing Zipf's Law"]
 & @@
 Take[
  SortBy[
    Tally[
       StringSplit[ToLowerCase[b], RegularExpression["\\W+"]]
    ], 
   Last],
 -1000]

Результат (довольно линейный)

альтернативный текст http://i46.tinypic.com/33fcmdk.jpg

Редактировать 6> (242 символа)

Рефакторинг Regex (больше нет функции Select)
Удаление 1 символьных слов
Более эффективное определение функции "f"

f = Flatten[Take[#1, All, #2]]&; 
BarChart[
     f[{##}, -1], 
     BarOrigin -> Left, 
     ChartLabels -> Placed[f[{##}, 1], After], 
     Axes -> None] 
& @@
  Take[
    SortBy[
       Tally[
         StringSplit[ToLowerCase[Import[i]], 
          RegularExpression["(\\W|\\b(.|the|and|of|to|i[tns]|or)\\b)+"]]
       ],
    Last],
  -22]

Изменить 7 → 199 символов

BarChart[#2, BarOrigin->Left, ChartLabels->Placed[#1, After], Axes->None]&@@ 
  Transpose@Take[SortBy[Tally@StringSplit[ToLowerCase@Import@i, 
    RegularExpression@"(\\W|\\b(.|the|and|of|to|i[tns]|or)\\b)+"],Last], -22]
  • Заменены аргументы f на Transpose и Slot (#1 / #2).
  • Нам не нужны вонючие скобки (используйте f@x вместо f[x], где это возможно)

Gabe
4 июля 2010 в 16:39
9

Вы думаете, что «RegularExpression» - это плохо? Я плакал, когда набирал «System.Text.RegularExpressions.Regex.Split» в версии C #, пока не увидел код Objective-C: «stringWithContentsOfFile», «enumerateSubstringsInRange», «NSStringEnumerationByWords», «sortedArrayUsingComparator» .

Dr. belisarius
4 июля 2010 в 17:20
2

@Gabe Спасибо ... Мне уже лучше. По-испански мы говорим "mal de muchos, consuelo de tontos" .. Что-то вроде "Многие встревожены, дураки получили облегчение": D

Gabe
4 июля 2010 в 23:29
1

|i| избыточен в вашем регулярном выражении, потому что у вас уже есть .|.

dreeves
5 июля 2010 в 03:01
1

Мне нравится эта испанская поговорка. Самое близкое, что я могу придумать на английском, - это «несчастье любит компанию». Вот моя попытка перевода: «Глупец, страдая, утешается тем, что думает о других в такой же ситуации». Замечательная работа над реализацией Mathematica, кстати.

Dr. belisarius
5 июля 2010 в 04:24
0

@dreeves Глупость легко преодолевает языковой барьер ... Рад видеть, что вам нравится моя маленькая программа Mathematica, я только начинаю изучать язык

Dr. belisarius
9 июля 2010 в 04:39
0

@Michael Pilat Вау! Мне нужно многому научиться ... замечательно!

Joey
11 июля 2010 в 08:45
0

Версия 199 не будет интерпретировать такие вещи, как the_foo в соответствии со спецификацией, верно?

Dr. belisarius
17 июля 2010 в 16:38
0

@Johannes Rössel Хороший глаз! Ошибка во всех версиях связана с тем, что Mathematica сопоставляет подчеркивание как букву char (почему они это сделали ?? !!). Регулярное выражение должно иметь вид «(_ | \\ W | \\ b (. | | И | из | to | i [tns] | или) \\ b) +», но \\ W также распознает цифры как буквы, так что, возможно, совершенно правильный вариант немного длиннее.

Joey
17 июля 2010 в 19:36
0

@belisarius: На самом деле все движки с регулярными выражениями рассматривают \w как что-то вроде [a-zA-Z0-9_] или, возможно, [\p{L}\p{Nd}_] для движков с поддержкой Unicode. И поскольку \b считается границей между \w и \W, это не работает в соответствии со спецификацией здесь. Но во многих решениях есть эта проблема, и мне потребовалось немало персонажей, чтобы исправить эту часть в моем решении. Что касается почему , я думаю, что он соответствует тому, что многие языки программирования допускают в качестве идентификаторов. Вы можете просто сопоставить их с \w+ (не вполне , но достаточно близко для большинства хакерских решений).

avatar
mob
8 июля 2010 в 20:05
6

Perl, 185 символов

200 (слегка сломанный) 199 197 195 193 187 185 знаков. Последние два символа новой строки значимы. Соответствует спецификации.

map$X{+lc}+=!/^(.|the|and|to|i[nst]|o[rf])$/i,/[a-z]+/gfor<>;
$n=$n>($:=$X{$_}/(76-y+++c))?$n:$:for@w=(sort{$X{$b}-$X{$a}}%X)[0..21];
die map{$U='_'x($X{$_}/$n);" $U
"x!$z++,"|$U| $_
"}@w

Первая строка загружает количество допустимых слов в %X.

Вторая строка вычисляет минимальный коэффициент масштабирования, чтобы все выходные строки были <= 80 символов.

Третья строка (содержит два символа новой строки) производит вывод.

Joey
6 июля 2010 в 14:02
0

Это не удалит стоп-слова из таких строк, как "foo_the_bar". Длина строки также слишком велика (перечитайте спецификацию: «полоса + пробел + слово + пробел <= 80 символов»)

avatar
8 июля 2010 в 18:53
2

Clojure - 611 символов (не свернуто)

Я попытался написать код на как можно более идиоматическом языке Clojure, так поздно ночью. Я не слишком горжусь функцией draw-chart, но полагаю, что код многое говорит о лаконичности Clojure.

(ns word-freq
(:require [clojure.contrib.io :as io]))

(defn word-freq
  [f]
  (take 22 (->> f
                io/read-lines ;;; slurp should work too, but I love map/red
                (mapcat (fn [l] (map #(.toLowerCase %) (re-seq #"\w+" l))))
                (remove #{"the" "and" "of" "to" "a" "i" "it" "in" "or" "is"})
                (reduce #(assoc %1 %2 (inc (%1 %2 0))) {})
                (sort-by (comp - val)))))

(defn draw-chart
  [fs]
  (let [[[w f] & _] fs]
    (apply str
           (interpose \newline
                      (map (fn [[k v]] (apply str (concat "|" (repeat (int (* (- 76 (count w)) (/ v f 1))) "_") "| " k " ")) ) fs)))))

;;; (println (draw-chart (word-freq "/Users/ghoseb/Desktop/alice.txt")))

Вывод:

|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|____________________________________________________| alice 
|_______________________________________________| was 
|___________________________________________| that 
|____________________________________| as 
|________________________________| her 
|_____________________________| with 
|_____________________________| at 
|____________________________| t 
|____________________________| s 
|__________________________| on 
|__________________________| all 
|_______________________| for 
|_______________________| had 
|_______________________| this 
|_______________________| but 
|______________________| be 
|_____________________| not 
|____________________| they 
|____________________| so

Я знаю, это не соответствует спецификации, но, эй, это очень чистый код Clojure, который и так мал :)

avatar
Martin Smith
7 июля 2010 в 18:55
35

Решение на основе набора Transact SQL (SQL Server 2005) 1063 892 873 <499353793411351135> 8549935793411358 > 820 783 683 647 644 <

35> 6

Спасибо Гейбу за несколько полезных советов по сокращению количества символов.

NB: добавлены разрывы строк, чтобы избежать полос прокрутки, требуется только последний разрыв строки.

DECLARE @ VARCHAR(MAX),@F REAL SELECT @=BulkColumn FROM OPENROWSET(BULK'A',
SINGLE_BLOB)x;WITH N AS(SELECT 1 i,LEFT(@,1)L UNION ALL SELECT i+1,SUBSTRING
(@,i+1,1)FROM N WHERE i<LEN(@))SELECT i,L,i-RANK()OVER(ORDER BY i)R INTO #D
FROM N WHERE L LIKE'[A-Z]'OPTION(MAXRECURSION 0)SELECT TOP 22 W,-COUNT(*)C
INTO # FROM(SELECT DISTINCT R,(SELECT''+L FROM #D WHERE R=b.R FOR XML PATH
(''))W FROM #D b)t WHERE LEN(W)>1 AND W NOT IN('the','and','of','to','it',
'in','or','is')GROUP BY W ORDER BY C SELECT @F=MIN(($76-LEN(W))/-C),@=' '+
REPLICATE('_',-MIN(C)*@F)+' 'FROM # SELECT @=@+' 
|'+REPLICATE('_',-C*@F)+'| '+W FROM # ORDER BY C PRINT @

Версия для чтения

DECLARE @  VARCHAR(MAX),
        @F REAL
SELECT @=BulkColumn
FROM   OPENROWSET(BULK'A',SINGLE_BLOB)x; /*  Loads text file from path
                                             C:\WINDOWS\system32\A  */

/*Recursive common table expression to
generate a table of numbers from 1 to string length
(and associated characters)*/
WITH N AS
     (SELECT 1 i,
             LEFT(@,1)L

     UNION ALL

     SELECT i+1,
            SUBSTRING(@,i+1,1)
     FROM   N
     WHERE  i<LEN(@)
     )
  SELECT   i,
           L,
           i-RANK()OVER(ORDER BY i)R
           /*Will group characters
           from the same word together*/
  INTO     #D
  FROM     N
  WHERE    L LIKE'[A-Z]'OPTION(MAXRECURSION 0)
             /*Assuming case insensitive accent sensitive collation*/

SELECT   TOP 22 W,
         -COUNT(*)C
INTO     #
FROM     (SELECT DISTINCT R,
                          (SELECT ''+L
                          FROM    #D
                          WHERE   R=b.R FOR XML PATH('')
                          )W
                          /*Reconstitute the word from the characters*/
         FROM             #D b
         )
         T
WHERE    LEN(W)>1
AND      W NOT IN('the',
                  'and',
                  'of' ,
                  'to' ,
                  'it' ,
                  'in' ,
                  'or' ,
                  'is')
GROUP BY W
ORDER BY C

/*Just noticed this looks risky as it relies on the order of evaluation of the 
 variables. I'm not sure that's guaranteed but it works on my machine :-) */
SELECT @F=MIN(($76-LEN(W))/-C),
       @ =' '      +REPLICATE('_',-MIN(C)*@F)+' '
FROM   #

SELECT @=@+' 
|'+REPLICATE('_',-C*@F)+'| '+W
             FROM     #
             ORDER BY C

PRINT @

Вывод

 _________________________________________________________________________ 
|_________________________________________________________________________| she
|_______________________________________________________________| You
|____________________________________________________________| said
|_____________________________________________________| Alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| at
|_____________________________| with
|__________________________| on
|__________________________| all
|_______________________| This
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| So
|___________________| very
|__________________| what

И с длинной строкой

 _______________________________________________________________ 
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|____________________________________________________| said
|______________________________________________| Alice
|________________________________________| was
|_____________________________________| that
|_______________________________| as
|____________________________| her
|_________________________| at
|_________________________| with
|_______________________| on
|______________________| all
|____________________| This
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|__________________| not
|_________________| they
|_________________| So
|________________| very
|________________| what
user174624
4 июля 2010 в 00:03
12

Я поставил вам +1, потому что вы сделали это в T-SQL, и процитирую Команду Америки: «У вас есть яйца. Я люблю яйца».

Gabe
4 июля 2010 в 07:33
0

Я взял на себя смелость преобразовать некоторые пробелы в символы новой строки, чтобы сделать его более читабельным. Надеюсь, я ничего не напортачил. Я также немного уменьшил его.

Martin Smith
4 июля 2010 в 12:06
0

@Gabe Спасибо. Однако в итоге я в значительной степени его переписал. Теперь он стал короче и быстрее, чем раньше.

Joey
4 июля 2010 в 14:27
3

Этот код кричит на меня! : O

Gabe
4 июля 2010 в 15:13
1

Один хороший способ сэкономить - изменить 0.000 на 0, а затем использовать -C вместо 1.0/C. И преобразование FLOAT в REAL также сэкономит ход. Но самое главное - похоже, что у вас много экземпляров AS, которые должны быть необязательными.

Martin Smith
4 июля 2010 в 19:24
0

@Gabe - Спасибо за советы. Я смог заменить float на real и избавиться от некоторых AS, два оставшихся необходимы. Фишка -C не сработала. Строка с 0 - это верх верхней панели. Он оказался внизу, и мне пришлось бы заменить 0,000 отрицательным числом с большой величиной, чтобы получить его в нужном месте. Спасибо хоть!

Gabe
4 июля 2010 в 20:02
0

Как насчет этого: SELECT $0 O, ' '+REPLICATE('_', MAX(C)*@F)+' ' [ ] FROM # UNION SELECT $1/C, '|'+REPLICATE('_',C*@F)+'| '+W FROM # ORDER BY 1

Martin Smith
4 июля 2010 в 20:52
0

@Gabe - Да, это работает, спасибо, я реализую вещь $. Проблема в том, что он возвращает дополнительный; столбец к выходу, который не является частью спецификации (отсюда необходимость в дополнительном шаге временной таблицы)

Gabe
4 июля 2010 в 23:06
1

Хорошо, а как насчет SELECT [ ] FROM (SELECT $0 O, ' '+REPLICATE('_', MAX(C)*@F)+' ' [ ] FROM # UNION SELECT $1/C, '|'+REPLICATE('_',C*@F)+'| '+W FROM #)X ORDER BY O?

Martin Smith
5 июля 2010 в 00:32
0

@Gabe - Отлично! В результате его комфортно меньше 800. Спасибо за вашу помощь!

Gabe
5 июля 2010 в 04:09
0

Вам не нужно объявлять @F, где он используется. Вы можете объявить его с помощью @ и сохранить все символы DECLARE.

Gabe
5 июля 2010 в 04:44
0

i-ROW_NUMBER то же самое, что и RANK? Можно ли переместить второй CTE в раздел FROM, где он используется? Можно ли преобразовать запрос таблицы #D в CTE? Можно ли превратить запрос таблицы #t в CTE или хотя бы поместить в предложение FROM запроса SELECT TOP 22?

Martin Smith
5 июля 2010 в 06:40
0

@Gabe - Спасибо, все хорошие моменты. Также были внесены некоторые другие упрощения и в совокупности сбиты еще 100. "#D" должна быть временной таблицей. На данный момент на моей машине это занимает около 12 секунд. Переход на CTE значительно замедлил его (я отменил запрос через 2 минуты, поэтому не знаю, сколько времени это заняло бы - или действительно ли оно было бы завершено вообще) - Мартин Смит 6 минут назад

RichardTheKiwi
13 февраля 2012 в 01:28
0

@Gabe Мне нравится твой дуэт с Мартином. Я взял плоскодонку и попытался ее укоротить (другой ответ) - мне показалось, что CTE выглядит длинновато.

avatar
7 июля 2010 в 16:53
1

Go, 613 символов, вероятно, может быть намного меньше:

package main
import(r "regexp";. "bytes";. "io/ioutil";"os";st "strings";s "sort";. "container/vector")
type z struct{c int;w string}
func(e z)Less(o interface{})bool{return o.(z).c<e.c}
func main(){b,_:=ReadAll(os.Stdin);g:=r.MustCompile
c,m,x:=g("[A-Za-z]+").AllMatchesIter(b,0),map[string]int{},g("the|and|of|it|in|or|is|to")
for w:=range c{w=ToLower(w);if len(w)>1&&!x.Match(w){m[string(w)]++}}
o,y:=&Vector{},0
for k,v:=range m{o.Push(z{v,k});if v>y{y=v}}
s.Sort(o)
for i,v:=range *o{if i>21{break};x:=v.(z);c:=int(float(x.c)/float(y)*80)
u:=st.Repeat("_",c);if i<1{println(" "+u)};println("|"+u+"| "+x.w)}}

Я чувствую себя такой грязной.

avatar
pr1001
7 июля 2010 в 12:24
4

Scala, 368 символов

Во-первых, разборчивый вариант из 592 символов:

object Alice {
  def main(args:Array[String]) {
    val s = io.Source.fromFile(args(0))
    val words = s.getLines.flatMap("(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r.findAllIn(_)).map(_.toLowerCase)
    val freqs = words.foldLeft(Map[String, Int]())((countmap, word)  => countmap + (word -> (countmap.getOrElse(word, 0)+1)))
    val sortedFreqs = freqs.toList.sort((a, b)  => a._2 > b._2)
    val top22 = sortedFreqs.take(22)
    val highestWord = top22.head._1
    val highestCount = top22.head._2
    val widest = 76 - highestWord.length
    println(" " + "_" * widest)
    top22.foreach(t => {
      val width = Math.round((t._2 * 1.0 / highestCount) * widest).toInt
      println("|" + "_" * width + "| " + t._1)
    })
  }
}

Вывод консоли выглядит следующим образом:

$ scalac alice.scala 
$ scala Alice aliceinwonderland.txt
 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| at
|______________________________| with
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
|___________________| very
|___________________| what

Мы можем выполнить агрессивное минимизирование и сократить его до 415 символов:

object A{def main(args:Array[String]){val l=io.Source.fromFile(args(0)).getLines.flatMap("(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r.findAllIn(_)).map(_.toLowerCase).foldLeft(Map[String, Int]())((c,w)=>c+(w->(c.getOrElse(w,0)+1))).toList.sort((a,b)=>a._2>b._2).take(22);println(" "+"_"*(76-l.head._1.length));l.foreach(t=>println("|"+"_"*Math.round((t._2*1.0/l.head._2)*(76-l.head._1.length)).toInt+"| "+t._1))}}

Сеанс консоли выглядит так:

$ scalac a.scala 
$ scala A aliceinwonderland.txt
 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| at
|______________________________| with
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
|___________________| very
|___________________| what

Я уверен, что эксперт по Scala может добиться большего.

Обновление: В комментариях Томас дал еще более короткую версию, на 368 символов:

object A{def main(a:Array[String]){val t=(Map[String, Int]()/:(for(x<-io.Source.fromFile(a(0)).getLines;y<-"(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r findAllIn x) yield y.toLowerCase).toList)((c,x)=>c+(x->(c.getOrElse(x,0)+1))).toList.sortBy(_._2).reverse.take(22);val w=76-t.head._1.length;print(" "+"_"*w);t map (s=>"\n|"+"_"*(s._2*w/t.head._2)+"| "+s._1) foreach print}}

Разборчиво, из 375 знаков:

object Alice {
  def main(a:Array[String]) {
    val t = (Map[String, Int]() /: (
      for (
        x <- io.Source.fromFile(a(0)).getLines
        y <- "(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r.findAllIn(x)
      ) yield y.toLowerCase
    ).toList)((c, x) => c + (x -> (c.getOrElse(x, 0) + 1))).toList.sortBy(_._2).reverse.take(22)
    val w = 76 - t.head._1.length
    print (" "+"_"*w)
    t.map(s => "\n|" + "_" * (s._2 * w / t.head._2) + "| " + s._1).foreach(print)
  }
}
Thomas Jung
6 июля 2010 в 11:53
0

383 символа: object A{def main(a:Array[String]){val t=(Map[String, Int]()/:(for(x<-io.Source.fromFile(a(0)).getLines;y<-"(?i)\\w+\\b(?<!\\bthe|and|of|to|a|i|it|in|or|is)".r findAllIn x) yield y.toLowerCase).toList)((c,x)=>c+(x->(c.getOrElse(x,0)+1))).toList.sortBy(_._2).reverse.take(22);val w=76-t.head._1.length;print(" "+"_"*w);t map (s=>"\n|"+"_"*(s._2*w/t.head._2)+"| "+s._1) foreach print}}

pr1001
7 июля 2010 в 11:52
0

Конечно, всегда пригодится для понимания! Отлично!

avatar
7 июля 2010 в 12:21
4

Clojure 282 strict

(let[[[_ m]:as s](->>(slurp *in*).toLowerCase(re-seq #"\w+\b(?<!\bthe|and|of|to|a|i[tns]?|or)")frequencies(sort-by val >)(take 22))[b](sort(map #(/(- 76(count(key %)))(val %))s))p #(do(print %1)(dotimes[_(* b %2)](print \_))(apply println %&))](p " " m)(doseq[[k v]s](p \| v \| k)))

Несколько более разборчиво:

(let[[[_ m]:as s](->> (slurp *in*)
                   .toLowerCase
                   (re-seq #"\w+\b(?<!\bthe|and|of|to|a|i[tns]?|or)")
                   frequencies
                   (sort-by val >)
                   (take 22))
     [b] (sort (map #(/ (- 76 (count (key %)))(val %)) s))
     p #(do
          (print %1)
          (dotimes[_(* b %2)] (print \_))
          (apply println %&))]
  (p " " m)
  (doseq[[k v] s] (p \| v \| k)))
avatar
6 июля 2010 в 22:18
1

Руби, 205


Эта версия Ruby обрабатывает «superlongstringstring». (Первые две строки почти идентичны предыдущим программам Ruby.)

Он должен быть запущен следующим образом:

ruby -n0777 golf.rb Alice.txt


W=($_.upcase.scan(/\w+/)-%w(THE AND OF TO A I IT
IN OR IS)).group_by{|x|x}.map{|k,v|[-v.size,k]}.sort[0,22]
u=proc{|m|"_"*(W.map{|n,s|(76.0-s.size)/n}.max*m)}
puts" "+u[W[0][0]],W.map{|n,s|"|%s| "%u[n]+s}

Третья строка создает замыкание или лямбду, которая дает правильно масштабированную строку подчеркивания:

u = proc{|m|
  "_" *
    (W.map{|n,s| (76.0 - s.size)/n}.max * m)
}

.max используется вместо .min, потому что числа отрицательные.

ChristopheD
5 июля 2010 в 05:11
0

Реализация полной спецификации и все еще очень короткая (213 символов на данный момент согласно wc -c), отличная работа!

avatar
pdehaan
6 июля 2010 в 16:13
11

perl, 205 191 189 символов / 205 символов (полностью реализовано)

Некоторые части были вдохновлены более ранними представлениями perl / ruby, пара похожих идей была выработана независимо, другие оригинальны. Более короткая версия также включает в себя некоторые вещи, которые я видел / узнал из других материалов.

Оригинал:

$k{$_}++for grep{$_!~/^(the|and|of|to|a|i|it|in|or|is)$/}map{lc=~/[a-z]+/g}<>;@t=sort{$k{$b}<=>$k{$a}}keys%k;$l=76-length$t[0];printf" %s
",'_'x$l;printf"|%s| $_
",'_'x int$k{$_}/$k{$t[0]}*$l for@t[0..21];

Последняя версия до 191 символа:

/^(the|and|of|to|.|i[tns]|or)$/||$k{$_}++for map{lc=~/[a-z]+/g}<>;@e=sort{$k{$b}<=>$k{$a}}keys%k;$n=" %s
";$r=(76-y///c)/$k{$_=$e[0]};map{printf$n,'_'x($k{$_}*$r),$_;$n="|%s| %s
"}@e[0,0..21]

Последняя версия до 189 символов:

/^(the|and|of|to|.|i[tns]|or)$/||$k{$_}++for map{lc=~/[a-z]+/g}<>;@_=sort{$k{$b}<=>$k{$a}}keys%k;$n=" %s
";$r=(76-m//)/$k{$_=$_[0]};map{printf$n,'_'x($k{$_}*$r),$_;$n="|%s| %s
"}@_[0,0..21]

Эта версия (205 символов) учитывает строки со словами длиннее, чем то, что будет найдено позже.

/^(the|and|of|to|.|i[tns]|or)$/||$k{$_}++for map{lc=~/[a-z]+/g}<>;($r)=sort{$a<=>$b}map{(76-y///c)/$k{$_}}@e=sort{$k{$b}<=>$k{$a}}keys%k;$n=" %s
";map{printf$n,'_'x($k{$_}*$r),$_;$n="|%s| %s
";}@e[0,0..21]
avatar
6 июля 2010 в 11:55
1

GNU Smalltalk (386)

Думаю, его можно сделать немного короче, но пока не знаю, как это сделать.

|q s f m|q:=Bag new. f:=FileStream stdin. m:=0.[f atEnd]whileFalse:[s:=f nextLine.(s notNil)ifTrue:[(s tokenize:'\W+')do:[:i|(((i size)>1)&({'the'.'and'.'of'.'to'.'it'.'in'.'or'.'is'}includes:i)not)ifTrue:[q add:(i asLowercase)]. m:=m max:(i size)]]].(q:=q sortedByCount)from:1to:22 do:[:i|'|'display.((i key)*(77-m)//(q first key))timesRepeat:['='display].('| %1'%{i value})displayNl]
avatar
ShinTakezou
6 июля 2010 в 11:55
6

С (828)

Он очень похож на запутанный код и использует glib для строки, списка и хэша. Счетчик символов с wc -m означает 828 . Односимвольные слова не рассматриваются. Чтобы вычислить максимальную длину полосы, учитывается самое длинное слово среди всех, а не только первые 22. Это отклонение от спецификации?

Он не обрабатывает сбои и не освобождает используемую память.

#include <glib.h>
#define S(X)g_string_##X
#define H(X)g_hash_table_##X
GHashTable*h;int m,w=0,z=0;y(const void*a,const void*b){int*A,*B;A=H(lookup)(h,a);B=H(lookup)(h,b);return*B-*A;}void p(void*d,void*u){int *v=H(lookup)(h,d);if(w<22){g_printf("|");*v=*v*(77-z)/m;while(--*v>=0)g_printf("=");g_printf("| %s\n",d);w++;}}main(c){int*v;GList*l;GString*s=S(new)(NULL);h=H(new)(g_str_hash,g_str_equal);char*n[]={"the","and","of","to","it","in","or","is"};while((c=getchar())!=-1){if(isalpha(c))S(append_c)(s,tolower(c));else{if(s->len>1){for(c=0;c<8;c++)if(!strcmp(s->str,n[c]))goto x;if((v=H(lookup)(h,s->str))!=NULL)++*v;else{z=MAX(z,s->len);v=g_malloc(sizeof(int));*v=1;H(insert)(h,g_strdup(s->str),v);}}x:S(truncate)(s,0);}}l=g_list_sort(H(get_keys)(h),y);m=*(int*)H(lookup)(h,g_list_first(l)->data);g_list_foreach(l,p,NULL);}
Stéphan Kochen
4 июля 2010 в 10:31
0

Новые строки считаются символами, но вы можете удалить любую из строк, которые не являются инструкциями препроцессора. Что касается гольфа, я бы не стал считать отказ от освобождения памяти плохой практикой.

ShinTakezou
4 июля 2010 в 10:48
0

хорошо ... поместите все в строку (ожидайте макросы препроцессора) и дайте vers без освобождения памяти (и с удалением двух других пробелов ... небольшое улучшение можно сделать в "обфускации", например, *v=*v*(77-lw)/m будет дайте 929 ... но я думаю, что все будет хорошо, если я не найду способ сделать это намного короче)

Joey
4 июля 2010 в 11:27
0

Я думаю, вы можете переместить по крайней мере int c в объявление main, а main неявно int (как и любые нетипизированные аргументы, afaik): main(c){...}. Возможно, вы могли бы просто написать 0 вместо NULL.

ShinTakezou
4 июля 2010 в 11:36
0

делать это ... конечно, вызовет какое-то предупреждение с включенным флагом -Wall или -std=c99 ... но я полагаю, что это бессмысленно для кодового гольфа, верно?

ShinTakezou
4 июля 2010 в 11:48
0

уфф, извините за редактирование с коротким промежутком времени, ... Я должен заменить Without freeing memory stuff, it reaches 866 (removed some other unuseful space) на что-то другое, чтобы люди не думали, что разница с версией со свободной памятью заключается в этом: теперь версия без свободной памяти имеет еще много "улучшений".

ShinTakezou
5 июля 2010 в 06:25
0

еще можно сделать некоторые улучшения, сокращая имена переменных + функция

dmckee --- ex-moderator kitten
6 июля 2010 в 05:59
0

@Shin: Кстати, на один вопрос может быть несколько ответов. Прокрутите страницу до самого низа и найдите кнопку [Добавить другой ответ]. Я предположил, что он сдвинулся вниз, потому что ожидалось, что множественный ответ будет исключением, а не правилом.

ShinTakezou
6 июля 2010 в 11:54
0

@dmckee спасибо, я собираюсь распутать C и Smalltalk!

avatar
mkneissl
6 июля 2010 в 07:20
4

Scala 2.8, 311 314 320 332 <347337349855> 33798557337349855> 3379855733734834> > 375 символов

включая настройку длинного слова. Идеи позаимствованы из других решений.

Теперь как сценарий (a.scala):

val t="\\w+\\b(?<!\\bthe|and|of|to|a|i[tns]?|or)".r.findAllIn(io.Source.fromFile(argv(0)).mkString.toLowerCase).toSeq.groupBy(w=>w).mapValues(_.size).toSeq.sortBy(-_._2)take 22
def b(p:Int)="_"*(p*(for((w,c)<-t)yield(76.0-w.size)/c).min).toInt
println(" "+b(t(0)._2))
for(p<-t)printf("|%s| %s \n",b(p._2),p._1)

Запустить с

scala -howtorun:script a.scala alice.txt

Кстати, при редактировании с 314 до 311 символов фактически удаляется только 1 символ. Кто-то раньше ошибался при подсчете (Windows CR?).

avatar
Nas Banov
6 июля 2010 в 04:44
19

Python 2.x, широтный подход = 227 183 символа

import sys,re
t=re.split('\W+',sys.stdin.read().lower())
r=sorted((-t.count(w),w)for w in set(t)if w not in'andithetoforinis')[:22]
for l,w in r:print(78-len(r[0][1]))*l/r[0][0]*'=',w

Допуская свободу в реализации, я построил конкатенацию строк, которая содержит все слова, запрошенные для исключения (the, and, of, to, a, i, it, in, or, is), плюс она также исключает два печально известных «слова» s и t из примера - и я добавил бесплатно исключение для an, for, he. Я попробовал все конкатенации этих слов с корпусом слов из Алисы, Библии короля Иакова и файла жаргона, чтобы увидеть, есть ли какие-то слова, которые будут ошибочно исключены строкой. И вот так я закончил двумя строками исключения: itheandtoforinis и andithetoforinis.

PS. заимствовано из других решений для сокращения кода.

=========================================================================== she 
================================================================= you
============================================================== said
====================================================== alice
================================================ was
============================================ that
===================================== as
================================= her
============================== at
============================== with
=========================== on
=========================== all
======================== this
======================== had
======================= but
====================== be
====================== not
===================== they
==================== so
=================== very
=================== what
================= little

Рэнт

Что касается слов, которые следует игнорировать, можно подумать, что они взяты из списка наиболее часто используемых слов в английском языке. Этот список зависит от используемого текстового корпуса . По одному из самых популярных списков (http://en.wikipedia.org/wiki/Most_common_words_in_English, http://www.english-for-students.com/Frequent-Used-Words .html, http://www.sporcle.com/games/common_english_words.php), первые 10 слов: the be(am/are/is/was/were) to of and a in that have I

Первые 10 слов из текста «Алиса в стране чудес»: the and to a of it she i you said
Первые 10 слов из файла жаргона (v4.4.7): the a of to and in is that or for

Итак, вопрос в том, почему or был включен в список игнорирования проблемы, где он ~ 30-й по популярности, тогда как слово that (8-е место по популярности) нет. и т. д. и т. д. Следовательно, я считаю, что список игнорирования должен предоставляться динамически (или его можно не указывать).

Альтернативный вариант - просто пропустить первые 10 слов из результата - что фактически сократит решение (элементарно - должно отображаться только с 11-й по 32-ю записи).


Python 2.x, щепетильный подход = 277 243 символа

Диаграмма, нарисованная в приведенном выше коде, упрощена (с использованием только одного символа для столбцов). Если кто-то хочет точно воспроизвести диаграмму из описания проблемы (что не требовалось), этот код сделает это:

import sys,re
t=re.split('\W+',sys.stdin.read().lower())
r=sorted((-t.count(w),w)for w in set(t)-set(sys.argv))[:22]
h=min(9*l/(77-len(w))for l,w in r)
print'',9*r[0][0]/h*'_'
for l,w in r:print'|'+9*l/h*'_'+'|',w

У меня проблема с несколько случайным выбором из 10 слов для исключения the, and, of, to, a, i, it, in, or, is, поэтому они должны быть переданы как параметры командной строки, например:
python WordFrequencyChart.py the and of to a i it in or is <"Alice's Adventures in Wonderland.txt"

Это 213 символов + 30, если мы учитываем "исходный" список игнорирования, переданный в командной строке = 243

PS. Второй код также выполняет «корректировку» длин всех верхних слов, поэтому ни одно из них не будет переполняться в вырожденном регистре.

 _______________________________________________________________
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|_____________________________________________________| said
|______________________________________________| alice
|_________________________________________| was
|______________________________________| that
|_______________________________| as
|____________________________| her
|__________________________| at
|__________________________| with
|_________________________| s
|_________________________| t
|_______________________| on
|_______________________| all
|____________________| this
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|___________________| not
|_________________| they
|_________________| so
ChristopheD
3 июля 2010 в 07:05
0

Хорошее решение, хотя список игнорирования слов не реализован (пока), а полосы на данный момент немного рудиментарны.

Nas Banov
3 июля 2010 в 09:47
0

@ChristopheD: оно было, но не было «руководства пользователя». Только что добавлен текст

Joey
11 июля 2010 в 09:10
0

Что касается вашего списка языков и решений: пожалуйста, ищите решения, которые используют разделение по \W или \b в регулярном выражении, потому что они, скорее всего, не в соответствии со спецификацией, то есть они не будут разделены на цифры или _, и они также могут не удалять стоп-слова из строк, таких как the_foo_or123bar. Они могут не появляться в тестовом тексте, но в этом случае спецификация довольно ясна.

intgr
2 апреля 2012 в 18:09
0

Потрясающая работа. Nas, я потратил день, пытаясь оптимизировать это, и нашел только одно улучшение. Вы можете сократить его до 239 символов, удалив хак sys.argv и используя: re.findall(r'\b(?!(?:the|and|.|of|to|i[tns]|or)\b)\w+',sys.stdin.read().lower())

avatar
kriss
6 июля 2010 в 02:55
3

Еще один Python 2.x - 206 символов (или 232 с полосой ширины)

Я считаю, что это полностью соответствует вопросу. Список игнорирования находится здесь, он полностью проверяет длину строки (см. Пример, где я заменил Alice на Aliceinwonderlandbylewiscarroll через текст, делающий пятый элемент самой длинной строкой. Даже имя файла предоставляется из командной строки, а не жестко закодировано (жесткое кодирование будет удалите около 10 символов). У него есть один недостаток (но я считаю, что с этим вопросом все в порядке), поскольку он вычисляет целочисленный делитель, чтобы сделать строку короче 80 символов, самая длинная строка короче 80 символов, а не точно 80 символов. Python Версия 3.x не имеет этого дефекта (но намного длиннее).

Также я считаю, что это не так сложно читать.

import sys,re
t=re.split("\W+(?:(?:the|and|o[fr]|to|a|i[tns]?)\W+)*",sys.stdin.read().lower())
b=sorted((-t.count(x),x)for x in set(t))[:22]
for l,w in b:print"|"+l/min(z/(78-len(e))for z,e in b)*'-'+"|",w

|----------------------------------------------------------------| she
|--------------------------------------------------------| you
|-----------------------------------------------------| said
|----------------------------------------------| aliceinwonderlandbylewiscarroll
|-----------------------------------------| was
|--------------------------------------| that
|-------------------------------| as
|----------------------------| her
|--------------------------| at
|--------------------------| with
|-------------------------| s
|-------------------------| t
|-----------------------| on
|-----------------------| all
|---------------------| this
|--------------------| for
|--------------------| had
|--------------------| but
|-------------------| be
|-------------------| not
|------------------| they
|-----------------| so

Поскольку непонятно, должны ли мы печатать только максимальную полосу в этой строке (как в примере вывода). Ниже приведен еще один, но 232 символа.

import sys,re
t=re.split("\W+(?:(?:the|and|o[fr]|to|a|i[tns]?)\W+)*",sys.stdin.read().lower())
b=sorted((-t.count(x),x)for x in set(t))[:22]
f=min(z/(78-len(e))for z,e in b)
print"",b[0][0]/f*'-'
for y,w in b:print"|"+y/f*'-'+"|",w

Python 3.x - 256 символов

Используя класс Counter из python 3.x, были большие надежды сделать его короче (поскольку Counter делает все, что нам здесь нужно). Получается не лучше. Ниже мои пробные 266 символов:

import sys,re,collections as c
b=c.Counter(re.split("\W+(?:(?:the|and|o[fr]|to|a|i[tns]?)\W+)*",
sys.stdin.read().lower())).most_common(22)
F=lambda p,x,w:print(p+'-'*int(x/max(z/(77.-len(e))for e,z in b))+w)
F(" ",b[0][1],"")
for w,y in b:F("|",y,"| "+w)

Проблема в том, что collections и most_common - очень длинные слова и даже Counter не короткие ... действительно, без использования Counter код становится длиннее всего на 2 символа ;-(

Python 3.x также вводит другие ограничения: деление двух целых чисел больше не является целым числом (поэтому мы должны преобразовать его в int), print теперь является функцией (необходимо добавить скобки) и т. Д. Вот почему получается 22 символов длиннее версии python2.x, но намного быстрее. Может быть, еще у кого-нибудь из опытных программистов на Python 3.x появятся идеи по сокращению кода.

Ponkadoodle
7 июля 2010 в 03:39
0

Это умный способ сортировки по убыванию.

cemper93
31 декабря 2011 в 00:35
0

В решении Python 2 вы можете сделать for l,w in b:print"|"+int(l/min(z/(76.-len(e))for z,e in b))*'-'+"|",w в последней строке, чтобы правильно выровнять ваши строки. Это добавляет пять символов и заставляет ваш код придерживаться правил («Максимально увеличьте ширину полосы в рамках этих ограничений и соответствующим образом масштабируйте полосы»). Однако вы можете удалить несколько символов, импортировав os вместо sys, а затем выполнив os.read(0,1e9) вместо sys.stdin.read(). Это составляет 208 символов, что по-прежнему является одним из лучших решений.

avatar
6 июля 2010 в 02:46
1

perl , 188 символов

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

Я также включил некоторые другие предложения (- вместо <=> для / foreach отброшены "ключи"), чтобы добраться до

$c{$_}++for grep{$_}map{lc=~/\b(?!(?:the|and|a|of|or|i[nts]?|to)\b)[a-z]+/g}<>;@s=sort{$c{$b}-$c{$a}}%c;$f=76-length$s[0];say$"."_"x$f;say"|"."_"x($c{$_}/$c{$s[0]}*$f)."| $_ "for@s[0..21]

Я не знаю perl, но предполагаю, что (?! (?: ...) \ b) может потерять?:, Если обработка вокруг него исправлена.

Joey
6 июля 2010 в 14:08
0

Это вызывает у меня синтаксическую ошибку: »Строка найдена там, где ожидался оператор в строке 1 c.pl, рядом с синтаксической ошибкой" say "|" "в строке 1 c.pl, рядом с" say "|" "Шаблон поиска не завершен на c .pl строка 1. «(Perl 5.10.1). Также код выглядит так, как будто ограничение длины полосы не работает. И также вполне может быть, что такие строки, как foo_the_bar, не будут удалять стоп-слова (из-за \b).

avatar
mvds
6 июля 2010 в 02:39
1

shell, grep, tr, grep, sort, uniq, sort, head, perl - 194 символа

Добавление флагов -i может привести к потере слишком длинного tr A-Z a-z | шаг; в спецификации ничего не сказано об отображаемом регистре, а uniq -ci устраняет любые различия регистра.

egrep -oi [a-z]+|egrep -wiv 'the|and|o[fr]|to|a|i[tns]?'|sort|uniq -ci|sort -nr|head -22|perl -lape'($f,$w)=@F;$.>1or($q,$x)=($f,76-length$w);$b="_"x($f/$q*$x);$_="|$b| $w ";$.>1or$_=" $b\n$_"'

Это минус 11 для tr плюс 2 для -i по сравнению с исходными 206 символами.

редактировать: минус 3 для \\ b, который можно не указывать, поскольку сопоставление с образцом все равно начнется на границе.

sort сначала выдает строчные буквы, а uniq -ci принимает первое вхождение, поэтому единственное реальное изменение в выводе будет заключаться в том, что Алиса сохранит начальные буквы в верхнем регистре.

Joey
6 июля 2010 в 14:05
0

Ограничение длины стержня не работает.

avatar
6 июля 2010 в 00:29
1

Оболочка Борна, 213/240 символов

Улучшение версии оболочки, опубликованной ранее, я могу уменьшить ее до 213 символов:

tr A-Z a-z|tr -Cs a-z \\n|sort|egrep -v '^(the|and|of|to|a|i|it|in|or|is)$'|uniq -c|sort -rn|sed 22q>g
n=1
>o
until egrep -q .{80} o
do
awk '{printf "|%0*d| %s\n",$1*'$n'/1e3,0,$2}' g|tr 0 _>o 
((n++))
done
cat o

Чтобы получить верхний контур на верхней панели, мне пришлось расширить его до 240 символов:

tr A-Z a-z|tr -Cs a-z \\n|sort|egrep -v "^(the|and|of|to|a|i|it|in|or|is)$"|uniq -c|sort -r|sed 1p\;22q>g
n=1
>o
until egrep -q .{80} o
do
awk '{printf "|%0*d| %s\n",$1*'$n'/1e3,0,NR==1?"":$2}' g|sed '1s,|, ,g'|tr 0 _>o 
((n++))
done
cat o
avatar
sdolan
6 июля 2010 в 00:22
11

Python 3.1 - 245 229 символов

Я полагаю, что использование счетчика - это своего рода обман :) Я только что прочитал об этом около недели назад, так что это был прекрасный шанс увидеть, как это работает.

import re,collections
o=collections.Counter([w for w in re.findall("[a-z]+",open("!").read().lower())if w not in"a and i in is it of or the to".split()]).most_common(22)
print('\n'.join('|'+76*v//o[0][1]*'_'+'| '+k for k,v in o))

Распечатывает:

|____________________________________________________________________________| she
|__________________________________________________________________| you
|_______________________________________________________________| said
|_______________________________________________________| alice
|_________________________________________________| was
|_____________________________________________| that
|_____________________________________| as
|__________________________________| her
|_______________________________| with
|_______________________________| at
|______________________________| s
|_____________________________| t
|____________________________| on
|___________________________| all
|________________________| this
|________________________| for
|________________________| had
|________________________| but
|______________________| be
|______________________| not
|_____________________| they
|____________________| so

Часть кода была «заимствована» из решения AKX.

Joey
3 июля 2010 в 17:38
0

Первая строка отсутствует. И длина планки неправильная.

Nas Banov
3 июля 2010 в 21:22
0

в вашем коде кажется, что open('!') читает из stdin - какая это версия / ОС? или вы должны назвать файл '!'?

Sam Dolan
3 июля 2010 в 21:56
0

Назовите файл "!" :) Извините, это было довольно непонятно, и я должен был упомянуть об этом.

avatar
6 июля 2010 в 00:02
11

Версия PHP CLI (450 символов)

Это решение учитывает последнее требование, которое большинство пуристов предпочитают игнорировать. Это стоило 170 символов!

Использование: php.exe <this.php> <file.txt>

Минимизированный:

<?php $a=array_count_values(array_filter(preg_split('/[^a-z]/',strtolower(file_get_contents($argv[1])),-1,1),function($x){return !preg_match("/^(.|the|and|of|to|it|in|or|is)$/",$x);}));arsort($a);$a=array_slice($a,0,22);function R($a,$F,$B){$r=array();foreach($a as$x=>$f){$l=strlen($x);$r[$x]=$b=$f*$B/$F;if($l+$b>76)return R($a,$f,76-$l);}return$r;}$c=R($a,max($a),76-strlen(key($a)));foreach($a as$x=>$f)echo '|',str_repeat('-',$c[$x]),"| $x\n";?>

Читаемый человеком:

<?php

// Read:
$s = strtolower(file_get_contents($argv[1]));

// Split:
$a = preg_split('/[^a-z]/', $s, -1, PREG_SPLIT_NO_EMPTY);

// Remove unwanted words:
$a = array_filter($a, function($x){
       return !preg_match("/^(.|the|and|of|to|it|in|or|is)$/",$x);
     });

// Count:
$a = array_count_values($a);

// Sort:
arsort($a);

// Pick top 22:
$a=array_slice($a,0,22);


// Recursive function to adjust bar widths
// according to the last requirement:
function R($a,$F,$B){
    $r = array();
    foreach($a as $x=>$f){
        $l = strlen($x);
        $r[$x] = $b = $f * $B / $F;
        if ( $l + $b > 76 )
            return R($a,$f,76-$l);
    }
    return $r;
}

// Apply the function:
$c = R($a,max($a),76-strlen(key($a)));


// Output:
foreach ($a as $x => $f)
    echo '|',str_repeat('-',$c[$x]),"| $x\n";

?>

Вывод:

|-------------------------------------------------------------------------| she
|---------------------------------------------------------------| you
|------------------------------------------------------------| said
|-----------------------------------------------------| alice
|-----------------------------------------------| was
|-------------------------------------------| that
|------------------------------------| as
|--------------------------------| her
|-----------------------------| at
|-----------------------------| with
|--------------------------| on
|--------------------------| all
|-----------------------| this
|-----------------------| for
|-----------------------| had
|-----------------------| but
|----------------------| be
|---------------------| not
|--------------------| they
|--------------------| so
|-------------------| very
|------------------| what

Когда есть длинное слово, полосы отрегулированы правильно:

|--------------------------------------------------------| she
|---------------------------------------------------| thisisareallylongwordhere
|-------------------------------------------------| you
|-----------------------------------------------| said
|-----------------------------------------| alice
|------------------------------------| was
|---------------------------------| that
|---------------------------| as
|-------------------------| her
|-----------------------| with
|-----------------------| at
|--------------------| on
|--------------------| all
|------------------| this
|------------------| for
|------------------| had
|-----------------| but
|-----------------| be
|----------------| not
|---------------| they
|---------------| so
|--------------| very
avatar
6502
5 июля 2010 в 23:36
1

Python 290 , 255 , 253


290 символов в Python (текст читается со стандартного ввода)

import sys,re
c={}
for w in re.findall("[a-z]+",sys.stdin.read().lower()):c[w]=c.get(w,0)+1-(","+w+","in",a,i,the,and,of,to,it,in,or,is,")
r=sorted((-v,k)for k,v in c.items())[:22]
sf=max((76.0-len(k))/v for v,k in r)
print" "+"_"*int(r[0][0]*sf)
for v,k in r:print"|"+"_"*int(v*sf)+"| "+k

но ... прочитав другие решения, я внезапно понял, что эффективность - это не требование; так что это еще один короче и намного медленнее (255 символов)

import sys,re
w=re.findall("\w+",sys.stdin.read().lower())
r=sorted((-w.count(x),x)for x in set(w)-set("the and of to a i it in or is".split()))[:22]
f=max((76.-len(k))/v for v,k in r)
print" "+"_"*int(f*r[0][0])
for v,k in r:print"|"+"_"*int(f*v)+"| "+k

и после прочтения других решений ...

import sys,re
w=re.findall("\w+",sys.stdin.read().lower())
r=sorted((-w.count(x),x)for x in set(w)-set("the and of to a i it in or is".split()))[:22]
f=max((76.-len(k))/v for v,k in r)
print"","_"*int(f*r[0][0])
for v,k in r:print"|"+"_"*int(f*v)+"|",k

И теперь это решение почти побайтно идентично решению Астатина :-D

kriss
5 июля 2010 в 02:24
0

Я разработал очень похожее решение. Глядя на ваш, кажется, есть способы объединить оба, вы придумали некоторые уловки, которых я не ...

avatar
DMA57361
5 июля 2010 в 20:49
3

C ++, 647 символов

Я не рассчитываю получить высокие оценки при использовании C ++, но это не важно. Я почти уверен, что он соответствует всем требованиям. Обратите внимание, что я использовал ключевое слово C ++ 0x auto для объявления переменной, поэтому настройте компилятор соответствующим образом, если вы решите протестировать мой код.

Свернутая версия

#include <iostream>
#include <cstring>
#include <map>
using namespace std;
#define C string
#define S(x)v=F/a,cout<<#x<<C(v,'_')
#define F t->first
#define G t->second
#define O &&F!=
#define L for(i=22;i-->0;--t)
int main(){map<C,int>f;char d[230];int i=1,v;for(;i<256;i++)d[i<123?i-1:i-27]=i;d[229]=0;char w[99];while(cin>>w){for(i=0;w[i];i++)w[i]=tolower(w[i]);char*p=strtok(w,d);while(p)++f[p],p=strtok(0,d);}multimap<int,C>c;for(auto t=f.end();--t!=f.begin();)if(F!="the"O"and"O"of"O"to"O"a"O"i"O"it"O"in"O"or"O"is")c.insert(pair<int,C>(G,F));auto t=--c.end();float a=0,A;L A=F/(76.0-G.length()),a=a>A?a:A;t=--c.end();S( );L S(\n|)<<"| "<<G;}

Вот вторая версия, которая больше похожа на "C ++" за счет использования string, а не char[] и strtok. Он немного больше, на 669 (+22 против выше) , но я не могу его уменьшить в данный момент, поэтому решил опубликовать его в любом случае.

#include <iostream>
#include <map>
using namespace std;
#define C string
#define S(x)v=F/a,cout<<#x<<C(v,'_')
#define F t->first
#define G t->second
#define O &&F!=
#define L for(i=22;i-->0;--t)
#define E e=w.find_first_of(d,g);g=w.find_first_not_of(d,e);
int main(){map<C,int>f;int i,v;C w,x,d="abcdefghijklmnopqrstuvwxyz";while(cin>>w){for(i=w.size();i-->0;)w[i]=tolower(w[i]);unsigned g=0,E while(g-e>0){x=w.substr(e,g-e),++f[x],E}}multimap<int,C>c;for(auto t=f.end();--t!=f.begin();)if(F!="the"O"and"O"of"O"to"O"a"O"i"O"it"O"in"O"or"O"is")c.insert(pair<int,C>(G,F));auto t=--c.end();float a=0,A;L A=F/(76.0-G.length()),a=a>A?a:A;t=--c.end();S( );L S(\n|)<<"| "<<G;}

Я удалил полную версию, потому что мне не нужно постоянно обновлять ее с моими настройками до минимальной версии. См. Историю изменений, если вас интересует (возможно, устаревшая) длинная версия.

Gabe
3 июля 2010 в 21:38
0

Если вы собираетесь установить произвольное ограничение на длину слова, вы можете сделать его 999 вместо 1024 и сохранить штрих.

Gabe
3 июля 2010 в 21:40
0

Если вы используете float a=0,A;L A=F/(76.0-G.length()),a=a>A?a:A;, вы можете убрать #define и сбрить несколько штрихов.

DMA57361
3 июля 2010 в 22:45
0

@Gabe - спасибо за вторую, немного убранную. Что касается word, произвольная длина кажется неправильной, но я не уверен в том, как лучше всего извлечь cin в массив char, в отличие от string, без риска разрыва в середине слова (т. е. если я просто выделил его кусками по 80 символов). Но я отложил поиск «лучшего» решения до завтрашнего дня.

Gabe
3 июля 2010 в 23:01
0

Разве d[i-27]=0; не то же самое, что d[229]=0;?

EvilTeach
3 июля 2010 в 23:23
0

Почему вы решили использовать буфер символов вместо строки?

Gabe
4 июля 2010 в 07:37
0

Вы можете сэкономить место, превратив L{A=F/(76.0-G.length()),a=a>A?a:A;} в L A=F/(76.0-G.length()),a=a>A?a:A;.

DMA57361
4 июля 2010 в 14:29
0

@EvilTeach - чтобы я мог использовать strtok. Мне неизвестна функция разметки строк C ++ (см. coderhelper.com/questions/53849/…), которая потребовала бы "много" разделителей и нуждалась в надежном методе для разделения слов типа "don" t "по пунктуации. @Gabe - хороший улов (опять же, спасибо!) На d [229], что касается второго предложения - вы уже говорили об этом раньше, и я, очевидно, не уделил достаточного внимания ...

avatar
Sean Patrick Floyd
5 июля 2010 в 20:28
2

Groovy, 424 389 378 321 символ

заменил b=map.get(a) на b=map[a], заменен split на сопоставитель / итератор

def r,s,m=[:],n=0;def p={println it};def w={"_".multiply it};(new URL(this.args[0]).text.toLowerCase()=~/\b\w+\b/).each{s=it;if(!(s==~/(the|and|of|to|a|i[tns]?|or)/))m[s]=m[s]==null?1:m[s]+1};m.keySet().sort{a,b->m[b]<=>m[a]}.subList(0,22).each{k->if(n++<1){r=(m[k]/(76-k.length()));p" "+w(m[k]/r)};p"|"+w(m[k]/r)+"|"+k}

(выполняется как Groovy-скрипт с URL-адресом в качестве аргумента строки cmd. Импорт не требуется!)

Версия для чтения здесь:

def r,s,m=[:],n=0;
def p={println it};
def w={"_".multiply it};
(new URL(this.args[0]).text.toLowerCase()
        =~ /\b\w+\b/
        ).each{
        s=it;
        if (!(s ==~/(the|and|of|to|a|i[tns]?|or)/))
            m[s] = m[s] == null ? 1 : m[s] + 1
        };
    m.keySet()
        .sort{
            a,b -> m[b] <=> m[a]
        }
        .subList(0,22).each{
            k ->
                if( n++ < 1 ){
                    r=(m[k]/(76-k.length()));
                    p " " + w(m[k]/r)
                };
                p "|" + w(m[k]/r) + "|" + k
}
avatar
Sean Patrick Floyd
5 июля 2010 в 10:57
1

Java, постепенно укорачивающаяся ( 1500 1358 1241 <754/82557553646> <754/825425550> 936525550> 936525532525550950950950550

лишено еще большего количества пробелов и длины имени переменной. удалены дженерики, где это возможно, удален встроенный класс и блок try / catch очень плохо, в моей версии 900 была ошибка

удален другой блок try / catch

import java.net.*;import java.util.*;import java.util.regex.*;import org.apache.commons.io.*;public class G{public static void main(String[]a)throws Exception{String text=IOUtils.toString(new URL(a[0]).openStream()).toLowerCase().replaceAll("\\b(the|and|of|to|a|i[tns]?|or)\\b","");final Map<String,Integer>p=new HashMap();Matcher m=Pattern.compile("\\b\\w+\\b").matcher(text);Integer b;while(m.find()){String w=m.group();b=p.get(w);p.put(w,b==null?1:b+1);}List<String>v=new Vector(p.keySet());Collections.sort(v,new Comparator(){public int compare(Object l,Object m){return p.get(m)-p.get(l);}});boolean t=true;float r=0;for(String w:v.subList(0,22)){if(t){t=false;r=p.get(w)/(float)(80-(w.length()+4));System.out.println(" "+new String(new char[(int)(p.get(w)/r)]).replace('\0','_'));}System.out.println("|"+new String(new char[(int)(((Integer)p.get(w))/r)]).replace('\0','_')+"|"+w);}}}

Версия для чтения:

import java.net.*;
import java.util.*;
import java.util.regex.*;
import org.apache.commons.io.*;

public class G{

    public static void main(String[] a) throws Exception{
        String text =
            IOUtils.toString(new URL(a[0]).openStream())
                .toLowerCase()
                .replaceAll("\\b(the|and|of|to|a|i[tns]?|or)\\b", "");
        final Map<String, Integer> p = new HashMap();
        Matcher m = Pattern.compile("\\b\\w+\\b").matcher(text);
        Integer b;
        while(m.find()){
            String w = m.group();
            b = p.get(w);
            p.put(w, b == null ? 1 : b + 1);
        }
        List<String> v = new Vector(p.keySet());
        Collections.sort(v, new Comparator(){

            public int compare(Object l, Object m){
                return p.get(m) - p.get(l);
            }
        });
        boolean t = true;
        float r = 0;
        for(String w : v.subList(0, 22)){
            if(t){
                t = false;
                r = p.get(w) / (float) (80 - (w.length() + 4));
                System.out.println(" "
                    + new String(new char[(int) (p.get(w) / r)]).replace('\0',
                        '_'));
            }
            System.out.println("|"
                + new String(new char[(int) (((Integer) p.get(w)) / r)]).replace('\0',
                    '_') + "|" + w);
        }
    }
}

John Y
3 июля 2010 в 02:54
7

Мне нравятся игры в гольф с большим количеством персонажей. Хорошо разбить монотонность линейного шума чем-нибудь читабельным и почти смехотворно многословным.

dmckee --- ex-moderator kitten
3 июля 2010 в 06:14
3

@ Джон: Я не согласен. Даже если вы собираетесь использовать многословный язык (например, см. Мои записи fortran 77 в некоторых более ранних кодах гольфа), вам следует кодировать его настолько жестко, насколько позволяет язык. Код гольф - это не о хороших практиках; действительно, это почти полная противоположность хорошей практике.

John Y
3 июля 2010 в 14:14
2

@dmckee: Я полностью понимаю и принимаю вашу точку зрения. Тем не менее, мне лично нравится видеть практически любую заявку. Разнообразие - это изюминка жизни, и для меня это даже включает в себя разные (даже противоположные) духа и идеалы кодового гольфа. Лучше танцевать, но танцевать «плохо» (для любого определения танца), чем стоять в углу или, что еще хуже, даже не появляться.

avatar
5 июля 2010 в 01:58
1

Объект Rexx 4.0 с PC-Pipes

Где можно найти библиотеку PC-Pipes.
Это решение игнорирует однобуквенные слова.

address rxpipe 'pipe (end ?) < Alice.txt',
   '|regex split /[^a-zA-Z]/', -- split at non alphbetic character
   '|locate 2',                -- discard words shorter that 2 char  
   '|xlate lower',             -- translate all words to lower case
   ,                           -- discard list words that match list
   '|regex not match /^(the||and||of||to||it||in||or||is)$/',
   '|l:lookup autoadd before count',  -- accumulate and count words
 '? l:',                       -- no master records to feed into lookup 
 '? l:',                       -- list of counted words comes here
   ,                           -- columns 1-10 hold count, 11-n hold word
   '|sort 1.10 d',             -- sort in desending order by count
   '|take 22',                 -- take first 22 records only
   '|array wordlist',          -- store into a rexx array
   '|count max',               -- get length of longest record 
   '|var maxword'              -- save into a rexx variable

parse value wordlist[1] with count 11 .  -- get frequency of first word
barunit = count % (76-(maxword-10))      -- frequency units per chart bar char

say ' '||copies('_', (count+barunit)%barunit)  -- first line of the chart
do cntwd over wordlist                    
  parse var cntwd count 11 word          -- get word frequency and the word
  say '|'||copies('_', (count+barunit)%barunit)||'| '||word||' '
end
Результат произведен
 ________________________________________________________________________________
|________________________________________________________________________________| she
|_____________________________________________________________________| you
|___________________________________________________________________| said
|__________________________________________________________| alice
|____________________________________________________| was
|________________________________________________| that
|________________________________________| as
|____________________________________| her
|_________________________________| at
|_________________________________| with
|______________________________| on
|_____________________________| all
|__________________________| this
|__________________________| for
|__________________________| had
|__________________________| but
|________________________| be
|________________________| not
|_______________________| they
|______________________| so
|_____________________| very
|_____________________| what
Nas Banov
5 июля 2010 в 23:54
0

Как долго решение (количество знаков) - это код-гольф?

avatar
Jonathon
5 июля 2010 в 00:28
3

Java - 896 символов

931 символ

1233 символа стали нечитаемыми

1977 символов "без сжатия"


Обновление: я резко уменьшил количество персонажей. В обновленной спецификации пропускаются однобуквенные слова.

Я очень завидую C # и LINQ.

import java.util.*;import java.io.*;import static java.util.regex.Pattern.*;class g{public static void main(String[] a)throws Exception{PrintStream o=System.out;Map<String,Integer> w=new HashMap();Scanner s=new Scanner(new File(a[0])).useDelimiter(compile("[^a-z]+|\\b(the|and|of|to|.|it|in|or|is)\\b",2));while(s.hasNext()){String z=s.next().trim().toLowerCase();if(z.equals(""))continue;w.put(z,(w.get(z)==null?0:w.get(z))+1);}List<Integer> v=new Vector(w.values());Collections.sort(v);List<String> q=new Vector();int i,m;i=m=v.size()-1;while(q.size()<22){for(String t:w.keySet())if(!q.contains(t)&&w.get(t).equals(v.get(i)))q.add(t);i--;}int r=80-q.get(0).length()-4;String l=String.format("%1$0"+r+"d",0).replace("0","_");o.println(" "+l);o.println("|"+l+"| "+q.get(0)+" ");for(i=m-1;i>m-22;i--){o.println("|"+l.substring(0,(int)Math.round(r*(v.get(i)*1.0)/v.get(m)))+"| "+q.get(m-i)+" ");}}}

«Читаемый»:

import java.util.*;
import java.io.*;
import static java.util.regex.Pattern.*;
class g
{
   public static void main(String[] a)throws Exception
      {
      PrintStream o = System.out;
      Map<String,Integer> w = new HashMap();
      Scanner s = new Scanner(new File(a[0]))
         .useDelimiter(compile("[^a-z]+|\\b(the|and|of|to|.|it|in|or|is)\\b",2));
      while(s.hasNext())
      {
         String z = s.next().trim().toLowerCase();
         if(z.equals(""))
            continue;
         w.put(z,(w.get(z) == null?0:w.get(z))+1);
      }
      List<Integer> v = new Vector(w.values());
      Collections.sort(v);
      List<String> q = new Vector();
      int i,m;
      i = m = v.size()-1;
      while(q.size()<22)
      {
         for(String t:w.keySet())
            if(!q.contains(t)&&w.get(t).equals(v.get(i)))
               q.add(t);
         i--;
      }
      int r = 80-q.get(0).length()-4;
      String l = String.format("%1$0"+r+"d",0).replace("0","_");
      o.println(" "+l);
      o.println("|"+l+"| "+q.get(0)+" ");
      for(i = m-1; i > m-22; i--)
      {
         o.println("|"+l.substring(0,(int)Math.round(r*(v.get(i)*1.0)/v.get(m)))+"| "+q.get(m-i)+" ");
      }
   }
}

Вывод Алисы:

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| with
|______________________________| at
|___________________________| on
|__________________________| all
|________________________| this
|________________________| for
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so
|___________________| very
|___________________| what

Вывод Дон Кихота (также из Гутенберга):

 ________________________________________________________________________
|________________________________________________________________________| that
|________________________________________________________| he
|______________________________________________| for
|__________________________________________| his
|________________________________________| as
|__________________________________| with
|_________________________________| not
|_________________________________| was
|________________________________| him
|______________________________| be
|___________________________| don
|_________________________| my
|_________________________| this
|_________________________| all
|_________________________| they
|________________________| said
|_______________________| have
|_______________________| me
|______________________| on
|______________________| so
|_____________________| you
|_____________________| quixote
Nas Banov
3 июля 2010 в 04:43
8

Сплошной карп, неужели в Java нет способа сделать его короче? Надеюсь, вам платят по количеству символов, а не по функциональности :-)

avatar
stor
4 июля 2010 в 19:37
35

206

оболочка, grep, tr, grep, sort, uniq, sort, head, perl

~ % wc -c wfg
209 wfg
~ % cat wfg
egrep -oi \\b[a-z]+|tr A-Z a-z|egrep -wv 'the|and|of|to|a|i|it|in|or|is'|sort|uniq -c|sort -nr|head -22|perl -lape'($f,$w)=@F;$.>1or($q,$x)=($f,76-length$w);$b="_"x($f/$q*$x);$_="|$b| $w ";$.>1or$_=" $b\n$_"'
~ % # usage:
~ % sh wfg < 11.txt

хм, только что видно выше: sort -nr -> sort -n, а затем head -> tail => 208 :)
update2: эээ, конечно, сказанное выше глупо, так как тогда все будет наоборот. Итак, 209.
update3: оптимизировано регулярное выражение исключения -> 206

egrep -oi \\b[a-z]+|tr A-Z a-z|egrep -wv 'the|and|o[fr]|to|a|i[tns]?'|sort|uniq -c|sort -nr|head -22|perl -lape'($f,$w)=@F;$.>1or($q,$x)=($f,76-length$w);$b="_"x($f/$q*$x);$_="|$b| $w ";$.>1or$_=" $b\n$_"'



для удовольствия, вот версия только для Perl (намного быстрее):

~ % wc -c pgolf
204 pgolf
~ % cat pgolf
perl -lne'$1=~/^(the|and|o[fr]|to|.|i[tns])$/i||$f{lc$1}++while/\b([a-z]+)/gi}{@w=(sort{$f{$b}<=>$f{$a}}keys%f)[0..21];$Q=$f{$_=$w[0]};$B=76-y///c;print" "."_"x$B;print"|"."_"x($B*$f{$_}/$Q)."| $_"for@w'
~ % # usage:
~ % sh pgolf < 11.txt
avatar
4 июля 2010 в 15:58
2

Оболочка, 228 символов, с рабочим ограничением 80 символов

tr A-Z a-z|tr -Cs a-z "\n"|sort|egrep -v "^(the|and|of|to|a|i|it|in|or|is)$" |uniq -c|sort -r|head -22>g
n=1
while :
do
awk '{printf "|%0*s| %s\n",$1*'$n'/1e3,"",$2;}' g|tr 0 _>o 
egrep -q .{80} o&&break
n=$((n+1))
done
cat o

Я удивлен, что, кажется, никто не использовал удивительную * особенность printf.

кот 11-very.txt> golf.sh

|__________________________________________________________________________| she
|________________________________________________________________| you
|_____________________________________________________________| said
|______________________________________________________| alice
|_______________________________________________| was
|____________________________________________| that
|____________________________________| as
|_________________________________| her
|______________________________| with
|______________________________| at
|_____________________________| s
|_____________________________| t
|___________________________| on
|__________________________| all
|________________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|______________________| not
|____________________| they
|____________________| so

кот 11 | golf.sh

|_________________________________________________________________| she
|_________________________________________________________| verylongstringstring
|______________________________________________________| said
|_______________________________________________| alice
|__________________________________________| was
|_______________________________________| that
|________________________________| as
|_____________________________| her
|___________________________| with
|___________________________| at
|__________________________| s
|_________________________| t
|________________________| on
|_______________________| all
|_____________________| this
|_____________________| for
|_____________________| had
|____________________| but
|___________________| be
|___________________| not
|__________________| they
|__________________| so
Joey
4 июля 2010 в 21:15
0

Отсутствует самая первая строка в выводе (верхняя строка первого столбца). Также не могли бы вы просто отсортировать по возрастанию, а затем вместо этого использовать последние 22 строки? Не знаю, сделает ли это здесь короче, но для меня это было серьезным соображением.

mb14
4 июля 2010 в 21:47
0

Я знаю впервые. Я просто не вижу простого способа сделать это, и я не был уверен, действительно ли это было обязательным. Я действительно не мог перевернуть, но тогда вывод был бы инвертирован (она в последней строке)

avatar
Syntaera
4 июля 2010 в 05:51
10

Perl: 203 202 201 198 195 208 203/231 символов

$/=\0;/^(the|and|of|to|.|i[tns]|or)$/i||$x{lc$_}++for<>=~/[a-z]+/gi;map{$z=$x{$_};$y||{$y=(76-y///c)/$z}&&warn" "."_"x($z*$y)."\n";printf"|%.78s\n","_"x($z*$y)."| $_"}(sort{$x{$b}<=>$x{$a}}keys%x)[0..21]

Альтернативная полная реализация, включая указанное поведение (глобальное сжатие полос) для патологического случая, в котором вторичное слово является одновременно популярным и достаточно длинным, чтобы объединить более 80 символов ( эта реализация - 231 символ ) :

$/=\0;/^(the|and|of|to|.|i[tns]|or)$/i||$x{lc$_}++for<>=~/[a-z]+/gi;@e=(sort{$x{$b}<=>$x{$a}}keys%x)[0..21];for(@e){$p=(76-y///c)/$x{$_};($y&&$p>$y)||($y=$p)}warn" "."_"x($x{$e[0]}*$y)."\n";for(@e){warn"|"."_"x($x{$_}*$y)."| $_\n"}

В спецификации нигде не говорилось, что это должно идти в STDOUT, поэтому я использовал perl warn () вместо print - четыре символа, сохраненные там. Используется карта вместо foreach, но я чувствую, что еще можно сэкономить на split (join ()). Тем не менее, довел до 203 - может спать на нем. По крайней мере, Perl теперь находится в подсчете символов "shell, grep, tr, grep, sort, uniq, sort, head, perl";)

PS: Reddit говорит «Привет»;)

Обновление: удалено соединение join () в пользу соединения с присваиванием и неявным скалярным преобразованием. Уменьшено до 202. Также обратите внимание, что я воспользовался дополнительным правилом «игнорировать 1-буквенные слова», чтобы убрать 2 символа, поэтому имейте в виду, что подсчет частоты будет отражать это.

Обновление 2: заменено назначение и неявное соединение для уничтожения $ /, чтобы получить файл одним залпом с использованием <> в первую очередь. Тот же размер, но посерьезнее. Заменил, если (! $ Y) {} на $ y || {} && сохранил еще 1 символ => 201.

Обновление 3: Раннее управление строчными буквами (lc <>) путем перемещения lc из блока карты - Заменены оба регулярных выражения, чтобы больше не использовать параметр / i, поскольку он больше не нужен. Явная условная конструкция x? Y: z заменена на традиционный perlgolf || неявная условная конструкция - /^...$/i?1:$x{$}++ для /^...$/||$x{$}++ Сохранено три символа! => 198, преодолел 200 барьер. Может, скоро усну ... возможно.

Обновление 4: лишение сна свело меня с ума. Хорошо. Более безумно. Полагая, что это должно только анализировать обычные счастливые текстовые файлы, я заставил его отказаться, если он достигнет нуля. Сохранены два персонажа. Заменено слово "длина" на 1-символьный короче (и гораздо более гольфисто) y /// c - вы меня слышите, GolfScript ?? Я иду за тобой!!! sob

Обновление 5: зависимость от сна заставила меня забыть об ограничении 22 строк и ограничении последующих строк. Резервное копирование до 208 с обработанными. Неплохо, 13 персонажей, с которыми можно справиться, это еще не конец света. Поигрался с perl regex inline eval, но не удалось заставить его работать и сохранить символы ... lol. Обновлен пример для соответствия текущему выходу.

Обновление 6: Удалены ненужные фигурные скобки, защищающие (...) for, поскольку синтаксическая конфета ++ позволяет успешно столкнуть его с for. Благодаря вкладу Часа. Оуэнс (напоминая мой усталый мозг) нашел решение для класса персонажей i [tns]. Вернемся к 203.

Обновление 7: добавлена ​​вторая часть работы, полная реализация спецификаций (включая полное сжатие полос для вторичных длинных слов вместо усечения, которое делает большинство людей, на основе исходной спецификации без патологического примера)

Примеры:

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| with
|_____________________________| at
|__________________________| on
|__________________________| all
|_______________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so
|___________________| very
|__________________| what

Альтернативная реализация в примере патологического случая:

 _______________________________________________________________
|_______________________________________________________________| she
|_______________________________________________________| superlongstringstring
|____________________________________________________| said
|______________________________________________| alice
|________________________________________| was
|_____________________________________| that
|_______________________________| as
|____________________________| her
|_________________________| with
|_________________________| at
|_______________________| on
|______________________| all
|____________________| this
|____________________| for
|____________________| had
|____________________| but
|___________________| be
|__________________| not
|_________________| they
|_________________| so
|________________| very
|________________| what
Joey
3 июля 2010 в 16:44
0

Вы можете сократить регулярное выражение для стоп-слов, свернув is|in|it|i в i[snt]? - и тогда больше нет разницы с необязательным правилом. (Хм, я бы никогда не подумал о том, чтобы рассказать парню, занимающемуся Perl, как делать Regex: D) - единственная проблема: мне нужно посмотреть, как я могу сократить три байта моего собственного решения, чтобы снова стать лучше, чем Perl: - |

Joey
3 июля 2010 в 16:55
0

Хорошо, не обращайте внимания на часть того, что я сказал ранее. Игнорирование однобуквенных слов действительно на байт короче, чем игнорирование.

Syntaera
3 июля 2010 в 17:16
0

На счету каждый байт;) Я подумал о том, чтобы сделать трюк с новой строкой, но решил, что на самом деле это такое же количество байтов, даже если печатаемых символов меньше. Все еще работаю над тем, чтобы посмотреть, смогу ли я уменьшить его еще немного :)

Joey
3 июля 2010 в 18:01
0

Ну ладно, нормализация дела отбросила меня обратно к 209. Я не знаю, что еще можно было вырезать. Хотя PowerShell может быть короче Perl. ;-)

Gabe
3 июля 2010 в 19:19
0

Я не вижу, где вы ограничиваете вывод 22 верхними словами или где вы следите за тем, чтобы длинное второе слово не переносилось.

Chas. Owens
4 июля 2010 в 03:43
0

Вы можете сэкономить еще больше, используя say: perl -E '$/=\0;map{/^(the|and|of|to|.|it|in|or|is|)$/||$x{$_}++}split(/[^a-z]/,lc<>);map{$z=$x{$_};$y||{$y=(76-y///c)/$z}&&say" "."_"x($z*$y);say"|"."_"x($z*$y)."| $_"}sort{$x{$b}<=>$x{$a}}keys%x'

Chas. Owens
4 июля 2010 в 03:51
0

Даже больше, если использовать класс символов и использовать for вместо map, где это возможно: perl -E '$/=\0;/^(the|and|of|to|.|i[tns]|or)$/||$x{$_}++for split(/[^a-z]/,lc<>);map{$z=$x{$_};$y||{$y=(76-y///c)/$z}&&say" "."_"x($z*$y);say"|"."_"x($z*$y)."| $_"}sort{$x{$b}<=>$x{$a}}keys%x'

Syntaera
4 июля 2010 в 04:50
0

Спасибо за это - я пришел к такому же выводу о for, но также избавился от split (), просто используя вместо него простое регулярное выражение. Вернемся к 203!

avatar
4 июля 2010 в 02:57
1

R, 298 символов

f=scan("stdin","ch")
u=unlist
s=strsplit
a=u(s(u(s(tolower(f),"[^a-z]")),"^(the|and|of|to|it|in|or|is|.|)$"))
v=unique(a)
r=sort(sapply(v,function(i) sum(a==i)),T)[2:23]  #the first item is an empty string, just skipping it
w=names(r)
q=(78-max(nchar(w)))*r/max(r)
cat(" ",rep("_",q[1])," \n",sep="")
for(i in 1:22){cat("|",rep("_",q[i]),"| ",w[i],"\n",sep="")}

Вывод:

 _________________________________________________________________________ 
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| at
|_____________________________| with
|__________________________| on
|__________________________| all
|_______________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so
|___________________| very
|__________________| what

А если «ты» заменить на что-то более длинное:

 ____________________________________________________________ 
|____________________________________________________________| she
|____________________________________________________| veryverylongstring
|__________________________________________________| said
|___________________________________________| alice
|______________________________________| was
|___________________________________| that
|_____________________________| as
|__________________________| her
|________________________| at
|________________________| with
|______________________| on
|_____________________| all
|___________________| this
|___________________| for
|___________________| had
|__________________| but
|__________________| be
|__________________| not
|________________| they
|________________| so
|_______________| very
|_______________| what
6502
4 июля 2010 в 08:19
1

Это не максимальное масштабирование

avatar
Matt
4 июля 2010 в 00:18
11

JavaScript 1.8 (SpiderMonkey) - 354

x={};p='|';e=' ';z=[];c=77
while(l=readline())l.toLowerCase().replace(/\b(?!(the|and|of|to|a|i[tns]?|or)\b)\w+/g,function(y)x[y]?x[y].c++:z.push(x[y]={w:y,c:1}))
z=z.sort(function(a,b)b.c-a.c).slice(0,22)
for each(v in z){v.r=v.c/z[0].c
c=c>(l=(77-v.w.length)/v.r)?l:c}for(k in z){v=z[k]
s=Array(v.r*c|0).join('_')
if(!+k)print(e+s+e)
print(p+s+p+e+v.w)}

К сожалению, for([k,v]in z) из версии Rhino, похоже, не хочет работать в SpiderMonkey, а readFile() немного проще, чем использование readline(), но переход на 1.8 позволяет нам использовать закрытие функций, чтобы вырезать еще несколько строк ....

Добавление пробелов для удобства чтения:

x={};p='|';e=' ';z=[];c=77
while(l=readline())
  l.toLowerCase().replace(/\b(?!(the|and|of|to|a|i[tns]?|or)\b)\w+/g,
   function(y) x[y] ? x[y].c++ : z.push( x[y] = {w: y, c: 1} )
  )
z=z.sort(function(a,b) b.c - a.c).slice(0,22)
for each(v in z){
  v.r=v.c/z[0].c
  c=c>(l=(77-v.w.length)/v.r)?l:c
}
for(k in z){
  v=z[k]
  s=Array(v.r*c|0).join('_')
  if(!+k)print(e+s+e)
  print(p+s+p+e+v.w)
}

Использование: js golf.js < input.txt

Вывод:

 _________________________________________________________________________ 
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|____________________________________________________| alice
|______________________________________________| was
|___________________________________________| that
|___________________________________| as
|________________________________| her
|_____________________________| at
|_____________________________| with
|____________________________| s
|____________________________| t
|__________________________| on
|_________________________| all
|_______________________| this
|______________________| for
|______________________| had
|______________________| but
|_____________________| be
|_____________________| not
|___________________| they
|___________________| so

(базовая версия - неправильно обрабатывает ширину полосы)

JavaScript (Rhino) - 405 395 387 377 <624685737374476> 377 377 304 символа

Я думаю, что моя логика сортировки отключена, но ... я думаю. Brainfart исправлен.

Минифицированный (злоупотребление \n иногда интерпретируется как ;):

x={};p='|';e=' ';z=[]
readFile(arguments[0]).toLowerCase().replace(/\b(?!(the|and|of|to|a|i[tns]?|or)\b)\w+/g,function(y){x[y]?x[y].c++:z.push(x[y]={w:y,c:1})})
z=z.sort(function(a,b){return b.c-a.c}).slice(0,22)
for([k,v]in z){s=Array((v.c/z[0].c)*70|0).join('_')
if(!+k)print(e+s+e)
print(p+s+p+e+v.w)}
dmckee --- ex-moderator kitten
3 июля 2010 в 04:09
0

Ах, сэр. Я считаю, что это твоя перчатка. Пусть ваш второй поговорит со мной.

dmckee --- ex-moderator kitten
3 июля 2010 в 04:10
2

Кстати - мне нравится бит i[tns]?. Очень подлый.

Matt
3 июля 2010 в 13:31
0

@dmckee - хорошо сыграно, не думаю, что смогу обыграть ваш 336, наслаждайтесь вашим заслуженным голосованием :)

gnarf
3 июля 2010 в 20:29
0

Вы определенно можете победить 336 ... Доступно сокращение на 23 символа - .replace(/[^\w ]/g, e).split(/\s+/).map( можно заменить на .replace(/\w+/g, и использовать ту же функцию, что и ваш .map ... Также не уверен, поддерживает ли Rhino вместо этого function(a,b)b.c-a.c вашей функции сортировки (spidermonkey делает), но это сбрит {return } ... b.c-a.c лучше, чем a.c<b.c кстати ... Редактирование версии Spidermonkey внизу с этими изменениями

gnarf
3 июля 2010 в 23:48
0

Я переместил свою версию SpiderMonkey вверх, так как она соответствует ограничению ширины полосы ... Также удалось вырезать еще несколько символов в исходной версии, используя регулярное выражение отрицательного просмотра вперед, чтобы запретить слова, позволяющие использовать одну replace (), и несколько раз поиграл в гольф с ?: Отличная база для работы!

Joey
4 июля 2010 в 15:38
0

Это не устранит стоп-слова, если они окружены цифрами или символами подчеркивания, например, в foo_the123, где должен остаться только foo.

avatar
dmckee
3 июля 2010 в 23:11
7

Гавк - 336 (первоначально 507) символов

(после исправления форматирования вывода; исправления сужений; тонкой настройки; снова настройки; удаления совершенно ненужного шага сортировки; еще раз настройки; и снова (упс, это нарушило форматирование); еще немного поправить; взять вверх по задаче Мэтта Я отчаянно подправляю так больше; нашел другое место, чтобы сэкономить несколько, но вернул два, чтобы исправить ошибку длины стержня)

Хе-хе! Я на мгновение опередил [Matt's JavaScript] [1] решение встречный вызов! ;) и [питон AKX] [2].

Проблема, похоже, связана с языком, реализующим собственные ассоциативные массивы, поэтому , конечно, я выбрал один с ужасно недостаточным набором операторов на них. В частности, вы не можете контролировать порядок, в котором awk предлагает элементы хэш-карты, поэтому я неоднократно просматривал всю карту , чтобы найти самый многочисленный в настоящее время элемент, распечатать его и удалить из массива.

Все это ужасно неэффективно, со всеми улучшениями, которые я сделал, это тоже довольно ужасно.

Минимизированный:

{gsub("[^a-zA-Z]"," ");for(;NF;NF--)a[tolower($NF)]++}
END{split("the and of to a i it in or is",b," ");
for(w in b)delete a[b[w]];d=1;for(w in a){e=a[w]/(78-length(w));if(e>d)d=e}
for(i=22;i;--i){e=0;for(w in a)if(a[w]>e)e=a[x=w];l=a[x]/d-2;
t=sprintf(sprintf("%%%dc",l)," ");gsub(" ","_",t);if(i==22)print" "t;
print"|"t"| "x;delete a[x]}}

разрывы строк только для ясности: они не нужны и не должны учитываться.


Вывод:

$ gawk -f wordfreq.awk.min < 11.txt 
 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|____________________________________________________| alice
|______________________________________________| was
|__________________________________________| that
|___________________________________| as
|_______________________________| her
|____________________________| with
|____________________________| at
|___________________________| s
|___________________________| t
|_________________________| on
|_________________________| all
|______________________| this
|______________________| for
|______________________| had
|_____________________| but
|____________________| be
|____________________| not
|___________________| they
|__________________| so
$ sed 's/you/superlongstring/gI' 11.txt | gawk -f wordfreq.awk.min
 ______________________________________________________________________
|______________________________________________________________________| she
|_____________________________________________________________| superlongstring
|__________________________________________________________| said
|__________________________________________________| alice
|____________________________________________| was
|_________________________________________| that
|_________________________________| as
|______________________________| her
|___________________________| with
|___________________________| at
|__________________________| s
|__________________________| t
|________________________| on
|________________________| all
|_____________________| this
|_____________________| for
|_____________________| had
|____________________| but
|___________________| be
|___________________| not
|__________________| they
|_________________| so

Читаемый; 633 символа (первоначально 949):

{
    gsub("[^a-zA-Z]"," ");
    for(;NF;NF--)
    a[tolower($NF)]++
}
END{
    # remove "short" words
    split("the and of to a i it in or is",b," ");
    for (w in b) 
    delete a[b[w]];
    # Find the bar ratio
    d=1;
    for (w in a) {
    e=a[w]/(78-length(w));
    if (e>d)
        d=e
    }
    # Print the entries highest count first
    for (i=22; i; --i){               
    # find the highest count
    e=0;
    for (w in a) 
        if (a[w]>e)
        e=a[x=w];
        # Print the bar
    l=a[x]/d-2;
    # make a string of "_" the right length
    t=sprintf(sprintf("%%%dc",l)," ");
    gsub(" ","_",t);
    if (i==22) print" "t;
    print"|"t"| "x;
    delete a[x]
    }
}
ChristopheD
3 июля 2010 в 12:31
0

Отличная работа, хорошо, что вы включили версию с отступом / комментариями ;-)

avatar
3 июля 2010 в 23:04
0

Python, 250 символов

заимствование из всех других фрагментов Python

import re,sys
t=re.findall("\w+","".join(sys.stdin).lower())
W=sorted((-t.count(w),w)for w in set(t)-set("the and of to a i it in or is".split()))[:22]
Z,U=W[0],lambda n:"_"*int(n*(76.-len(Z[1]))/Z[0])
print"",U(Z[0])
for(n,w)in W:print"|"+U(n)+"|",w

Если вы дерзки и используете слова, которых следует избегать, в качестве аргументов, 223 символа

import re,sys
t=re.findall("\w+","".join(sys.stdin).lower())
W=sorted((-t.count(w),w)for w in set(t)-set(sys.argv[1:]))[:22]
Z,U=W[0],lambda n:"_"*int(n*(76.-len(Z[1]))/Z[0])
print"",U(Z[0])
for(n,w)in W:print"|"+U(n)+"|",w

Вывод:

$ python alice4.py  the and of to a i it in or is < 11.txt 
 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|____________________________________| as
|________________________________| her
|_____________________________| at
|_____________________________| with
|____________________________| s
|____________________________| t
|__________________________| on
|__________________________| all
|_______________________| this
|_______________________| for
|_______________________| had
|_______________________| but
|______________________| be
|_____________________| not
|____________________| they
|____________________| so
6502
4 июля 2010 в 08:04
1

Это не решает проблему определения масштаба по слову, которое не является самым частым.

avatar
Gabe
3 июля 2010 в 22:47
26

C # - 510 451 436 44381438149680296404381496802964043814614802964043814614629629168 уменьшено)

Не так уж и коротко, но теперь, наверное, правильно! Обратите внимание, что в предыдущей версии не отображалась первая строка столбцов, они не масштабировались правильно, загружался файл вместо того, чтобы получить его из стандартного ввода, и не включал всю необходимую многословность C #. Вы могли бы легко сбрить много штрихов, если бы C # не требовал столько лишнего дерьма. Может, у Powershell получится лучше.

using C=System.Console;   // alias for Console
using System.Linq;  // for Split, GroupBy, Select, OrderBy, etc.

class Class // must define a class
{
    static void Main()  // must define a Main
    {
        // split into words
        var allwords = System.Text.RegularExpressions.Regex.Split(
                // convert stdin to lowercase
                C.In.ReadToEnd().ToLower(),
                // eliminate stopwords and non-letters
                @"(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|\W)+")
            .GroupBy(x => x)    // group by words
            .OrderBy(x => -x.Count()) // sort descending by count
            .Take(22);   // take first 22 words

        // compute length of longest bar + word
        var lendivisor = allwords.Max(y => y.Count() / (76.0 - y.Key.Length));

        // prepare text to print
        var toPrint = allwords.Select(x=> 
            new { 
                // remember bar pseudographics (will be used in two places)
                Bar = new string('_',(int)(x.Count()/lendivisor)), 
                Word=x.Key 
            })
            .ToList();  // convert to list so we can index into it

        // print top of first bar
        C.WriteLine(" " + toPrint[0].Bar);
        toPrint.ForEach(x =>  // for each word, print its bar and the word
            C.WriteLine("|" + x.Bar + "| " + x.Word));
    }
}

422 символа с лендивизором встроенным (что делает его в 22 раза медленнее) в приведенной ниже форме (новые строки используются для выбранных пробелов):

using System.Linq;using C=System.Console;class M{static void Main(){var
a=System.Text.RegularExpressions.Regex.Split(C.In.ReadToEnd().ToLower(),@"(?:\b(?:the|and|of|to|a|i[tns]?|or)\b|\W)+").GroupBy(x=>x).OrderBy(x=>-x.Count()).Take(22);var
b=a.Select(x=>new{p=new string('_',(int)(x.Count()/a.Max(y=>y.Count()/(76d-y.Key.Length)))),t=x.Key}).ToList();C.WriteLine(" "+b[0].p);b.ForEach(x=>C.WriteLine("|"+x.p+"| "+x.t));}}
sarnold
3 июля 2010 в 00:24
0

+1 для умников, скачивающих файл inline. :)

indiv
3 июля 2010 в 00:31
1

Украдите короткий URL-адрес из ответа Мэтта.

thorkia
3 июля 2010 в 01:19
2

В спецификации сказано, что файл должен быть передан по конвейеру или как аргумент. Если вы предположите, что args [0] содержит имя локального файла, вы можете значительно сократить его, используя args [0] вместо (new WebClient ()). DownloadString (@ "gutenberg.org/files/11 /11.txt ") -> это сэкономит вам примерно 70 символов

thorkia
3 июля 2010 в 01:41
1

Вот версия, в которой вызов WebClient заменяется аргументом 0, вызовом StreamReader и удаляется несколько лишних пробелов. Общее количество символов = 413 var a = Regex.Replace ((new StreamReader (args [0])). ReadToEnd (), «[^ a-zA-Z]», «») .ToLower (). Split ('' ) .Where (x =>! (New [] {"the", "and", "of", "to", "a", "i", "it", "in", "or", " is "}). Содержит (x)). GroupBy (x => x) .Select (g => new {w = g.Key, c = g.Count ()}». OrderByDescending (x => xc). Skip (1) .Take (22) .ToList (); var m = a.OrderByDescending (x => xc) .First (); a.ForEach (x => Console.WriteLine ("|" + new String ('' _ ', xc * (80-mwLength-4) / mc) + "|" + xw));

Rotsor
3 июля 2010 в 03:10
0

«новый StreamReader» без «использования» - это грязно. File.ReadAllText (args [0]) или Console.In.ReadToEnd () намного лучше. В последнем случае вы даже можете удалить аргумент из своего Main (). :)

Rotsor
3 июля 2010 в 03:52
0

Неправильная ширина полосы. Полоса "with" короче, чем "at".

Gabe
3 июля 2010 в 05:40
0

Ротзор: Насколько я могу судить, «with» и «at» имеют одинаковую ширину полосы, что им и должно быть, потому что они имеют одинаковую частоту.

John K
3 июля 2010 в 06:13
0

Вы используете Console.WriteLine несколько раз. Сохраните еще несколько символов, используя псевдоним using C=System.Console;, а затем в своем коде C.WriteLine(..) или другой символ, поскольку у вас уже есть C в качестве имени класса.

James Davies
5 июля 2010 в 02:01
0

Это прекрасный пример мощи LINQ. Только представьте себе это на Java.

Joey
5 июля 2010 в 07:55
0

@ Zoomzoom83: Было бы здорово иметь, но, вероятно, все еще было бы на два порядка больше. В конце концов, мы говорим о Java;) (и, вероятно, он появится только в Java 8, дата выпуска которой установлена ​​ после Duke Nukem Forever).

avatar
Nabb
3 июля 2010 в 18:59
39

GolfScript, 177 175 173 167 164 163 144 131 130 символов

Медленно - 3 минуты для образца текста (130)

{32|.123%97<n@if}%]''*n%"oftoitinorisa"2/-"theandi"3/-$(1@{.3$>1{;)}if}/]2/{~~\;}$22<.0=~:2; 76\-:1'_':0*' '\@{"
|"\~1*2/0*'| '@}/

Пояснение:

{           #loop through all characters
 32|.       #convert to uppercase and duplicate
 123%97<    #determine if is a letter
 n@if       #return either the letter or a newline
}%          #return an array (of ints)
]''*        #convert array to a string with magic
n%          #split on newline, removing blanks (stack is an array of words now)
"oftoitinorisa"   #push this string
2/          #split into groups of two, i.e. ["of" "to" "it" "in" "or" "is" "a"]
-           #remove any occurrences from the text
"theandi"3/-#remove "the", "and", and "i"
$           #sort the array of words
(1@         #takes the first word in the array, pushes a 1, reorders stack
            #the 1 is the current number of occurrences of the first word
{           #loop through the array
 .3$>1{;)}if#increment the count or push the next word and a 1
}/
]2/         #gather stack into an array and split into groups of 2
{~~\;}$     #sort by the latter element - the count of occurrences of each word
22<         #take the first 22 elements
.0=~:2;     #store the highest count
,76\-:1     #store the length of the first line
'_':0*' '\@ #make the first line
{           #loop through each word
"
|"\~        #start drawing the bar
1*2/0       #divide by zero
*'| '@      #finish drawing the bar
}/

"Правильно" (надеюсь). (143)

{32|.123%97<n@if}%]''*n%"oftoitinorisa"2/-"theandi"3/-$(1@{.3$>1{;)}if}/]2/{~~\;}$22<..0=1=:^;{~76@,-^*\/}%$0=:1'_':0*' '\@{"
|"\~1*^/0*'| '@}/

Менее медленное - полминуты. (162)

'"'/' ':S*n/S*'"#{%q
'\+"
.downcase.tr('^a-z','
')}\""+~n%"oftoitinorisa"2/-"theandi"3/-$(1@{.3$>1{;)}if}/]2/{~~\;}$22<.0=~:2; 76\-:1'_':0*S\@{"
|"\~1*2/0*'| '@}/

Вывод отображается в журналах редакций.

Assaf Lavie
3 июля 2010 в 16:12
2

О GolfScript: golfscript.com/golfscript

Gabe
3 июля 2010 в 19:48
2

Неправильно, поскольку если второе слово действительно длинное, оно будет перенесено на следующую строку.

JAB
6 июля 2010 в 16:20
5

"делить на ноль" ... GolfScript это позволяет?

avatar
3 июля 2010 в 16:52
2

Python 2.6, 273 269 267 266 символов.

(Редактировать: поддержка ChristopheD для предложений по бритью персонажей)

import sys,re
t=re.findall('[a-z]+',"".join(sys.stdin).lower())
d=sorted((t.count(w),w)for w in set(t)-set("the and of to a i it in or is".split()))[:-23:-1]
r=min((78.-len(m[1]))/m[0]for m in d)
print'','_'*(int(d[0][0]*r-2))
for(a,b)in d:print"|"+"_"*(int(a*r-2))+"|",b

Вывод:

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|____________________________________________________________| said
|____________________________________________________| alice
|______________________________________________| was
|__________________________________________| that
|___________________________________| as
|_______________________________| her
|____________________________| with
|____________________________| at
|___________________________| s
|___________________________| t
|_________________________| on
|_________________________| all
|______________________| this
|______________________| for
|______________________| had
|_____________________| but
|____________________| be
|____________________| not
|___________________| they
|__________________| so
ChristopheD
3 июля 2010 в 14:13
0

Вы можете опустить квадратные скобки в r=min([(78.0-len(m[1]))/m[0] for m in d]) (удаляет 2 символа: min((78.0-len(m[1]))/m[0] for m in d)). То же самое касается квадратных скобок в третьей строке: sorted([...

ChristopheD
3 июля 2010 в 14:14
0

Также в третьей и четвертой строке вы можете потерять ненужное пространство непосредственно перед for (сокращает 2 символа).

ChristopheD
3 июля 2010 в 14:34
0

Мне нравится, как вы злоупотребляете этим print'', для печати начального пробела в первой строке; умный ;-)

user382714
3 июля 2010 в 16:54
0

Только что понял, что мне не нужен следующий ноль, чтобы объявить число с плавающей запятой в четвертой строке. Это единственная запись Python, которая учитывает, что некоторые слова могут быть значительно длиннее, чем наиболее распространенное?

6502
5 июля 2010 в 23:13
0

вместо 78 можно использовать 76 и сэкономить два «-2»; вместо m [0], m [1] вы можете использовать w и r, выполнив «for w, r in d». вы можете использовать \ w вместо [a-z]. sys.stdin.read () короче. Мне нравится идея использовать запятые!

user382714
7 июля 2010 в 11:15
0

Хорошие моменты; однако \ w соответствует символам подчеркивания, поэтому я его не использовал.

avatar
nico
3 июля 2010 в 16:34
2

R 449 символов

может быть короче ...

bar <- function(w, l)
    {
    b <- rep("-", l)
    s <- rep(" ", l)
    cat(" ", b, "\n|", s, "| ", w, "\n ", b, "\n", sep="")
    }

f <- "alice.txt"
e <- c("the", "and", "of", "to", "a", "i", "it", "in", "or", "is", "")
w <- unlist(lapply(readLines(file(f)), strsplit, s=" "))
w <- tolower(w)
w <- unlist(lapply(w, gsub, pa="[^a-z]", r=""))
u <- unique(w[!w %in% e])
n <- unlist(lapply(u, function(x){length(w[w==x])}))
o <- rev(order(n))
n <- n[o]
m <- 77 - max(unlist(lapply(u[1:22], nchar)))
n <- floor(m*n/n[1])
u <- u[o]

for (i in 1:22)
    bar(u[i], n[i])
nico
3 июля 2010 в 14:46
0

@Johannes Rössel: Он динамический, просто масштабирован до 100% = 60 пикселей = максимальная длина. Например: 1-й мир = 50 вхождений, 2-й мир = 25 вхождений. 1-я полоса = 60 пикселей, 2-я полоса = 30 пикселей

nico
3 июля 2010 в 16:37
0

@Johannes Rössel: Хорошо, я не читал часть, в которой говорилось, что вы должны максимизировать длину, подумал, что нужно просто уместить 80 символов ... теперь все работает как задумано :) Спасибо, что заметили это

Joey
3 июля 2010 в 16:41
0

Думаю, это единственное, что чаще всего делают неправильно в ответах. Мне также потребовалось немало времени, чтобы придумать элегантный способ сделать это.

avatar
Ventero
3 июля 2010 в 12:20
42

Ruby 1.9, 185 символов

(в значительной степени основан на других решениях Ruby)

w=($<.read.downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).group_by{|x|x}.map{|x,y|[-y.size,x]}.sort[0,22]
k,l=w[0]
puts [?\s+?_*m=76-l.size,w.map{|f,x|?|+?_*(f*m/k)+"| "+x}]

Вместо использования каких-либо переключателей командной строки, как в других решениях, вы можете просто передать имя файла в качестве аргумента. (т.е. ruby1.9 wordfrequency.rb Alice.txt)

Поскольку здесь я использую символьные литералы, это решение работает только в Ruby 1.9.

Изменить: точка с запятой заменена переносом строки для "удобочитаемости". : P

Редактировать 2: Штеф указал, что я забыл конечный пробел - исправил это.

Редактировать 3: снова удалили конечный пробел;)

Stéphan Kochen
3 июля 2010 в 12:11
0

После каждого слова отсутствует конечный пробел.

Stéphan Kochen
3 июля 2010 в 12:19
0

Ох, стреляй, не обращай на это внимания. Похоже, что гольф только что обновили, висящее место больше не требуется. :)

Nas Banov
6 июля 2010 в 04:49
0

Кажется, не подходит для «superlongstringstring» во 2-й или более поздней позиции? (см. описание проблемы)

Zombies
14 июля 2010 в 18:43
2

Это выглядит действительно ремонтопригодным.

avatar
archgoon
3 июля 2010 в 11:56
34

Руби 207 213 211 210 210 <719997302626> <7199919602626> <7199919602626> <719997302626> <71999603026> <71999603026> <71999603026> 200 символов

Улучшение Anurag, включая предложение rfusca. Также удаляет аргумент для сортировки и несколько других незначительных игр в гольф.

w=(STDIN.read.downcase.scan(/[a-z]+/)-%w{the and of to a i it in or is}).group_by{|x|x}.map{|x,y|[-y.size,x]}.sort.take 22;k,l=w[0];m=76.0-l.size;puts' '+'_'*m;w.map{|f,x|puts"|#{'_'*(m*f/k)}| #{x} "}

Выполнить как:

ruby GolfedWordFrequencies.rb < Alice.txt

Редактировать: вернуть 'put', должно быть там, чтобы избежать кавычек в выводе.
Edit2: измененный файл-> IO
Edit3: удалено / i
Edit4: удалены скобки вокруг (f * 1.0), пересчитано
Edit5: использовать добавление строки для первой строки; развернуть s на месте.
Edit6: Сделано m float, удалено 1.0. РЕДАКТИРОВАТЬ: не работает, меняет длину. РЕДАКТИРОВАТЬ: не хуже, чем раньше
Edit7: используйте STDIN.read.

Anurag
3 июля 2010 в 09:39
0

+1 - люблю сортировку, очень умно :)

archgoon
3 июля 2010 в 10:01
0

Эй, небольшая оптимизация по сравнению с основной задачей. :)

Stéphan Kochen
3 июля 2010 в 10:57
0

Отлично! Добавлены два изменения, которые я также внес в версию Анурага. Сбривает еще 4.

archgoon
3 июля 2010 в 11:06
0

Решение отклонилось от исходного результата, я попытаюсь выяснить, где это произошло.

archgoon
3 июля 2010 в 11:11
0

Ха, обратите внимание, что последние два имеют одинаковую длину (в нашей и некоторых других версиях), но у исходного вопрошающего они разные. Оригинальное решение Anurag имеет эту проблему. Будет больно выслеживать это. Я снова прибегаю к уловке 76.0, потому что проблема не в этом.

Stéphan Kochen
3 июля 2010 в 11:26
0

@archgoon: Я приветствую ваши благородные усилия, но добавление строк не короче для цикла. Он короче только потому, что вы убрали конечное пространство. Но не расстраивайтесь, это не делает Perl лучше. ;)

archgoon
3 июля 2010 в 11:33
0

@ Штеф, ах, это объясняет, почему ты этого еще не сделал;). По крайней мере, мы получили правильный счет. Поздравляю тебя.

Dogbert
3 июля 2010 в 14:07
0

Как насчет [0..21] вместо .take 22?

archgoon
3 июля 2010 в 22:16
1

Дальше есть более короткий вариант.

avatar
Frank Farmer
3 июля 2010 в 06:34
7

* sh (+ curl), частичное решение

Это неполно, но, черт возьми, вот частота слов, учитывающая половину проблемы в 192 байтах:

curl -s http://www.gutenberg.org/files/11/11.txt|sed -e 's@[^a-z]@\n@gi'|tr '[:upper:]' '[:lower:]'|egrep -v '(^[^a-z]*$|\b(the|and|of|to|a|i|it|in|or|is)\b)' |sort|uniq -c|sort -n|tail -n 22
avatar
3 июля 2010 в 06:33
1

Javascript, 348 символов

Закончив свою, я позаимствовал некоторые идеи у Мэтта: 3

t=prompt().toLowerCase().replace(/\b(the|and|of|to|a|i[tns]?|or)\b/gm,'');r={};o=[];t.replace(/\b([a-z]+)\b/gm,function(a,w){r[w]?++r[w]:r[w]=1});for(i in r){o.push([i,r[i]])}m=o[0][1];o=o.slice(0,22);o.sort(function(F,D){return D[1]-F[1]});for(B in o){F=o[B];L=new Array(~~(F[1]/m*(76-F[0].length))).join('_');print(' '+L+'\n|'+L+'| '+F[0]+' \n')}

Требуется поддержка функции print и подсказки .

Joey
5 июля 2010 в 07:52
0

Это будет иметь некоторые проблемы со строками типа the_foo, верно? (Потому что тогда \b распадается)

avatar
AKX
2 июля 2010 в 23:50
8

Python 2.6, 347 символов

import re
W,x={},"a and i in is it of or the to".split()
[W.__setitem__(w,W.get(w,0)-1)for w in re.findall("[a-z]+",file("11.txt").read().lower())if w not in x]
W=sorted(W.items(),key=lambda p:p[1])[:22]
bm=(76.-len(W[0][0]))/W[0][1]
U=lambda n:"_"*int(n*bm)
print "".join(("%s\n|%s| %s "%((""if i else" "+U(n)),U(n),w))for i,(w,n)in enumerate(W))

Вывод:

 _________________________________________________________________________
|_________________________________________________________________________| she 
|_______________________________________________________________| you 
|____________________________________________________________| said 
|_____________________________________________________| alice 
|_______________________________________________| was 
|___________________________________________| that 
|____________________________________| as 
|________________________________| her 
|_____________________________| with 
|_____________________________| at 
|____________________________| s 
|____________________________| t 
|__________________________| on 
|__________________________| all 
|_______________________| this 
|_______________________| for 
|_______________________| had 
|_______________________| but 
|______________________| be 
|_____________________| not 
|____________________| they 
|____________________| so 
ChristopheD
3 июля 2010 в 14:28
1

Вы можете потерять строку bm=(76.-len(W[0][0]))/W[0][1], так как вы используете bm только один раз (сделайте следующую строку U=lambda n:"_"*int(n*(76.-len(W[0][0]))/W[0][1]), удалит 5 символов. Также: зачем вам использовать двухсимвольное имя переменной в коде игры в гольф? ;-)

ChristopheD
3 июля 2010 в 14:29
0

В последней строке пробел после print не нужен, убирает один символ

Joey
4 июля 2010 в 23:12
1

Не учитывает случай, когда второе по частоте слово очень длинное, правда?

AKX
5 июля 2010 в 10:11
0

@ChristopheD: Потому что я слишком долго смотрел на этот код. : P Хороший улов. @Johannes: Да, это тоже можно исправить. Не уверен, что все другие реализации сделали это, когда я писал это.

avatar
Brian
2 июля 2010 в 21:58
9

F #, 452 символа

Прямо вперед: получите последовательность a пар подсчет слов, найдите лучший множитель количества слов на столбец k, затем распечатайте результаты.

let a=
 stdin.ReadToEnd().Split(" .?! \":;'\r\n".ToCharArray(),enum 1)
 |>Seq.map(fun s->s.ToLower())|>Seq.countBy id
 |>Seq.filter(fun(w,n)->not(set["the";"and";"of";"to";"a";"i";"it";"in";"or";"is"].Contains w))
 |>Seq.sortBy(fun(w,n)-> -n)|>Seq.take 22
let k=a|>Seq.map(fun(w,n)->float(78-w.Length)/float n)|>Seq.min
let u n=String.replicate(int(float(n)*k)-2)"_"
printfn" %s "(u(snd(Seq.nth 0 a)))
for(w,n)in a do printfn"|%s| %s "(u n)w

Пример (у меня другое количество частот, чем у вас, не знаю почему):

% app.exe < Alice.txt

 _________________________________________________________________________
|_________________________________________________________________________| she
|_______________________________________________________________| you
|_____________________________________________________________| said
|_____________________________________________________| alice
|_______________________________________________| was
|___________________________________________| that
|___________________________________| as
|________________________________| her
|_____________________________| with
|_____________________________| at
|____________________________| t
|____________________________| s
|__________________________| on
|_________________________| all
|_______________________| this
|______________________| had
|______________________| for
|_____________________| but
|_____________________| be
|____________________| not
|___________________| they
|__________________| so
ChristopheD
2 июля 2010 в 22:15
0

оказывается, что мое собственное решение действительно было немного не так (из-за немного другой спецификации), теперь решения соответствуют ;-)

Rotsor
3 июля 2010 в 04:40
0

+1 за единственно правильную реализацию масштабирования полосы на данный момент

Brian
3 июля 2010 в 08:34
2

(@Rotsor: Иронично, учитывая, что у меня самое старое решение.)

Gabe
3 июля 2010 в 11:59
0

Бьюсь об заклад, вы могли бы немного сократить его, объединив этапы разделения, отображения и фильтрации. Я также ожидал, что вам не понадобится так много float.

Joey
3 июля 2010 в 12:40
0

Разве функции вложения обычно не короче, чем использование оператора конвейера |>?