Generowanie histogramu

12

Napisz najkrótszy program, który generuje histogram (graficzna reprezentacja rozkładu danych).

Zasady:

  • Musi wygenerować histogram na podstawie długości znaków słów (łącznie z interpunkcją) wprowadzanych do programu. (Jeśli słowo ma 4 litery, pasek reprezentujący cyfrę 4 zwiększa się o 1)
  • Musi wyświetlać etykiety pasków, które korelują z długością znaków reprezentowanych przez paski.
  • Wszystkie znaki muszą zostać zaakceptowane.
  • Jeśli paski muszą być skalowane, musi istnieć jakiś sposób pokazany na histogramie.

Przykłady:

$ ./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
źródło
4
Proszę napisać specyfikację, zamiast podawać pojedynczy przykład, który wyłącznie z tego powodu, że nie jest w stanie wyrazić zakresu dopuszczalnych stylów wyjściowych i który nie gwarantuje uwzględnienia wszystkich przypadków narożnych. Dobrze jest mieć kilka przypadków testowych, ale jeszcze ważniejsze jest mieć dobrą specyfikację.
Peter Taylor
@PeterTaylor Podano więcej przykładów.
syb0rg,
1
1. Jest to oznaczone wyjściem graficznym , co oznacza, że ​​chodzi o rysowanie na ekranie lub tworzenie pliku obrazu, ale twoje przykłady są ascii-art . Czy jest to do przyjęcia? (Jeśli nie, to plannabus może nie być szczęśliwy). 2. Interpunkcję definiuje się jako tworzącą policzalne znaki w słowie, ale nie podaje się, które znaki oddzielają słowa, które znaki mogą, ale nie muszą występować na wejściu, oraz jak obsługiwać znaki, które mogą występować, ale które nie są alfabetyczne, interpunkcja lub separatory słów. 3. Czy przeskalowanie prętów w celu uzyskania rozsądnego rozmiaru jest dopuszczalne, wymagane lub zabronione?
Peter Taylor,
@PeterTaylor Nie oznaczyłem go jako ascii-art, ponieważ tak naprawdę to nie jest „sztuka”. Rozwiązanie Phannabus jest w porządku.
syb0rg,
@PeterTaylor Dodałem kilka zasad opartych na tym, co opisałeś. Jak dotąd wszystkie rozwiązania tutaj są nadal zgodne z wszystkimi zasadami.
syb0rg,

Odpowiedzi:

3

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

.

Dłuższy przykład

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| #
tartin
źródło
Co się stanie, jeśli będą słowa zawierające więcej niż 9 liter?
Działa dla słów dowolnej długości
tmartin
5

R, 55 47 znaków

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

Na szczęście R jest wyposażony w funkcję wykresu histdla histogramów, tutaj dostarczaną z breaksargumentem, w którym przerwy wynoszą 0,5, 1,5, ... aż do maksimum (wejście) +0,5. sapply(scan(,""),nchar)przyjmuje dane wejściowe (jako standardowe), oddziela je po spacjach i zlicza liczbę znaków każdego elementu.

Przykłady:

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

wprowadź opis zdjęcia tutaj

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

wprowadź opis zdjęcia tutaj

Edytować:

Wariacja na 71 znaków z etykietą osi dla każdej możliwej wartości:

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

wprowadź opis zdjęcia tutaj

plannapus
źródło
3
Uwielbiam, gdy normalnie pełny język przejmuje prowadzenie!
Nie jest to jednak zgodne ze specyfikacją ...
Klamka
@ Doorknob, której specyfikacji nie spełnia?
plannapus,
Przykładowe przypadki testowe.
Klamka
3
Są to przykłady, a nie specyfikacje ...
plannapus,
5

Python - 83 znaki

Wydaje się, że możemy pobierać dane wejściowe z dowolnego miejsca, więc pobiera dane wejściowe podczas wykonywania, a nie z wiersza poleceń, i korzysta z sugestii Ejrba, aby skrócić go o 8.

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

Python - 91 znaków

To się przewróci z cytatami.

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

Wejście:

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

Wynik:

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

