Генерация гистограммы

12

Напишите самую короткую программу, которая генерирует гистограмму (графическое представление распределения данных).

Правила:

  • Необходимо сгенерировать гистограмму на основе длины символов слов (включая знаки препинания), введенных в программу. (Если слово имеет длину 4 буквы, столбец, представляющий число 4, увеличивается на 1)
  • Должны отображаться метки строк, которые коррелируют с длиной символов, которые представляют полосы.
  • Все символы должны быть приняты.
  • Если столбцы должны быть масштабированы, должен быть какой-то путь, который показан на гистограмме.

Примеры:

$ ./histogram This is a hole in one!
1 |#
2 |##
3 |
4 |###

$./histogram Extensive word length should not be very problematic.
1 |
2 |#
3 |#
4 |##
5 |
6 |##
7 |
8 |
9 |#
10|
11|
12|#

./histogram Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for.
1 |##
2 |#######
3 |#
4 |#######
5 |###
6 |#
7 |##
8 |##
9 |##
syb0rg
источник
4
Пожалуйста, напишите спецификацию, а не приведите один пример, который, будучи единственным примером, не может выразить диапазон допустимых стилей вывода и который не гарантирует охват всех угловых случаев. Хорошо иметь несколько тестовых случаев, но еще важнее иметь хорошую спецификацию.
Питер Тейлор
@PeterTaylor Больше примеров.
syb0rg
1
1. Это помечено графическим выводом , что означает рисование на экране или создание файла изображения, но ваши примеры - ascii-art . Является ли это приемлемым? (Если нет, то планнабус может не быть счастливым). 2. Вы определяете пунктуацию как формирование счетных символов в слове, но не указываете, какие символы разделяют слова, какие символы могут и не могут встречаться во вводе, и как обрабатывать символы, которые могут встречаться, но не являются буквенными, пунктуация или разделители слов. 3. Допустимо ли, требуется или запрещено масштабировать планки, чтобы они подходили по размеру?
Питер Тейлор
@PeterTaylor Я не помечал это ascii-art, потому что это действительно не "art". Решение Phannabus просто отлично.
syb0rg
@PeterTaylor Я добавил некоторые правила, основанные на том, что вы описали. Пока что все решения здесь придерживаются всех правил до сих пор.
syb0rg

Ответы:

3

К, 35

