Girinti Tabanlı Sıralama


35

Her harfin 0 veya daha fazla boşluk () karakterinden önce geldiği sıralı harfli dizgelerin (az XOR AZ) sıralı bir listesi göz önüne alındığında, aynı listeyi ancak her girinti düzeyinde sıralanmış dizeler çıkar. Farklı ebeveynlerin altındaki girinti derinlikleri, sıralama amaçları için ayrı listeler olarak sayılır.

Örnek

Girişiniz:

bdellium
  fox
  hound
  alien
aisle
  wasabi
    elf
    alien
  horseradish
    xeno
irk
wren
tsunami
djinn
      zebra

çıktınız olmalı

aisle
  horseradish
    xeno
  wasabi
    alien
    elf
bdellium
  alien
  fox
  hound
djinn
      zebra
irk
tsunami
wren

İsterseniz, bir dizin listesi gibi düşünün ve her bir dizindeki adları sıralamanız gerekir.

Önemsiz ayrıntılar

  • Bir öğe herhangi bir sayıda boşlukla girintili olabilir. Önceki öğeyle aynı sayıda boşlukla girilirse, önceki öğeyle aynı sıralama hiyerarşisine aittir. Daha fazla boşluk ile girintili ise, yeni bir alt hiyerarşinin başlangıcıdır.
  • Bir çizgi, üstündeki çizgiden daha az boşlukla girintili ise, üstündeki en yakın alt gruba, ondan önce aynı # ya da daha az boşlukla bağlanır (yukarıdaki örnekteki yaban turpu gibi, yukarıdaki wasabi grubuna bağlanır; wasabi, yaban turpudan daha fazla alana sahip olmayan ilk öğedir)
  • Çıktınızdaki her giriş öğesinin girinti düzeyini korumalısınız
  • Çıktıdaki sekmelere izin verilmedi
  • Girişin ilk satırı hiçbir zaman girintili olmayacak
  • Programınız, büyük ve küçük harflerden en az birini işlemelidir; ikisini birden halletmek zorunda değildir.

puanlama

Bu bir , yani en az bayt kullanan cevap kazanır.


7
Güzel meydan okuma!
AdAm,

1
BTW, bir dahaki sefere, ana siteye göndermeden önce sorunları çözmek için Sandbox'ı kullanmayı düşünün .
Adám,

8
@ Adám Hayır, özyinelemeli dize ayrıştırma mantığı gerekli bu istemi yazmamın sebebidir.
Techrocket9

2
Giriş ise ['a','..b', '.c', '..d'], çıktı ne olmalıdır? ['a','..b', '.c', '..d']ya ['a','.c','..b', '..d']da başka bir şey? ( '.'Görsel netlik için boşluk yerine kullanıyorum ).
Chas Brown

2
@streetster dizeleri (az XOR AZ)
21'de

Yanıtlar:



14

Python 2 , 117 bayt

lambda S:[s[-1]for s in sorted(reduce(lambda t,s:t+[[v for v in t[-1]if v.count(' ')<s.count(' ')]+[s]],S,[[]]))[1:]]

Çevrimiçi deneyin!

Dizelerin listesini girdi olarak alır; ve gerektiği gibi sıralanan dizelerin bir listesini çıkarır.

Buradaki fikir, her bir elemanı bir liste olarak "mutlak yolu" içeren bir listeye dönüştürmek; ve sonra Python'un sıralama işlemesini sağlayın. Örneğin eğer giriş:

[
 'a',
 ' c',
 '  d',
 ' b'
]

Daha sonra reduce(), bir listeye dönüştük:

[
 ['a'],
 ['a',' c'],
 ['a',' c', '  d'],
 ['a',' b']
]

hangi sıralanır:

[
 ['a'],
 ['a',' b']
 ['a',' c'],
 ['a',' c', '  d'],
]

ve sonra almak için listeler listesindeki her listenin son öğesini çıkarır:

[
 'a',
 ' b'
 ' c',
 '  d',
]

Vay canına vermek üzereydim çözüm 183 bayt oldu ... lol emmek
Don Bin

4
@Rushabh Mehta: İlk denemem 205 bayt civarındaydı ... sonra kesildi! :)
Chas Brown

7

APL (Dyalog Unicode) , 31 bayt SBCS

Anonim önek lambda, dizelerin listesini alır ve döndürür.

{⍵[⍋{1=≢⍵:⍺⋄⍵}⍀↑' '(,⊂⍨⊣=,)¨⍵]}

Çevrimiçi deneyin!

