Gráfico de barras de dez linhas


13

Este é o Buraco-1 do Torneio de Outono da APL CodeGolf . Eu sou o autor original do problema lá e, portanto, posso republicá-lo aqui.


Dada uma lista de números, produza um gráfico de barras horizontal de #caracteres para quantos números cabem em cada um dos dez grupos de tamanhos iguais. Por exemplo, se os dados variarem de 0 a 100, os intervalos serão de 0 a 9,9, 10 a 19,9, ..., 90 a 100. (Formalmente, [0,10), [10,20),…, [90,100].). Você pode supor que haverá pelo menos dois números e que nem todos os números serão iguais.

Exemplos:

[1,0,0,0,0,0,0,0,0,0] dá:

#########








#        

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

#
#
#
#
#
#
#
#
#
#

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

#
#
#
#
#
#
#
#
#
##

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

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

[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] dá:

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

[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] dá:

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


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

[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] dá:

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

3
Então, o grupo final é um pouco maior? Como no primeiro exemplo, seria [0.9,1](e não [0.9,1))?
Felix Palmen

@FelixPalmen Kind of. É apenas maior em uma quantidade infinitamente pequena.
Adám 17/10/19

Ok, coisa importante a saber é que ele é de fato o último grupo que deve incluir tanto os endpoints, graças
Felix Palmen

@FelixPalmen Ah, vejo que isso não estava totalmente claro no OP. Vou editá-lo.
Adám

1
@ Adám Deve ser inverso? A linha superior [0,1)contém apenas 0enquanto a linha inferior [9,10]contém ambos 9e 10.
user202729

Respostas:




4

R , 77 81 bytes

+4 bytes para corrigir alguns casos de teste

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

Experimente online!

Link é para uma versão do código que recebe entrada separada por vírgula; esta versão ocupa espaço separado.

Lê de stdin, imprime em stdout.

R é uma linguagem de programação estatística que faz o possível para fornecer resultados de alta qualidade, o que às vezes é frustrante:

histcoloca as entradas em um histograma breakscomo segundo argumento. Normalmente, seria de esperar que você pudesse especificar que o número de quebras fosse 10. De fato, este é o caso:

breaks

um de:

  • um vetor que fornece os pontos de interrupção entre as células do histograma,
  • uma função para calcular o vetor de pontos de interrupção,
  • um único número fornecendo o número de células para o histograma,
  • uma sequência de caracteres nomeando um algoritmo para calcular o número de células (consulte 'Detalhes'),
  • uma função para calcular o número de células.

(enfase adicionada).

A próxima frase, no entanto, diz:

Nos últimos três casos, o número é apenas uma sugestão; como os pontos de interrupção serão definidos como prettyvalores, o número será limitado a 1e6(com um aviso se for maior).

Então, olhei para a documentação prettye ela simplesmente não funciona para a nossa situação, porque escolhe pontos de interrupção da seguinte maneira:

Calcule uma sequência de n+1valores "redondos" igualmente espaçados, que abrangem o intervalo dos valores em x. Os valores são escolhidos para que sejam 1, 2 ou 5 vezes a potência de 10.

O que simplesmente não serve.

Portanto, seq(min(x),max(x),,11)especifica 11 pontos igualmente espaçados como breaks, hist(x,breaks,r=F)$cfornece as contagens, r=Fgarante que os compartimentos tenham intervalos de abertura correta e o forloop cuidará do 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)}

Experimente online!


Eu acho que você pode fazer kcomo um global, (+ 1byte) no entanto, é inicializado como 0, assim, salvar 3 bytes de k=0.
user202729

Além disso, você pode alternar doublepara floate lfpara fsalvar outros 2 bytes. (pelo menos isso funciona no TIO)
user202729 17/17/17

@ user202729 para seu primeiro comentário: não, esta inicialização é necessária dentro do loop externo várias vezes. floatpode funcionar, eu não o usei porque não é o tipo de ponto flutuante "padrão" em C e reduz a precisão, por isso não tenho certeza se isso é permitido ...
Felix Palmen


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<=#&]]])&


Experimente online!


Como deve funcionar? O TIO possui apenas saída de texto. (resposta à parte "Dennis irá corrigi-lo") #
user202729 17/17/17

1
@ user202729 Você realmente acredita que não estou ciente disso? ou ...
J42161217 17/17/17

2
Não para ofender você, mas você menciona Range[0,9]enquanto eu estou falando Range[0,10]sem motivo. Mas ele realmente falha para Range[0,10]: TIO .
user202729

4
Você usou <=nas duas extremidades, o que está correto no último segmento, mas não nos outros 9.
user202729

3
@ user202729 ei !, este aqui me ajudou tanto quanto as informações anteriores, que variam [0, n] = {0, .. n}. +1 para obter ótimos conselhos. de qualquer maneira o código funciona bem agora
J42161217

3

JavaScript (ES6), 99 bytes

Editar 2 bytes salvar thx @JustinMariner

Uma função retornando uma matriz de strings

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 golfe

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
}

Teste

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>


Você poderá salvar alguns bytes movendo a atribuição para ios colchetes da matriz, seguida por vírgula, permitindo remover os parênteses ao redor do corpo da função do mapa: Experimente on-line!
23617 Justin Mariner