źródło
2
fajnie, możesz ogolić 4 znaki, przerabiając drugą linię (bez zmiany algorytmu), aby używać execi c=0;exec'c+=1;print"%3d|"%c+"#"*s.count(c);'*max(s)
łączyć
4

Haskell - 126 znaków

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

To pobiera dane wejściowe stdin, a nie wiersz poleceń:

& 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
źródło
Dla mnie wygląda dobrze! +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))

Dane wyjściowe:
(pierwszy wiersz to ciąg wejściowy)

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

Nie usprawiedliwia liczb jako rozwiązania Pythona Lego Stormtroopr (które jest również krótsze od mojego), ale to mój pierwszy udział w zawodach golfowych, więc równie dobrze mogę zostawić to tutaj :)

Roberto
źródło
Czy możesz edytować na przykład wygenerowanego histogramu przez ten program?
syb0rg,
Tak, ale właśnie zauważyłem, że ma jeden problem: nie usprawiedliwia liczb jako rozwiązania Lego Stormtroopr, więc właściwie myślę o wycofaniu odpowiedzi.
Roberto,
Tak długo, jak istnieją etykiety dla reprezentowanych słupków, odpowiedź jest akceptowalna.
syb0rg,
Ok, gotowe! :)
Roberto
To pobiera dane wejściowe z danych wejściowych, a nie z argumentów. Czy to jest ważne @ syb0rg?
3

Perl, 56

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

Dodano przepisanie @ manatwork i dosłowną sugestię nowej linii, dziękuję bardzo! Dodano aktualizacje @ chinese_perl_goth.

Sposób użycia: zapisz jako hist.pl i uruchom perl hist.pl This is a test

Przykładowe dane wyjściowe:

$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|#
Dom Hastings
źródło
1
Dlaczego nie użyć printf? Możesz oszczędzić trochę znaków na temat formatowania. A niektóre z bardziej zmieniając hash do tablicy: $d[y///c]++for@ARGV;shift@d;printf"%2d|%s\n",++$i,"#"x$_ for@d.
manatwork
Czy mogę zobaczyć przykład tego programu w pracy?
syb0rg,
@manatwork printfnie przyszło mi do głowy i z jakiegoś powodu nie sądziłem, że mogę uzyskać pożądany efekt za pomocą tablicy, niesamowite! @ syb0rg dodaje teraz
Dom Hastings,
2
grał jeszcze w golfa, zmniejszył go do 57 bajtów:$d[y///c].='#'for@ARGV;printf"%2d|$d[$_]\n",$_ for+1..$#d
chiński perl goth
1
Przegapiliśmy tylko najprostszą sztuczkę: użyj dosłownego nowego wiersza zamiast \nzaoszczędzić 1 dodatkową postać. Mam na myśli tak: pastebin.com/496z2a0n
manatwork
3

J, 48 47 46 45 43 znaków

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

Stosowanie:

   (;#&'#')/"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
źródło
Tacit, 38 [:((](;#&'#')"0[:+/=/)1+[:i.>./)#@>@;:: Wypróbuj online!
Jonasz
2

Ruby, 98 85

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

Niewiele golfa. Będzie grał w golfa później.

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|#
Klamka
źródło
Działa ładnie (++ voteCount). Czy mógłbym coś zrobić, aby lepiej sformułować pytanie?
syb0rg,
1
@ syb0rg IMO pytanie brzmi dobrze, przykłady mówią same za siebie. Chociaż twój ostatni raz wydaje się mieć błąd ... Zliczam 2 8-literowe słowa (generuj i generuj) i 2 9-literowe słowa (histogram, histogram)
Klamka
Chłodny. Możesz zmienić za b ?(?#*b[1].size):''pomocą b&&?#*b[1].size.
manatwork,
2

PowerShell, 97 93

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

Przykład:

PS Z:\> .\hist.ps1 This is an example of this program running
1  |
2  |###
3  |
4  |##
5  |
6  |
7  |###
Danko Durbić
źródło
Czy mogę zobaczyć przykład uruchomionego programu?
syb0rg,
@ syb0rg Jasne, zaktualizowałem odpowiedź przykładem.
Danko Durbić
Wygląda dobrze! +1 dla Ciebie!
syb0rg
Ładny. Możesz usunąć dodatkowe spacje i zaoszczędzić 6 bajtów$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←⍞

Mógłbym być krótszy, gdybym mógł pominąć wiersze o wartości 0.

Wyjaśnienie:

  • ⎕ML←3: ustaw poziom migracji na 3 (dzięki temu (partycja) będzie bardziej przydatna).
  • I⊂⍨' '≠I←⍞: odczyt danych wejściowych, podział na spacje
  • M←↑∘⍴¨: uzyskaj rozmiar pierwszego wymiaru każdego elementu (długości słów) i zapisz M
  • K←⍳⌈/M: uzyskaj liczby od 1 do najwyższej wartości w M, zapisz wK
  • +⌿K∘.=M: dla każdej wartości w Mzobacz, ile razy jest zawarta w K.
  • ⊃⍴∘'▓'¨: dla każdej z tych wartości uzyskaj listę tylu s i sformatuj ją jako macierz.
  • K,: wstaw każdą wartość Kdo każdego wiersza w matrycy, podając etykiety.

Wynik:

      ⎕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 ▓▓     
marinus
źródło
2

Mathematica 97

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

Kiedy wprowadzam tekst Deklaracji Niepodległości jako pojedynczy ciąg (oczywiście poprzez wycinanie i wklejanie), generowane dane wyjściowe to:

deklaracja Niepodległości

DavidC
źródło
2

Dalej, 201

To było zabawne, ale moje zgłoszenie w Ruby jest bardziej konkurencyjne. ;-)

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

Przykładowy przebieg:

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

Maksymalna długość słowa wynosi 99.

Darren Stone
źródło
2

Ruby, 79

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

Przykładowy przebieg:

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

Proszę zobaczyć moje zgłoszenie Czwarty dla śmiechu.

Darren Stone
źródło
2

Ruby 1.8.7, 74

Nieco inne podejście niż inne rozwiązania rubinowe:

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

wynik:

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

 1:#
 2:###
 3:######
 4:#############################
 5:#####################################################
 6:############################################################
 7:########################################################################
 8:######################################################
 9:############################################################
10:########################
11:###########################
12:######
13:#####
AShelly
źródło
Przepraszam, początkowo nie widziałem tego zgłoszenia. +1
syb0rg
1

JavaScript ( 159 133)

Zdecydowanie nie konkurencyjny, ale jak dotąd jedyne rozwiązanie JavaScript. Dzięki @manatwork za wskazówkę dotyczącą używania 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++]||""))

Wejście

Code Golf to strona z pytaniami i odpowiedziami przeznaczona dla entuzjastów programowania i golfistów. Jest zbudowany i obsługiwany przez Ciebie jako część sieci Stack Exchange stron z pytaniami i odpowiedziami. Z twoją pomocą współpracujemy nad stworzeniem biblioteki łamigłówek programistycznych i ich rozwiązań.

Wynik

1 |##
2 |#######
3 |#########
4 |########
5 |######
6 |###
7 |####
8 |####
9 |
10|#
11|###
miętówka
źródło
1
Rzeczywiście, nie jest to tak naprawdę dziedzina, w której JavaScript się wyróżnia. Ale ze replace()zamiast split()+ fori Arrayzamiast Object+ oddzielne zmiennej długości można zmniejszyć za pomocą kilku znaków: 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++]||"")). (I jeszcze krócej w Harmony 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 Nice nadużycie .lengthtam.
quietmint,
1

Pure Bash 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

Próba:

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

Zaoszczędź 8 znaków, używając jednego widelca do 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 \  \#

Daj ten sam wynik:

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 )

render (na moim hoście :)

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|#
F. Hauri
źródło
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";

Stosowanie:

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|##
Piotr Kępka
źródło
1

8 , 162 bajty

Kod

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

Stosowanie

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

Wynik

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

Nieskluczony kod ( SED to diagram efektu stosu)

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
Dwór Chaosu
źródło