Alfabe Histogramı


33

Bir veya daha fazla kelime [a-z]+ve sıfır veya daha fazla boşluktan oluşan bir giriş cümlesi göz önüne alındığında, giriş cümlesinin harf dağılımının bir ASCII-art histogramını (çubuk grafik) çıkar.

Histogram yatay olarak, yani alt kısımdaki harf tuşu alfabetik sırayla soldan sağa, Y ekseni etiketli 1-ve her 5 ünitede belirtilmelidir. Y ekseni, en az en yüksek çubuk kadar yüksek olan beşin en küçük katı olmalı ve sağa hizalı olmalıdır. X ekseni, aralarında boşluk kalmadan, giriş harfleriyle etiketlenir. Örneğin, giriş a bb ddetiketi olmalıdır abdve ab d, atlama c. Çubukların kendileri tutarlı herhangi bir ASCII karakterinden yapılabilir - Xburada örneklerimde kullanacağım .

test example

5-

   X
   X   X
1-XXXXXXXX
  aelmpstx

Çünkü üç e, iki tve bir tane var almsx.

Daha fazla örnek:

the quick brown fox jumped over the lazy dogs

5-
      X         X
      X         X
     XX  X      X  X XX
1-XXXXXXXXXXXXXXXXXXXXXXXXXX
  abcdefghijklmnopqrstuvwxyz


now is the time for all good men to come to the aid of their country

10-
              X
              X
              X  X
      X       X  X
 5-   X       X  X
      X   X   X  X
      X  XX XXXX X
   XXXXX XXXXXXX X
 1-XXXXXXXXXXXXXXXXXX
   acdefghilmnorstuwy

a bb ccc dddddddddddd

15-


      X
      X
10-   X
      X
      X
      X
      X
 5-   X
      X
     XX
    XXX
 1-XXXX
   abcd

a bb ccccc

5-  X
    X
    X
   XX
1-XXX
  abc

G / Ç ve Kurallar

  • Giriş, herhangi bir makul formatta ve uygun bir yöntemle alınabilir . Bu, ayrıca kodunuz için daha anlamlı olması durumunda, büyük harflerle giriş yapabileceğiniz anlamına gelir.
  • Lider / izleyen yeni satırlar veya diğer boşluklar, karakterlerin uygun şekilde sıralanması şartıyla isteğe bağlıdır.
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlevse, çıktıyı yazdırmak yerine geri gönderebilirsiniz.
  • Çıktı konsola olabilir, dizelerin listesi olarak döndürülür, tek bir dizge olarak döndürülür vb.
  • Standart boşluklar yasaktır.
  • Bu olduğundan, tüm normal golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

3
Sayısal verilerden ziyade kategorik olduğu için bunun bir histogram yerine çubuk grafik olacağını düşünüyorum, ama çoğunlukla bilgiçlik yapıyorum.
Giuseppe

girişin boş olmadığı garanti edilir mi?
dzaima

2
Sadece bir kolye olmak, ama bu bir histogram değil , bir çubuk grafik. Yine de güzel bir meydan okuma!
caird coinheringaahing

4
Tuftian bir yaklaşım, çubukları temsil edilen karakterlerden çıkarmak ve ayrı bir etiket satırına sahip olmamaktır.
dmckee

2
Histogram karakterinin tutarlı olması gerekir, ancak durumlar arasında mı yoksa her durumda mı?
Ad am

Yanıtlar:



7

R , 239 230 bayt

K=table(el(strsplit(gsub(" ","",scan(,"")),"")));m=matrix(" ",L<-sum(K|1)+1,M<-(M=max(K))+-M%%5+1);m[2:L,M]=names(K);m[1,M-g]=paste0(g<-c(1,seq(5,M,5)),"-");m[1,]=format(m[1,],j="r");for(X in 2:L)m[X,M-1:K[X-1]]=0;write(m,1,L,,"")

Çevrimiçi deneyin!

table Burada ağır kaldırma, karakterleri birleştirme, sıralama ve saymalarını döndürme işlemi yapar.

Geriye kalan her şey, ofsetlerin baskıya uygun olmasını sağlamaktır, ki bu, bir sanat-sanat mücadelesinin "gerçek" eseridir.

