Graphique à barres à dix rangées


13

Il s'agit du trou 1 du tournoi d'automne d'APL CodeGolf . Je suis l'auteur original du problème là-bas, et donc autorisé à le publier à nouveau ici.


À partir d'une liste de nombres, produisez un diagramme à barres horizontales de #caractères pour le nombre de nombres qui correspondent à chacun des dix groupes de taille égale. Par exemple, si les données vont de 0 à 100, les plages seront 0–9,9, 10–19,9,…, 90–100. (Formellement, [0,10), [10,20),…, [90,100].). Vous pouvez supposer qu'il y aura au moins deux nombres et que tous ne seront pas identiques.

Exemples:

[1,0,0,0,0,0,0,0,0,0] donne:

#########








#        

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

#
#
#
#
#
#
#
#
#
#

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

#
#
#
#
#
#
#
#
#
##

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

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

[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] donne:

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

[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] donne:

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


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

[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] donne:

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

3
Donc, le groupe final est un tout petit peu plus grand? Comme dans le premier exemple, ce serait [0.9,1](et non [0.9,1))?
Felix Palmen

@FelixPalmen Genre de. Elle n'est plus grande que d'une quantité infiniment petite.
Adam

Ok, une chose importante à savoir est que c'est en effet le dernier groupe qui devrait inclure les deux points de terminaison, merci
Felix Palmen

@FelixPalmen Ah, je vois que ce n'était pas tout à fait clair dans le PO. Je vais le modifier.
Adam

1
@ Adám Doit-il être inversé à la place? La ligne du haut [0,1)ne contient que 0tandis que la ligne du bas [9,10]contient à la fois 9et 10.
user202729

Réponses:




4

R , 77 81 octets

+4 octets pour corriger certains cas de test

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

Essayez-le en ligne!

Le lien est vers une version du code qui prend une entrée séparée par des virgules; cette version prend l'espace séparé.

Lit depuis stdin, imprime vers stdout.

R est un langage de programmation statistique qui fait de son mieux pour donner des résultats de haute qualité, ce qui est parfois frustrant:

histplace les entrées dans un histogramme avec breakscomme deuxième argument. Normalement, on pourrait s'attendre à ce que vous puissiez spécifier que le nombre de pauses soit de 10. En effet, c'est le cas:

breaks

un des:

  • un vecteur donnant les points d'arrêt entre les cellules d'histogramme,
  • une fonction pour calculer le vecteur des points d'arrêt,
  • un numéro unique donnant le nombre de cellules pour l'histogramme,
  • une chaîne de caractères nommant un algorithme pour calculer le nombre de cellules (voir 'Détails'),
  • une fonction pour calculer le nombre de cellules.

(pas d'italique dans l'original).

Cependant, la phrase suivante dit:

Dans les trois derniers cas, le nombre n'est qu'une suggestion; comme les points d'arrêt seront définis sur des prettyvaleurs, le nombre est limité à 1e6(avec un avertissement s'il était plus grand).

J'ai donc regardé la documentation de prettyet cela ne fonctionne tout simplement pas pour notre situation, car elle sélectionne ainsi les points de rupture:

Calculez une séquence de n+1valeurs rondes à peu près également espacées qui couvrent la plage des valeurs en x. Les valeurs sont choisies de manière à être 1, 2 ou 5 fois une puissance de 10.

Ce qui ne fera tout simplement pas l'affaire.

Ainsi, le seq(min(x),max(x),,11)spécifie 11 points également espacés que le breaks, hist(x,breaks,r=F)$cdonne les comptes, r=Fgarantit que les bacs sont des intervalles ouverts à droite, et la forboucle s'occupe du reste.


3

C (gcc) , 241 octets

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

Essayez-le en ligne!


Je pense que vous pouvez faire kun global, (+ 1 octet) mais il est initialisé à 0, économisez donc 3 octets à partir de k=0.
user202729

Vous pouvez également basculer doublevers floatet lfvers f, enregistrer encore 2 octets. (au moins cela fonctionne sur TIO)
user202729

@ user202729 pour votre premier commentaire: non, cette initialisation est nécessaire plusieurs fois dans la boucle externe. floatpourrait fonctionner, je ne l'ai pas utilisé car ce n'est pas le type à virgule flottante "standard" en C et réduit la précision, donc pas sûr que cela soit autorisé ...
Felix Palmen


3

Mathematica, 152 octets

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


Essayez-le en ligne!


Comment cela devrait-il fonctionner? TIO n'a qu'une sortie texte. (réponse à la partie "Dennis va le réparer")
user202729

1
@ user202729 Croyez-vous vraiment que je ne suis pas au courant de cela? ou ...
J42161217

2
Pas pour vous offenser, mais vous mentionnez Range[0,9]pendant que je parle Range[0,10]sans raison. Mais il échoue en fait pour Range[0,10]: TIO .
user202729

4
Vous l'avez utilisé <=aux deux extrémités, ce qui est correct sur le dernier segment mais pas sur les 9 autres.
user202729

3
@ user202729 hey! celui-ci m'a autant aidé que vos informations précédentes que Range [0, n] = {0, .. n}. +1 pour de bons conseils. de toute façon le code fonctionne bien maintenant
J42161217

3

JavaScript (ES6), 99 octets

Modifier 2 octets de sauvegarde thx @JustinMariner

Une fonction renvoyant un tableau de chaînes

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

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

Tester

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>


Vous devriez pouvoir enregistrer quelques octets en déplaçant l'affectation pour idans les crochets du tableau suivie d'une virgule, vous permettant de supprimer les parenthèses autour du corps de la fonction de carte: Essayez-le en ligne!
Justin Mariner

