ฮิสโตแกรมตัวอักษร


33

ให้ประโยคอินพุตประกอบด้วยหนึ่งคำขึ้นไป[a-z]+และเว้นศูนย์หรือมากกว่านั้นให้ส่งเอาต์พุตฮิสโตแกรม ASCII-art (กราฟแท่ง) ของการกระจายตัวอักษรของประโยคอินพุต

ฮิสโตแกรมจะต้องวางในแนวนอนเช่นใช้ปุ่มตัวอักษรที่อยู่ด้านล่างตามลำดับตัวอักษรจากซ้ายไปขวาพร้อมป้าย Y แกน1-และทุก 5 หน่วย แกน Y จะต้องเป็นตัวคูณที่เล็กที่สุดในห้าที่สูงอย่างน้อยเท่ากับแถบที่สูงที่สุดและจะต้องจัดชิดขวา แกน X มีป้ายกำกับพร้อมตัวอักษรอินพุตโดยไม่มีช่องว่างระหว่าง ยกตัวอย่างเช่นการป้อนข้อมูลa bb ddควรจะมีป้ายชื่อabdและไม่ข้ามab d cตัวแท่งเองนั้นสามารถสร้างด้วยตัวอักษร ASCII ที่สอดคล้องกัน - ฉันจะใช้Xที่นี่ในตัวอย่างของฉัน

test example

5-

   X
   X   X
1-XXXXXXXX
  aelmpstx

เนื่องจากมีสามeสองtและหนึ่งใน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
แค่เป็นจี้ แต่นี่ไม่ใช่ฮิสโตแกรมแต่เป็นแผนภูมิแท่ง ยังคงเป็นความท้าทายที่ดี!
caird coinheringaahing

4
วิธีการของ Tuftian คือการทำให้แถบหลุดออกจากตัวละครที่แสดงและไม่มีแถวฉลากแยกต่างหาก
dmckee

2
อักขระฮิสโตแกรมจะต้องสอดคล้องกัน แต่ในแต่ละกรณีหรือภายในแต่ละกรณี?
อดัม

คำตอบ:



7

R , 239 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 การยกของหนักที่นี่ทำให้ตัวละครไม่ซ้ำกันเรียงลำดับพวกเขาและคืนค่าจำนวนของพวกเขา

ทุกสิ่งทุกอย่างเป็นเพียงการทำให้มั่นใจว่าออฟเซ็ตเหมาะสมสำหรับการพิมพ์ซึ่งเป็นผลงาน "ของจริง" ของความท้าทายศิลปะ ASCII

ขอบคุณ@dylnanสำหรับการชี้จุดบกพร่อง

ขอบคุณ@rturnbullสำหรับscanวิธีการลดลง 2 ไบต์



@rtbull ฉันจัดการเพื่อปิดไบต์อีกสองสามหลังจากนั้นขอบคุณ!
จูเซปเป้

6

gnu 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

ลองออนไลน์!


ฉันแน่ใจว่าสิ่งนี้สามารถปรับปรุงได้ แต่สำหรับตอนนี้สิ่งนี้น่าจะดีถ้าพิจารณาจากการพิมพ์ที่ไม่ดีซึ่งคุณไม่มีเลขคณิตหรือการเรียงลำดับ ดังนั้นฉันจึงโกหกว่ามันไม่ดีพอดังนั้นฉันจึงปรับปรุง (เขียนใหม่) อีก 212 ไบต์ด้วยคำแนะนำเกี่ยวกับอัลกอริทึมการเรียงลำดับจากCack quackซึ่งทำให้ฉันมีความคิดที่จะทำให้การแปลงทศนิยมเป็นทศนิยมให้สั้นลงเช่นกัน
คำอธิบายของการทำงานภายใน:

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

การวนซ้ำนี้ทำงานโดยการลดขนาดกลุ่มอักขระแต่ละตัวโดยเพิ่มหนึ่งบรรทัดต่อท้ายบรรทัดต้นฉบับที่เรียงและเพิ่มตัวนับ unary หลังโคลอนที่เหลือจากการเรียงลำดับ มันวนซ้ำจนกว่าจะถึงบรรทัดว่างที่มีจำนวน 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

และในที่สุดตัวแปลงทศนิยมก็ยังคงอยู่:

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