@Dylnan'a bir hatayı işaret ettiği için teşekkürler .

2 bayt bırakarak , yaklaşım için @ rturnbull teşekkürler scan.



@ rturnbull Bundan sonra bir kaç bayt daha nakavt etmeyi başardım, teşekkürler!
Giuseppe

6

gnu sed -r, 516 490 278 249 + 1 bayt

s/$/:ABCDEFGHIJKLMNOPQRSTUVWXYZ /
:a
s/(.)(:.*\1)/\2\1/I
ta
s/[A-Z]+/ /g
h
z
:b
s/ \w/ /g
G
s/:/&I/g
/:II{5}+ *$/M!bb
s/[a-z]/X/g
G
s/:(I{5}+|I)\b/0\1-/g
s/:I*/  /g
s/ (\w)\1*/\1/g
s/$/; 10123456789I0/
:c
s/(.)I(.*\1(I?.))|;.*/\3\2/
/\nI/s/^/ /Mg
tc

Çevrimiçi deneyin!


Bunun geliştirilebileceğinden eminim , ama şimdilik, yerel aritmetik veya sıralamaya sahip olmadığınız, sed'de yapıldığı düşünüldüğünde iyi olmalı. Bu yüzden yalan söyledim, bu yeterince iyi değildi, bu yüzden başka bir 212 byte daha geliştirdim (yeniden yazdım), Cows quack'in sıralama algoritmasıyla ilgili bir ipucu verdim;
İç çalışmaların tanımı:

s/$/:ABCDEFGHIJKLMNOPQRSTUVWXYZ /
:a
s/(.)(:.*\1)/\2\1/I
ta
s/[A-Z]+/ /g
h
z

Bu girdiyi sıralar ve grupları boşluklarla ayırır. Bu, önce büyük bir alfabe artı sonuna kadar iki nokta üst üste bırakılmış bir boşluk ekleyerek çalışır. Daha sonra, bir halkadaki büyük / küçük harfe duyarlı olmayan bir ikameyi kullanarak, kolonun önündeki her bir karakteri kolonun arkasındaki eşleşen bir karaktere taşır. Büyük harfler daha sonra boşluklarla değiştirilir ve dize, tutma alanına kopyalanır.

:b
s/ \w/ /g
G
s/:/&I/g
/:II{5}+ *$/M!bb

Bu döngü, sıralanan orijinal çizgiyi ekleyerek ve sıralamadan kalan iki noktadan sonra birleşik sayaçları artırarak her karakter grubu boyutunu birer küçülterek çalışır. 5 * n + 1 ile boş bir satıra ulaşılana kadar döngüler (son satır boşlukta sonuçlandığı için). Desen alanı döngüden sonra şöyle görünür:

:IIIIII           
:IIIII           
:IIII           
:III  e         
:II  ee     t    
:I a eee l m p s tt x   

Sonra biçimlendirme aşağıdaki gibidir:

s/[a-z]/X/g            # makes bars consistent
G                      # appends line that becomes x-axis
s/:(I{5}+|I)\b/0\1-/g  # moves zero in front of line 1 or 5-divisible
                       # lines for the decimal conversion and adds -
s/:I*/  /g             # removes numbers from other lines
s/ (\w)\1*/\1/g        # collapses groups of at least 1 into 1
                       # character, deleting the space before it
                       # so that only size-0-groups have spaces

Ve nihayet, ondalık dönüştürücü unary kalır:

s/$/; 10123456789I0/
:c
s/(.)I(.*\1(I?.))|;.*/\3\2/
/\nI/s/^/ /Mg
tc

