Génération d'histogramme

12

Écrivez le programme le plus court qui génère un histogramme (une représentation graphique de la distribution des données).

Règles:

  • Doit générer un histogramme basé sur la longueur des caractères des mots (ponctuation incluse) entrés dans le programme. (Si un mot fait 4 lettres, la barre représentant le chiffre 4 augmente de 1)
  • Doit afficher des étiquettes de barres en corrélation avec la longueur des caractères que les barres représentent.
  • Tous les caractères doivent être acceptés.
  • Si les barres doivent être mises à l'échelle, il doit y avoir un moyen qui est affiché dans l'histogramme.

Exemples:

$ ./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
la source
4
Veuillez écrire une spécification plutôt que de donner un seul exemple qui, uniquement en raison d'être un seul exemple, ne peut pas exprimer la gamme de styles de sortie acceptables, et qui ne garantit pas de couvrir tous les cas d'angle. C'est bien d'avoir quelques cas de test, mais c'est encore plus important d'avoir une bonne spécification.
Peter Taylor
@PeterTaylor Plus d'exemples donnés.
syb0rg
1
1. Il s'agit d' une sortie graphique balisée , ce qui signifie qu'il s'agit de dessiner à l'écran ou de créer un fichier image, mais vos exemples sont ascii-art . Est-ce acceptable? (Sinon, alors le plannabus pourrait ne pas être heureux). 2. Vous définissez la ponctuation comme formant des caractères dénombrables dans un mot, mais vous n'indiquez pas quels caractères séparent les mots, quels caractères peuvent ou non apparaître dans l'entrée, et comment gérer les caractères qui peuvent apparaître mais qui ne sont pas alphabétiques, la ponctuation ou séparateurs de mots. 3. Est-il acceptable, requis ou interdit de redimensionner les barres pour qu'elles tiennent dans une taille raisonnable?
Peter Taylor
@PeterTaylor Je ne l'ai pas marqué ascii-art, car ce n'est vraiment pas "art". La solution de Phannabus est très bien.
syb0rg
@PeterTaylor J'ai ajouté quelques règles basées sur ce que vous avez décrit. Jusqu'à présent, toutes les solutions ici respectent toujours toutes les règles.
syb0rg

Réponses:

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

.

Un exemple plus long

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
la source
Que se passe-t-il s'il y a des mots de plus de 9 lettres?
Cela fonctionne pour les mots de toute longueur
tmartin
5

R, 55 47 caractères

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

Heureusement, R est livré avec une fonction de tracé histpour les histogrammes, ici fournie avec un breaksargument où les ruptures sont de 0,5, 1,5, ... jusqu'à max (entrée) +0,5. sapply(scan(,""),nchar)prend une entrée (comme stdin), la sépare en suivant les espaces et compte le nombre de caractères de chaque élément.

Exemples:

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

entrez la description de l'image ici

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

entrez la description de l'image ici

Éditer:

Une variation à 71 caractères avec une étiquette d'axe à chaque valeur possible:

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

entrez la description de l'image ici

plannapus
la source
3
J'adore quand une langue normalement verbeuse prend les devants!
Ce n'est pas conforme aux spécifications, cependant ...
Poignée de porte
@Doorknob à quelle spécification n'est-elle pas conforme?
plannapus
Les exemples de tests.
Poignée de porte
3
Ce sont des exemples, pas des spécifications ...
plannapus
5

Python - 83 caractères

Semble que nous pouvons prendre des entrées de n'importe où, donc cela prend des entrées lors de l'exécution, plutôt que de la ligne de commande, et utilise la suggestion d'Ejrb pour la raccourcir de 8.

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

Python - 91 caractères

Cela tombera avec des citations.

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

Contribution:

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

Production:

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

la source
2
agréable, vous pouvez raser 4 caractères en retravaillant votre deuxième ligne (pas de changement d'algorithme) à utiliser execet la concaténation de chaînes:c=0;exec'c+=1;print"%3d|"%c+"#"*s.count(c);'*max(s)
ejrb
4

Haskell - 126 caractères

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

Cela prend l'entrée de stdin, pas la ligne de commande:

& 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
la source
Cela me semble correct! +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))