{(1+!|/g)#`$(#:'=g:#:'" "\:x)#'"#"}

,

k){(1+!|/g)#`$(#:'=g:#:'" "\:x)#'"#"}"Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for."
1| ##
2| #######
3| #
4| #######
5| ###
6| #
7| ##
8| ##
9| ##

,

Более длинный пример

k){(1+!|/g)#`$(#:'=g:#:'" "\:x)#'"#"}"Please write a specification rather than giving a single example which, solely by virtue of being a single example, cannot express the range of acceptable output styles, and which doesnt guarantee to cover all corner cases. Its good to have a few test cases, but its even more important to have a good spec."
1 | #####
2 | ######
3 | #######
4 | ########
5 | ######
6 | ##############
7 | ###
8 | #
9 | ##
10| #
11|
12|
13| #
tmartin
источник
Что произойдет, если найдутся слова, содержащие более 9 букв?
Это работает для слов любой длины
tmartin
5

R, 55 47 символов

hist(a<-sapply(scan(,""),nchar),br=.5+0:max(a))

К счастью, R поставляется с функцией построения графика histдля гистограмм, здесь он снабжен breaksаргументом, в котором разрывы составляют 0,5, 1,5, ... до максимума (ввод) +0,5. sapply(scan(,""),nchar)принимает входные данные (как stdin), разделяет их по пробелам и считает количество символов каждого элемента.

Примеры:

hist(a<-sapply(scan(,""),nchar),br=.5+0:max(a))
1: Extensive word length should not be very problematic.
9: 
Read 8 items

введите описание изображения здесь

hist(a<-sapply(scan(,""),nchar),br=.5+0:max(a))
1: Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for.
28: 
Read 27 items

введите описание изображения здесь

Редактировать:

Вариация в 71 символ с меткой оси на каждом возможном значении:

hist(a<-sapply(scan(,""),nchar),br=.5+0:max(a),ax=F);axis(1,at=1:max(a))

введите описание изображения здесь

plannapus
источник
3
Я люблю, когда обычно многословный язык берет на себя инициативу!
Это не соответствует спецификации, однако ...
Дверная ручка
@ Doorknob, какая спецификация не соответствует?
plannapus
Пример тестовых случаев.
Дверная ручка
3
Это примеры, а не спецификации ...
plannapus
5

Python - 83 символа

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

s=map(len,raw_input().split())
c=0;exec'c+=1;print"%3d|"%c+"#"*s.count(c);'*max(s)

Python - 91 символ

Это упадет с кавычками.

import sys;s=map(len,sys.argv[1:])
for i in range(1,max(s)+1):print"%3d|"%i+'#'*s.count(i)

Входные данные:

> python hist.py Please write a specification rather than giving a single example which, solely by virtue of being a single example, cannot express the range of acceptable output styles, and which doesnt guarantee to cover all corner cases. Its good to have a few test cases, but its even more important to have a good spec.

Выход:

  1|#####
  2|######
  3|#####
  4|##########
  5|######
  6|#############
  7|####
  8|#
  9|##
 10|#
 11|
 12|
 13|#

источник
2
хорошо, вы можете сбрить 4 символа, переработав вторую строку (без изменения алгоритма) execи конкатенацию строк:c=0;exec'c+=1;print"%3d|"%c+"#"*s.count(c);'*max(s)
ejrb
4

Хаскель - 126 символов

p[d]=[' ',d];p n=n
h l=[1..maximum l]>>= \i->p(show i)++'|':(l>>=($"#").drop.abs.(i-))++"\n"
main=interact$h.map length.words

Это принимает входные данные stdin, а не командную строку:

& head -500 /usr/share/dict/words | runhaskell 15791-Histogram.hs 
 1|##
 2|##
 3|######
 4|###############
 5|################################################
 6|###############################################################
 7|###################################################################
 8|###########################################################################
 9|#############################################################
10|##########################################################
11|#########################################################
12|#########################
13|#######
14|###
15|#####
16|###
17|#
18|
19|#
20|#
MtnViewMark
источник
Выглядит хорошо для меня! +1
syb0rg
3

Python 3,3 (93)

a=[len(i) for i in input().split()]
for i in range(1,max(a)+1):
 print(i,'|',"#"*a.count(i))

Вывод:
(первая строка - строка ввода)

Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for.
1 | ##
2 | #######
3 | #
4 | #######
5 | ###
6 | #
7 | ##
8 | ##
9 | ##

Это не оправдывает цифры как решение Lego Stormtroopr's Python (которое также короче моего), но это моя первая запись в соревновании по гольфу, так что я мог бы оставить ее здесь, я думаю :)

Роберто
источник
Не могли бы вы отредактировать в примере сгенерированной гистограммой этой программой?
syb0rg
Да, но я только что заметил, что у него есть одна проблема: это не оправдывает цифры как решение Lego Stormtroopr, так что я думаю об отмене ответа.
Роберто
Пока есть метки для представленных столбцов, ответ приемлем.
syb0rg
Хорошо, тогда сделано! :)
Роберто
Это принимает входные данные, а не аргументы. Это действительно @ syb0rg?
3

Perl, 56

