จัดเรียงตำรา


31

จัดเรียงตำรา

โรงเรียนจะเริ่มเร็ว ๆ นี้ (ถ้ายังไม่ได้ดำเนินการ) และถึงเวลาที่จะต้องสั่งหนังสือเรียนของเรา คุณต้องเรียงลำดับหนังสือตามลำดับตัวอักษร แต่ใช้เวลานานเกินไปคุณจึงตัดสินใจเขียนโปรแกรมเพื่อทำมัน

ตัวอย่าง

การป้อนข้อมูล:

 _
| |  _
|F| | |
|o|_|P|
|o|B|P|
| |a|C|
| |r|G|
|_|_|_|

เอาท์พุท:

   _
  | |_
  |F| | 
 _|o|P|
|B|o|P|
|a| |C|
|r| |G|
|_|_|_|

อินพุต

ข้อมูลที่ป้อนจะเป็นชุดหนังสือที่ต้องจัดเรียงตามตัวอักษรใหม่ มันจะมีเพียง: |, _, และ A-Za-zชื่อหนังสือถูกอ่านในแนวตั้งและบนล่าง

คุณอาจเลือกที่จะสมมติว่าอินพุตนั้นถูกเติมด้วยช่องว่างเพื่อให้พอดีกับสี่เหลี่ยม หากคุณเลือกที่จะใส่เบาะด้วยช่องว่างโปรดระบุสิ่งนี้ในคำตอบของคุณ

ความสูงของหนังสือสูงสุดที่โปรแกรมของคุณจะต้องจัดการมีความสูง 5,120 บรรทัดโดยไม่ล้มเหลว

หนังสือจะมีความหนา 1 และหนังสือของพวกเขาจะต้องมีอย่างน้อยหนึ่งเล่มในอินพุต

เอาท์พุต

ผลลัพธ์จะต้องเป็นหนังสือชุดเดียวกันที่จัดเรียงตามลำดับตัวอักษร ความสูงของหนังสือจะต้องอยู่ในระดับเดียวกันและหัวเรื่องจะต้องมีระยะห่างเท่ากันจากด้านบนเมื่อจัดเรียงใหม่

หนังสือควรจัดเรียงตามตัวอักษร หากภาษาของคุณมีฟังก์ชั่นการจัดเรียงคุณสามารถใช้มันได้ มิฉะนั้นคุณสามารถใช้การเรียงลำดับตัวอักษรตามที่อธิบายไว้ที่นี่ที่นี่

ตัวอย่างชื่อหนังสือ

 _
| |
| |
|F|
|o|
|o|
| |
| |
|B|
|a|
|r|
| |
| |
|_|

ชื่อหนังสือนี้คือ:

"Foo  Bar"

ชื่อหนังสือจะเท่านั้นประกอบด้วยตัวอักษรและช่องว่าง

อนุญาตช่องว่างต่อท้าย


การชนะ

นี่คือสั้นที่สุดในหน่วยไบต์


มีการจำกัดความสูงของหนังสือหรือไม่?
The_Basset_Hound

@BassetHound ไม่ขณะนี้ยังไม่มี แต่ไม่จำเป็นต้องกังวลเกี่ยวกับหนังสือที่สนับสนุนสูง 2 ^ 64-1 ฉันจะใส่สูงสุดที่ 5,120 "สูง" เป็นสิ่งที่โปรแกรมของคุณต้องจัดการโดยไม่ล้มเหลว
Downgoat

ดีเยี่ยม
The_Basset_Hound

@ETHproductions ใช่ชื่อหนังสือจะประกอบด้วยตัวอักษรและช่องว่างเท่านั้น
Downgoat

1
แล้วความหนาของหนังสือล่ะ? เสมอ 1 คอลัมน์
coredump

คำตอบ:


5

CJam, 60 ไบต์

