Dziesięciorzędowy wykres słupkowy

13

To jest Hole-1 z jesiennego turnieju APL CodeGolf . Jestem oryginalnym autorem problemu i dlatego mogę go ponownie opublikować tutaj.


Na podstawie listy liczb utwórz poziomy wykres słupkowy #znaków, określający liczbę liczb pasujących do każdej z dziesięciu grup o jednakowej wielkości. Na przykład, jeśli dane mieszczą się w zakresie od 0-100, zakresy będą wynosić 0–9,9, 10–19,9,…, 90–100. (Formalnie, [0,10), [10,20),…, [90,100].). Możesz założyć, że będą co najmniej dwie liczby i że nie wszystkie będą takie same.

Przykłady:

[1,0,0,0,0,0,0,0,0,0] daje:

#########








#        

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

#
#
#
#
#
#
#
#
#
#

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

#
#
#
#
#
#
#
#
#
##

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

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

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

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

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

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


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

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

#############             
######################    
##########################
######################### 
######################### 
#                         
########                  
################          
########################  
##########################
Adám
źródło
3
Więc ostatnia grupa jest trochę większa? Tak jak w pierwszym przykładzie byłoby [0.9,1](i nie [0.9,1))?
Felix Palmen
@FelixPalmen Rodzaj. Jest tylko większy o nieskończenie małą ilość.
Adám
Ok, ważne jest, aby wiedzieć, że jest to rzeczywiście ostatnia grupa, która powinna obejmować oba punkty końcowe, dzięki
Felix Palmen
@ FelixPalmen Ach, widzę, że nie było to całkowicie jasne w OP. Zmienię to.
Adám
1
@ Adám Czy zamiast tego powinno być odwrotnie? Górny rząd [0,1)zawiera tylko, 0podczas gdy dolny rząd [9,10]zawiera zarówno 9i 10.
user202729,

Odpowiedzi:

4

Python 2 , 107 95 bajtów

l=input();m=min(l);s=(max(l)-m)/10.;c=0
exec'print"#"*sum(m<=v-c*s<m+s+c/9for v in l);c+=1;'*10

Wypróbuj online!

ovs
źródło
Cofnąłem twoją edycję z moją sugestią, ponieważ *.1nie działa zamiast w /10.ostatnim przypadku testowym. TBH Nie wiem, dlaczego to nie działa.
Pan Xcoder,
4

R , 77 81 bajtów

+4 bajty, aby naprawić niektóre przypadki testowe

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

Wypróbuj online!

Link jest wersją kodu, która pobiera dane oddzielone przecinkami; ta wersja wymaga separacji spacji.

Odczytuje ze standardowego, drukuje na standardowe.

R jest statystycznym językiem programowania, który dokłada wszelkich starań, aby zapewniać wysokiej jakości wyniki, co czasem jest frustrujące:

histkojarzy dane wejściowe do histogramu breaksjako drugiego argumentu. Zwykle można oczekiwać, że można określić, że liczba przerw ma wynosić 10. Rzeczywiście, dzieje się tak:

breaks

jeden z:

  • wektor podający punkty przerwania między komórkami histogramu,
  • funkcja do obliczania wektora punktów przerwania,
  • pojedyncza liczba podająca liczbę komórek dla histogramu,
  • ciąg znaków nazywający algorytm do obliczania liczby komórek (patrz „Szczegóły”),
  • funkcja do obliczania liczby komórek.

(podkreślenie dodane).

Jednak następne zdanie mówi:

W ostatnich trzech przypadkach liczba jest tylko sugestią; ponieważ punkty przerwania zostaną ustawione na prettywartości, liczba jest ograniczona do 1e6(z ostrzeżeniem, jeśli była większa).

Spojrzałem więc na dokumentację prettyi to po prostu nie działa w naszej sytuacji, ponieważ w ten sposób wybiera punkty przerwania:

Oblicz sekwencję w przybliżeniu n+1jednakowo rozmieszczonych „okrągłych” wartości, które obejmują zakres wartości w x. Wartości są wybierane tak, aby były 1, 2 lub 5 razy mocą 10.

Co po prostu nie da rady.

seq(min(x),max(x),,11)Określa więc 11 równomiernie rozmieszczonych punktów jako breaks, hist(x,breaks,r=F)$cpodaje liczby, r=Fzapewnia, że ​​pojemniki są przedziałami otwartymi w prawo, a forpętla zajmuje się resztą.

Giuseppe
źródło
3

C (gcc) , 241 bajtów

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

Wypróbuj online!

