Generación de histograma.


12

Escriba el programa más corto que genere un histograma (una representación gráfica de la distribución de datos).

Reglas:

  • Debe generar un histograma basado en la longitud del carácter de las palabras (puntuación incluida) ingresadas en el programa. (Si una palabra tiene 4 letras, la barra que representa el número 4 aumenta en 1)
  • Debe mostrar etiquetas de barra que se correlacionen con la longitud de caracteres que representan las barras.
  • Todos los personajes deben ser aceptados.
  • Si las barras deben ser escaladas, debe haber alguna forma que se muestre en el histograma.

Ejemplos:

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

44
Escriba una especificación en lugar de dar un solo ejemplo que, únicamente en virtud de ser un solo ejemplo, no puede expresar el rango de estilos de salida aceptables, y que no garantiza cubrir todos los casos de esquina. Es bueno tener algunos casos de prueba, pero es aún más importante tener una buena especificación.
Peter Taylor

@PeterTaylor Más ejemplos dados.
syb0rg

1
1. Esto está etiquetado como salida gráfica , lo que significa que se trata de dibujar en la pantalla o crear un archivo de imagen, pero sus ejemplos son ascii-art . ¿Es aceptable? (Si no, entonces plannabus podría no ser feliz). 2. Define la puntuación como la formación de caracteres contables en una palabra, pero no indica qué caracteres separan las palabras, qué caracteres pueden y no pueden aparecer en la entrada, y cómo manejar los caracteres que pueden ocurrir pero que no son alfabéticos, la puntuación o separadores de palabras. 3. ¿Es aceptable, requerido o prohibido reescalar las barras para que quepan en un tamaño razonable?
Peter Taylor

@PeterTaylor No lo etiqueté como ascii-art, porque realmente no es "arte". La solución de Phannabus está bien.
syb0rg

@PeterTaylor He agregado algunas reglas basadas en lo que describiste. Hasta ahora, todas las soluciones aquí se adhieren a todas las reglas todavía.
syb0rg

Respuestas:


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 ejemplo mas largo

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

¿Qué sucede si hay palabras con más de 9 letras?

Funciona para palabras de cualquier longitud
tmartin 12/12/2013

5

R, 55 47 caracteres

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

Afortunadamente, R viene con una función de trazado histpara histogramas, aquí provista con un breaksargumento donde los saltos son 0.5, 1.5, ... hasta max (input) +0.5. sapply(scan(,""),nchar)toma una entrada (como stdin), la separa siguiendo los espacios y cuenta el número de caracteres de cada elemento.

Ejemplos:

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

ingrese la descripción de la imagen aquí

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

ingrese la descripción de la imagen aquí

Editar:

Una variación de 71 caracteres con una etiqueta de eje en cada valor posible:

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

ingrese la descripción de la imagen aquí


3
¡Me encanta cuando un lenguaje normalmente detallado toma la delantera!

Sin embargo, esto no cumple con la especificación ...
Pomo de la puerta

@Doorknob, ¿con qué especificación no cumple?
plannapus

El ejemplo de casos de prueba.
Pomo de la puerta

3
Son ejemplos, no especificaciones ...
plannapus

5

Python - 83 caracteres

Parece que podemos tomar información desde cualquier lugar, por lo que esto toma información durante la ejecución, en lugar de desde la línea de comando, y utiliza la sugerencia de Ejrb para acortarla en 8.

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

Python - 91 caracteres

Esto caerá con comillas.

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.

Salida:

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

2
bueno, puedes recortar 4 caracteres al reelaborar tu segunda línea (sin cambio de algoritmo) para usar execy concatenación de cadenas: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

Esto toma la entrada de stdin, no la línea 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|#

¡Me parece bien! +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))

Salida:
(la primera línea es la cadena 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 | ##

No justifica los números como la solución Python de Lego Stormtroopr (que también es más corta que la mía), pero es mi primera entrada en un concurso de golf, por lo que podría dejarlo aquí, supongo :)


¿Podría editar en un ejemplo de un histograma generado por este programa?
syb0rg

Sí, pero acabo de notar que tiene un problema: no justifica los números como la solución de Lego Stormtroopr, por lo que en realidad estoy pensando en retirar la respuesta.
Roberto

Mientras haya etiquetas para las barras representadas, la respuesta es aceptable.
syb0rg

Ok, hecho entonces! :)
Roberto

Esto toma entrada de entrada, no de argumentos. ¿Es esto válido @ syb0rg?

3

Perl, 56

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

Se agregó la reescritura de @ manatwork y la sugerencia literal de nueva línea, ¡muchas gracias! Se agregaron las actualizaciones de @ chinese_perl_goth.

Uso: guardar como hist.pl y ejecutar perl hist.pl This is a test

Salida de ejemplo:

$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
¿Por qué no usar printf? Podría ahorrar algunos caracteres en el formateo. Y un poco más por el cambio de hash para matriz: $d[y///c]++for@ARGV;shift@d;printf"%2d|%s\n",++$i,"#"x$_ for@d.
manatwork

¿Puedo ver un ejemplo de este programa en el trabajo?
syb0rg

@manatwork printfno se me ocurrió en absoluto y por alguna razón no pensé que podría obtener el efecto que quería con una variedad, ¡increíble! @ syb0rg agregando ahora
Dom Hastings

2
golfé un poco más, lo bajé a 57 bytes:$d[y///c].='#'for@ARGV;printf"%2d|$d[$_]\n",$_ for+1..$#d
perl goth chino

1
Nos perdimos el truco más simple: usar una nueva línea literal en lugar de \nahorrar 1 personaje más. Quiero decir así: 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│##     │
└─┴───────┘

Tácito, 38 [:((](;#&'#')"0[:+/=/)1+[:i.>./)#@>@;:: ¡ Pruébelo en línea!
Jonás

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}

No jugaba mucho al golf. Jugará más golf más 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|#

Funciona bien (++ voteCount). ¿Algo que pueda hacer para formular mejor la pregunta?
syb0rg

1
@ syb0rg IMO la pregunta está bien redactada, los ejemplos hablan por sí mismos. Aunque su última vez parece tener un error ... Cuento 2 palabras de 8 letras (generar y generar) y 2 palabras de 9 letras (histograma, histograma)
Pomo de la puerta

Frio. Podrías cambiar b ?(?#*b[1].size):''con b&&?#*b[1].size.
manatwork

2

Powershell, 97 93

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

Ejemplo:

PS Z:\> .\hist.ps1 This is an example of this program running
1  |
2  |###
3  |
4  |##
5  |
6  |
7  |###

¿Puedo ver un ejemplo de este programa en ejecución?
syb0rg

@ syb0rg Claro, he actualizado la respuesta con un ejemplo.
Danko Durbić

¡Se ve bien! +1 para ti!
syb0rg

Agradable. Puede eliminar espacios adicionales y ahorrar 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←⍞

Podría ser más corto si pudiera omitir líneas donde el valor es 0.

Explicación:

  • ⎕ML←3: establece el nivel de migración en 3 (esto hace que (partición) sea más útil).
  • I⊂⍨' '≠I←⍞: entrada de lectura, dividida en espacios
  • M←↑∘⍴¨: obtenga el tamaño de la primera dimensión de cada elemento (longitud de palabras) y almacene en M
  • K←⍳⌈/M: obtenga los números del 1 al valor más alto en M, almacene enK
  • +⌿K∘.=M: para cada valor en M, vea cuántas veces está contenido en K.
  • ⊃⍴∘'▓'¨: para cada valor en eso, obtenga una lista de tantos s, y formatee como una matriz.
  • K,: antepone cada valor Ka cada fila de la matriz, dando las etiquetas.

Salida:

      ⎕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]

Cuando ingresé el texto de la Declaración de Independencia como una sola cadena (a través de cortar y pegar, por supuesto), el resultado generado fue:

declaración de la independencia


2

Adelante, 201

Esto fue divertido, pero mi presentación de Ruby es más 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

Ejecución de muestra:

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

La longitud máxima de palabra es 99.


2

Rubí, 79

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

Ejemplo de ejecución:

$ 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, mira mi presentación de Forth para reírse.


2

Rubí 1.8.7, 74

Una toma ligeramente diferente a las otras soluciones de rubí:

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

salida:

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

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

No vi esta presentación inicialmente, lo siento. +1
syb0rg

1

JavaScript ( 159133 )

Definitivamente no es competitivo, pero hasta ahora es la única solución de JavaScript. Gracias a @manatwork por el consejo sobre el 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

Code Golf es un sitio de preguntas y respuestas para programar entusiastas de los rompecabezas y golfistas de código. Está construido y administrado por usted como parte de la red Stack Exchange de sitios de preguntas y respuestas. Con su ayuda, estamos trabajando juntos para construir una biblioteca de rompecabezas de programación y sus soluciones.

Salida

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

1
De hecho, este no es realmente un campo en el que JavaScript sobresalga. Pero con el replace()lugar de split()+ fory Arrayen lugar de Object+ longitud variable independiente puede ser reducido con unos pocos 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++]||"")). (Y aún más corto en 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

@manatwork Buen abuso de .lengthallí.
quietmint

1

Puro 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

Muestra:

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

Ahorre 8 caracteres utilizando un tenedor 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 \  \#

Dar el mismo 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 (en mi 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|#

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

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

Salida

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

Código no protegido ( SED es el diagrama de efecto de pila)

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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.