qN/:Kz1>2%{_{" _"-}#>}$_{_'_#>,}%2,\*2ew{:e>('|*K,Se[}%.\zN*

ฉันลองตอบคำตอบของ Python ซึ่งคล้ายกับแนวทางของ @ RetoKoradiวิธี

ลองมันออนไลน์ อินพุตควรถูกบุด้วยช่องว่างในรูปแบบสี่เหลี่ยมผืนผ้า


7

Python 3, 231 ไบต์

def f(s):
 *M,L=sorted(["".join(c).strip()for c in zip(*s.split("\n"))][1::2],key=lambda x:x[1:-1].strip()),;l=m=0
 for r in L+[""]:n=len(r);M+="|"*~-max(n,l),r;m=max(n,m);l=n
 for r in zip(*[x.rjust(m)for x in M]):print(*r,sep="")

แฮ็คอย่างรวดเร็ว Zip หนังสือเรียงลำดับ rezip ดูแลคอลัมน์|ในขณะที่เราอยู่ที่มัน

ใส่สตริงหลายบรรทัดที่มีช่องว่างต่อท้ายไปที่สี่เหลี่ยมผืนผ้า เอาต์พุตมีพื้นที่ต่อท้ายหนึ่งบรรทัดในแต่ละบรรทัดเกินความจำเป็น

Ungolfed

def f(s):
  new_cols = []

  # Zip columns, removing the spaces above each book
  # [1::2] is to skip columns of |s, keeping only the books
  books = ["".join(c).strip() for c in zip(*s.split("\n"))][1::2]

  # Sort based on title, [1:-1] to remove the top and bottom _s
  books.sort(key=lambda x:x[1:-1].strip())

  last = 0
  max_height = 0

  for book in (books + [""]):
    height = len(book)

    # Append |s as necessary for the left edge of the current book
    # The +[""] above is for the right edge of the last book
    new_cols.extend(["|"*(max(height, last) - 1), book])

    max_height = max(height, max_height)
    last = height

  # Rezip columns, add back spaces as necessary and print
  for col in zip(*[x.rjust(max_height) for x in new_cols]):
      print("".join(col))

ฉันชอบที่จะเห็นเวอร์ชั่นที่ไม่ดีหากเป็นไปได้โปรด
Pureferret

1
@Pureferret เพิ่มรุ่น ungolfed ที่มีความคิดเห็นไม่กี่
Sp3000

6

ทับทิม (209 204 200 198 ไบต์)

a=n.tr(?|,' ').split$/
i=!p;t=a.map(&:chars).transpose.map(&:join).select{i^=a}.sort_by{|s|s[/[A-Z]/][0]}
x=0;t.map{|t|y=0;u=p;t.chars{|c|u&&a[y][x,3]=?|*3;a[y][x+1]=c;y+=1;u|=c=='_'};x+=2}
a.join$/

transposeฟังก์ชั่นในการแก้ปัญหานี้จำเป็นต้องให้ทุกสายมีความยาวเดียวกันด้วยเหตุนี้การป้อนข้อมูลจะต้องมีเบาะด้วยช่องว่าง

คำอธิบาย

def sort_books(n)
  a = n.tr(?|,' ')  # pre-emptively remove all the '|'.
    .split $/         # and split into an array of lines
                      # ($/ is the INPUT_RECORD_SEPARATOR, typically "\n")
                      # we're going to write our answer into `a` later

  i = !p # i = true; we'll use this as a flip-flop variable
         # Kernel#p returns nil with no args

  # we're now going to get a sorted array of book titles (t)
  t = a.map(&:chars)  # break array into nested array of every character
       .transpose     # and transpose the entire array
       .map(&:join)   # this gives us an array of "horizontal" book titles with dividers

       .select { i ^= a } # select every second line
                          # (i.e. just titles without dividers)
                          # `i` starts off true
                          # `a` is truish (it's our original array)
                          # `^=` is the bitwise xor assignment,
                          #      it will alternate true/false on each execution

       .sort_by { |s| s[/[A-Z]/][0] } # sort by the first alphabetical char

  # use counters for less chars than `each_with_index`
  # x and y are cartesian coordinates in the final array

  x = 0 # start in the left-hand column

  # go through each title
  t.map { |t|
    y = 0 # each book title starts on the top row

    u = p # `u` is "have we reached the book's spine yet?" (or are we above it?)
          # `u` starts off false and we'll set it true when we see the first '_'
          # after which we'll start writing the book's edges

    # go through each character of each title, including leading spaces and '_'s
    # this will "descend" down the array writing each letter of the title
    # along with the "edges"
    t.chars { |c|

      u &&                  # if we're on the spine
        a[y][x,3] = ?|*3;   # write ||| in the next 3 columns
                            # the middle | will be overwriten by the title char

      a[y][x+1] = c; # write the current title char into the second (x+1) column

      y+=1; # descend to the next row

      u |= c == '_' # Since '_' is the top and bottom of the book,
                    # this toggles whether we're on the spine
    }
    x += 2 # jump to the right 2 columns and start on the next title
  }
  a.join $/ # hopefully this is obvious
end

ซึ่งrubyรุ่นที่ถูกต้อง? ด้วย 2.1.2 สำหรับการป้อนตัวอย่างจากคำถามที่ฉันได้รับ "` transpose ': ขนาดองค์ประกอบแตกต่างกัน (6 ควรเป็น 2) (IndexError) "
จัดการ

@ การทำงานขอโทษฉันควรได้ระบุว่าฟังก์ชั่นต้องมีเบาะสี่เหลี่ยมโดยช่องว่าง ฉันจะอัปเดตคำตอบ
Daniel Fone

1
โอ้ จริง ขออภัยไม่วิเคราะห์อย่างละเอียดถี่ถ้วน ทั้งในวันนี้ดังนั้นฉันพูดถึง→gsub(?|,' ') tr(?|,' ')
จัดการ

5

Python 2 - 399 ไบต์

คาดว่าอินพุตจะไม่มีการขึ้นบรรทัดใหม่

import sys;a=str.strip;L=list(sys.stdin);b=len(L[-1])/2;s=['']*b
for l in L:
    i=0
    for c in l[1:-1:2]:s[i]+=c;i+=1
s=sorted([a(a(x),'_')for x in s],key=a);y=map(len,s);m=[y[0]]+[max(y[i],y[i+1])for i in range(b-1)]
for i in range(max(y)+1):
    h=max(y)-i;l='';j=0
    for x in s:l+='|'if h<m[j]else' ';l+='_' if h==len(x)else' 'if h>len(x)else x[-h-1];j+=1
    print l+('|'if h<y[-1]else' ')
print'|_'*b+'|'

5

CJam, 75 66 65 ไบต์

qN/z(;2%{_{" _"#W=}#>}$es:P;_W>+{_'_#_Pe<)S*2$,'|*.e<@@:P;}%);zN*

สิ่งนี้คาดว่าอินพุตจะถูกเติมด้วยช่องว่างเพื่อสร้างสี่เหลี่ยมผืนผ้า

ลองออนไลน์

ขอขอบคุณ @ Sp3000 และ @Dennis สำหรับคำแนะนำเกี่ยวกับการตัดแต่งสตริงในการแชท $ผู้ปฏิบัติงานสามารถบล็อกเป็นอาร์กิวเมนต์ได้

ฉันยังไม่พอใจกับลูปที่สองอย่างสิ้นเชิง แต่หลังจากลองใช้ตัวเลือกอื่น ๆ สองสามตัวโดยไม่ประสบความสำเร็จฉันก็เหนื่อย

คำอธิบาย:

qN/     Read input and split at newlines.
z       Transpose to turn columns into lines.
(;      Drop first line...
2%      ... and every second line after that, to keep only lines with titles.
{       Start block that maps lines for sort.
  _       Copy.
  {       Start block for matching first title letter.
    " _"#   Search for character in " _".
    W=      True if not found.
  }#      End match block. This gets position of first character not in " _".
  >       Trim leading spaces and '_.
}$      End of sort block. Lines are now sorted alphabetically by title.
es:P;   Store large number in P. P holds previous position of '_ in following loop.
_W>+    Repeat last title line, so that final separator line is generated.
{       Loop over title lines.
  _'_#    Find position of '_.
  _       Copy position. Will store it in P after the minimum has been determined.
  P       Get position of '_ in previous line.
  e<)     Take the smaller of the two '_ positions, and decrement.
  S*      Generate leading spaces from the count.
  2$,     Get length of title line.
  '|*     Generate full line length sequence of '|.
  .e<     Overlap spaces with '| to give the final separator.
  @@      Get '_ position to top, and stack in order for next loop iteration.
  :P;     Store '_ position in P.
}%      End of loop over lines.
);      Remove last line, which was a repeat.
z       Transpose to turn lines into columns again.
N*      Join with newline characters.

1

สกาล่า359 341 ไบต์

คาดว่าทุกบรรทัดจะมีความยาวเท่ากัน (เช่นบุด้วยช่องว่าง)

(s:String)=>{def f(s:String)=(" "/:s)((r,c)=>if(r.last=='|'||c=='_')r+"|"else r+" ").init;val h=s.lines.toSeq.transpose.collect{case s if s.exists(_.isLetter)=>s.mkString}.sortBy(_.filter(!_.isWhitespace));((Seq(f(h(0)))/:h.sliding(2))((s,l)=>s:+l(0):+f(l.minBy(_.indexOf('_')))):+h.last:+f(h.last)).transpose.map(_.mkString).mkString("\n")}

ungolfed & แสดงความคิดเห็น:

//anonymous method that takes the books ascii-art string
(s: String) => {

  //method to convert the middle to a border
  def f(s: String) =
    //fold (starting from non empty string since we use `.last`)
    (" "/:s)((r,c) =>
      if(r.last=='|'||c=='_')r+"|"
      else r+" "
    ).init.tail

  //h is a sequence of strings of the middle of the books
  val h =
    //transpose lines of input string, and take only the lines the contains letters (middle of the books)
    s.lines.toSeq.transpose.collect{
      case s if s.exists(_.isLetter) =>
        s.mkString
    }.sortBy(_.filter(!_.isWhitespace)) //sort the books by title (actually by "_$title" since we filter out just whitspaces)

  //fold over pairs of books and add the last manually
  (
    (Seq(f(h(0)))/:h.sliding(2))((s,l) =>
      s :+ l(0) :+ f(l.minBy(_.indexOf('_'))) //convert higher book to border and append to folded accumulator
    ) :+ h.last :+ f(h.last) //add last book manually
  ).transpose.map(_.mkString).mkString("\n") //transpose back and construct the output string
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.