アルファベットヒストグラム


33

1つ以上の単語[a-z]+と0個以上のスペースで構成される入力文が与えられた場合、入力文の文字分布のASCIIアートヒストグラム(棒グラフ)を出力します。

ヒストグラムは水平に配置する必要があります。つまり、左から右へアルファベット順にアルファベットキーを使用し、Y軸にラベルを付け1-、5単位ごとに配置します。Y軸は、少なくとも最も高いバーと同じ高さの最小の5の倍数でなければならず、右揃えでなければなりません。X軸には入力文字のラベルが付けられ、間に隙間はありません。例えば、入力は、a bb ddラベル持つべきabdではなくab d、スキップをc。バー自体は、一貫性のあるASCII文字で作成できますX。ここでは、例で使用します。

test example

5-

   X
   X   X
1-XXXXXXXX
  aelmpstx

の3つe、2つt、および1つがありalmsxます。

その他の例:

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

I / Oとルール

  • 入力は任意の合理的な形式で任意の便利な方法で取得できます。これは、コードでより意味のある場合は、すべて大文字で入力できることも意味します。
  • 文字が適切に整列している場合、先頭または末尾の改行またはその他の空白はオプションです。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • コンソールへの出力、文字列のリストとして返される、単一の文字列として返されるなど。
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

3
これはヒストグラムではなく棒グラフになると思います。これは数値データではなくカテゴリカルデータであるためです。
ジュゼッペ

入力は空でないことが保証されていますか?
dzaima

2
単なるペンダントですが、これはヒストグラムではなく、棒グラフです。それでもいい挑戦です!
コイナーリンガーアーイング

4
Tuftianのアプローチは、表示される文字からバーを作成し、個別のラベル行を持たないようにすることです。
dmckee

2
ヒストグラムの文字は一貫している必要がありますが、ケース間または各ケース内でですか?
アダム

回答:



7

R239 230バイト

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

オンラインでお試しください!

table ここで面倒な作業を行い、キャラクターを一意化し、ソートし、カウントを返します。

それ以外はすべて、オフセットが印刷に適していることを保証するだけです。これは、アスキーアートの課題の「実際の」作業です。

バグを指摘してくれた@dylnanに感謝します。

アプローチをしてくれた@rturnbullに感謝しscanます。2バイトを落とします。



@rturnbullその後、さらに数バイトをノックオフすることができました、ありがとう!
ジュゼッペ

6

ヌー sedの -r、516個の 490 278 249 + 1バイト

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

オンラインでお試しください!


これは改善できると確信していますが、現時点では、ネイティブの算術や並べ替えがないsedで作られていることを考えると、これは良いはずです。だから私は嘘をついた、これは十分ではなかったので、Couss quackのソートアルゴリズムに関するヒントで、それをさらに212バイト改善(書き換え)しました。これは単項から小数への変換も短くするアイデアを与えました。
内部の仕組みの説明:

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

このループは、各文字グループのサイズを1つずつ減らし、ソートされた元の行を追加し、ソートで残ったコロンの後に単項カウンターを増分することで機能します。5 * n + 1の数の空の行に達するまでループします(最後の行が最終的に空白になるため)。ループ後のパターンスペースは次のようになります。

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

次に、フォーマットが続きます。

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

最後に、単項から10進数へのコンバータは残ります。

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

基本的に、変換の知識がある場所に文字列を追加します。:space:-> 1および0-> 1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> 9-> I0として解釈できます。置換式s/(.)I(.*\1(I?.))|;.*/\3\2/は、ソート(.)I文字列と同様に機能し、Iの[ ]の前の文字を変換文字列[のIの前の文字の隣の文字に置き換えます(.*\1(I?.))と同様 ] Iが残っていない場合は削除します。追加された文字列[ |;.*]。置換[ /\nI/s/^/ /Mg]は、必要に応じてパディングを追加します。

26バイトサイズを縮小し、ソートアルゴリズムを短縮したCowsのおかげです。


PPCGへようこそ。最初の回答はいいですね。
Kritixiリソス

\wいくつかのバイトを節約するために、多くの場所で(単語の文字に一致する)を使用できます。また、:b ... tb単純になりs/\B\w/X/gます。s/:/:,/g以前の置換を変更することにより、後続の行を削除できます。goo.gl/JvD7Rs(sedプログラムへの短縮されたTIOリンク)を見て、意味を確認できます。
KritixiのLithos