Felix Palmen
źródło
Myślę, że możesz zrobić kjako globalny, (+ 1 bajt), ale jest on inicjowany na 0, więc oszczędzasz 3 bajty k=0.
user202729,
Ponadto można przełączyć doublesię floati lfdo f, Zapisz kolejne 2 bajtów. (przynajmniej działa na TIO)
202729
@ user202729 dla pierwszego komentarza: nie, ta inicjalizacja jest potrzebna wiele razy w zewnętrznej pętli. floatmoże działać, nie użyłem go, ponieważ nie jest to „standardowy” typ zmiennoprzecinkowy w C i zmniejsza precyzję, więc nie jestem pewien, czy jest to dozwolone ...
Felix Palmen
234 bajty
ceilingcat
3

Mathematica, 152 bajty

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


Wypróbuj online!

J42161217
źródło
Jak to powinno działać? TIO mają tylko wyjście tekstowe. (odpowiedz na część „Dennis to naprawi”)
user202729,
1
@ user202729 Czy naprawdę wierzysz, że nie jestem tego świadomy? lub ...
J42161217,
2
Nie obrażam cię, ale wspominasz o tym, Range[0,9]kiedy mówię Range[0,10]bez powodu. Ale tak naprawdę zawodzi dla Range[0,10]: TIO .
user202729,
4
Użyłeś <=na obu końcach, co jest poprawne na ostatnim segmencie, ale nie na 9 pozostałych.
user202729,
3
@ user202729 hej! ten pomógł mi tak samo jak twoje poprzednie informacje, że zakres [0, n] = {0, .. n}. +1 za świetną poradę. w każdym razie kod działa teraz poprawnie
J42161217,
3

JavaScript (ES6), 99 bajtów

Edytuj 2 bajty, oszczędzaj dzięki @JustinMariner

Funkcja zwracająca tablicę ciągów

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

Mniej golfa

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>

edc65
źródło
Powinieneś być w stanie zapisać kilka bajtów, przenosząc przypisanie ido nawiasów tablicowych, po których następuje przecinek, umożliwiając usunięcie nawiasów wokół korpusu funkcji mapy: Wypróbuj online!
Justin Mariner
@JustinMariner right, thx
edc65
Możesz faktycznie zapisać jeszcze jeden bajt, jeśli się go pozbędziesz ii użyjesz Math.minponownie, używając aliasu: Wypróbuj online!
Justin Mariner
2

Python 2 , 126 121 bajtów

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

Wypróbuj online!

TFeld
źródło
2

Galaretka , 21 bajtów

Łącze monadyczne zwraca listę ciągów.

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

Wypróbuj online!

użytkownik202729
źródło
Chociaż dozwolone jest zwracanie listy wierszy, wyświetlany wynik nie jest w żaden sposób rozdzielany. Nie wiem czy to jest poprawne.
user202729,
Jest to dozwolone, ponieważ w ten sposób Jelly traktuje listy ciągów. Możesz dodać ÇŒṘlub ÇYw stopce w celu wizualizacji wyniku. Również zamiast pełnego programu można powiedzieć, że przesłanie jest linkiem monadycznym, który zwraca zamiast drukować, dzięki czemu jest automatycznie poprawny.
Pan Xcoder,
2

Pyth ,  32  31 bajtów

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

Wypróbuj tutaj! lub Zweryfikuj wszystkie przypadki testowe. (przy użyciu ładnego wydrukuj)

Jak to działa

Jest to pełny program, który pobiera dane wejściowe ze STDIN. Dotyczy to wersji 32-bajtowej. Niedługo to zaktualizuję.

* R \ #_ M. ++ msmgk + hSQ * dc-eSQhSQTQTZ ~ Pełny program.

         m T ~ Mapuj na [0, 10) z var d.
           m Q ~ Mapuj dane wejściowe za pomocą var k.
            g ~ Czy jest wyższa czy równa?
             k ~ Bieżący element wejścia, k.
              + hSQ * dc-eSQhSQT ~ Podzielimy to na części:
               hSQ ~ Najniższy element listy wejściowej.
              + ~ Plus:
                  * dc-eSQhSQT ~ Podzielimy to na kolejne części:
                  * ~ Mnożenie.
                   d ~ Bieżący element [0, 10), d.
                    c T ~ Podział pływaka według 10 z:
                     -eSQhSQ ~ Różnica między maksimum a minimum
                                        listy wejściowej.
          s ~ Sum. Policz liczbę prawdziwych wyników.
        + Z ~ Dodaj 0.
      . + ~ Uzyskaj delty.
    _M ~ Pobiera -delta dla każdej delty z powyższej listy.
  \ # ~ Dosłowny znak „#”.
