インデントベースのソート


35

各文字列の前に0個以上のスペース()文字が含まれる大文字と小文字の文字列(az XOR AZ)の順序付きリストが与えられた場合、同じリストを出力しますが、文字列はインデントの各レベルでソートされます。異なる親の下のインデントの深さは、ソートの目的で個別のリストとしてカウントされます。

入力が次の場合:

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

必要に応じて、ディレクトリリストのように考えてください。各ディレクトリ内の名前を並べ替える必要があります。

ミヌティアエ

  • アイテムは、任意の数のスペースでインデントできます。前のアイテムと同じ数のスペースでインデントされている場合、前のアイテムと同じソート階層に属します。より多くのスペースでインデントされている場合、それは新しいサブ階層の始まりです。
  • 行がその上の行よりも少ないスペースでインデントされている場合、同じ#またはそれより少ないスペースでその上の最も近いサブグループにリンクします(上の例の西洋わさびのように、上のわさびグループにリンクしますわさびは、その上にある西洋わさびよりも多くのスペースがない最初のアイテムです)
  • 出力の各入力項目のインデントレベルを保持する必要があります
  • 出力のタブは許可されません
  • 入力の最初の行はインデントされません
  • プログラムは、すべて大文字とすべて小文字の文字列の少なくとも1つを処理する必要があります。両方を処理する必要はありません。

得点

これはであるため、使用するバイト数が最も少ない答えが優先されます。


7
ナイスチャレンジ!
アダム

1
ところで、次回は、メインサイトに投稿する前に、Sandboxを使用してチャレンジに関する問題を解決することを検討しください。
アダム

8
@Adámいいえ、必要な再帰文字列解析ロジックが、このプロンプトを書いた理由です。
Techrocket9

2
入力がの場合、出力は['a','..b', '.c', '..d']どうなりますか?['a','..b', '.c', '..d']または['a','.c','..b', '..d']他の何か?('.'視覚的にわかりやすくするために、スペースの代わりに使用しています)。
チャスブラウン

2
@streetster 文字列(az XOR AZ)
アダム

回答:



14

Python 2、117バイト

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:]]

オンラインでお試しください!

入力として文字列のリストを受け取ります。必要に応じてソートされた文字列のリストを出力します。

アイデアは、各要素をリストとして「絶対パス」を含むリストに変換することです。そして、Pythonにソートを処理させます。たとえば、入力が次の場合:

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

次にreduce()、を介して、リストのリストに変換します。

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

次のようにソートされます:

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

次に、リストのリストの各リストの最後の要素を出力して取得します。

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

うわー、私はポストを約あったソリューションは、183バイトでした...私は大爆笑吸う
ドン・サウザンド・

4
@Rushabh Mehta:私の最初の試みは約205バイトでした...それからハックしてください!:)
チャスブラウン

7

APL(Dyalog Unicode)、31 バイトSBCS

匿名プレフィックスラムダは、文字列のリストを取得して返します。

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

オンラインでお試しください!

{} "dfn"; 引数です

⍵[…次の] インデックスを使用して引数にインデックスを付けます。

  ' '()¨⍵ 左引数としてスペースを含む各文字列に次の暗黙関数を適用します。

   , スペースを文字列に連結します

   ⊣= スペースが各文字と等しい場所を示すブールリスト

   ,⊂⍨ それを使用して、スペースと文字列の連結をパーティションに分割します(trueの場合は開始)

   文字列のリストのリストを文字列のマトリックスに混ぜる

  {}⍀ この「dfn」による垂直累積削減。そして、上下の引数は、次のとおりです。

   ≢⍵ 下の文字列の長さ

   1= それは1に等しいですか?(つまり、そこには単一のスペースしかありませんか?)

   :⍺ もしそうなら、上の引数を返します

   ⋄⍵ それ以外の場合、下位の引数を返します

   グレードアップ(それをソートするインデックスを見つけます)


7

網膜、47バイト

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

オンラインでお試しください!注:複数の行には末尾スペースがあります。説明:

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

最初のステップは、各単語を同じインデントで次の行に挿入することです。例えば、線でaisle wasabiそして elf得られた線であるaisleaisle wasabiaisle wasabi elf。この正規表現は試行錯誤によって発見されたため、エッジケースが存在する可能性があります。

O$`
$L$&

行を大文字と小文字を区別せずにソートできるようになりました。

\S+ 
 

挿入されたすべての単語を削除します。


4

Perlの6120 83 81 63 54 37 47 42バイト

nwellnhofのおかげで-5バイト

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

オンラインでお試しください!

これはChas Brownの方法を使用しますます。行のリストを受け取り、行のリストを返す匿名コードブロック。

説明:

{                                        }  # 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それを指摘してくれてありがとう。私は最新バージョンではそれを修正したと思う
ジョー・キング

@nwellnhofああ、それは前のイテレーションで短くなりました。バイトがありませんが、少し変更しなければなりませんでした
ジョーキング

ああ、そう。実際、{my@a;.sort:{@a[+.comb(' ')...*>@a]=$_;~@a}}より高いインデントレベルをサポートするには、次のようなものが必要です。
nwellnhof

3

クリーン112 101バイト

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

f o$

オンラインでお試しください!

正しい出力形式に:: [[Char]] -> [[Char]]ラップ$ :: [[Char]] -> [[[Char]]]する匿名関数。$文字列を「より多くのスペース」と「他のすべての後」にグループ化し、各グループを再帰し、隣接しているときに並べ替えます。各ステップで、ソートされるリストは次のようになります。

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

クリーン、127バイト

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=[]

オンラインでお試しください!

$ :: [[Char]] -> [[Char]]文字列を(spaces, letters)、ヘルパー関数によって再帰的にソートされる形式のタプルに分離する関数を定義します ? :: [([Char],[Char])] -> [[([Char],[Char])]]

説明:

$ 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バイト

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

オンラインでお試しください!

Chas BrownのPythonの答えと同様のアプローチですが、代わりに正規表現を使用します。

説明

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バイト

溶液:

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

例:

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"

仮定:

a。各階層が最低レベルから始まること、つまり、以下は取得されません。

bdellium
      fox
    hound
    alien

説明:

{,/(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バイト

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(のような):

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]}

これは非常に単純な再帰的な実装です。インデントレベルをチェックするには、最初の非スペース文字(/\S/)を検索し、そのインデックスを取得します($-[0])。残念ながら、再帰で使用されるいくつかの変数を実際に宣言する必要があります。そうしないと、暗黙的にグローバルになり、再帰が正しく機能しません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.