@JustinMariner right, thx
edc65

Vous pouvez réellement enregistrer un octet de plus si vous vous en débarrassez iet le réutilisez Math.min, avec un alias: essayez-le en ligne!
Justin Mariner du


2

Gelée , 21 octets

Un lien monadique renvoie une liste de chaînes.

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

Essayez-le en ligne!


Bien que le retour d'une liste de lignes soit autorisé, le résultat affiché n'est en aucun cas séparé. Je ne sais pas si c'est valable.
user202729

C'est permis, car c'est ainsi que Jelly traite les listes de chaînes. Vous pouvez ajouter ÇŒṘou ÇYdans votre pied de page afin de visualiser le résultat. De plus, au lieu d'un programme complet, vous pouvez dire que votre soumission est un lien monadique, qui renvoie plutôt que d'imprimer, ce qui la rend automatiquement valide.
M. Xcoder

2

Pyth ,  32  31 octets

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

Essayez-le ici! ou Vérifiez tous les cas de test. (avec jolie impression en utilisantj)

Comment ça marche

Il s'agit d'un programme complet qui accepte les données de STDIN. C'est pour la version 32 octets. Je vais le mettre à jour bientôt.

* R \ #_ M. ++ msmgk + hSQ * dc-eSQhSQTQTZ ~ Programme complet.

         m T ~ Carte sur [0, 10) avec var d.
           m Q ~ Mappez l'entrée avec var k.
            g ~ Est-il supérieur ou égal à?
             k ~ L'élément courant de l'entrée, k.
              + hSQ * dc-eSQhSQT ~ Nous allons décomposer cela en plusieurs morceaux:
               hSQ ~ L'élément le plus bas de la liste d'entrée.
              + ~ Plus:
                  * dc-eSQhSQT ~ Nous décomposerons cela en plusieurs morceaux:
                  * ~ Multiplication.
                   d ~ L'élément courant de [0, 10), d.
                    c T ~ Division flottante par 10 de:
                     -eSQhSQ ~ La différence entre le maximum et le minium
                                        de la liste d'entrée.
          s ~ Sum. Comptez le nombre de résultats véridiques.
        + Z ~ Ajouter un 0.
      . + ~ Obtenez les deltas.
    _M ~ Obtient -delta pour chaque delta dans la liste ci-dessus.
  \ # ~ Le caractère littéral "#".
* R ~ Multiplication vectorisée. En option, vous pouvez
                                    utilisez j pour rejoindre par des nouvelles lignes (comme le fait le lien).
                                  ~ Sortie implicite.

2

Fusain , 31 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. La saisie de listes de longueur variable semble un peu gênante dans Charcoal, j'ai donc dû encapsuler la liste dans un tableau contenant une chaîne. Explication:

   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 octets

Je l'ai écrit sur GNU gfortran 5.4.0 et compilé sans aucun drapeau supplémentaire.

Il lit depuis STDIN, une valeur à la fois, et imprime vers STDOUT.

Ça y est:

programme h; réel, allocable :: a (:); caractère f * 9; allocate (a (0)); do; read (*, *, end = 8) r; a = [a, r]; enddo; 9 format ("(", i0, "(" "#" "))")
8 a = (a-minval (a)) + epsilon (1.); A = plafond (10 * a / maxval (a)); do i = 1,10; j = count (a == i); if (j == 0) print *; if (j == 0) cycle; write (f, 9) j;
imprimer f; enddo; fin

Explication non golfée: (je ne sais pas si "golfé" peut être appliqué à fortran mais de toute façon: P)

programme h
réel, attribuable :: a (:)! Créer un tableau allouable afin que nous puissions réallouer dynamiquement
caractère f * 9! Un tableau de caractères pour formater la sortie
allouer (a (0))! Attribuez "a" vide au début
faire
  lire (*, *, fin = 8) r! Lire à partir de STDIN. Si EOF, passe à 8, sinon
  a = [a, r]! Ajoute à "a"
enddo
9 format ("(", i0, "(" "#" "))")! Une étiquette de format
8 a = (a-minval (a)) + epsilon (1.)! (8) Normalise a (ajoute epsilon pour éviter l'indexation zéro)
a = plafond (10 * a / maxval (a))! Normaliser et multiplier par le nombre de bacs
dois-je = 1,10! Boucle sur tous les bacs
  j = compter (a == i)! Compter le nombre d'occurrences
  if (j == 0) print *! Si aucun, imprime une ligne vide
  si (j == 0) cycle! Et saute le reste de la boucle
  écrire (f, 9) j! Sinon, écrit le nombre (j) sur l'étiquette d'impression
  imprimer f! Et imprime sur STDOUT
enddo
fin

Fait amusant: j'ai fait un code similaire hier pour tester mon implémentation d'un générateur de nombres aléatoires Weibull, donc il n'a fallu qu'une petite adaptation :)




1

Perl 5, 102 octets

$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

Essayez-le en ligne .

Non 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 octets

Solution:

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

Essayez-le en ligne! (Notez que le lien TIO est un port K (oK) de 44 octets de cette solution car il n'y a pas de TIO pour q / kdb +).

Exemples:

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

Explication:

La plupart du code est utilisé pour créer les compartiments qui binregroupent l'entrée.

{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ée , 19 octets

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

Essayez-le en ligne!

Ceci est basé sur ma réponse APL pour le problème d'origine, que je publierai après la fin de la compétition.

Comment? (Je ne suis pas bon pour expliquer les choses)

_Ṃµ÷Ṁ×⁵Ḟ«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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.