Gráfico de barras de diez filas


13

Este es el hoyo 1 del Torneo de otoño de APL CodeGolf . Soy el autor original del problema allí y, por lo tanto, me permite volver a publicarlo aquí.


Dada una lista de números, produzca un gráfico de barras horizontales de #caracteres para cuántos números caben en cada uno de los diez grupos de igual tamaño. Por ejemplo, si los rangos de datos van de 0 a 100, los rangos serán 0–9.9, 10–19.9,…, 90–100. (Formalmente, [0,10), [10,20),…, [90,100].). Puede suponer que habrá al menos dos números y que no todos los números serán iguales.

Ejemplos:

[1,0,0,0,0,0,0,0,0,0] da:

#########








#        

[0,1,2,3,4,5,6,7,8,9] da:

#
#
#
#
#
#
#
#
#
#

[0,1,2,3,4,5,6,7,8,9,10] da:

#
#
#
#
#
#
#
#
#
##

[0,1,2,3,4,5,6,7,8,9,10,11] da:

##
#
#
#
#
#
#
#
#
##

[0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,-4.5,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,3,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,-1,4,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,4.5,4,3.5,3,2.5,2,1.5,1,0.5,0] da:

###                
#######            
###########        
###############    
#########          
###################
###############    
###########        
#######            
###                

[9014,9082,9077,9068,8866,8710,9049,8364,8867,9015,9064,9023,9024,8804,8805,8800,8744,8743,8714,9076,8593,8595,9075,9675,8968,8970,8711,8728,8834,8835,8745,8746,8869,8868,9073,9074,9042,9035,9033,9021,8854,9055,9017,9045,9038,9067,9066,8801,8802,9496,9488,9484,9492,9532,9472,9500,9508,9524,9516,9474,8739,9079,8900,8592,8594,9053,9109,9054,9059] da:

#                        
####                     
#########                
############             
######                   
#########################


###########              
#                        

[0,8,10,13,32,12,6,7,27,9,37,39,95,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,1,2,175,46,48,49,50,51,52,53,54,55,56,57,3,165,36,163,162,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,4,5,253,183,127,193,194,195,199,200,202,203,204,205,206,207,208,210,211,212,213,217,218,219,221,254,227,236,240,242,245,123,125,168,192,196,197,198,201,209,214,216,220,223,224,225,226,228,229,230,231,232,233,234,235,237,238,239,241,91,47,92,60,61,62,45,43,247,215,63,126,42,40,124,59,44,33,243,244,246,248,34,35,30,38,180,64,249,250,251,94,252,96,182,58,191,161,41,93,31,160,167] da:

#############             
######################    
##########################
######################### 
######################### 
#                         
########                  
################          
########################  
##########################

3
Entonces, ¿el grupo final es un poquito más grande? Como en el primer ejemplo, ¿sería [0.9,1](y no [0.9,1))?
Felix Palmen

@FelixPalmen Tipo de. Solo es más grande en una cantidad infinitamente pequeña.
Adám

Ok, lo importante es saber que es el último grupo que debería incluir ambos puntos finales, gracias
Felix Palmen

@FelixPalmen Ah, veo que eso no estaba del todo claro en el OP. Lo
editaré

1
@ Adám ¿Debería ser inverso en su lugar? La fila superior [0,1)contiene solo 0mientras que la fila inferior [9,10]contiene ambos 9y 10.
usuario202729

Respuestas:




4

R , 77 81 bytes

+4 bytes para arreglar algunos casos de prueba

for(i in hist(x<-scan(),seq(min(x),max(x),,11),r=F)$c)cat(rep('#',i),'\n',sep='')

Pruébalo en línea!

El enlace es a una versión del código que toma entradas separadas por comas; Esta versión lleva espacio separado.

Lee desde stdin, imprime en stdout.

R es un lenguaje de programación estadística que hace todo lo posible para dar resultados de alta calidad, lo que a veces es frustrante:

histagrupa las entradas en un histograma con breakssu segundo argumento. Normalmente, uno esperaría que pudiera especificar que el número de descansos sea 10. De hecho, este es el caso:

breaks

uno de:

  • un vector que proporciona los puntos de ruptura entre las celdas de histograma,
  • una función para calcular el vector de puntos de interrupción,
  • un solo número que da el número de celdas para el histograma,
  • una cadena de caracteres que nombra un algoritmo para calcular el número de celdas (ver 'Detalles'),
  • Una función para calcular el número de celdas.

(énfasis añadido).

La siguiente oración, sin embargo, dice:

En los últimos tres casos, el número es solo una sugerencia; Como los puntos de interrupción se establecerán en prettyvalores, el número se limita a 1e6(con una advertencia si era mayor).

Así que miré la documentación de prettyy simplemente no funciona para nuestra situación, ya que selecciona puntos de quiebre por lo tanto:

Calcule una secuencia de n+1valores 'redondos' igualmente espaciados que cubran el rango de los valores en x. Los valores se eligen de modo que sean 1, 2 o 5 veces una potencia de 10.

Lo que simplemente no servirá.

Por lo tanto, seq(min(x),max(x),,11)especifica 11 puntos igualmente espaciados como breaks, hist(x,breaks,r=F)$cda los recuentos, r=Fasegura que los contenedores sean intervalos abiertos a la derecha, y el forbucle se encarga del resto.


3

C (gcc) , 241 bytes

#define P(x)for(;x--;putchar('#'));puts("");
double a[999],u,l,x;i,j,n[9];main(k){for(;scanf("%lf",&x)>0;u=u>x?u:x,l=l<x?l:x,a[i++]=x);for(;j<i;++j)for(k=0;k<9;)if(a[j]<l+(++k)*(u-l)/10){n[k-1]++;break;}for(k=0;k<9;++k){i-=n[k];P(n[k])}P(i)}

Pruébalo en línea!


Creo que puede hacer kcomo global, (+ 1byte), sin embargo, se inicializa a 0, por lo tanto, guarde 3 bytes de k=0.
usuario202729

También puede cambiar doublea floaty lfa f, salvar a otro de 2 bytes. (al menos eso funciona en TIO)
user202729

@ user202729 para su primer comentario: no, esta inicialización es necesaria dentro del bucle externo varias veces. floatfuerza de trabajo, que no usamos porque no es el tipo de punto flotante "estándar" en C y reduce la precisión, por lo que no está seguro de esto es permitido ...
Félix palmeras


3

Mathematica, 152 bytes