โดยทั่วไปจะต่อท้ายสตริงที่ความรู้เรื่องการแปลงเป็น คุณสามารถ interprete เป็น: space: -> 1 และ 0-> 1-> 2-> 3-> 4-> 5-> 6-> 7-> 8-> 9> I- นิพจน์การแทนที่s/(.)I(.*\1(I?.))|;.*/\3\2/ทำงานคล้ายกับการเรียงลำดับแทนที่อักขระที่อยู่ด้านหน้าฉัน [ (.)I] ด้วยอักขระที่อยู่ถัดจากอักขระจากด้านหน้าของฉันในสตริงการแปลง [ (.*\1(I?.))] และหากไม่มีฉันเหลือมันจะลบ สตริงต่อท้าย [ |;.*] การทดแทน [ /\nI/s/^/ /Mg] เพิ่มการเติมหากจำเป็น

ขอบคุณCows quackสำหรับการลดขนาด 26 ไบต์และอัลกอริทึมการเรียงลำดับที่สั้นลง


ยินดีต้อนรับสู่ PPCG และคำตอบแรกที่ดี!
Kritixi Lithos

คุณสามารถใช้\w(จับคู่อักขระคำ) ในหลาย ๆ ที่เพื่อบันทึกบางไบต์ นอกจากนี้ก็จะกลายเป็น:b ... tb s/\B\w/X/gคุณสามารถลบบรรทัดที่ตามมาs/:/:,/gด้วยการแก้ไขการแทนที่ก่อนหน้านี้ คุณสามารถดูgoo.gl/JvD7Rs (ย่อ TIO ลิงก์ไปยังโปรแกรม sed) เพื่อดูว่าฉันหมายถึงอะไร
Kritixi Lithos

1
คุณสามารถปรับปรุงขั้นตอนวิธีการเรียงลำดับคำแนะนำ: ลองต่อท้ายzyx...cbaอินพุต
Kritixi Lithos

ยอดเยี่ยม unary เพื่อแปลงทศนิยม! ของคุณอย่างน้อย 30 ไบต์สั้นกว่าหนึ่งในเคล็ดลับสำหรับการเล่นกอล์ฟใน sed
Kritixi Lithos

5

Dyalog APL , 109 97 96 95 93 88 ไบต์

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

ลองออนไลน์!

ต้องใช้ ⎕IO←0

วิธีการบันทึกจำนวนไบต์มากเกินไปต้องขอบคุณAdámและCrick นักต้มตุ๋น !


สำหรับบิตสุดท้ายที่คุณสามารถลอง⍵[⍋⍵]~' '(ทุกประเภทและขจัดช่องว่างก่อนที่จะผ่าน)
Kritixi Lithos

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

และ⍵>0×⍵
Kritixi Lithos

ลิงก์ TIO ของคุณมีส่วนหัวที่ไม่จำเป็น
อดัม

2⌷⍴≢⍉สองครั้ง
Adám

5

05AB1E , 58 47 ไบต์

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

ลองออนไลน์!

-11 ไบต์ขอบคุณ @Emigna


บางทีนี่อาจช่วยได้? ไม่มีเวลาผูกพวกเขาเข้าด้วยกัน แต่บางทีพวกเขาอาจให้แรงบันดาลใจ
Emigna

@Emigna ฉันจะดูแตกต่างจากของฉันอย่างแน่นอน :)
Magic Octopus Urn

@Emigna 57 ไบต์หลังจากที่ฉันเย็บมัน ... เพราะฉันไม่ได้พยายามปรับให้เหมาะสมเกินไป ลองออนไลน์!
Magic Octopus Urn

47 ไบต์พร้อมการปรับโครงสร้างและการเพิ่มประสิทธิภาพบางอย่าง
Emigna

ตัวอักษรของคุณไม่สอดคล้องกับ 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 คำนวณค่า histogram ' 'ในทางที่เป็นธรรมตรงไปตรงมาทิ้ง

บรรทัดที่ 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หรือTrueสำหรับ {1, 5, 10, …} และ0หรือFalseหรือแม้แต่จำนวนเต็มลบสำหรับค่าอื่น ๆ ทั้งหมดy)

  • เราจัดชิดขวาของฉลาก (หรือพื้นที่ว่าง) ลงในlen(`-h`)ช่องว่าง: นี่เป็นการประหยัดเนื้อที่ขนาดหนึ่งไบต์len(`h`)+1!

  • จากนั้นเราจะพิมพ์X's และช่องว่างสำหรับแถวนี้ (ถ้าy≥ 1) หรือตัวอักษร (ถ้าy= 0) โดยเรียกใช้คู่คีย์ - ค่าตามdลำดับจากน้อยไปมาก


1
'%d-'%y*(y%5==2>>y)การสร้างขีดความสุขกับ คุณรังเกียจไหมถ้าฉันใช้มันในคำตอบของฉัน?
dylnan

