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


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

4
Будь ласка, напишіть специфікацію, а не наводячи єдиний приклад, який, виключно в силу того, що є єдиним прикладом, не може виразити діапазон прийнятних стилів виводу і що не гарантує охоплення всіх кутових випадків. Добре мати кілька тестових випадків, але ще важливіше мати хорошу специфікацію.
Пітер Тейлор

@PeterTaylor Наведено більше прикладів.
syb0rg

1
1. Це позначено графічним виходом , це означає, що мова йде про малювання на екрані або створення файлу зображення, але ваші приклади - ascii-art . Чи прийнятний чи? (Якщо ні, то планнабус може не радіти). 2. Ви визначаєте розділові знаки як утворюючі лічильні символи у слові, але ви не вказуєте, які символи відокремлюють слова, які символи можуть, а можуть не виникати на вводі, і як поводитися з символами, які можуть виникати, але які не буквені, пунктуаційні або роздільники слів. 3. Чи прийнятний, необхідний чи заборонений розмір штанги таким чином, щоб вони відповідали розміру?
Пітер Тейлор

@PeterTaylor Я не позначив це ascii-art, оскільки це насправді не "мистецтво". Рішення Фаннабуса просто чудове.
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| #

Що станеться, якщо є слова з більш ніж 9 літерами?

Це працює для слів будь-якої довжини
tmartin

5

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

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

На щастя, R має функцію histграфіку для гістограм, тут подається breaksаргумент, коли перерви становлять 0,5, 1,5, ... до max (вхід) +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))

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


3
Я люблю, коли нормально багатослівна мова переважає!

Однак це не відповідає специфікації ...
Doorknob

@Doorknob, якій специфікації вона не відповідає?
планнапус

Приклади тестових вікон.
Дверна ручка

3
Вони є прикладами, а не технічними характеристиками ...
plannapus

5

Пітон - 83 символи

Здається, ми можемо взяти дані з будь-якого місця, тому це вимагає введення під час виконання, а не з командного рядка, і використовує пропозицію Ejrb, щоб скоротити його на 8.

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

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

Haskell - 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|#

Мені добре виглядає! +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 | ##

Це не виправдовує цифри як рішення Python Lego Stormtroopr (яке також коротше, ніж у мене), але це моє перше входження в змагання з гольфу, тому я, можливо, також залиште його тут, мабуть :)


Чи можете ви відредагувати приклад згенерованої гістограми цією програмою?
syb0rg

Так, але я щойно помітив, що у нього є одна проблема: вона не виправдовує числа як рішення Лего Штормтроопра, тому я насправді замислююся над тим, щоб залишити відповідь.
Роберто

Поки існують мітки для представлених смуг, відповідь прийнятна.
syb0rg

Гаразд, зробили тоді! :)
Роберто

Це вимагає введення даних, а не аргументів. Чи дійсно це @ syb0rg?

3

Перл, 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.
манатура

Чи можу я побачити приклад цієї програми на роботі?
syb0rg

@manatwork printfу мене взагалі не траплявся, і я чомусь не думав, що зможу отримати ефект, який я хотів із масиву, дивовижно! @ syb0rg додає зараз
Dom Hastings

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│##     │
└─┴───────┘

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

Працює чудово (++ кількість голосів). Що б я міг зробити, щоб сформулювати питання краще?
syb0rg

1
@ syb0rg IMO питання чітко сформульовано, приклади говорять самі за себе. Хоча, здається, у Вашого останнього разу є помилка ... Я рахую 2 8-літерні слова (генерувати та генерувати) та 2 9-літерні слова (гістограма, гістограма)
Doorknob

Класно. Ви можете змінити b ?(?#*b[1].size):''з b&&?#*b[1].size.
манатство

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

Математика 97

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

Коли я ввожу текст Декларації незалежності як єдиний рядок (звичайно через вирізання та вставку), отриманий результат був:

декларація незалежності


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

Будь ласка, дивіться моє подальше подання на сміх.


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:#####

Спочатку я не бачив цього повідомлення, вибачте! +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 сайтів Q&A. З вашою допомогою ми працюємо разом над тим, щоб створити бібліотеку загадок програмування та їх рішення.

Вихідні дані

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

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 Приємне зловживання .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|#

Невикористаний код ( 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.