* R ~ Wektoryzacja mnożenia. Opcjonalnie możesz
                                    użyj j, aby dołączyć do nowego wiersza (tak jak link).
                                  ~ Wynik niejawnie.
Pan Xcoder
źródło
2

Węgiel drzewny , 31 bajtów

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

Wypróbuj online! Link jest do pełnej wersji kodu. Wprowadzanie list o zmiennej długości wydaje się trochę niewygodne w Charcoal, więc musiałem zawinąć listę w tablicę zawierającą ciąg znaków. Wyjaśnienie:

   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
Neil
źródło
2

Fortran 2003, 263 bajty

Napisałem to na GNU gfortran 5.4.0 i skompilowałem bez żadnych dodatkowych flag.

Odczytuje ze STDIN, po jednej wartości na raz, i drukuje do STDOUT.

Oto jest:

program h; rzeczywisty, alokowalny :: a (:); znak f * 9; alokuj (a (0)); do; czytaj (*, *, end = 8) r; a = [a, r]; enddo; 9 format („(„, i0, ”(„ „#” „))”)
8 a = (a-minval (a)) + epsilon (1.); A = pułap (10 * a / maxval (a)); do i = 1,10; j = liczba (a == i); jeśli (j == 0) drukuj *; jeśli (j == 0) cykl; napisz (f, 9) j;
print f; enddo; end

Niegolfowane wyjaśnienie: (Nie wiem, czy „golf” można zastosować do fortranu, ale tak czy inaczej: P)

program h
prawdziwe, do przydzielenia :: a (:)! Utwórz tablicę alokowalną, abyśmy mogli dynamicznie dokonywać alokacji
postać f * 9! Tablica znaków do sformatowania wyniku
przydziel (a (0))! Najpierw przydziel „a” puste
robić
  czytaj (*, *, end = 8) r! Czytaj ze STDIN. Jeśli EOF, idzie do 8, w przeciwnym razie
  a = [a, r]! Dołącza do „a”
enddo
9 format („(„, i0, ”(„ „#” ”))”)! Etykieta formatu
8 a = (a-minval (a)) + epsilon (1.)! (8) Normalizuje a (dodaje epsilon, aby uniknąć indeksowania zera)
a = pułap (10 * a / maxval (a))! Normalizowanie i mnożenie przez liczbę pojemników
czy i = 1,10! Pętle na wszystkich pojemnikach
  j = liczba (a == i)! Zliczanie liczby wystąpień
  jeśli (j == 0) wydrukuj *! Jeśli nie, drukuje pustą linię
  jeśli (j == 0) cykl! I pomija resztę pętli
  napisz (f, 9) j! W przeciwnym razie zapisuje liczbę (j) na etykiecie drukowanej
  wydrukuj f! I drukuje do STDOUT
enddo
koniec

Ciekawostka: stworzyłem podobny kod zaledwie wczoraj, aby przetestować moją implementację generatora liczb losowych Weibull, więc potrzebowałem tylko niewielkiej adaptacji :)

Phelype Oleinik
źródło
2

Perl 5 , 85 + 1 ( -a) = 86 bajtów

@F=sort{$a<=>$b}@F;map$r[($_-$F[0])/($F[-1]-$F[0])*10].='#',@F;$r[9].=pop@r;say for@r

Wypróbuj online!

Xcali
źródło
1

Perl 5, 84 + 19 (-MList :: Util = min, max) bajty

$s=-($m=min@_=@ARGV)+max@_;$a[($_-$m)*10/$s]++for@_;$a[9]+=pop@a;print"#"x$_,$/for@a

Wypróbuj online

Nahuel Fouilleul
źródło
1

Perl 5, 102 bajtów

$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

Wypróbuj online .

Nie golfowany:

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);
Denis Ibaev
źródło
1

Java (OpenJDK 8) , 246 221 209 207 206 163 162 161 157 bajtów

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

Wypróbuj online!

Roberto Graham
źródło
1

q / kdb +, 52 bajty

Rozwiązanie:

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

Wypróbuj online! (Uwaga: łącze TIO jest 44-bajtowym portem K (oK) tego rozwiązania, ponieważ nie ma TIO dla q / kdb +).

Przykłady:

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

Wyjaśnienie:

Większość kodu jest używana do tworzenia segmentów, do których binsegmenty są wprowadzane.

{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)
streetster
źródło
0

Galaretka , 19 bajtów

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

Wypróbuj online!

Jest to oparte na mojej odpowiedzi APL na oryginalny problem, którą opublikuję po zakończeniu konkursu.

W jaki sposób? (Nie jestem dobry w wyjaśnianiu rzeczy)

_Ṃµ÷Ṁ×⁵Ḟ«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
Zacharý
źródło