{} "Dfn"; tartışma

⍵[] Argümanı aşağıdaki endekslerle indeksleyin:

  ' '()¨⍵ Her argümana sol argüman olarak boşluk bırakarak aşağıdaki taksit işlevini uygulayın:

   , alanı dize ile birleştirmek

   ⊣= Boşluğun her karaktere eşit olduğu yeri gösteren Boole listesi

   ,⊂⍨ boşluk ve dizgenin birleşimini bölümlemek için kullanın (doğru olan bölüme başlayın)

   dizelerin listelerini dizelerin matrisine karıştırın

  {}⍀ Bu "dfn" ile dikey kümülatif azalma; ve üst ve alt kısımlar:

   ≢⍵ alt dizenin uzunluğu

   1= bu 1'e eşit mi? (yani orada tek boşluktan başka bir şey yok mu?)

   :⍺ öyleyse, üst argümanı döndür

   ⋄⍵ Aksi takdirde, alt argümanı döndür

   notlandırma (bunu sıralayacak endeksleri bulun)


7

Retina , 47 bayt

+-1m`(?<=^\2(\S+).*?¶( *)) 
$1 
O$`
$L$&
\S+ 
 

Çevrimiçi deneyin! Not: Birkaç satırın arkada boşlukları vardır. Açıklama:

+-1m`(?<=^\2(\S+).*?¶( *)) 
$1 

İlk adım, her sözcüğü aynı girintideki izleyen satırlara eklemektir. Örneğin olan hatlar aisle, wasabive elfelde edilen çizgiler aisle, aisle wasabive aisle wasabi elf. Bu regex'i deneme yanılma yoluyla keşfettim;

O$`
$L$&

Artık satırları büyük / küçük harf duyarlı olarak sıralayabiliriz.

\S+ 
 

Girilen tüm kelimeleri silin.


4

Perl 6 , 120 83 81 63 54 37 47 42 bayt

Nwellnhof sayesinde -5 bayt

{my@a;.sort:{@a[+.comb(' ')..*+1]=$_;~@a}}

Çevrimiçi deneyin!

Bu Chas Brown'ın yöntemini kullanır . Satır listesini alan ve satır listesini döndüren adsız bir kod bloğu.

Açıklama:

{                                        }  # Anonymous code block
 my@a;  # Declare a local list
      .sort # Sort the given list of lines
           :{                           }  # By converting each line to:
             @a[+.comb(' ')..*+1]=$_;      # Set the element at that indentation level onwards to that line
                                     ~@a   # And return the list coerced to a string

@nwellnhof Buna dikkat çektiğiniz için teşekkürler. Sanırım en son sürümde düzelttim
Jo King

@nwellnhof Ah, önceki bir yinelemede kısaydı. Baytlar için teşekkürler, ama biraz değiştirmek zorunda kaldım
Jo King

Ah, doğru. Aslında, {my@a;.sort:{@a[+.comb(' ')...*>@a]=$_;~@a}}daha yüksek girinti seviyelerini desteklemek için benzeri bir şey gereklidir.
nwellnhof

3

Temiz , 112 101 bayt

import StdEnv
f=flatten
?e=[0\\' '<-e]
$[h:t]#(a,b)=span(\u= ?u> ?h)t
=sort[[h:f($a)]: $b]
$e=[]

f o$

Çevrimiçi deneyin!

Doğru çıktı biçimine :: [[Char]] -> [[Char]]saran isimsiz işlev $ :: [[Char]] -> [[[Char]]]. $dizeleri "daha fazla boşluk" ve "daha sonra her şey" olarak gruplandırır, her bir gruba yeniden odaklanır ve birleşik olduklarında sıralar. Her adımda, sıralanan liste şuna benzer:

[[head-of-group-1,child-1,child-2..],[head-of-group-2,child-1,child-2..]..]

127 bayt temiz

import StdEnv
$l=[x++y\\z<- ?(map(span((>)'!'))l),(x,y)<-z]
?[h:t]#(a,b)=span(\(u,_)=u>fst h)t
=sort[[h:flatten(?a)]: ?b]
?e=[]

Çevrimiçi deneyin!

$ :: [[Char]] -> [[Char]]Dizeleri (spaces, letters), yardımcı işlev tarafından özyinelemeli olarak sıralanan biçimde tekillere ayıran işlevi tanımlar ? :: [([Char],[Char])] -> [[([Char],[Char])]].

Açıklaması:

$ list                                  // the function $ of the list
    = [                                 // is
        spaces ++ letters               // the spaces joined with the letters
        \\ sublist <- ? (               // from each sublist in the application of ? to
            map (                       // the application of
                span ((>)'!')           // a function separating spaces and letters
            ) list                      // to every element in the list
        )
        , (spaces, letters) <- sublist  // the spaces and letters from the sublist
    ]

? [head: tail]                              // in the function ? of the head and tail of the input
    # (group, others)                       // let the current group and the others equal
        = span (                            // the result of separating until ... is false
            \(u, _) = u >                   // only elements where there are more spaces
                          fst head          // than in the head of the input
        ) tail                              // the tail of the input
    = sort [
        [head                               // prepend the head of the input to
             : flatten (?group)             // the flat application of ? to the first group
                               ]            // and prepend this to
                                : ?others   // the application of ? to the other group(s)
    ]

? empty = [] // match the empty list

1

JavaScript (Node.js) , 114 100 92 88 bayt

x=>x.map(y=>a=a.split(/ */.exec(y)[0]||a)[0]+y,a="_").sort().map(x=>/ *\w+$/.exec(x)[0])

Çevrimiçi deneyin!

Chas Brown'ın Python'una benzer bir yaklaşım, bunun yerine normal ifadeleri kullanıyor.

açıklama

x => x.map(                         // 
 y => a = a.split(                  // Renders the indentation paths
  / */.exec(y)[0]                   //  Checks the indentation level
  || a                              //  If this is the top level, go to root
 )[0] + y,                          //  Appends the child to the parent
 a = "_"                            // At first the cursor is at the root
)                                   // 
.sort()                             // Sorts the indentation paths
.map(                               // 
 x => / *\w+$/.exec(x)[0]           // Extracts only the last level of the path
)                                   //

0

K4 , 51 bayt

Çözüm:

{,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x}

Örnek:

q)k){,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x}("bdellium";"  fox";"  hound";"  alien";"aisle";"  wasabi";"    elf";"    alien";"  horseradish";"    xeno";"irk";"wren";"tsunami";"djinn";"      zebra")
"aisle"
"  horseradish"
"    xeno"
"  wasabi"
"    alien"
"    elf"
"bdellium"
"  alien"
"  fox"
"  hound"
"djinn"
"      zebra"
"irk"
"tsunami"
"wren"

Varsayımlar:

a. Her hiyerarşinin en düşük seviyede başlayacağı, yani elde edemeyeceğiniz:

bdellium
      fox
    hound
    alien

Açıklama:

{,/(1#'r),'.z.s@'1_'r:(w_x)@<x@w:&s=&/s:+/'" "=/:x} / the solution
{                                                 } / lambda function, implicit x
                                           " "=/:x  / " " equal to each right (/:) x
                                        +/'         / sum up each
                                      s:            / save as s
                                    &/              / find the minimum (ie highest level)
                                  s=                / is s equal to the minimum?
                                 &                  / indices where true 
                               w:                   / save as w
                             x@                     / index into x at these indices
                            <                       / return indices to sort ascending
                           @                        / index into
                      (   )                         / do this together
                       w_x                          / cut x at indices w
                    r:                              / save as r
                 1_'                                / drop first from each r
            .z.s@                                   / apply recurse (.z.s)
          ,'                                        / join each both
    (    )                                          / do this together
     1#'r                                           / take first from each r
  ,/                                                / flatten

0

Perl 5, 166 bayt

sub f{my$p=shift;my@r;while(@i){$i[0]=~/\S/;$c=$-[0];if($p<$c){$r[-1].=$_ for f($c)}elsif($p>$c){last}else{push@r,shift@i}}sort@r}push@i,$_ while<>;print sort@{[f 0]}

Ungolfed (tür):

sub f {
    my $p = shift;
    my @r;
    while(@i) {
        $i[0] =~ /\S/;
        $c = $-[0];
        if($p < $c) {
            $r[-1] .= $_ for f($c)
        } elsif ($p > $c) {
            last
        } else {
            push @r, shift @i
        }
    }
    sort @r
}

push @i, $_ while <>;
print sort@{[f 0]}

Oldukça basit bir özyinelemeli uygulama. Boşluk olmayan ilk karakteri ( /\S/) arayarak ve dizini ( $-[0]) alarak girintiyi kontrol ederiz . Ne yazık ki, biz aslında zorunda beyan özyinelemede kullanılan değişkenlerin bir avuç, yoksa örtük küresel olacak ve tekrarlama doğru çalışmayacak.

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.