Ders Kitaplarını Sırala


31

Ders Kitaplarını Sırala

Okul yakında başlıyor (eğer henüz gelmediyse) ve ders kitaplarımızı düzenli hale getirmenin zamanı geldi. Kitaplarınızı alfabetik olarak sıralamanız gerekiyor ama bu çok uzun sürüyor, bu yüzden bunu yapmak için bir program yazmaya karar veriyorsunuz.

Örnekler

Giriş:

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

Çıktı:

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

Giriş

Giriş, alfabetik olarak yeniden düzenlenmesi gereken bir kitap seti olacaktır. Bu içerecektir sadece: |, _, , ve A-Za-z. Kitapların başlıkları dikey olarak yukarıdan aşağıya doğru okunur.

Bir dikdörtgenin sığması için girişin boşlukla doldurulduğunu varsaymayı seçebilirsiniz. Girişinizi boşluk ile doldurmayı tercih ederseniz, lütfen cevabınızı belirtin.

Programınızın kullanması gereken en yüksek kitap yüksekliği, başarısız olmadan 5.120 satır yüksekliğindedir.

Kitaplar her zaman 1 kalınlığında olacak ve girişlerinde her zaman en az bir kitap olacak

Çıktı

Çıktının, alfabetik sıraya göre düzenlenmiş kitapların aynı olması gerekir. Kitapların yüksekliği aynı kalmalı ve başlıklar yeniden düzenlendiğinde üstten aynı boşluk bırakılmalıdır.

Kitaplar alfabetik olarak sıralanmalıdır. Diliniz sıralama fonksiyonunu kullanıyorsa bunu kullanabilirsiniz. Aksi takdirde, burada açıklandığı şekilde alfabetik sıralamayı kullanabilirsiniz .

Kitap Başlığı Örnekleri

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

Bu kitapların başlığı:

"Foo  Bar"

Kitap başlıkları sadece harf ve boşluk içerecektir.

İzleyen boşlukta izin var


Kazanan

Bu yani bayt cinsinden en kısa kod kazanır.


Kitapların "yüksekliği" için bir sınır var mı?
The_Basset_Hound

@BassetHound Hayır, şu anda 2 ^ 64-1 boyunda kitapları destekleme konusunda endişelenmenize gerek yok. Maksimum olarak 5.120 "boyunda" koyacağım, programınızın başarısız olmadan başa
çıkması

Tamam, harika.
The_Basset_Hound

@ETHproductions Evet, kitap başlıkları sadece harfler ve boşluklar içerecektir
Downgoat

1
Peki ya kitapların kalınlığı? Her zaman 1 sütun?
coredump

Yanıtlar:



7

Python 3, 231 bayt

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

Sadece hızlı bir kesmek. Kitapları sıkıştır, sırala, rezip, |biz varken sütunlarına dikkat et.

Dikdörtgene giden boşluklarla doldurulmuş çok satırlı bir dize girin. Çıktı, her satırda gereğinden fazla bir boşluk içeriyor.

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

Mümkünse, lütfen ungolfed versiyonunu görmek isterim.
Pureferret

1
@Pureferret Birkaç yorum yaparak ungolfed bir sürüm eklendi
Sp3000

6

Yakut (209 204 200 198 bayt)

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

transposeBu çözelti içinde işlev tüm hatlar dolayısıyla giriş boşluk ile takviye edilmesi gerekmektedir, aynı uzunlukta olmasını gerektirir.

açıklama

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

Hangi rubyversiyon gerekli? Sorudan numune girişi için 2.1.2 ile “` transpose ”alıyorum: eleman boyutu farklı (6 olmalı 2) (IndexError)”.
Manatwork

@ manatwork üzgünüm, fonksiyonun boşlukla doldurulmuş bir dikdörtgen gerektirdiğini belirtmeliydim. Cevabı güncelleyeceğim.
Daniel Fone

1
Ah. Aslında. Üzgünüz, ayrıntılı olarak analiz etmedim. Bugün de değil, bu yüzden sadece gsub(?|,' ')→ bahsediyorum tr(?|,' ').
Manat çalışması

5

Python 2 - 399 bayt

Girişin sonunda yeni bir satırsonu olmamasını bekler.

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 bayt

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

Bu, bir dikdörtgen oluşturmak için boşluklarla doldurulmuş girdiler bekler.

Çevrimiçi deneyin

Sohbet sırasında dize kırpma ile ilgili öneriler için @ Sp3000 ve @Dennis, $operatörün argüman olarak bir blok alabileceği konusunda bana ipucu vererek teşekkür ederim .

İkinci döngüden hala tamamen memnun değilim. Ancak daha iyi başarı elde etmeden birkaç seçenek daha denedikten sonra yoruluyorum.

Açıklama:

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 bayt

tüm çizgilerin aynı uzunlukta olmasını bekler (yani boşluklarla doldurulmuş)

(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 ve yorumladı:

//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
}
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.