Temelde dönüşüm bilgisinin olduğu bir dize ekler. Bunu şu şekilde yorumlayabilirsiniz: boşluk: -> 1 ve 0-> 1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> 9-> I0. Yer değiştirme ifadesi s/(.)I(.*\1(I?.))|;.*/\3\2/, sıralama (.)Idizisine benzer şekilde çalışır, I [[ 'nin önündeki karakterleri [ (.*\1(I?.))] dizisindeki [I ] önündeki karakterin yanında bulunan karakterle değiştirir. eklenen dize [ |;.*]. [ /\nI/s/^/ /Mg] İkamesi gerekirse gerekirse dolgu ekler.

Cows sayesinde , büyüklüğü 26 byte azaltma ve daha kısa sıralama algoritması için teşekkürler .


PPCG'ye hoş geldiniz ve güzel bir cevap!
Kritixi Lithos,

\wBazı baytları kaydetmek için birçok yerde kullanabilirsiniz (kelime karakterleriyle eşleşir). Ayrıca :b ... tbbasitçe olabilir s/\B\w/X/g. s/:/:,/gÖnceki değiştirmeleri değiştirerek, onu izleyen çizgiyi kaldırabilirsiniz . Ne demek istediğimi görmek için goo.gl/JvD7Rs (sed programına kısaltılmış TIO bağlantısı) bakabilirsiniz .
Kritixi Lithos,

1
Sıralama algoritmasını geliştirebilirsiniz, ipucu: zyx...cbagirişe eklemeyi deneyin .
Kritixi Lithos

Ondalık dönüştürücü Parlak unary! Sizinkiler, golf
sahasındaki Püf Noktalarındakinden

5

Dyalog APL , 109 97 96 95 93 88 bayt

{⊖(⍉r),⍨⍕↑(⊂'')@{1@0~⍵∊1,5×⍵}⍳≢⍉↑r←↑r,⍨⊂' -','   - '⍴⍨5×⌈5÷⍨≢1↓⍉↑r←↓{⍺,∊⍕¨0×⍵}⌸⍵[⍋⍵]∩⎕A}

Çevrimiçi deneyin!

gerektirir ⎕IO←0

Yol çok fazla bayt sayesinde kaydedilen ADAM ve inekler şarlatan !


Geçen bit için deneyebileceğiniz ⍵[⍋⍵]~' '(geçerek önce sıralar ve kaldırır boşluk )
Kritixi Lithos

'X'/⍨≢∊⍕¨×
Adám

ve ⍵>0×⍵
Kritixi Lithos

TIO bağlantınızın gereksiz bir Başlığı var.
Adám

2⌷⍴≢⍉iki kez
Adám

5

05AB1E , 58 47 bayt

áê©S¢Z5‰`Ā+L5*1¸ì'-«ð5×ý#À¦Áí.Bís'X×ζ‚ζJR»,®3ú,

Çevrimiçi deneyin!

@Emigna sayesinde -11 bayt


Belki bu yardımcı olabilir? Onları bir araya getirmek için zaman yok ama belki biraz ilham verebilirler.
Emigna

@Emigna Kesinlikle benimkinden farklı bir göz atacağım :).
Magic Octopus Urn

@Emigna 57 byte dikişim bittikten sonra ... optimize etmek için fazla çabalamadığım için. Çevrimiçi deneyin!
Magic Octopus Urn

Bazı yeniden yapılandırma ve optimizasyon ile 47 bayt .
Emigna

Mektuplarınız belirli girişler için X'lerle aynı hizada değil. tio.run/##AVUAqv8wNWFiMWX//…
mbomb007

3

Python 2 , 192 bayt

s=input()
d={c:s.count(c)for c in s if' '<c}
h=-max(d.values())/5*-5
for y in range(h,-1,-1):print('%d-'%y*(y%5==2>>y)).rjust(len(`-h`))+''.join(('X '[y>v],k)[y<1]for k,v in sorted(d.items()))

Çevrimiçi deneyin!

açıklama

Satır 2, histogram değerlerini atma işlemini oldukça basit bir şekilde hesaplar ' '.

Satır 3 kullanımları işlem hile ceil(x/5)olarak -(-x/5): formülü kullanılarak 5 sonraki katına maksimum frekans yuvarlak -x/5*-5. Bu h.

Satır 4, haşağıdan içeriye doğru sayılan bir döngüdür ve 0her satırı yazdırır:

  • Eğer y%5==2>>ybir etiket yazdırabilirsiniz. Bu, y∈ {1, 5, 10, 15, 20,…}

    (Bu formül daha kısa olabilir. {1, 5, 10,…} ve 0 veya Yanlış veya hatta diğer tüm değerler için negatif bir tamsayı için 1 veya Doğru olan bir şeye ihtiyacımız var .)y

  • Etiketi (veya boş alanı) len(`-h`)boşluklara doğru şekilde haklı çıkarırız: bu, temiz bir bayt tasarrufudur len(`h`)+1!

  • Ardından, Xbu satır için ( y≥ 1 ise) harfleri veya boşlukları veya artan ydeğerde anahtar / değer çiftlerinden geçen harfleri (eğer = 0) yazdırırız d.


1
İle güzel kene oluşturma '%d-'%y*(y%5==2>>y). Bunu cevabımda kullanırsam sorun olur mu?
dylnan

-~-(y%5*~-y)çok çalışır ama maalesef artık bir bayt.
dylnan

2

Kömür , 62 bayt

≔E²⁷⟦⟧ηFθ⊞§η⌕βιι≔⊟ηθ≦LηP⭆β⎇§ηκιω↑↑ΦηιF÷⁺⁹⌈η⁵«≔∨×⁵ι¹ιJ±¹±ι←⮌⁺ι-

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. Açıklama:

≔E²⁷⟦⟧η

27 listenin bir listesini oluşturun.

Fθ⊞§η⌕βιι

Her giriş karakterini küçük harfli alfabedeki konumuna karşılık gelen listeye itin. Küçük harf olmayan karakterler 27. listeye itilir.

≔⊟ηθ

Listenin 27. elemanını atın.

≦Lη

Listedeki tüm öğelerin uzunluklarını al.

P⭆β⎇§ηκιω

Sıfır olmayan liste öğelerine karşılık gelen küçük harfleri yazdırın.

↑↑Φηι

Sıfır olmayan liste öğelerini yukarı doğru yazdırın. Bu bir tamsayı dizisi olduğundan, her bir tamsayı, her biri ayrı bir sütuna (şimdi dikey) bir çizgi olarak yazdırılır.

F÷⁺⁹⌈η⁵«

Y eksenindeki onay işaretlerinin sayısını hesaplayın ve bunların üzerinden geçirin.

≔∨×⁵ι¹ι

Bir sonraki onay işaretinin konumunu hesaplayın.

J±¹±ι

Bir sonraki onay işaretine atla.

←⮌⁺ι-

İşaretleme çizgisinin tersine çevrilmiş ve öne, baskıya doğru hizalayarak yazdırın.


2

Jöle , 48 bayt

Geçiş yapmak için ne mayın tarlası!

J’⁶D;”-Ɗ%5^ỊƲ?€Uz⁶ZU
ḟ⁶ṢµĠ¬;⁶$L%5Ɗ¿€;"@Qz⁶Ç;"$ṚY

Sonucu basan tam program (monadik bir bağlantı olarak karakterleri ve tamsayıları içeren bir liste döndürür [0,9])

Çevrimiçi deneyin! Veya test odasına bakın

Nasıl?

J’⁶D;”-Ɗ%5^ỊƲ?€Uz⁶ZU - Link 1, get y-axis: list of columns (including x-axis & top-spaces)
J                    - range of length  [1,2,3,4,5,6,...,height+1] (+1 for x-axis)
 ’                   - decrement        [0,1,2,3,4,5,...] (line it up with the content)
             ?€      - if for €ach...
            Ʋ        - ...condition: last four links as a monad:
        %5           -   modulo by five
           Ị         -   insignificant? (1 for 0 and 1, else 0)
          ^          -   XOR (0 for 1 or multiples of 5 greater than 0, else 0)
  ⁶                  - ...then: literal space character
       Ɗ             - ...else: last three links as a monad:
   D                 -   decimal list of the number, e.g. 10 -> [1,0]
     ”-              -   literal '-' character
    ;                -   concatenate, e.g. [1,0,'-']
               U     - upend (reverse each)
                z⁶   - transpose with a filler of space characters
                  Z  - transpose
                   U - upend (i.e. Uz⁶ZU pads the left with spaces as needed)

ḟ⁶ṢµĠ¬;⁶$L%5Ɗ¿€;"@Qz⁶Ç;"$ṚY - Main link: list of characters
ḟ⁶                          - filter out space characters
  Ṣ                         - sort
   µ                        - start a new monadic chain, call that S
    Ġ                       - group indices of S by their values
     ¬                      - logical NOT (vectorises) (getting 0 for the X "characters")
             ¿€             - while for €ach...
            Ɗ               - ...condition: last three links as a monad:
         L                  -   length
          %5                -   modulo by five
        $                   - ...do: last two links as a monad:
      ;⁶                    -   concatenate a space character
                  Q         - deduplicate S (get the x-axis)
               ;"@          - zip with (") concatenation (;) with swapped arguments (@)
                   z⁶       - transpose a with filler of space characters
                        $   - last two links as a monad:
                     Ç      -   call last link (1) as a monad (get y-axis)
                      ;"    -   zip with concatenation (complete the layout)
                         Ṛ  - reverse (otherwise it'll be upside-down)
                          Y - join with newlines
                            - implicit print


2

Ruby , 250 248 234 188 173 157 153 bayt

->s{a=s.scan(/\w/).sort|[]
m=-(c=a.map{|l|s.count l}).max/5*-5
m.downto(1).map{|i|(i%5<1||i<2?"#{i}-":'').rjust(m)+c.map{|l|l<i ?' ':?X}*''}<<' '*m+a*''}

Çevrimiçi deneyin!

Sayesinde:

  • az katı dolgulu -16 baytlık dylnan
  • Lynn ile-2 bayt için yuvarlayarak-x/5*-5
  • Kirill L. ile -2 bayt için benzersiz dizi elemanları elde|[]

2

Java (JDK 10) , 296 bayt

s->{int d[]=new int[26],m=0;char a;for(int c:s.getBytes())m=c>32&&++d[c-=65]>m?(d[c]+4)/5*5:m;String r=m+"-",z=r.replaceAll("."," ");for(;m>0;r+="\n"+(--m%5<1|m==1&&m>0?z.format("%"+~-z.length()+"s-",m):z))for(a=0;a<26;a++)r+=d[a]>0?m>d[a]?" ":"x":"";for(a=64;a++<90;)r+=d[a-65]>0?a:"";return r;}

Çevrimiçi deneyin!

Kredi


@aoemica Doğru. Düzelttim.
Olivier Grégoire

1
Çok değil, ama 2 byte tasarruf edebilirsiniz. --m%5==0olabilir --m%5<1, çünkü siz de &m>0çekiniz var. Ve m<=d[a]?"x":" "olabilir m>d[a]?" ":"x".
Kevin Cruijssen

@KevinCruijssen 2 bayt 2 bayt! Farklı bir algoritma dışında artık golf oynamaktan daha fazlası olduğunu sanmıyorum.
Olivier Grégoire

1
Değiştirerek 1 daha bayt (--m%5<1|m==1)&m>0için--m%5<1|m==1&&m>0
Kevin Cruijssen

1

Pyth, 65 bayt

J.tm+ed*hd\Xr8S-Qd)=+J*]d%_tlJ5_.e+?q<k2%k5.F"{:{}d}-",klQ*dhlQbJ

Burada dene

açıklama

J.tm+ed*hd\Xr8S-Qd)=+J*]d%_tlJ5_.e+?q<k2%k5.F"{:{}d}-",klQ*dhlQbJ
J.tm+ed*hd\Xr8S-Qd)
     Get the bars.
                   =+J*]d%_tlJ5
     Round up the height to the next number that's 1 mod 5.
                               _.e+?q<k2%k5.F"{:{}d}-",klQ*dhlQbJ
     Stick the axis labels on.

1

JavaScript (Node.js) , 262 256 bayt

* 2 bayt azaltan @Shaggy sayesinde

a=>[...a].map(x=>x>" "&&(d=c[x]=(c[x]||x)+"X")[m]?m=d.length-1:0,c={},m=i=0)&&Object.keys(c).sort().map(x=>[...c[x].padEnd(m)].map((l,j)=>A[m-j-1]+=l),A=[...Array(m+=6-m%5)].map(x=>(++i>=m||((D=m-i)%5&&m-i^1)?"":D+"-").padStart((m+" ").length)))&&A.join`
`

Çevrimiçi deneyin!


Telefonumda nokta olabilir hızlı tasarrufların Çift: 1.bireysel karakterlerin bir dizi olarak giriş almak 2.değiştirin x!=" "ile x>" ".
Shaggy

3.Değiştir m=0ile i=m=0ve map((x,i)=>ile map(x=>.
Shaggy

1

Python 2 , 249 224 219 215 205 197 187 188 182 176 bayt

def f(s):S=sorted(set(s)^{' '});C=map(s.count,S);P=max(C)+4;return zip(*(zip(*[('%d-'%y*(y%5==2>>y)).rjust(P)for y in range(P,0,-1)])+[(n*'#').rjust(P)for n in C]))+[[' ']*P+S]

Çevrimiçi deneyin!

Satırları temsil eden karakter listelerinin bir listesini döndürür.

  • Çok fazla boş alan ekleyerek bazı baytlar kaydedildi.
  • map(list,yticks)Orada gereksiz bir şey vardı.
  • Bazı baytları kaydetmek için değişen alan dolgusu.
  • Sıralama yaptığımı sanıyordum ama değildim: +2 byte. Ama aynı anda bağımsız olarak bir tane kurtardım. y==1ile değiştirildi y<2.
  • -6 bayt yerine Lynn kullanarak .'%d-'%y*(y%5==2>>y)(`y`+'-')*(not y%5or y<2)

Biraz ungolfed:

def f(s):
	S=sorted(set(s)^{' '})  # sorted list of unique letters (without ' ')
	C=map(s.count,S)        # count of each unique letter in the input
	P=max(C)+4              # used for padding and getting highest y tick
	B=[(n*'#').rjust(P)for n in C]     # create bars
	yticks = [('%d-'%y*(y%5==2>>y)).rjust(P)for y in range(P,0,-1)]  # create y ticks at 1 and multiples of 5
	yticks = zip(*yticks)                      # need y ticks as columns before combining with bars
	return zip(*(yticks+B))+[[' ']*P+S]        # zip ticks+bars then add row of sorted unique letters.

1

C # (.NET Core) , 344 340 338 + 18 bayt

18 bayt içerir using System.Linq;

@KevinCruijssen sayesinde 6 bayt kaydedildi.

n=>{var l=n.Where(c=>c!=32).GroupBy(c=>c).OrderBy(c=>c.Key).ToDictionary(k=>k.Key,c=>c.Count());int h=(l.Values.Max()/5+1)*5,o=(h+"").Length+1,m=l.Keys.Count+o,t=h+1,i=0,j;var a=new string[t];for(string p,q;i<t;a[i++]=q)for(q=(p=i>0&i%5<1|i==1?i+"-":"").PadLeft(j=o);j<m;){var c=l.ElementAt(j++-o).Key;q+=i<1?c:l[c]>=i?'X':' ';}return a;}

Çevrimiçi deneyin!


Sen de bir boşluk var j< m;olduğu çıkarılabilir. Ve int i=0,jolarak yerleştirilebilir ,i=0,jtoplamda -4 byte diğer ints sonra. using System.Linq;Ancak 18 bayt dahil etmek zorunda kalacaksınız ..
Kevin Cruijssen

@KevinCruijssen Teşekkürler, bunları özledim. Ve 18 bayt ekledim.
Ian H.

Benden +1. Oh, ve değiştirerek 2 daha bayt kaydedebilirsiniz for(;i<t;){string p=i>0&i%5<1|i==1?i+"-":"",q=p.PadLeft(o);for(j=o;j<m;){...}a[i++]=q;}için for(string p,q;i<t;)for(p=i>0&i%5<1|i==1?i+"-":"",q=p.PadLeft(j=o);j<m;a[i++]=q){...}. Çevrimiçi deneyin.
Kevin Cruijssen

@KevinCruijssen Bu gerçekten zekice, teşekkürler!
Ian H.

1

Bash + coreutils, 332 324 323 318 312 302 298 296 293 291 bayt

c()(cut -d\  -f$@)
p=printf
cd `mktemp -d`
grep -o [^\ ]<<<$@|sort|uniq -c|c 7->a
sort -k2<a>b
r=$[`c 1 <a|sort -n|tail -1`+5]
s=${#r}
t()($p \ ;((i++<s))&&t;i=)
for((;--r;));{
((r%5&&r>1))&&t||$p %${s}s- $r;IFS='
'
for l in `<b`;{ ((r<=`c 1 <<<$l`))&&$p X||$p \ ;}
echo
}
t
c 2 <b|tr -d \\n

Çevrimiçi deneyin!

Açıklamalı:

c()(cut -d\  -f$@)
p=printf              # saving a few bytes

cd `mktemp -d`        # for temp files

grep -o [^\ ]<<<$@    # grabs all non-space characters
    |sort|uniq -c     # get character frequency
    |c 7->a           # slightly hacky way of stripping leading spaces;
                      #     uniq -c adds 6 spaces in front of each line

sort -k2<a>b          # store frequencies sorted alphabetically in b

r=$[`                 # r = highest frequency +5:
    c 1 <a            #     get frequencies
    |sort -n|tail -1  #     get maximum frequency
    `+5]              #     +4 so at least one multiple of 5 is
                      #     labeled, +1 because r gets pre-decremented

s=${#r}                    # s = length of r as a string
t()($p \ ;((i++<s))&&t;i=) # pad line with s+1 spaces

for((;--r;));{         # while (--r != 0)
    ((r%5&&r>1))&&     # if r isn't 1 or a multiple of 5
        t||            #     then indent line 
        $p %${s}s- $r; # otherwise print right-aligned "${r}-"
        IFS='
'                      # newline field separator
    for l in `<b`;{          # for all letters and their frequencies:
        ((r<=`c 1 <<<$l`))&& #     if frequency <= current height 
            $p X||           #         then print an X
            $p \ ;}          #     otherwise print a space
    echo
}
t # indent x-axis labels
c 2 <b|tr -d \\n # print alphabetically sorted characters

3 byte tasarruf için @IanM_Matrix teşekkürler.


cat b<b3 karakter
kaydediyor

0

C, 201 bayt

char c[256],*p,d;main(int a,char **b){for(p=b[1];*p;p++)++c[*p|32]>d&*p>64?d++:0;for(a=(d+4)/5*5;a+1;a--){printf(!a||a%5&&a!=1?"    ":"%3i-",a);for(d=96;++d>0;c[d]?putchar(a?32|c[d]>=a:d):0);puts(p);}}

Giriş komut satırından alınır (ilk argüman). Kod boyutunu daha da azaltmak için X'ler yerine ünlem işareti kullanır. Soldaki sayaç her zaman üç karakter uzunluğundadır.

GCC ve clang ile test edilmiştir.


for(p=b[1];*p;p++)büyük olasılıkla olabilir for(p=b[1]-1;*++p;), main(int a,char **b)muhtemelen golf olabilir m(a,b)char**b;.
Jonathan Frech

Yana a!=1boole olacak, a%5&&a!=1?eşdeğer olmalıdır a%5&a!=1?ya a%5&&~-a.
Jonathan Frech

0

Excel VBA, 316 bayt

Hücreden girdi alan [A1]ve VBE acil durum penceresine çıkan Anonim VBE acil durum pencere işlevi .

For i=1To 26:Cells(2,i)=Len(Replace([Upper(A1)],Chr(i+64),11))-[Len(A1)]:Next:m=-5*Int(-[Max(2:2)]/5):l=Len(m)+1:For i=-m To-1:?Right(Space(l) &IIf(i=-1Xor i Mod 5,"",-i &"-"),l);:For j=1To 26:?IIf(Cells(2,j),IIf(Cells(2, j) >= -i, "X", " "),"");:Next:?:Next:?Spc(l);:For i=1To 26:?IIf(Cells(2,i),Chr(i+96),"");:Next

Ungolfed Sürümü

Public Sub bar_graph()
    For i = 1 To 26
        ''  gather the count of the letter into cells
        Cells(2, i) = Len(Replace([Upper(A1)], Chr(i + 64), 11)) - [Len(A1)]
    Next
    m = -5 * Int(-[Max(2:2)] / 5)   ''  get max bar height
    l = Len(m) + 1                  ''  length of `m` + 1
    For i = -m To -1
        ''  print either a label or free space (y-axis)
        Debug.Print Right(Space(l) & IIf((i = -1) Xor i Mod 5, "", -i & "-"), l);
        For j = 1 To 26
            ''  print 'X' or ' ' IFF the count of the letter is positive
            If Cells(2, j) Then Debug.Print IIf(Cells(2, j) >= -i, "X", " ");
        Next
        Debug.Print                 ''  print a newline
    Next
    Debug.Print Spc(l);             ''  print spaces
    For i = 1 To 26
        ''  print the letters that were used (x-axis)
        Debug.Print IIf(Cells(2, i), Chr(i + 96), "");
    Next
End Sub

0

Perl 5 -n , 198 168 bayt

s/[a-z]/$\<++${$&}?$\=${$&}:0/eg;$\++while$\%5;$;=1+length$\++;printf"%$;s".'%s'x26 .$/,$\%5&&$\-1?"":"$\-",map$$_>=$\?X:$$_&&$",a..z while--$\;say$"x$;,map$$_&&$_,a..z

Çevrimiçi deneyin!


0

Python 3 , 177 bayt

lambda s:[[list(("%d-"%i*(i%5==2>>i)).rjust(len(q)))+["* "[s.count(c)<i]for c in q]for i in range(max(map(s.count,q))+4,0,-1)]+[[" "]*len(q)+q]for q in[sorted(set(s)-{' '})]][0]

Çevrimiçi deneyin!

Bu Python'daki en fazla bayt etkin yaklaşım olmayabilir, ancak bunu gerçekten "tek bir astar" lambda ile çözmek istedim.

Karakter listelerinin bir listesini verir. Tıpkı diğerleri gibi birçok önde gelen yeni hatları ve alanları kötüye kullanır. Son [0]endekslemeyi altbilgiye aktarabilmemiz için sonucu başka bir listeye sarmak kabul edilebilirse, aslında 174 byte'a düşürülebilir .


0

JavaScript (ES8), 200 bayt

Girdiyi karakter dizisi olarak alır. Bir dize döndürür.

s=>(s.sort().join``.replace(/(\w)\1*/g,s=>a.push(s[0]+'X'.repeat(l=s.length,h=h<l?l:h)),h=a=[]),g=y=>y--?(y<2^y%5?'':y+'-').padStart(`${h}_`.length)+a.map(r=>r[y]||' ').join``+`
`+g(y):'')(h+=5-~-h%5)

Çevrimiçi deneyin!

Yorumlananlar

s => (                    // s[] = input array of characters (e.g. ['a','b','a','c','a'])
  s.sort()                // sort it in lexicographical order (--> ['a','a','a','b','c'])
  .join``                 // join it (--> 'aaabc')
  .replace(/(\w)\1*/g,    // for each run s of consecutive identical letters (e.g. 'aaa'):
    s => a.push(          //   push in a[]:
      s[0] +              //     the letter, which will appear on the X-axis
      'X'.repeat(         //     followed by 'X' repeated L times
        L = s.length,     //     where L is the length of the run (--> 'aXXX')
        h = h < L ? L : h //     keep track of h = highest value of L
    )),                   //   initialization:
    h = a = []            //     h = a = empty array (h is coerced to 0)
  ),                      // end of replace() (--> a = ['aXXX','bX','cX'] and h = 3)
  g = y =>                // g = recursive function taking y
    y-- ?                 //   decrement y; if there's still a row to process:
      (                   //     build the label for the Y-axis:
        y < 2 ^ y % 5 ?   //       if y != 1 and (y mod 5 != 0 or y = 0):
          ''              //         use an empty label
        :                 //       else:
          y + '-'         //         use a mark
      ).padStart(         //     pad the label with leading spaces,
        `${h}_`.length    //     using the length of the highest possible value of y
      ) +                 //     (padStart() is defined in ECMAScript 2017, aka ES8)
      a.map(r => r[y]     //     append the row,
                 || ' ')  //     padded with spaces when needed
      .join`` + `\n` +    //     join it and append a linefeed
      g(y)                //     append the result of a recursive call
    :                     //   else:
      ''                  //     stop recursion
)(h += 5 - ~-h % 5)       // call g() with h adjusted to the next multiple of 5 + 1
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.