Sắp xếp sách giáo khoa


31

Sắp xếp sách giáo khoa

Trường học sẽ bắt đầu sớm (nếu chưa có) và vì vậy đây là lúc để có được sách giáo khoa của chúng tôi theo thứ tự. Bạn cần sắp xếp các cuốn sách của bạn theo thứ tự bảng chữ cái nhưng mất quá nhiều thời gian để bạn quyết định viết một chương trình để làm điều đó.

Ví dụ

Đầu vào:

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

Đầu ra:

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

Đầu vào

Đầu vào sẽ là một bộ sách cần được sắp xếp lại theo thứ tự abc. Nó sẽ chứa chỉ: |, _, , và A-Za-z. Tiêu đề của các cuốn sách được đọc theo chiều dọc, từ trên xuống dưới.

Bạn có thể chọn giả sử đầu vào được đệm bằng khoảng trắng để vừa với hình chữ nhật. Nếu bạn chọn để có đầu vào của bạn được đệm bằng khoảng trắng, vui lòng chỉ định điều này trong câu trả lời của bạn.

Chiều cao sách tối đa mà chương trình của bạn sẽ cần xử lý là 5.120 dòng mà không bị lỗi.

Các cuốn sách sẽ luôn dày 1 và chúng sẽ luôn có ít nhất một cuốn sách trong đầu vào

Đầu ra

Đầu ra sẽ cần phải là cùng một bộ sách được sắp xếp theo thứ tự bảng chữ cái. Chiều cao của các cuốn sách phải giữ nguyên và tiêu đề phải có cùng khoảng cách từ đầu khi sắp xếp lại.

Sách nên được sắp xếp theo thứ tự abc. Nếu ngôn ngữ của bạn có chức năng sắp xếp, bạn có thể sử dụng chức năng đó. Nếu không, bạn có thể sử dụng sắp xếp theo thứ tự chữ cái như được mô tả ở đây .

Ví dụ về tiêu đề sách

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

Tiêu đề sách này là:

"Foo  Bar"

Tên sách sẽ chỉ chứa các chữ cái và dấu cách.

Khoảng trắng Trailing được cho phép


Chiến thắng

Đây là để mã ngắn nhất tính theo byte thắng.


Có giới hạn về "chiều cao" của sách không?
The_Basset_Hound

@BassetHound Không, hiện tại không có nhưng không cần phải lo lắng về việc hỗ trợ sách cao 2 ^ 64-1. Tôi sẽ đặt tối đa ở mức 5.120 "cao" là những gì chương trình của bạn cần xử lý mà không thất bại
Downgoat

Được rồi, tuyệt vời.
The_Basset_Hound

@ETHproductions Có, tên sách sẽ chỉ chứa các chữ cái và dấu cách
Downgoat

1
Độ dày của sách thì sao? Luôn 1 cột?
coredump

Câu trả lời:



7

Python 3, 231 byte

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

Chỉ cần một bản hack nhanh chóng. Zip các cuốn sách, sắp xếp, nén lại, chăm sóc các cột |trong khi chúng ta đang ở đó.

Nhập một chuỗi nhiều dòng, được đệm với các khoảng trắng ở cuối hình chữ nhật. Đầu ra có thêm một khoảng trống trên mỗi dòng hơn mức cần thiết.

Ung dung

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

Tôi rất thích xem một phiên bản không có bản quyền, nếu có thể, xin vui lòng.
Pureferret

1
@Pureferret Đã thêm một phiên bản chưa được chỉnh sửa với một vài bình luận
Sp3000

6

Ruby (209 204 200 198 byte)

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$/

Các transposechức năng trong giải pháp này đòi hỏi tất cả các dòng là cùng độ dài, do đó các đầu vào cần được đệm bằng khoảng trắng.

Giải trình

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

rubyPhiên bản nào là bắt buộc? Với 2.1.2 cho đầu vào mẫu từ câu hỏi tôi nhận được 'transpose': kích thước phần tử khác nhau (6 nên là 2) (IndexError).
manatwork

@manatwork xin lỗi, tôi đã xác định rằng hàm yêu cầu một hình chữ nhật được đệm bởi khoảng trắng. Tôi sẽ cập nhật câu trả lời.
Daniel Fone

1
Oh. Thật. Xin lỗi, không phân tích nó một cách triệt để. Không phải hôm nay, vì vậy tôi chỉ đề cập đến gsub(?|,' ')tr(?|,' ').
manatwork

5

Python 2 - 399 byte

Dự kiến ​​đầu vào sẽ không có một dòng mới.

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 byte

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

Điều này hy vọng đầu vào được đệm với khoảng trắng để tạo thành một hình chữ nhật.

Dùng thử trực tuyến

Cảm ơn @ Sp3000 và @Dennis về các đề xuất về cắt xén chuỗi khi trò chuyện, cũng như gợi ý cho tôi rằng $nhà điều hành có thể lấy một khối làm đối số.

Tôi vẫn chưa hoàn toàn hài lòng với vòng lặp thứ hai. Nhưng sau khi thử một vài lựa chọn khác mà không thành công hơn, tôi cảm thấy mệt mỏi.

Giải trình:

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

Scala 359 341 byte

hy vọng tất cả các dòng có cùng độ dài (nghĩa là được đệm bằng khoảng trắng)

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

vô ý và nhận xét:

//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
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.