$d[y///c].='#'for@ARGV;printf"%2d|$d[$_]
",$_ for+1..$#d

Добавлено предложение по переписыванию и буквальному переводу строки @ manatwork, большое спасибо! Добавлены обновления @ chinese_perl_goth.

Использование: сохранить как Hist.pl и запустить perl hist.pl This is a test

Пример вывода:

$perl ~/hist.pl This is a test of the histogram function and how it will count the number of words of specific lengths. This sentence contains a long word 'complexity'.
 1|##
 2|#####
 3|####
 4|######
 5|##
 6|#
 7|
 8|#####
 9|#
10|
11|#
Дом Гастингс
источник
1
Почему бы не использовать printf? Вы можете сэкономить некоторые символы на форматирование. И еще немного изменив от хэша к массиву: $d[y///c]++for@ARGV;shift@d;printf"%2d|%s\n",++$i,"#"x$_ for@d.
manatwork
Могу ли я увидеть пример этой программы на работе?
syb0rg
@manatwork printfвообще не приходил мне в голову, и по какой-то причине я не думал, что смогу получить желаемый эффект с массивом, потрясающе! @ syb0rg добавим сейчас
Дом Гастингс
2
немного поиграл в гольф, сократил его до 57 байт:$d[y///c].='#'for@ARGV;printf"%2d|$d[$_]\n",$_ for+1..$#d
китайский Perl Goth
1
Мы пропустили только самый простой трюк: используйте буквальный перевод строки вместо того, \nчтобы сэкономить еще 1 символ. Я имею в виду, как это: pastebin.com/496z2a0n
manatwork
3

J, 48 47 46 45 43 символов

(;#&'#')/"1|:((],[:+/=/)1+[:i.>./)$;._1' ',

Использование:

   (;#&'#')/"1|:((],[:+/=/)1+[:i.>./)$;._1' ','Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for.'
┌─┬───────┐
│1│##     │
├─┼───────┤
│2│#######│  
├─┼───────┤
│3│#      │
├─┼───────┤
│4│#######│
├─┼───────┤
│5│###    │
├─┼───────┤
│6│#      │
├─┼───────┤
│7│##     │
├─┼───────┤
│8│##     │
├─┼───────┤
│9│##     │
└─┴───────┘
Gareth
источник
Tacit, 38 [:((](;#&'#')"0[:+/=/)1+[:i.>./)#@>@;:: попробуйте онлайн!
Иона
2

Рубин, 98 85

a=$*.group_by &:size
1.upto(a.max[0]){|i|b=a.assoc i
puts"%-2i|#{b&&?#*b[1].size}"%i}

Не много в гольф. Будет гольф позже.

c:\a\ruby>hist This is a test for the histogram thingy. yaaaaaaaaaaaay
1 |#
2 |#
3 |##
4 |##
5 |
6 |
7 |#
8 |
9 |#
10|
11|
12|
13|
14|#
Дверная ручка
источник
Прекрасно работает (++ voiceCount). Что-нибудь, что я мог сделать, чтобы лучше сформулировать вопрос?
syb0rg
1
@ syb0rg ИМО, вопрос сформулирован хорошо, примеры говорят сами за себя. Хотя в вашем последнем случае, похоже, произошла ошибка ... Я считаю 2 8-буквенных слова (сгенерировать и сгенерировать) и 2 9-буквенных слова (гистограмма, гистограмма)
Ручка
Здорово. Вы можете изменить b ?(?#*b[1].size):''с b&&?#*b[1].size.
manatwork
2

Powershell, 97 93

$a=@{};$args-split ' '|%{$a[$_.length]++};1..($a.Keys|sort)[-1]|%{"{0,-2} |"-f $_+"#"*$a[$_]}

Пример:

PS Z:\> .\hist.ps1 This is an example of this program running
1  |
2  |###
3  |
4  |##
5  |
6  |
7  |###
Данко Дурбич
источник
Могу ли я увидеть пример запуска этой программы?
syb0rg
@ syb0rg Конечно, я обновил ответ с примером.
Данко Дурбич
Выглядит хорошо! +1 тебе!
syb0rg
Ницца. Вы можете удалить лишние пробелы и сохранить 6 байтов$a=@{};-split$args|%{$a[$_.length]++};1..($a.Keys|sort)[-1]|%{"{0,-2}|"-f$_+"#"*$a[$_]}
mazzy
2

APL (42)

⎕ML←3⋄K,⊃⍴∘'▓'¨+⌿M∘.=K←⍳⌈/M←↑∘⍴¨I⊂⍨' '≠I←⍞

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

Объяснение:

  • ⎕ML←3: установите уровень миграции на 3 (это делает (раздел) более полезным).
  • I⊂⍨' '≠I←⍞: читать ввод, разбить на пробелы
  • M←↑∘⍴¨: получить размер первого измерения каждого элемента (длина слова) и сохранить в M
  • K←⍳⌈/M: получить числа от 1 до наибольшего значения в M, сохранить вK
  • +⌿K∘.=M: для каждого значения в M, посмотрите, сколько раз оно содержится в K.
  • ⊃⍴∘'▓'¨: для каждого значения в этом, получите список с таким количеством s и отформатируйте его как матрицу.
  • K,: перед каждым значением в Kкаждой строке матрицы добавьте метки.

Выход:

      ⎕ML←3⋄K,⊃⍴∘'▓'¨+⌿M∘.=K←⍳⌈/M←↑∘⍴¨I⊂⍨' '≠I←⍞
This is a hole in one!
1 ▓  
2 ▓▓ 
3    
4 ▓▓▓
      ⎕ML←3⋄K,⊃⍴∘'▓'¨+⌿M∘.=K←⍳⌈/M←↑∘⍴¨I⊂⍨' '≠I←⍞
Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for.
1 ▓▓     
2 ▓▓▓▓▓▓▓
3 ▓      
4 ▓▓▓▓▓▓▓
5 ▓▓▓    
6 ▓      
7 ▓▓     
8 ▓▓     
9 ▓▓     
Мэринус
источник
2

Mathematica 97

Histogram["" <> # & /@ StringCases[StringSplit[InputString[]], WordCharacter] /. 
a_String :> StringLength@a]

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

декларация независимости

DavidC
источник
2

Далее 201

Это было весело, но моя работа с Ruby более конкурентоспособна. ;-)

variable w 99 cells allot w 99 cells erase : h begin
1 w next-arg ?dup while swap drop dup w @ > if dup w
! then cells + +! repeat w @ 1+ 1 ?do i . 124 emit i
cells w + @ 0 ?do 35 emit loop cr loop ; h

Образец прогона:

$ gforth histo.fth Forth words make for tough golfing!
1 |
2 |
3 |#
4 |#
5 |###
6 |
7 |
8 |#

Максимальная длина слова 99.

Даррен Стоун
источник
2

Руби, 79

(1..(w=$*.group_by &:size).max[0]).map{|i|puts"%2i|#{?#*w.fetch(i,[]).size}"%i}

Пример выполнения:

$ ruby hist.rb Histograms, histograms, every where, nor any drop to drink.
 1|
 2|#
 3|##
 4|#
 5|#
 6|##
 7|
 8|
 9|
10|
11|##

Пожалуйста, см. Мое представление Forth для смеха.

Даррен Стоун
источник
2

Руби 1.8.7, 74

Немного другой дубль, чем в других рубиновых решениях:

i=0;$*.map{|v|v.size}.sort.map{|v|$><<(i+1..v).map{|n|"
%2i:"%i=n}+['#']}

выход:

ruby hist.rb `head -400 /usr/share/dict/words`

 1:#
 2:###
 3:######
 4:#############################
 5:#####################################################
 6:############################################################
 7:########################################################################
 8:######################################################
 9:############################################################
10:########################
11:###########################
12:######
13:#####
AShelly
источник
Изначально я не видел это представление, извините! +1
syb0rg
1

JavaScript ( 159 133)

Определенно не конкурентное, но пока единственное решение JavaScript. Спасибо @manatwork за подсказку по использованию String.replace.

prompt(o=[]).replace(/\S+/g,function(p){o[l=p.length]=(o[l]||'')+'#'});for(i=1;i<o.length;)console.log(i+(i>9?"|":" |")+(o[i++]||""))

вход

Code Golf - это сайт вопросов и ответов для программистов-энтузиастов и любителей кода. Он создан и поддерживается вами как часть сети вопросов и ответов Stack Exchange. С вашей помощью мы вместе работаем над созданием библиотеки головоломок для программирования и их решений.

Выход

1 |##
2 |#######
3 |#########
4 |########
5 |######
6 |###
7 |####
8 |####
9 |
10|#
11|###
quietmint
источник
1
На самом деле, это не та область, где JavaScript превосходит. Но replace()вместо split()+ forи Arrayвместо Object+ отдельной переменной длины может быть уменьшена с помощью нескольких символов: prompt(o=[]).replace(/\S+/g,function(p){o[l=p.length]=(o[l]||"")+"#"});for(i=1;i<o.length;)console.log(i+(i>9?"|":" |")+(o[i++]||"")). (И еще короче в Гармонии:. prompt(o=[]).replace(/\S+/g,p=>o[l=p.length]=(o[l]||"")+"#");for(i=1;i<o.length;)console.log(i+(i>9?"|":" |")+(o[i++]||"")))
manatwork
@manatwork Хорошее злоупотребление .lengthтам.
спокойная мята
1

Чистая Баш 120

d="$@"
d=${d//[ -z]/#}
for a;do((b[${#a}]++));done
e="${!b[@]}"
for((i=1;i<=${e##* };i++));do
echo $i\|${d:0:b[i]}
done

Образец:

./histogram.sh Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for.
1|##
2|#######
3|#
4|#######
5|###
6|#
7|##
8|##
9|##

Сохраните 8 символов, используя одну вилку для tr: 112

for a;do((b[${#a}]++));done
e="${!b[@]}"
for((i=1;i<=${e##* };i++));do
printf "%d|%${b[i]}s\n" $i
done|tr \  \#

Дайте тот же результат:

bash -c 'for a;do((b[${#a}]++));done;e="${!b[@]}";for((i=1;i<=${e##* };i++));
do printf "%d|%${b[i]}s\n" $i;done|tr \  \#' -- $( sed 's/<[^>]*>//g;
s/<[^>]*$//;s/^[^<]*>//' < /usr/share/scribus/loremipsum/english.xml )

сделать (на моем хосте :)

1|############################################################
2|#################################################################################################################################################################################################################
3|####################################################################################################################################################################################################################################################
4|####################################################################################################################################################################################################
5|####################################################################################################################################################################
6|#######################################################################################
7|##########################################################################################
8|###################################################
9|###############################
10|####################
11|#########
12|############
13|#####
14|####
15|##
16|
17|
18|
19|
20|
21|
22|
23|
24|
25|
26|
27|
28|
29|
30|
31|
32|
33|
34|#
Ф. Хаури
источник
1

PHP, 162

<?php error_reporting(0);$b=0;while($argv[$b])$c[strlen($argv[++$b])]++;for($t=1;$t<=max(array_keys($c));$t++)echo $t.'|'.($c[$t]?str_repeat('#',$c[$t]):'')."\n";

Использование:

php histogram.php Very long strings of words should be just as easy to generate a histogram just as short strings of words are easy to generate a histogram for.
1|##
2|#######
3|#
4|#######
5|###
6|#
7|##
8|##
9|##
Петр Кепка
источник
1

8-е , 162 байта

Код

a:new ( args s:len nip tuck a:@ ( 0 ) execnull rot swap n:1+ a:! ) 0 argc n:1- loop 
a:len n:1- ( dup . "|" . a:@ ( 0 ) execnull "#" swap s:* . cr ) 1 rot loop bye

использование

$ 8th histogram.8th Nel mezzo del cammin di nostra vita mi ritrovai per una selva oscura

Выход

1|
2|##
3|####
4|#
5|##
6|###
7|
8|#

Ungolfed код ( SED - диаграмма эффекта стека)

a:new               \ create an empty array 
( 
    args s:len      \ length of each argument
                    \ SED: array argument lengthOfArgument
    nip             \ SED: array lengthOfArgument
    tuck            \ SED: lengthOfArgument array lengthOfArgument
    a:@             \ get item array at "lengthOfArgument" position
    ( 0 ) execnull  \ if null put 0 on TOS
                    \ SED: lengthOfArgument array itemOfArray
    rot             \ SED: array itemOfArray lengthOfArgument    
    swap            \ SED: array lengthOfArgument itemOfArray
    n:1+            \ increment counter for the matching length
    a:!             \ store updated counter into array 
) 0 argc n:1- loop  \ loop through each argument
\ print histogram
a:len n:1- ( dup . "|" . a:@ ( 0 ) execnull "#" swap s:* . cr ) 1 rot loop 
bye                 \ exit program
Усадьба Хаоса
источник