1
ソートアルゴリズムを改善することができzyx...cbaます。ヒント:入力に追加してみてください。
Kritixi Lithos

素晴らしい単項から10進数へのコンバーター!あなたは、少なくとも30の内の1つのより短いバイトであるのsedでゴルフをするためのヒント
KritixiのLithos

5

Dyalog APL109 97 96 95 93 88バイト

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

オンラインでお試しください!

が必要です ⎕IO←0

道はあまりにも多くのバイトがのおかげで保存されたアダムいんちき牛を


最後のビットのために、あなたは試すことができます⍵[⍋⍵]~' '(通過前にソートや削除しスペースを
KritixiのLithos

'X'/⍨≢∊⍕¨×
アダム

および⍵>0×⍵
Kritixi Lithos

TIOリンクに不要なヘッダーがあります。
アダム

2⌷⍴≢⍉2回
アダム

5

05AB1E58 47バイト

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

オンラインでお試しください!

@Emignaのおかげで-11バイト


たぶんこれが役立つでしょうか?それらを結びつける時間はありませんが、彼らはいくつかのインスピレーションを与えることができます。
エミグナ

@Emigna私は、私のものとは間違いなく異なる外観を持っています:)。
魔法のタコ

@Emignaをステッチしてから57バイト...最適化するのに一生懸命努力しなかったので。オンラインでお試しください!
魔法のタコ

再編成と最適化を伴う47バイト
エミグナ

特定の入力では、文字がXに一致しません。tio.run/##AVUAqv8wNWFiMWX//...
mbomb007

3

Python 2、192バイト

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

オンラインでお試しください!

説明

行2は、ヒストグラム値をかなり単純な方法で計算し、破棄してい' 'ます。

3行目では、計算のトリックを使用してceil(x/5)-(-x/5)ます。最大周波数を次の5の倍数に切り上げ-x/5*-5ます。これがありますh

行4は、各行を出力する、h下から下までカウントするループ0です。

  • y%5==2>>yラベルを印刷する場合。これは、y∈{1、5、10、15、20、…}の場合です

    (この式はもっと短くなる可能性があります。{1、5、10、…}に対して1またはTrue0またはFalse、または他のすべての値に対して負の整数さえ必要ですy。)

  • ラベル(または空のスペース)をlen(`-h`)スペースに右揃えします。これは1バイトの節約len(`h`)+1です!

  • 次に、キーと値のペアを昇順で実行して、Xこの行(およびy≥1)の文字とスペースを印刷します。yd


1
を使用した素敵なティックの作成'%d-'%y*(y%5==2>>y)。私の答えでそれを使用しても構いませんか?
ディルナン

-~-(y%5*~-y)動作しますが、残念ながら1バイト長くなります。
ディルナン

2

、62バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔E²⁷⟦⟧η

27個のリストのリストを作成します。

Fθ⊞§η⌕βιι

小文字のアルファベットの位置に対応するリストに各入力文字をプッシュします。小文字以外の文字は、27番目のリストにプッシュされます。

≔⊟ηθ

リストの27番目の要素を破棄します。

≦Lη

リストのすべての要素の長さを取得します。

P⭆β⎇§ηκιω

ゼロ以外のリスト要素に対応する小文字を印刷します。

↑↑Φηι

ゼロ以外のリスト要素を上向きに印刷します。これは整数の配列であるため、各整数は(現在は垂直の)行として、それぞれ個別の列に印刷されます。

F÷⁺⁹⌈η⁵«

Y軸の目盛りの数を計算し、ループします。

≔∨×⁵ι¹ι

次の目盛りの位置を計算します。

J±¹±ι

次の目盛りにジャンプします。

←⮌⁺ι-

目盛りを逆にして、前後に印刷し、効果的に右揃えにします。


2

ゼリー、48 バイト

横断するなんて地雷原だ!

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