(Do[Print[""<>Table["#",Length@Select[s=#,Min@s+(t=#2-#&@@MinMax@s/10)(i-1)<=#<Min@s+t*i&]]],{i,9}];Print[""<>Table["#",Length@Select[s,Max@s-t<=#&]]])&


Pruébalo en línea!


¿Cómo debería funcionar? TIO solo tiene salida de texto. (respuesta a la parte "Dennis lo arreglará")
user202729

1
@ user202729 ¿Realmente crees que no soy consciente de esto? o ...
J42161217

2
No para ofenderte, pero lo mencionas Range[0,9]mientras hablo Range[0,10]sin razón. Pero en realidad falla por Range[0,10]: TIO .
user202729

44
Usaste <=en ambos extremos, lo cual es correcto en el último segmento pero no en los otros 9.
user202729

3
@ user202729 ¡hey! este me ayudó tanto como tu información anterior que Range [0, n] = {0, .. n}. +1 para buenos consejos. de todos modos el código funciona bien ahora
J42161217

3

JavaScript (ES6), 99 bytes

Editar 2 bytes guardar thx @JustinMariner

Una función que devuelve una matriz de cadenas

l=>l.map(v=>o[i=(v-n)/(Math.max(...l)-n)*10|0,i>9?9:i]+='#',o=Array(10).fill``,n=Math.min(...l))&&o

Menos golf

list => {
   var max = Math.max(...list),
       min = Math.min(...list),
       output = Array(10).fill(''),
       index;

   list.forEach( value => (
      index = (value - min) / (max - min) * 10 | 0,
      output [index > 9 ? 9 : index] += '#'
   ) )
   return output
}

Prueba

var F=
l=>l.map(v=>o[i=(v-n)/(Math.max(...l)-n)*10|0,i>9?9:i]+='#',o=Array(10).fill``,n=Math.min(...l))&&o

var test=[
[1,0,0,0,0,0,0,0,0,0],
[0,1,2,3,4,5,6,7,8,9],
[0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,-4.5,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,-4,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,-3.5,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,-3,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,-2.5,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,-2,3,2.5,2,1.5,1,0.5,0,-0.5,-1,-1.5,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,-1,4,3.5,3,2.5,2,1.5,1,0.5,0,-0.5,4.5,4,3.5,3,2.5,2,1.5,1,0.5,0],
[0,8,10,13,32,12,6,7,27,9,37,39,95,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,1,2,175,46,48,49,50,51,52,53,54,55,56,57,3,165,36,163,162,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,4,5,253,183,127,193,194,195,199,200,202,203,204,205,206,207,208,210,211,212,213,217,218,219,221,254,227,236,240,242,245,123,125,168,192,196,197,198,201,209,214,216,220,223,224,225,226,228,229,230,231,232,233,234,235,237,238,239,241,91,47,92,60,61,62,45,43,247,215,63,126,42,40,124,59,44,33,243,244,246,248,34,35,30,38,180,64,249,250,251,94,252,96,182,58,191,161,41,93,31,160,167],
[9014,9082,9077,9068,8866,8710,9049,8364,8867,9015,9064,9023,9024,8804,8805,8800,8744,8743,8714,9076,8593,8595,9075,9675,8968,8970,8711,8728,8834,8835,8745,8746,8869,8868,9073,9074,9042,9035,9033,9021,8854,9055,9017,9045,9038,9067,9066,8801,8802,9496,9488,9484,9492,9532,9472,9500,9508,9524,9516,9474,8739,9079,8900,8592,8594,9053,9109,9054,9059]];

output=x=>O.textContent+=x+'\n\n'

test.forEach(t=>output(t+'\n'+F(t).join`\n`))
<pre id=O></pre>


Debería poder guardar un par de bytes moviendo la asignación ia los corchetes seguidos de una coma, lo que le permite eliminar los paréntesis alrededor del cuerpo de la función de mapa: ¡ Pruébelo en línea!
Justin Mariner

@JustinMariner a la derecha, gracias
edc65

En realidad, puede guardar un byte más si se deshace de él iy lo usa Math.minnuevamente, con un alias: ¡ Pruébelo en línea!
Justin Mariner


2

Jalea , 21 bytes

Un enlace monádico devuelve una lista de cadenas.

_Ṃµ÷Ṁ×⁵Ḟµ<⁵+ċЀ⁵R¤”#ẋ

Pruébalo en línea!


Aunque se permite devolver una lista de líneas, el resultado mostrado no está separado de ninguna manera. No sé si eso es válido.
user202729

Está permitido, ya que así es como Jelly trata las listas de cuerdas. Puede agregar ÇŒṘo ÇYen su pie de página para visualizar el resultado. Además, en lugar del programa completo, puede decir que su envío es un enlace monádico, que devuelve en lugar de imprimir, lo que lo hace automáticamente válido.
Sr. Xcoder

2

Pyth ,  32  31 bytes

*R\#_M.++msmgk+JhSQ*dc-eSQJTQTZ

Pruébalo aquí! o Verificar todos los casos de prueba. (con impresión bonita usandoj)

Como funciona esto

Este es un programa completo que recibe información de STDIN. Esto es para la versión de 32 bytes. Lo actualizaré pronto.

* R \ #_M. ++ msmgk + hSQ * dc-eSQhSQTQTZ ~ Programa completo.

         m T ~ Mapa sobre [0, 10) con var d.
           m Q ~ Mapa sobre la entrada con var k.
            g ~ ¿Es mayor o igual que?
             k ~ El elemento actual de la entrada, k.
              + hSQ * dc-eSQhSQT ~ Vamos a dividir esto en pedazos:
               hSQ ~ El elemento más bajo de la lista de entrada.
              + ~ Plus:
                  * dc-eSQhSQT ~ Vamos a dividir esto en más partes:
                  * ~ Multiplicación.
                   d ~ El elemento actual de [0, 10), d.
                    c T ~ División de flotación por 10 de:
                     -eSQhSQ ~ La diferencia entre el máximo y el mínimo
                                        de la lista de entrada.
          s ~ Suma. Cuente la cantidad de resultados verdaderos.
        + Z ~ Agregar un 0.
      . + ~ Obtener los deltas.
    _M ~ Obtiene -delta para cada delta en la lista anterior.
  \ # ~ El carácter literal "#".
* R ~ Multiplicación vectorizada. Opcionalmente puedes
                                    use j para unirse mediante nuevas líneas (como lo hace el enlace).
                                  ~ Salida implícita.

2

Carbón , 31 bytes

≔I⪪S,θEχ×#ΣEθ⁼ι⌊⟦⁹⌊×χ∕⁻λ⌊θ⁻⌈θ⌊θ

Pruébalo en línea! El enlace es a la versión detallada del código. La entrada de listas de longitud variable parece un poco incómoda en Charcoal, por lo que tuve que ajustar la lista en una matriz que contiene una cadena. Explicación:

   S                            Input string
  ⪪ ,                           Split on commas
 I                              Cast elements to integer
≔    θ                          Assign to variable q
      Eχ                        Map from 0 to 9
           Eθ                   Map over the list
                      ⁻λ⌊θ      Subtract the minimum from the current
                          ⁻⌈θ⌊θ Subtract the minimum from the maximum
                     ∕          Divide
                   ×χ           Multiply by 10
                  ⌊             Floor
               ⌊⟦⁹              Take minimum with 9
             ⁼ι                 Compare to outer map variable
          Σ                     Take the sum
        ×#                      Repeat # that many times
                                Implicitly print on separate lines

2

Fortran 2003, 263 bytes

Lo escribí en GNU gfortran 5.4.0 y lo compilé sin ningún indicador adicional.

Lee de STDIN, un valor a la vez, e imprime en STDOUT.

Aquí va:

programa h; real, asignable :: a (:); carácter f * 9; asignar (a (0)); hacer; leer (*, *, end = 8) r; a = [a, r]; enddo; 9 formato ("(", i0, "(" "#" "))")
8 a = (a-minval (a)) + epsilon (1.); A = techo (10 * a / maxval (a)); do i = 1,10; j = cuenta (a == i); si (j == 0) print *; if (j == 0) cycle; write (f, 9) j;
imprimir f; enddo; fin

Explicación sin golf: (no sé si "golf" se puede aplicar a fortran pero de cualquier manera: P)

programa h
real, asignable :: a (:)! Cree una matriz asignable para que podamos reasignar dinámicamente
personaje f * 9! Una matriz de caracteres para formatear la salida
asignar (a (0))! Asignar "a" vacío al principio
hacer
  leer (*, *, end = 8) r! Leer de STDIN. Si EOF, pasa a 8, de lo contrario
  a = [a, r]! Anexa a "a"
enddo
9 formato ("(", i0, "(" "#" "))")! Una etiqueta de formato
8 a = (a-minval (a)) + épsilon (1.)! (8) Normaliza a (agrega épsilon para evitar la indexación cero)
a = techo (10 * a / maxval (a))! Normalizando y multiplicando por el número de contenedores
¿i = 1,10! Bucle en todos los contenedores
  j = cuenta (a == i)! Contando el número de ocurrencias
  if (j == 0) print *! Si ninguno, imprime la línea vacía
  if (j == 0) ciclo! Y se salta el resto del bucle
  escribe (f, 9) j! De lo contrario, escribe el recuento (j) en la etiqueta de impresión
  imprimir f! E imprime en STDOUT
enddo
final

Dato curioso: ayer hice un código similar para probar mi implementación de un generador de números aleatorios Weibull, por lo que solo necesité una pequeña adaptación :)




1

Perl 5, 102 bytes

$l=(@n=sort{$a<=>$b}<>)[-1]-($f=$n[0]);$m=$f+$l*$_/10,say'#'x(@n-(@n=grep$_>=$m,@n))for 1..9;say'#'x@n

Pruébalo en línea .

Sin golf:

my @n = sort { $a <=> $b } <>;
my $f = $n[0];
my $l = $n[-1] - $n[0];
for (1 .. 9) {
    my $m = $f + $l * ($_ / 10);
    my $c = scalar @n;
    @n = grep { $_ >= $m } @n;
    say('#' x ($c - scalar @n));
}
say('#' x scalar @n);


1

q / kdb +, 52 bytes

Solución:

{sum[t=/:bin[m+.1*(t:(!)10)*max[x]-m:min x;x]]#'"#"}

Pruébalo en línea! (Tenga en cuenta que el enlace TIO es un puerto K (oK) de 44 bytes de esta solución ya que no hay TIO para q / kdb +).

Ejemplos:

q){sum[t=/:bin[m+.1*(t:(!)10)*max[x]-m:min x;x]]#'"#"}1 0 0 0 0 0 0 0 0 0f
"#########"
""
""
""
""
""
""
""
""
,"#

q){sum[t=/:bin[m+.1*(t:(!)10)*max[x]-m:min x;x]]#'"#"}9014 9082 9077 9068 8866 8710 9049 8364 8867 9015 9064 9023 9024 8804 8805 8800 8744 8743 8714 9076 8593 8595 9075 9675 8968 8970 8711 8728 8834 8835 8745 8746 8869 8868 9073 9074 9042 9035 9033 9021 8854 9055 9017 9045 9038 9067 9066 8801 8802 9496 9488 9484 9492 9532 9472 9500 9508 9524 9516 9474 8739 9079 8900 8592 8594 9053 9109 9054 9059f
,"#"
"####"
"#########"
"############"
"######"
"#########################"
""
""
"###########"
,"#"

Explicación:

La mayor parte del código se usa creando los cubos en los que se bininserta la entrada.

{sum[t=/:bin[m+.1*(t:til 10)*max[x]-m:min x;x]]#'"#"} / ungolfed solution
{                                                   } / lambda function with implicit x as parameter
                                               #'"#"  / take (#) each-both "#", 1 2 3#'"#" => "#","##","###"
 sum[                                         ]       / sum up everything inside the brackets
         bin[                              ;x]        / binary search each x in list (first parameter)
                                    m:min x           / store minimum of list x in variable m
                             max[x]-                  / subtract from the maximum of list x
                  (t:til 10)*                         / range 0..9 vectorised multiplication against max delta of list
               .1*                                    / multiply by 0.1 (aka divide by 10)
             m+                                       / minimum of list vectorised addition against list
     t=/:                                             / match each-right against range 0..9 (buckets)

0

Jalea , 19 bytes

_Ṃµ÷Ṁ×⁵Ḟ«9ċЀ⁵Ḷ¤”#ẋ

Pruébalo en línea!

Esto se basa en mi respuesta APL para el problema original, que publicaré después de que termine la competencia.

¿Cómo? (No soy bueno explicando cosas)

_Ṃµ÷Ṁ×⁵Ḟ«9ċЀ⁵Ḷ¤”#ẋ
_Ṃ                  = subtract the minimum
  µ                 = Sort of like a reverse-order compose
   ÷Ṁ               = divide by the max
     ×⁵             = Multiply by 10
       Ḟ            = Take the floor
        «9          = x => min(x,9)
          ċЀ⁵Ḷ¤    = count occurrences of [0,...,9]
                ”#ẋ = create the list
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.