Geração de histograma

12

Escreva o programa mais curto que gera um histograma (uma representação gráfica da distribuição dos dados).

Regras:

  • É necessário gerar um histograma com base no tamanho dos caracteres das palavras (pontuação incluída) inseridas no programa. (Se uma palavra tiver 4 letras, a barra que representa o número 4 aumenta 1)
  • É necessário exibir rótulos de barra que estejam correlacionados com o comprimento dos caracteres que as barras representam.
  • Todos os caracteres devem ser aceitos.
  • Se as barras precisarem ser dimensionadas, é necessário que exista alguma maneira mostrada no histograma.

Exemplos:

$ ./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
fonte
4
Escreva uma especificação em vez de dar um único exemplo que, apenas por ser um exemplo único, não pode expressar a variedade de estilos de saída aceitáveis ​​e que não garante cobrir todos os casos de canto. É bom ter alguns casos de teste, mas é ainda mais importante ter uma boa especificação.
Peter Taylor
@PeterTaylor Mais exemplos dados.
syb0rg 11/12/2013
1
1. Isso é marcado como saída gráfica , o que significa que se trata de desenhar na tela ou criar um arquivo de imagem, mas seus exemplos são asciáticos . Ou é aceitável? (Caso contrário, o plannabus pode não ser feliz). 2. Você define pontuação como formando caracteres contáveis ​​em uma palavra, mas não indica quais caracteres separam palavras, quais caracteres podem ou não ocorrer na entrada e como lidar com caracteres que podem ocorrer, mas que não são alfabéticos, pontuação ou separadores de palavras. 3. É aceitável, necessário ou proibido redimensionar as barras para caber em um tamanho razoável?
Peter Taylor
@ PeterTaylor Eu não a identifiquei como arte-ascii, porque realmente não é "arte". A solução da Phannabus está bem.
amigos estão dizendo sobre syb0rg
@ PeterTaylor Adicionei algumas regras com base no que você descreveu. Até agora, todas as soluções aqui aderem a todas as regras ainda.
amigos estão dizendo sobre syb0rg

Respostas:

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

.

Um exemplo mais longo

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
fonte
O que acontece se houver palavras com mais de 9 letras?
Ele funciona para palavras de qualquer comprimento
tmartin
5

R, 55 47 caracteres

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

Felizmente, R vem com uma função de plotagem histpara histogramas, fornecida aqui com um breaksargumento em que as quebras são de 0,5, 1,5, ... até max (entrada) +0,5. sapply(scan(,""),nchar)pega uma entrada (como stdin), separa-a após os espaços e conta o número de caracteres de cada elemento.

Exemplos:

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

insira a descrição da imagem aqui

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

insira a descrição da imagem aqui

Editar:

Uma variação de 71 caracteres com um rótulo de eixo em cada valor possível:

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

insira a descrição da imagem aqui

plannapus
fonte
3
Adoro quando uma linguagem normalmente verbal assume a liderança!
Isso não está de acordo com a especificação, no entanto ...
Maçaneta da porta
@ Doorknob com qual especificação não está em conformidade?
plannapus
O exemplo testcases.
Maçaneta
3
São exemplos, não especificações ... #
plannapus
5

Python - 83 caracteres

Parece que podemos receber informações de qualquer lugar, portanto, essas informações são recebidas durante a execução, e não na linha de comando, e usam a sugestão de Ejrb para encurtá-la em 8.

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

Python - 91 caracteres

Isso vai cair entre aspas.

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

Entrada:

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

Resultado:

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

fonte
2
bom, você pode cortar 4 caracteres retrabalhando sua segunda linha (sem alteração de algoritmo) para usar exece concatenação de strings:c=0;exec'c+=1;print"%3d|"%c+"#"*s.count(c);'*max(s)
ejrb
4

Haskell - 126 caracteres

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

Isso pega a entrada stdin, não a linha de comando:

& 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
fonte
Parece bom para mim! 1
syb0rg 11/12/2013
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))

Saída:
(a primeira linha é a sequência de entrada)

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

Não justifica números como a solução Python do Lego Stormtroopr (que também é mais curta que a minha), mas é a minha primeira participação em um concurso de golfe, então é melhor deixá-la aqui, eu acho :)

Roberto
fonte
Você poderia editar um exemplo de um histograma gerado por este programa?
syb0rg 12/12
Sim, mas acabei de notar que ele tem um problema: não justifica os números como a solução da Lego Stormtroopr, por isso estou pensando em retirar a resposta.
10263 Roberto
Desde que haja etiquetas para as barras representadas, a resposta é aceitável.
syb0rg 12/12
Ok, pronto então! :)
Roberto
Isso recebe entrada de entrada, não de argumentos. Isso é válido @ syb0rg?
3

Perl, 56

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

Adicionada a reescrita de @ manatwork e a sugestão literal de nova linha, muito obrigado! Adicionadas atualizações de @ chinese_perl_goth.

Uso: salve como hist.pl e execute perl hist.pl This is a test

Exemplo de saída:

$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
fonte
1
Por que não usar printf? Você pode poupar alguns caracteres na formatação. E um pouco mais ao passar de hash para array: $d[y///c]++for@ARGV;shift@d;printf"%2d|%s\n",++$i,"#"x$_ for@d.
manatwork
Posso ver um exemplo deste programa em ação?
amigos estão dizendo sobre syb0rg
O @manatwork printfnão me ocorreu e, por algum motivo, não achei que poderia obter o efeito desejado com uma variedade, incrível! @ syb0rg adicionando agora
Dom Hastings
2
jogou um pouco mais, reduzi-o para 57 bytes:$d[y///c].='#'for@ARGV;printf"%2d|$d[$_]\n",$_ for+1..$#d
chinese perl goth
1
Perdemos o truque mais simples: use uma nova linha literal em vez de \npoupar mais 1 caractere. Quero dizer assim: pastebin.com/496z2a0n
manatwork
3

J, 48 47 46 45 43 caracteres

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

Uso:

   (;#&'#')/"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
fonte
Tácito, 38 [:((](;#&'#')"0[:+/=/)1+[:i.>./)#@>@;:: Experimente online!
Jonah
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}

Não jogou muito. Golf mais tarde.

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|#
Maçaneta da porta
fonte
Funciona bem (++ voteCount). Algo que eu poderia fazer para formular a pergunta melhor?
syb0rg 11/12/2013
1
@ syb0rg IMO a pergunta está bem redigida, os exemplos falam por si. Embora sua última vez pareça ter um erro ... conto 2 palavras de 8 letras (gerar e gerar) e 2 palavras de 9 letras (histograma, histograma)
Maçaneta da porta
Legal. Você pode mudar b ?(?#*b[1].size):''com b&&?#*b[1].size.
Manatwork
2

Powershell, 97 93

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

Exemplo:

PS Z:\> .\hist.ps1 This is an example of this program running
1  |
2  |###
3  |
4  |##
5  |
6  |
7  |###
Danko Durbić
fonte
Posso ver um exemplo deste programa em execução?
precisa
@ syb0rg Claro, atualizei a resposta com um exemplo.
Danko Durbić 11/12
Parece bom! +1 para você!
syb0rg 11/12/2013
Agradável. Você pode remover espaços extras e salvar 6 bytes$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←⍞

Poderia ser mais curto se eu pudesse omitir linhas em que o valor é 0.

Explicação:

  • ⎕ML←3: defina o nível de migração como 3 (isso torna (partição) mais útil).
  • I⊂⍨' '≠I←⍞: entrada de leitura, dividida em espaços
  • M←↑∘⍴¨: obtenha o tamanho da primeira dimensão de cada item (tamanho da palavra) e armazene em M
  • K←⍳⌈/M: obtenha os números de 1 ao valor mais alto em M, armazene emK
  • +⌿K∘.=M: para cada valor em M, veja quantas vezes ele está contido K.
  • ⊃⍴∘'▓'¨: para cada valor nesse valor, obtenha uma lista dos muitos se formate-o como uma matriz.
  • K,: acrescente cada valor Ka cada linha da matriz, fornecendo os rótulos.

Resultado:

      ⎕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
fonte
2

Mathematica 97

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

Quando inseri o texto da Declaração de Independência como uma única sequência (através de recortar e colar, é claro), a saída gerada foi:

declaração de independência

DavidC
fonte
2

Quarto, 201

Foi divertido, mas minha submissão ao Ruby é mais competitiva. ;-)

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

Exemplo de execução:

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

O comprimento máximo da palavra é 99.

Darren Stone
fonte
2

Ruby, 79

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

Exemplo de execução:

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

Por favor, veja minha quarta submissão para rir.

Darren Stone
fonte
2

Ruby 1.8.7, 74

Uma abordagem ligeiramente diferente das outras soluções ruby:

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

resultado:

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

 1:#
 2:###
 3:######
 4:#############################
 5:#####################################################
 6:############################################################
 7:########################################################################
 8:######################################################
 9:############################################################
10:########################
11:###########################
12:######
13:#####
AShelly
fonte
Não vi este envio inicialmente, desculpe! +1
syb0rg
1

JavaScript ( 159133 )

Definitivamente não é competitivo, mas até agora a única solução JavaScript. Obrigado a @manatwork pela dica de uso 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++]||""))

Entrada

O Code Golf é um site de perguntas e respostas para a programação de entusiastas de quebra-cabeças e jogadores de código. Ele foi desenvolvido e executado por você como parte da rede de sites de perguntas e respostas do Stack Exchange. Com sua ajuda, estamos trabalhando juntos para criar uma biblioteca de quebra-cabeças de programação e suas soluções.

Resultado

1 |##
2 |#######
3 |#########
4 |########
5 |######
6 |###
7 |####
8 |####
9 |
10|#
11|###
quietmint
fonte
1
Na verdade, esse não é realmente um campo em que o JavaScript se destaque. Mas com replace()em vez de split()+ fore Arrayem vez de Object+ variável comprimento separado pode ser reduzido com alguns caracteres: 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++]||"")). (E ainda mais curto em Harmonia: 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 Bom abuso de .lengthlá.
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

Amostra:

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

Economize 8 caracteres usando um garfo para 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 \  \#

Dê o mesmo resultado:

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 (no meu host :)

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
fonte
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";

Uso:

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 Kepka
fonte
1

8o , 162 bytes

Código

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

Uso

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

Resultado

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

Código não destruído ( SED é diagrama de efeito de pilha)

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
Chaos Manor
fonte