結果を出力するフルプログラム(モナドリンクとして、からの文字と整数を含むリストを返します[0,9]

オンラインでお試しください!またはテストスイートを見る

どうやって?

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

Java(JDK 10)、296バイト

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

オンラインでお試しください!

クレジット


@aoemica正しい。それを私が直した。
オリビエグレゴワール

1
それほど多くはありませんが、2バイト節約できます。あなたにもチェック--m%5==0があるので--m%5<1、することができます&m>0。とm<=d[a]?"x":" "することができますm>d[a]?" ":"x"
ケビンCruijssen

@KevinCruijssen 2バイトは2バイトです!別のアルゴリズムを除いて、ゴルフにはこれ以上はないと思います。
オリビエグレゴワール

1
に変更(--m%5<1|m==1)&m>0してさらに1バイト--m%5<1|m==1&&m>0
ケビンクルーッセン

1

Pyth、65バイト

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

ここで試してみてください

説明

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バイト

* 2バイト削減してくれた@Shaggyに感謝

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`
`

オンラインでお試しください!


電話で簡単に確認できるいくつかの節約:1.入力を個々の文字の配列として2.取得x!=" "し、に置き換えx>" "ます。
シャギー

3.交換するm=0i=m=0してmap((x,i)=>map(x=>
シャギー

1

Pythonの2249 224 219 215 205 197 187 188 182 176バイト

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]

オンラインでお試しください!

行を表す文字のリストのリストを返します。

  • 多くの余分な空白を含めることで、いくつかのバイトを節約しました。
  • 不要だった map(list,yticks)そこにでした。
  • いくつかのバイトを節約するためにスペースの埋め込みを変更しました。
  • 私はソートしていると思ったが、そうではなかった:+2バイト。しかし、同時に独立して保存しました。y==1と取り換えるy<2
  • を使用して、Lynnに感謝'%d-'%y*(y%5==2>>y)代わりに(`y`+'-')*(not y%5or y<2)

わずかに未使用:

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コア)344 340 338の+ 18のバイト

の18バイトを含む using System.Linq;

@KevinCruijssenのおかげで6バイト節約されました。

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

オンラインでお試しください!


j< m;削除できるスペースがあります。そしてint i=0,jように配置することができ,i=0,j、合計で-4バイトのための他のint後。あなたは18のバイトを含む必要があるでしょうusing System.Linq;が...
ケビンCruijssen

@KevinCruijssenありがとう、私はこれらを逃しました。そして、18バイトを追加しました。
イアンH.

私から+1。ああ、に変更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;}することでさらに2バイト節約できます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){...}オンラインでお試しください。
ケビンクルーッセン

@KevinCruijssenそれは本当に賢い、ありがとう!
イアンH.

1

バッシュ + coreutilsの、332 324 323 318 312の 302 298 296 293 291バイト

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

オンラインでお試しください!

注釈付き:

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バイトを節約してくれた@IanM_Matrixに感謝します。


cat b<b3文字を保存できます
-IanM_Matrix1

0

C、201バイト

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

入力はコマンドラインから取得されます(最初の引数)。Xの代わりに感嘆符を使用して、コードサイズをさらに削減します。左側のカウンターは常に3文字です。

GCCおよびclangでテスト済み。


for(p=b[1];*p;p++)おそらくすることができますfor(p=b[1]-1;*++p;)main(int a,char **b)おそらくゴルフをすることができましたm(a,b)char**b;
ジョナサンフレッチ

以来a!=1ブール値になります、a%5&&a!=1?と同等であるべきa%5&a!=1?a%5&&~-a
ジョナサンフレッチ

0

Excel VBA、316バイト

セルから入力を受け取り[A1]、VBEイミディエイトウィンドウに出力する匿名VBEイミディエイトウィンドウ関数。

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

非ゴルフバージョン

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

Python 3、177バイト

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]

オンラインでお試しください!

これはPythonで最もバイト効率の良いアプローチではないかもしれませんが、「真の1ライナー」ラムダでこれを解決したかったのです。

文字リストのリストを出力します。他の皆と同じように、複数の主要な改行とスペースを乱用します。結果を別のリストにラップすることが許容される場合、実際にはさらに174バイトに削減され、最終[0]インデックスをフッターに転送できます。


0

JavaScript(ES8)、200バイト

入力を文字の配列として受け取ります。文字列を返します。

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)

オンラインでお試しください!

コメント済み

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.