Grafico a barre a dieci righe


13

Questo è Hole-1 di The Autumn Tournament di APL CodeGolf . Sono l'autore originale del problema e quindi ho permesso di ripubblicarlo qui.


Dato un elenco di numeri, produce un grafico a barre orizzontale di #caratteri per quanti numeri si adattano a ciascuno dei dieci gruppi di dimensioni uguali. Ad esempio, se i dati vanno da 0 a 100, gli intervalli saranno 0-9,9, 10-19,9,…, 90–100. (Formalmente, [0,10), [10,20),…, [90.100].). Puoi presumere che ci saranno almeno due numeri e che non tutti i numeri saranno uguali.

Esempi:

[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
Quindi, il gruppo finale è un po 'più grande? Come nel primo esempio, sarebbe [0.9,1](e non [0.9,1))?
Felix Palmen,

@FelixPalmen Kind of. È solo più grande di una quantità infinitamente piccola.
Adám,

Ok, la cosa importante da sapere è che è davvero l' ultimo gruppo che dovrebbe includere entrambi gli endpoint, grazie
Felix Palmen,

@FelixPalmen Ah, vedo che non era del tutto chiaro nel PO. Lo modificherò.
Adám,

1
@ Adám Dovrebbe invece essere al contrario? La riga superiore [0,1)contiene solo 0mentre la riga inferiore [9,10]contiene sia 9e 10.
user202729

Risposte:




4

R , 77 81 byte

+4 byte per correggere alcuni casi di test

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

Provalo online!

Il collegamento è a una versione del codice che accetta input separati da virgola; questa versione richiede spazio separato.

Legge da stdin, stampa su stdout.

R è un linguaggio di programmazione statistica che fa del suo meglio per fornire risultati di alta qualità, che a volte è frustrante:

histbin gli input in un istogramma breakscome secondo argomento. Normalmente, ci si aspetterebbe che si possa specificare che il numero di interruzioni sia 10. In effetti, questo è il caso:

breaks

uno di:

  • un vettore che fornisce i punti di interruzione tra le celle dell'istogramma,
  • una funzione per calcolare il vettore di punti di interruzione,
  • un singolo numero che indica il numero di celle per l'istogramma,
  • una stringa di caratteri che nomina un algoritmo per calcolare il numero di celle (vedere "Dettagli"),
  • una funzione per calcolare il numero di celle.

(enfasi aggiunta).

La frase successiva, tuttavia, dice:

Negli ultimi tre casi il numero è solo un suggerimento; poiché i punti di interruzione verranno impostati su prettyvalori, il numero è limitato a 1e6(con un avviso se era maggiore).

Quindi ho guardato la documentazione di prettye semplicemente non funziona per la nostra situazione, perché seleziona così i punti di interruzione:

Calcola una sequenza di circa n+1valori 'arrotondati' ugualmente spaziati che coprono l'intervallo dei valori in x. I valori sono scelti in modo che siano 1, 2 o 5 volte una potenza di 10.

Che semplicemente non lo farà.

Quindi seq(min(x),max(x),,11)specifica 11 punti equidistanti come breaks, hist(x,breaks,r=F)$cindica i conteggi, r=Fgarantisce che i bin siano intervalli ad apertura a destra e il forloop si occupi del resto.


3

C (gcc) , 241 byte

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

Provalo online!


Penso che tu possa fare k come globale, (+ 1byte) tuttavia è inizializzato su 0, quindi risparmia 3 byte da k=0.
user202729,

Inoltre è possibile passare doublea floate lfa f, salvare altri 2 byte. (almeno funziona su TIO)
user202729

@utente202729 per il tuo primo commento: no, questa inizializzazione è necessaria più volte all'interno del circuito esterno. floatpotrebbe funzionare, non l'ho usato perché non è il tipo "standard" in virgola mobile in C e riduce la precisione, quindi non sono sicuro che questo sia permesso ...
Felix Palmen,


3

Mathematica, 152 byte

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


Provalo online!


Come dovrebbe funzionare? TIO ha solo output di testo. (rispondi alla parte "Dennis lo risolverà")
user202729,

1
@ user202729 Credi davvero che non ne sia a conoscenza? oppure ...
J42161217,

2
Per non offenderti, ma menzionate Range[0,9]mentre sto parlando Range[0,10]senza motivo. Ma in realtà non riesce per Range[0,10]: TIO .
user202729,

4
Hai usato <=su entrambe le estremità, il che è corretto sull'ultimo segmento ma non sugli altri 9.
user202729,

3
@ user202729 hey! questo mi ha aiutato tanto quanto le tue informazioni precedenti che Range [0, n] = {0, .. n}. +1 per un ottimo consiglio. comunque il codice funziona bene ora
J42161217

3

JavaScript (ES6), 99 byte

Modifica 2 byte salva thx @JustinMariner

Una funzione che restituisce una matrice di stringhe

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

Meno 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
}

Test

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>


Dovresti essere in grado di salvare un paio di byte spostando l'assegnazione itra parentesi quadre seguita da una virgola, permettendoti di rimuovere le parentesi attorno al corpo della funzione della mappa: provalo online!
Justin Mariner,

@JustinMariner a destra, grazie
edc65

Puoi effettivamente salvare un altro byte se ti sbarazzi di ie Math.minriutilizzi, con un alias: provalo online!
Justin Mariner,

2

Python 2 , 126 121 byte

def f(a):
 m=min(a);r=range(10);A=[sum(x>=m+i*(max(a)-m)/10.for x in a)for i in r]+[0]
 for i in r:print'#'*(A[i]-A[i+1])