@JustinMariner direito, thx
edc65 17/10

Na verdade, você pode salvar mais um byte se se livrar ie usá-lo Math.minnovamente, com um pseudônimo: Experimente on-line!
Justin Mariner


2

Gelatina , 21 bytes

Um link monádico retorna uma lista de cadeias.

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

Experimente online!


Embora o retorno de uma lista de linhas seja permitido, o resultado exibido não é separado de forma alguma. Não sei se isso é válido.
user202729

É permitido, já que é assim que Jelly trata listas de cordas. Você pode adicionar ÇŒṘou ÇYno rodapé para visualizar o resultado. Além disso, em vez do programa completo, você pode dizer que seu envio é um link monádico, que retorna em vez de imprimir, tornando-o automaticamente válido.
Mr. Xcoder

2

Pitão ,  32  31 bytes

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

Experimente aqui! ou Verifique todos os casos de teste. (com impressão bonita usandoj)

Como isso funciona

Este é um programa completo que recebe informações do STDIN. Isto é para a versão de 32 bytes. Vou atualizá-lo em breve.

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

         m T ~ Mapa sobre [0, 10) com var d.
           m Q ~ Mapa sobre a entrada com var k.
            g ~ É maior ou igual a?
             k ~ O elemento atual da entrada, k.
              + hSQ * dc-eSQhSQT ~ Vamos dividir isso em pedaços:
               hSQ ~ O elemento mais baixo da lista de entrada.
              + ~ Plus:
                  * dc-eSQhSQT ~ Vamos dividir isso em mais partes:
                  * ~ Multiplicação.
                   d ~ O elemento atual de [0, 10), d.
                    c ~ Divisão de flutuação por 10 de:
                     -eSQhSQ ~ A diferença entre o máximo e o mínimo
                                        da lista de entrada.
          s ~ Sum. Conte o número de resultados de verdade.
        + Z ~ Anexa um 0.
      . + ~ Obtenha os deltas.
    _M ~ Obtém -delta para cada delta na lista acima.
  \ # ~ O caractere literal "#".
* R ~ Multiplicação vetorizada. Opcionalmente, você pode
                                    use j para ingressar em novas linhas (como o link faz).
                                  ~ Saída implicitamente.

2

Carvão , 31 bytes

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

Experimente online! Link é a versão detalhada do código. A entrada de listas de tamanho variável parece um pouco estranha no Charcoal, então tive que agrupar a lista em uma matriz contendo uma string. Explicação:

   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

Eu escrevi no GNU gfortran 5.4.0 e compilei sem nenhum sinalizador adicional.

Ele lê STDIN, um valor de cada vez, e imprime em STDOUT.

Aqui vai:

programa h; real, alocável :: a (:); caractere f * 9; alocar (a (0)); do; read (*, *, end = 8) r; a = [a, r]; enddo; 9 formato ("(", i0, "(" "#" ")))")
8 a = (a-minval (a)) + epsilon (1.); A = teto (10 * a / maxval (a)); do i = 1,10; j = count (a == i); se (j == 0) imprima *; se (j == 0) ciclo; escreva (f, 9) j;
print f; enddo; end

Explicação ungolfed: (não sei se "golfed" pode ser aplicado ao fortran, mas de qualquer maneira: P)

programa h
real, alocável :: a (:)! Crie uma matriz alocável para que possamos realocar dinamicamente
personagem f * 9! Uma matriz de caracteres para formatar a saída
alocar (a (0))! Aloque "a" vazio no início
Faz
  leia (*, *, final = 8) r! Leia a partir de STDIN. Se EOF, passa para 8, caso contrário
  a = [a, r]! Anexa a "a"
enddo
9 formato ("(", i0, "(" "#" ")))")! Um rótulo de formato
8 a = (a-minval (a)) + epsilon (1.)! (8) Normaliza a (adiciona epsilon para evitar a indexação zero)
a = teto (10 * a / maxval (a))! Normalizando e multiplicando pelo número de posições
eu = 1,10! Looping em todas as caixas
  j = contagem (a == i)! Contando o número de ocorrências
  se (j == 0) imprimir *! Se nenhuma, imprime linha vazia
  se (j == 0) ciclo! E pula o resto do ciclo
  escreva (f, 9) j! Caso contrário, grava a contagem (j) na etiqueta de impressão
  print f! E imprime em STDOUT
enddo
fim

Curiosidade: ontem, eu fiz um código semelhante para testar minha implementação de um gerador de números aleatórios Weibull, por isso só precisava de uma pequena adaptação :)




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

Experimente online .

Ungolfed:

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

Solução:

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

Experimente online! (Observe que o link TIO é uma porta de 44 bytes K (oK) desta solução, pois não há TIO para q / kdb +).

Exemplos:

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

Explicação:

A maior parte do código é usada para criar os buckets nos quais bino input é inserido.

{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

Geléia , 19 bytes

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

Experimente online!

Isso se baseia na minha resposta do APL para o problema original, que postarei depois que a competição terminar.

Quão? (Eu não sou bom em explicar as coisas)

_Ṃµ÷Ṁ×⁵Ḟ«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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.