Sortie:
(la première ligne est la chaîne d'entrée)

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

Cela ne justifie pas les chiffres en tant que solution Python de Lego Stormtroopr (qui est également plus courte que la mienne), mais c'est ma première entrée dans un concours de golf, alors je pourrais aussi bien laisser ici, je suppose :)

Roberto
la source
Pourriez-vous modifier un exemple d'histogramme généré par ce programme?
syb0rg
Oui, mais je viens de remarquer qu'il a un problème: il ne justifie pas les chiffres comme solution de Lego Stormtroopr, donc je pense en fait à retirer la réponse.
Roberto
Tant qu'il y a des étiquettes pour les barres représentées, la réponse est acceptable.
syb0rg
Ok, c'est fait alors! :)
Roberto
Cela prend l'entrée de l'entrée, pas des arguments. Est-ce valide @ syb0rg?
3

Perl, 56

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

Ajout de la réécriture de @ manatwork et de la suggestion de nouvelle ligne littérale, merci beaucoup! Ajout des mises à jour de @ chinese_perl_goth.

Utilisation: enregistrer sous hist.pl et exécuter perl hist.pl This is a test

Exemple de sortie:

$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
la source
1
Pourquoi ne pas utiliser printf? Vous pouvez épargner certains caractères lors du formatage. Et un peu plus en changeant de hachage tableau: $d[y///c]++for@ARGV;shift@d;printf"%2d|%s\n",++$i,"#"x$_ for@d.
manatwork
Puis-je voir un exemple de ce programme au travail?
syb0rg
@manatwork printfne m'est pas venu du tout à l' esprit et pour une raison quelconque, je ne pensais pas pouvoir obtenir l'effet que je voulais avec un tableau, incroyable! @ syb0rg ajoutant maintenant
Dom Hastings
2
golfé un peu plus, il est descendu à 57 octets:$d[y///c].='#'for@ARGV;printf"%2d|$d[$_]\n",$_ for+1..$#d
chinois perl goth
1
Nous avons raté juste l'astuce la plus simple: utilisez une nouvelle ligne littérale au lieu de \nménager 1 caractère supplémentaire. Je veux dire comme ça: pastebin.com/496z2a0n
manatwork
3

J, 48 47 46 45 43 caractères

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

Usage:

   (;#&'#')/"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
la source
Tacite, 38 ans [:((](;#&'#')"0[:+/=/)1+[:i.>./)#@>@;:: essayez-le en ligne!
Jonah
2

Rubis, 98 85

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

Pas beaucoup joué au golf. Jouera au golf plus tard.

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|#
Poignée de porte
la source
Fonctionne bien (++ voteCount). Quelque chose que je pourrais faire pour mieux formuler la question?
syb0rg
1
@ syb0rg OMI, la question est bien formulée, les exemples parlent d'eux-mêmes. Bien que votre dernière fois semble avoir une erreur ... Je compte 2 mots de 8 lettres (générer et générer) et 2 mots de 9 lettres (histogramme, histogramme)
Poignée de porte
Cool. Vous pourriez changer b ?(?#*b[1].size):''avec b&&?#*b[1].size.
manatwork
2

Powershell, 97 93

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

Exemple:

PS Z:\> .\hist.ps1 This is an example of this program running
1  |
2  |###
3  |
4  |##
5  |
6  |
7  |###
Danko Durbić
la source
Puis-je voir un exemple de ce programme en cours d'exécution?
syb0rg
@ syb0rg Bien sûr, j'ai mis à jour la réponse avec un exemple.
Danko Durbić
Cela semble bon! +1 à vous!
syb0rg
Agréable. Vous pouvez supprimer des espaces supplémentaires et économiser 6 octets$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←⍞

Pourrait être plus court si je pouvais omettre des lignes où la valeur est 0.

Explication:

  • ⎕ML←3: définissez le niveau de migration sur 3 (ce qui rend (partition) plus utile).
  • I⊂⍨' '≠I←⍞: lire l'entrée, diviser les espaces
  • M←↑∘⍴¨: obtenez la taille de la première dimension de chaque élément (longueur des mots) et stockez-la dans M
  • K←⍳⌈/M: obtenir les nombres de 1 à la valeur la plus élevée dans M, stocker dansK
  • +⌿K∘.=M: pour chaque valeur dans M, voyez combien de fois elle est contenue dans K.
  • ⊃⍴∘'▓'¨: pour chaque valeur, obtenez une liste de ce nombre et formatez-la comme une matrice.
  • K,: ajoutez chaque valeur Kà chaque ligne de la matrice, en donnant les étiquettes.

Production:

      ⎕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
la source
2

Mathematica 97

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

Lorsque j'entre le texte de la déclaration d'indépendance sous la forme d'une seule chaîne (par couper-coller, bien sûr), la sortie générée est la suivante:

déclaration d'indépendance

DavidC
la source
2

Forth, 201

C'était amusant mais ma soumission Ruby est plus compétitive. ;-)

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

Exemple d'exécution:

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

La longueur maximale des mots est de 99.

Darren Stone
la source
2

Rubis, 79

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

Exemple d'exécution:

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

Veuillez voir ma soumission pour rire.

Darren Stone
la source
2

Rubis 1.8.7, 74

Une prise légèrement différente des autres solutions rubis:

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

production:

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

 1:#
 2:###
 3:######
 4:#############################
 5:#####################################################
 6:############################################################
 7:########################################################################
 8:######################################################
 9:############################################################
10:########################
11:###########################
12:######
13:#####
AShelly
la source
Je n'ai pas vu cette soumission au départ, désolé! +1
syb0rg
1

JavaScript ( 159133 )

Certainement pas compétitif, mais jusqu'à présent la seule solution JavaScript. Merci à @manatwork pour l'astuce sur l'utilisation 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++]||""))

Contribution

Code Golf est un site de questions et réponses pour les amateurs de puzzle de programmation et les golfeurs de code. Il est conçu et géré par vous dans le cadre du réseau Stack Exchange de sites de questions et réponses. Avec votre aide, nous travaillons ensemble pour créer une bibliothèque d'énigmes de programmation et leurs solutions.

Production

1 |##
2 |#######
3 |#########
4 |########
5 |######
6 |###
7 |####
8 |####
9 |
10|#
11|###
menthe douce
la source
1
En effet, ce n'est pas vraiment un domaine où JavaScript excelle. Mais avec au replace()lieu de split()+ foret au Arraylieu de Object+ longueur variable séparée peut être réduite avec quelques caractères: 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++]||"")). (Et encore plus court dans 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 abuse of .lengththere.
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

Échantillon:

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

Enregistrez 8 caractères en utilisant une seule fourche pour 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 \  \#

Donne le même résultat:

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 )

rendre (sur mon hôte :)

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
la source
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";

Usage:

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
la source
1

8ème , 162 octets

Code

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

Usage

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

Production

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

Code non golfé ( SED est un diagramme d'effet de pile)

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
Manoir du Chaos
la source