基于缩进的排序


35

给定一个大小写相同的字母字符串列表(az XOR AZ),其中每个字符串前面都带有0个或多个空格()字符,输出相同的列表,但字符串在每个缩进级别进行排序。出于排序目的,不同父项下的压痕深度算作不同的列表。

如果您输入的是:

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

如果愿意,可以将其视为目录列表,并且需要对每个目录中的名称进行排序。

细节

  • 一个项目可以缩进任意数量的空格。如果缩进的空格与上一项的空格相同,则它属于与上一项相同的排序层次结构。如果缩进更多空格,则这是新的子层次结构的开始。
  • 如果缩进的行比上一行的行,它会以相同的#或更少的空格链接到其上方最近的子组(例如上例中的辣根,它链接到其上方的wasabi组),因为芥末是它上面的第一个没有比辣根更多的空间)
  • 您必须在输出中保留每个输入项目的缩进级别
  • 禁止在输出中使用制表符
  • 输入的第一行将永远不会缩进
  • 您的程序必须至少处理全部大写和全部小写的字符串之一;它不必同时处理两者。

计分

这是一个,因此使用最少字节的答案将获胜。


7
好挑战!
阿达姆(Adám)

1
顺便说一句,下一次,请考虑使用沙盒解决有挑战的问题,然后再将其发布到主站点。
亚当

8
@Adám不,所需的递归字符串解析逻辑是我编写此提示的原因。
Techrocket18年

2
如果输入为['a','..b', '.c', '..d'],则输出应该是什么?['a','..b', '.c', '..d']还是['a','.c','..b', '..d']其他东西?('.'为了视觉清晰,我使用的不是空间)。
Chas Brown

2
@streetster 字符串(AZ XOR AZ)
亚当

Answers:



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个字节...我吮吸大声笑
Don Thousand

4
@Rushabh Mehta:我的第一次尝试是大约205个字节...然后砍掉!:)
Chas Brown

7

APL(Dyalog Unicode),31 字节SBCS

匿名前缀lambda,获取并返回字符串列表。

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

在线尝试!

{…… } “ dfn”;是争论

⍵[] 使用以下索引对自变量编制索引:

  ' '()¨⍵ 对每个带有空格作为左参数的字符串应用以下默认函数:

   , 将空间连接到字符串

   ⊣= 布尔列表,指示空格等于每个字符

   ,⊂⍨ 用它来分割(在真实的地方开始)空间和字符串的连接

   将字符串列表混合成字符串矩阵

  {…… }⍀ 垂直累计减少量为“ dfn”;在上部和下部ARGS:

   ≢⍵ 下弦的长度

   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 6的120 83 81 63 54 37个47个 42字节

-5字节归功于nwellnhof

{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)由helper函数递归排序 ? :: [([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"

假设:

一种。每个层次将从最低级别开始,即您将不会获得:

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

松散的(某种):

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])来检查缩进级别。不幸的是,我们实际上必须声明一些在递归中使用的变量,否则它们将是隐式全局的,并且递归将无法正常工作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.