-~-(y%5*~-y)ทำงานเกินไป แต่น่าเสียดายอีกหนึ่งไบต์
dylnan

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

การพิมพ์โปรแกรมแบบเต็มผลลัพธ์ (เป็นลิงก์แบบ monadic ซึ่งจะส่งคืนรายการที่มีอักขระและจำนวนเต็มจาก[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

Ruby , 250 248 234 188 173 157 153 ไบต์

->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*''}

ลองออนไลน์!

ขอบคุณที่:

  • dylnanสำหรับ -16 bytes กับ padding ที่เข้มงวดน้อยกว่า
  • ลินน์สำหรับ -2 ไบต์โดยปัดเศษขึ้นด้วย-x/5*-5
  • Kirill L.สำหรับ -2 ไบต์โดยรับองค์ประกอบอาร์เรย์ที่ไม่ซ้ำกับ|[]

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 ถูกต้อง ฉันซ่อมมัน.
Olivier Grégoire

1
มันไม่มาก แต่คุณสามารถบันทึกได้ 2 ไบต์ --m%5==0สามารถเป็น--m%5<1เพราะคุณยังมีการ&m>0ตรวจสอบ และสามารถm<=d[a]?"x":" " m>d[a]?" ":"x"
Kevin Cruijssen

@KevinCruijssen 2 ไบต์คือ 2 ไบต์! ฉันไม่คิดว่าจะเล่นกอล์ฟได้อีกต่อไปยกเว้นอัลกอริทึมที่ต่างออกไป
Olivier Grégoire

1
อีก 1 ไบต์โดยเปลี่ยน(--m%5<1|m==1)&m>0เป็น--m%5<1|m==1&&m>0
Kevin Cruijssen


1

JavaScript (Node.js) , 262 256 ไบต์

* ขอบคุณ @Shaggy สำหรับการลดขนาด 2 ไบต์

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>" "
Shaggy

3.แทนที่m=0ด้วยi=m=0และมีmap((x,i)=> map(x=>
Shaggy

1

Python 2 , 249 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==1y<2
  • -6 ไบต์ขอบคุณที่ลินน์โดยใช้แทน'%d-'%y*(y%5==2>>y)(`y`+'-')*(not y%5or y<2)

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 ไบต์

รวมถึง 18 ไบต์สำหรับ using System.Linq;

บันทึกแล้ว 6 ไบต์ขอบคุณ @KevinCruijssen

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หลังจาก ints อื่น ๆ รวม -4 ไบต์ คุณจะต้องรวมขนาด 18 ไบต์ด้วยusing System.Linq;..
Kevin Cruijssen

@KevinCruijssen ขอบคุณฉันคิดถึงสิ่งเหล่านี้ และฉันเพิ่ม 18 ไบต์
Ian H.

+1 จากฉัน โอ้และคุณสามารถบันทึก 2 ไบต์มากขึ้นโดยการเปลี่ยนไป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;} ลองออนไลน์ 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){...}
Kevin Cruijssen

@KevinCruijssen นั่นฉลาดจริงๆขอบคุณ!
Ian H.

1

Bash + 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

ขอบคุณ @IanM_Matrix สำหรับการบันทึก 3 ไบต์


cat bสามารถ<bบันทึกได้ 3 ตัวอักษร
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's เพื่อลดขนาดรหัสเพิ่มเติม ตัวนับทางด้านซ้ายมีความยาวสามอักขระเสมอ

ทดสอบกับ GCC และเสียงดังกราว


for(p=b[1];*p;p++)ส่วนใหญ่มีแนวโน้มสามารถfor(p=b[1]-1;*++p;), สามารถอาจจะแข็งแรงเล่นกอล์ฟไปmain(int a,char **b) m(a,b)char**b;
Jonathan Frech

เนื่องจากa!=1จะเป็นบูลีนa%5&&a!=1?ควรจะเทียบเท่าหรือa%5&a!=1? a%5&&~-a
Jonathan Frech

0

Excel VBA ขนาด 316 ไบต์

ฟังก์ชันหน้าต่างแบบไม่ระบุชื่อ VBE ทันทีที่รับอินพุตจากเซลล์[A1]และเอาต์พุตไปยังหน้าต่างทันที 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 แต่ฉันต้องการแก้ปัญหานี้ด้วยแลมบ์ดา "ไลน์เดียวที่แท้จริง"

ส่งออกรายการของรายการตัวละคร การละเมิดช่องทางใหม่และช่องว่างชั้นนำหลายแห่งเหมือนทุกคน อาจลดลงไปอีก 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.