Provalo online!


2

Gelatina , 21 byte

Un collegamento monadico restituisce un elenco di stringhe.

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

Provalo online!


Sebbene sia consentito restituire un elenco di righe, il risultato visualizzato non è separato in alcun modo. Non so se sia valido.
user202729,

È permesso, poiché è così che Jelly tratta gli elenchi di stringhe. È possibile aggiungere ÇŒṘo ÇYnel piè di pagina per visualizzare il risultato. Inoltre, invece del programma completo, puoi dire che il tuo invio è un collegamento monadico, che restituisce anziché stampare, rendendolo automaticamente valido.
Mr. Xcoder,

2

Pyth ,  32  31 byte

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

Provalo qui! oppure Verifica tutti i casi di test. (con pretty-print utilizzandoj)

Come funziona

Questo è un programma completo che accetta input da STDIN. Questo è per la versione a 32 byte. Lo aggiornerò presto.

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

         m T ~ Mappa su [0, 10) con var d.
           m Q ~ Mappa sull'input con var k.
            g ~ È maggiore o uguale a?
             k ~ L'elemento corrente dell'input, k.
              + hSQ * dc-eSQhSQT ~ Lo suddivideremo in pezzi:
               hSQ ~ L'elemento più basso dell'elenco di input.
              + ~ Plus:
                  * dc-eSQhSQT ~ Lo suddivideremo in più pezzi:
                  * ~ Moltiplicazione.
                   d ~ L'elemento corrente di [0, 10), d.
                    c T ~ Divisione float per 10 di:
                     -eSQhSQ ~ La differenza tra il massimo e il minimo
                                        dell'elenco di input.
          s ~ Sum. Conta il numero di risultati veritieri.
        + Z ~ Aggiungi uno 0.
      . + ~ Ottieni i delta.
    _M ~ Ottiene -delta per ciascun delta nell'elenco precedente.
  \ # ~ Il carattere letterale "#".
* R ~ Moltiplicazione vettoriale. Opzionalmente, puoi
                                    usa j per unirti a newline (come fa il link).
                                  ~ Uscita implicita.

2

Carbone , 31 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. L'immissione di elenchi a lunghezza variabile sembra un po 'imbarazzante in Charcoal, quindi ho dovuto avvolgere l'elenco in un array contenente una stringa. Spiegazione:

   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 byte

L'ho scritto su GNU gfortran 5.4.0 e compilato senza flag aggiuntivi.

Legge da STDIN, un valore alla volta, e stampa su STDOUT.

Eccolo:

programma h; reale, allocabile :: a (:); carattere f * 9; allocate (a (0)); do; read (*, *, end = 8) r; a = [a, r]; enddo; 9 formato ("(", i0, "(" "#" "))")
8 a = (a-minval (a)) + epsilon (1.); A = soffitto (10 * a / maxval (a)); do i = 1,10; j = count (a == i); se (j == 0) stampa *; if (j == 0) ciclo; write (f, 9) j;
stampa f; enddo; end

Spiegazione ungolf: (Non so se "golfed" può essere applicato a fortran ma in entrambi i casi: P)

programma h
reale, allocabile :: a (:)! Crea un array allocabile in modo che possiamo riallocare dinamicamente
carattere f * 9! Un array di caratteri per formattare l'output
allocare (a (0))! Inizialmente assegnare "a" vuoto
fare
  leggi (*, *, end = 8) r! Leggi da STDIN. Se EOF, passa a 8, altrimenti
  a = [a, r]! Si aggiunge a "a"
ENDDO
9 format ("(", i0, "(" "#" "))")! Un'etichetta di formato
8 a = (a-minval (a)) + epsilon (1.)! (8) Normalizza a (aggiunge epsilon per evitare l'indicizzazione zero)
a = soffitto (10 * a / maxval (a))! Normalizzazione e moltiplicazione per il numero di bin
faccio i = 1,10! Ciclo su tutti i bidoni
  j = count (a == i)! Contando il numero di occorrenze
  if (j == 0) stampa *! Se nessuno, stampa una riga vuota
  if (j == 0) ciclo! E salta il resto del ciclo
  scrivi (f, 9) j! Altrimenti scrive il conteggio (j) sull'etichetta di stampa
  stampa f! E stampa su STDOUT
ENDDO
fine

Curiosità: ieri ho creato un codice simile per testare la mia implementazione di un generatore di numeri casuali Weibull, quindi è stato necessario solo un piccolo adattamento :)




1

Perl 5, 102 byte

$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

Provalo 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

Java (OpenJDK 8) , 246 221 209 207 206 163 162 161 157 byte

l->{String x="";double b=l[0],m=b,q,i;for(double d:l){b=d<b?d:b;m=d>m?d:m;}for(i=(m-b)/10,q=b;q<m;q+=i,x+="\n")for(double d:l)x+=d>=q&d<q+i?"#":"";return x;}

Provalo online!


1

q / kdb +, 52 byte

Soluzione:

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

Provalo online! (Notare che il collegamento TIO è un 44 byte K (oK) di questa soluzione in quanto non esiste un TIO per q / kdb +).

Esempi:

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

Spiegazione:

La maggior parte del codice viene utilizzata per creare i bucket in cui vengono bininseriti gli input.

{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

Gelatina , 19 byte

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

Provalo online!

Questo si basa sulla mia risposta APL per il problema originale, che posterò dopo la fine della competizione.

Come? (Non sono bravo a spiegare le cose)

_Ṃµ÷Ṁ×⁵Ḟ«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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.