爆炸后缀


20

给定一个ASCII字符串,输出它的爆炸后缀。例如,如果字符串是abcde,则有5个后缀,按从长到短的顺序排列:

abcde
bcde
cde
de
e

然后,每个后缀都会爆炸,这意味着每个字符将被复制与其后缀中的一个索引位置一样多的次数。例如,展开后缀abcde

abcde
12345
abbcccddddeeeee

bcde
1234
bccdddeeee

cde
123
cddeee

de
12
dee

e
1
e

总之,的爆炸后缀abcde

abbcccddddeeeee
bccdddeeee
cddeee
dee
e

规则

  • 这是因此最短的代码获胜。
  • 输入将包含可打印的ASCII字符。(这不包括换行符,但包括空格。)
  • 输出将每个字符串放在单独的行中。
  • 每行都允许使用尾随空格,并且末尾可能会有多余的换行符。

测试用例

''

'a'
a

'bc'
bcc
c

'xyz'
xyyzzz
yzz
z

'code-golf'
coodddeeee-----ggggggooooooollllllllfffffffff
oddeee----gggggoooooolllllllffffffff
dee---ggggooooollllllfffffff
e--gggoooolllllffffff
-ggooollllfffff
goolllffff
ollfff
lff
f

's p a c e'
s  ppp    aaaaa      ccccccc        eeeeeeeee
 pp   aaaa     cccccc       eeeeeeee
p  aaa    ccccc      eeeeeee
 aa   cccc     eeeeee
a  ccc    eeeee
 cc   eeee
c  eee
 ee
e



'ccodegolf'中会发生什么?
RosLuP

Answers:


14

果冻,5 个字节

ṫJxJY

在线尝试!验证所有测试用例

怎么运行的

ṫJxJY  Main link. Argument: s (string)

 J     Indices; yield I := [1, ..., len(s)].
ṫ      Tail; get the suffixes of s starting at indices [1, ..., len(s)].
   J   Indices; yield I again.
  x    Repeat. The atom 'x' vectorizes at depth 1 (1D arrays of numbers/characters)
       in its arguments. This way, each suffix t gets repeated I times, meaning
       that the first character of t is repeated once, the second twice, etc.
       If left and right argument have different lengths, the longer one is
       truncated, so I can safely be applied to all suffixes.
    Y  Join, separating by linefeeds.

8

J,22 12 8字节

感谢Miles节省14个字节!

(#~#\)\.

现在,这是一个非常好的解决方案。也很简洁。

这是#~#\应用于\.输入后缀()的钩子。当在输入上调用该钩子时y,其分解如下:

(#~#\) y
y #~ #\ y

以下是一些中间结果:

   ]s =: 's p a c e'
s p a c e
   #\ s
1 2 3 4 5 6 7 8 9
   (quote) s
's p a c e'
   (quote;#)\ s
+-----------+-+
|'s'        |1|
+-----------+-+
|'s '       |2|
+-----------+-+
|'s p'      |3|
+-----------+-+
|'s p '     |4|
+-----------+-+
|'s p a'    |5|
+-----------+-+
|'s p a '   |6|
+-----------+-+
|'s p a c'  |7|
+-----------+-+
|'s p a c ' |8|
+-----------+-+
|'s p a c e'|9|
+-----------+-+
   1 2 3 # '123'
122333
   3 3 3 # '123'
111222333
   ]\. s
s p a c e
 p a c e
p a c e
 a c e
a c e
 c e
c e
 e
e
   quote\. s
's p a c e'
' p a c e'
'p a c e'
' a c e'
'a c e'
' c e'
'c e'
' e'
'e'
   (#~#\) s
s  ppp    aaaaa      ccccccc        eeeeeeeee
   (#~#\)\. s
s  ppp    aaaaa      ccccccc        eeeeeeeee
 pp   aaaa     cccccc       eeeeeeee
p  aaa    ccccc      eeeeeee
 aa   cccc     eeeeee
a  ccc    eeeee
 cc   eeee
c  eee
 ee
e

测试用例

   f =: (#~#\)\.
   f
(#~ #\)\.
   f ''
   f 'a'
a
   f 'bc'
bcc
c
   f 'xyz'
xyyzzz
yzz
z
   f 'code-golf'
coodddeeee-----ggggggooooooollllllllfffffffff
oddeee----gggggoooooolllllllffffffff
dee---ggggooooollllllfffffff
e--gggoooolllllffffff
-ggooollllfffff
goolllffff
ollfff
lff
f
   f 's p a c e'
s  ppp    aaaaa      ccccccc        eeeeeeeee
 pp   aaaa     cccccc       eeeeeeee
p  aaa    ccccc      eeeeeee
 aa   cccc     eeeeee
a  ccc    eeeee
 cc   eeee
c  eee
 ee
e

   ]tc =: <;._1 '|' , '|a|bc|xyz|code-golf|s p a c e'
++-+--+---+---------+---------+
||a|bc|xyz|code-golf|s p a c e|
++-+--+---+---------+---------+
   ,. f &. > tc
+---------------------------------------------+
+---------------------------------------------+
|a                                            |
+---------------------------------------------+
|bcc                                          |
|c                                            |
+---------------------------------------------+
|xyyzzz                                       |
|yzz                                          |
|z                                            |
+---------------------------------------------+
|coodddeeee-----ggggggooooooollllllllfffffffff|
|oddeee----gggggoooooolllllllffffffff         |
|dee---ggggooooollllllfffffff                 |
|e--gggoooolllllffffff                        |
|-ggooollllfffff                              |
|goolllffff                                   |
|ollfff                                       |
|lff                                          |
|f                                            |
+---------------------------------------------+
|s  ppp    aaaaa      ccccccc        eeeeeeeee|
| pp   aaaa     cccccc       eeeeeeee         |
|p  aaa    ccccc      eeeeeee                 |
| aa   cccc     eeeeee                        |
|a  ccc    eeeee                              |
| cc   eeee                                   |
|c  eee                                       |
| ee                                          |
|e                                            |
+---------------------------------------------+

很酷,另一种节省字节的方法是使用副词
英里

@miles是什么意思?
科纳·奥布莱恩

您可以获取每个前缀的长度,作为生成该范围的更短方法
英里

@miles啊,当然。
科纳·奥布莱恩

7

Python,61个字节

f=lambda s,i=0:s[i:]and-~i*s[i]+f(s,i+1)or s and'\n'+f(s[1:])

备选方案63:

f=lambda s,b=1:s and f(s[:-1],0)+s[-1]*len(s)+b*('\n'+f(s[1:]))

6

Python 3,91 68 65字节

def f(s):f(s[1:print(''.join(i*c for i,c in enumerate(s[0]+s)))])

打印所需的输出后,终止并出错。在Ideone上进行测试

怎么运行的

f可以递归调用之前,s[1:...]必须先计算的索引。

First enumerate(s[0]+s)产生s的字符c的所有对(i,c) -重复第一个字符-以及相应的索引i。前置在这里有两个目的。s[0]

  • s的第一个字符必须重复一次,但第一个索引为0

  • 处理所有字符后,s[0]将引发IndexError,导致f以错误终止,而不是打印换行符,直到达到递归限制为止。

''.join(i*c for i,c in ...)建立一个重复的i字符串,每个c重复一次,返回到STDOUT。print

最终,由于print返回Nones[1:None]简单地为s[1:],因此递归调用f(s[1:...])s重复上述过程,但不使用第一个字符。


6

Perl 6、38个字节

m:ex/.+$/.map:{put [~] .comb Zx 1..*}

37个字节+ 1个-n命令行开关

例:

$ perl6 -ne 'm:ex/.+$/.map:{put [~] .comb Zx 1..*}' <<< 'code-golf'
coodddeeee-----ggggggooooooollllllllfffffffff
oddeee----gggggoooooolllllllffffffff
dee---ggggooooollllllfffffff
e--gggoooolllllffffff
-ggooollllfffff
goolllffff
ollfff
lff
f

展开:

# -n command line switch takes each input line and places it in 「$_」

# You can think of it as surrounding the whole program with a for loop
# like this:
for lines() {

  # match
  m
  :exhaustive # every possible way
  / .+ $/     # at least one character, followed by the end of the string

  .map:

  {
    put           # print with newline
      [~]         # reduce using string concatenation ( don't add spaces between elements )
        .comb     # split into individual chars
        Z[x]      # zip using string repetition operator
        1 .. *    # 1,2,3,4 ... Inf
  }

}

5

Brachylog,17个字节

@]Elyk:Erz:jac@w\

在线尝试!

说明

@]E                 E is a suffix of the Input
   lyk              The list [0, ..., length(E) - 1]
      :Erz          The list [[0th char of E, 0], ..., [Last char of E, length(E) - 1]]
          :ja       For all elements of that list, concatenate the Ith char I times to itself
             c      Concatenate the list into a string
              @w    Write followed by a line break
                \   False: backtrack to another suffix of the Input

4

05AB1E,13个字节

.sRvyvyN>×}J,

在线尝试!

说明

.s              # push list of suffixes of input
  R             # reverse the list
   vy           # for each string
     vy   }     # for each char in string
       N>×      # repeat it index+1 times
           J,   # join and print with newline

4

CJam,14个字节

Sl+{_eee~n1>}h

在线尝试!

说明

Sl+   e# Read input and prepend a space.
{     e# While the string is non-empty...
  _   e#   Make a copy.
  ee  e#   Enumerate. Gives, e.g. [[0 ' ] [1 'a] [2 'b] [3 'c]].
  e~  e#   Run-length decode. Gives "abbccc".
  n   e#   Print with trailing linefeed.
  1>  e#   Discard first character.
}h

4

C#,101个字节

f=s=>{var r="\n";for(int i=0;i<s.Length;)r+=new string(s[i],++i);return""==s?r:r+f(s.Substring(1));};

递归匿名函数,该函数还会打印一个前导换行符。如果不允许前导换行符,则额外的3个字节会将其转换为尾随的换行符:

f=s=>{var r="";for(int i=0;i<s.Length;)r+=new string(s[i],++i);return""==s?r:r+"\n"+f(s.Substring(1));};

完整的程序,包含未使用的方法和测试用例:

using System;

namespace ExplodedSuffixes
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string, string> f = null;
            f = s =>
            {
                var r = "\n";
                for (int i = 0; i < s.Length; )
                    r += new string(s[i], ++i);
                return "" == s ? r : r + f(s.Substring(1));
            };

            // test cases:
            string x = "abcde";
            Console.WriteLine("\'" + x + "\'" + f(x));
            x = "";
            Console.WriteLine("\'" + x + "\'" + f(x));
            x = "a";
            Console.WriteLine("\'" + x + "\'" + f(x));
            x = "bc";
            Console.WriteLine("\'" + x + "\'" + f(x));
            x = "xyz";
            Console.WriteLine("\'" + x + "\'" + f(x));
            x = "code-golf";
            Console.WriteLine("\'" + x + "\'" + f(x));
            x = "s p a c e";
            Console.WriteLine("\'" + x + "\'" + f(x));
        }
    }
}

4

Haskell,48个字节

e=map(concat.zipWith replicate[1..]).scanr(:)[] 

由以下任何一个接口

ghc exploded_suffixes.hs -e 'e"abcde"'
ghc exploded_suffixes.hs -e 'mapM_ putStrLn.e=<<getLine' <<<code-golf
ghc exploded_suffixes.hs -e 'Control.Monad.forever$putStr.unlines.e=<<getLine'

我喜欢无拘无束的感觉。您应该将63字节的代码放在自己的块中,然后分别显示调用。
xnor

您不需要putStr.,我们接受为函数输出。您确实需要import Data.List使用tails
xnor

您可以替换uncurry ... zipzipWithunlines.map(concat.zipWith replicate[1..]).tails
nimi

确实是的!zipWith replicate当我醒来时,这种缩短也发生了。我tails没有的同情Prelude可以隐含地tails从中获取,Data.List没有完整import ,也没有超出foldr等效的范围。对于没有IO样板的纯净度,我也将mapM_ putStrLn调味料留给读者自己看,不做unlines。定义一个块e=将花费字节数。
Roman Czyborra

不使用合格名称imports不是标准的Haskell,而是ghcirepl 的功能。视此类情况作为单独的语言,因此我建议将答案的标题更改为Haskell (ghci)。(另请参阅此元讨论)。
nimi

3

Perl,36 + 1(-n)= 37字节

/.+$(?{$.=say$&=~s%.%$&x$.++%rge})^/

需要-n-E(或-M5.010)运行:

perl -nE '/.+$(?{$.=say$&=~s%.%$&x$.++%rge})^/' <<< "code-golf"

请注意,它每次运行时仅在一个实例上运行(因为它使用的变量$.每次读取一行时都会递增,因此1仅在第一次读取一行时才保留)。(但是这里没有问题,只需^D重新运行它即可!)



3

Java中,150 127个字节

编辑:

  • 关闭-23个字节。感谢@Kevin Cruijssen

片段:

f->{String s[]=f.split(""),o="";int i=-1,j,l=s.length;for(;++i<l;)for(j=-2;++j<i;o+=s[i]);return l<1?"":o+"\n"+f.substring(1);}

取消高尔夫:

public static String explodeSuff(String suff){
  char [] s = suff.toCharArray();
  String out = "";
  if(s.length==0)return "";
  for(int i=-1;++i<s.length;){
    for(int j=-2;++j<i;){
      out+=s[i];
    }
  }
  return out+"\n"+suff.subString(1);
}

嗨,您可以轻松地打高尔夫球,只需删除空间和一些小技巧即可:f->{String s[]=f.split(""),o="";int i=-1,j,l=s.length;for(;++i<l;)for(j=-2;++j<i;o+=s[i]);return l<1?o:o+"\n"+f.substring(1);}
Kevin Cruijssen

2

拍框184字节

(let p((l(string->list s))(ol'()))(cond[(null? l)(display(list->string(flatten ol)))]
[else(p(cdr l)(append ol(list #\newline)(for/list((i l)(n(length l)))(for/list((j(+ 1 n)))i))))]))

取消高尔夫:

(define(f s)
 (let loop((l(string->list s))
             (outl '()))
    (cond
      [(null? l)
       (display
        (list->string
         (flatten outl)))]
      [else
       (loop
        (rest l)
        (append outl
                (list #\newline)
                (for/list ((i l)
                           (n (length l)))
                  (for/list ((j (add1 n)))
                    i
                    ))))]  )))


(f "abcde")
(f "xyz")

输出:

abbcccddddeeeee
bccdddeeee
cddeee
dee
e

xyyzzz
yzz
z

2

JavaScript(ES6),65个字节

f=s=>s?[s.replace(/./g,(c,i)=>c.repeat(i+1)),...f(s.slice(1))]:[]
<input oninput=o.textContent=f(this.value).join`\n`><pre id=o>

先前的尝试:

67: s=>[...s].map((_,i)=>s.slice(i).replace(/./g,(c,i)=>c.repeat(i+1)))
84: s=>s.replace(/./g,`$&$'
    `).match(/.+/g).map(s=>s.replace(/./g,(c,i)=>c.repeat(i+1)))
89: f=(s,t=s.replace(/./g,(c,i)=>c.repeat(i+1)))=>t?[]:[t,...f(s,t.replace(/(.)(?=\1)/g,''))]

2

PHP,103个字节(带有短标签的99个字节)

<?php for($s=$argv[1];""!=$s[$i++];$o.="
")for($j=0;""!=$l=$s[$j+$i-1];)$o.=str_pad('',++$j,$l);echo$o;

我敢肯定这不是最短的答案。


2

MATL,12字节

&+gYRYs"G@Y"

当引号一起出现时,我喜欢它!

在线尝试!

说明

这通过建立一个矩阵来工作,该矩阵的列被一一用来对输入进行游程长度解码。例如,输入'abcde'矩阵为

1 0 0 0 0
2 1 0 0 0
3 2 1 0 0
4 3 2 1 0
5 4 3 2 1

码:

&+g    % Implicit input. NxN matrix of ones, where N is input size
YR     % Set entries above diagonal to zero
Ys     % Cumulative sum of each column. This gives the desired matrix 
"      % For each column
  G    %   Push input (for example 'abcde')
  @    %   Push current column (for example [0;0;1;2;3])
  Y"   %   Run-length decode (example output 'cddeee')
       % Implicit end
       % Implicit display

1

Python 3,95个字节

def f(s):return'\n'.join(''.join(s[j:][i]*(i+1)for i in range(len(s)-j))for j in range(len(s)))

这比我预期的要难得多。我重做了整个功能,大概有4次。


1

Java 7,140字节

void c(char[]a,int l,int j){if(l<1)return;c(a,--l,++j);for(int i=0,k;i<j;i++)for(k=0;k++<=i;)System.out.print(a[i+l]);System.out.println();}

不打高尔夫球

 void c(char[]a,int l,int j)
{
if (l < 1) 
return ;
c(a , --l , ++j) ;
for(int i = 0 , k; i < j ; i++)
for(k = 0 ; k++ <= i ;)
System.out.print(a[i+l]);
System.out.println();
}

接下来的一行让我非常痛苦。我不知道该怎么打高尔夫球(因为有两个循环来破坏要放入"\n"打印语句的条件)。
System.out.println();


不需要也将数组长度作为参数发送的适当方法怎么样?当前,通过意外发送错误值可以触发IndexOutOfBounds异常……
adrianmp


1

Ruby,51个字节

使用-n+1字节的标志。

(k=0;puts$_.gsub(/./){$&*k+=1};$_[0]="")while$_>$/

1

R,108个字节

从stdin读取输入并打印到stdout

s=scan(,"");n=nchar(s);for(i in 1:n)cat(do.call("rep",list(strsplit(s,"")[[1]][i:n],1:(n-i+1))),"\n",sep="")

我觉得在do.call这里使用是合适的。它基本上需要两个输入:1.字符串形式的函数名称(rep在此处)和参数列表以及2.使用列表中的参数迭代地应用调用函数。

例如:

  • rep("c",3) 产生向量 "c" "c" "c"
  • do.call("rep",list(c("a","b","c"),1:3)) 产生向量 "a" "b" "b" "c" "c" "c"
  • 这等效于连续调用rep("a",1)rep("b",2)并且rep("c",3)

1

Vim,43个字节

qqYlpx@qq@qqr0<C-H><C-V>{$:s/\v%V(.)\1*/&\1/g<CR>@rq@r

第一个宏分隔后缀,第二个宏“分解”后缀。可能打败。空间很烦人。


1

C,186字节

#include <string.h>
#define S strlen
p(char* s){char *t=s;char u[999]="";for(int i=0;i<S(s);i++){for(int j=i+1;j>0;j--){sprintf(u+S(u),"%c",*t);}t++;}printf("%s\n",u);if(S(s)>1)p(s+1);}

这可能可以缩短很多,但我只是想尝试一下。这是我第二次尝试高尔夫,所以请给我任何可能的指示(* lol)。它以字符串作为参数,然后从那里爆炸。u用作存储爆炸字符串的缓冲区。

取消高尔夫:

#include <string.h>
#define S strlen 
p(char* s){
    char *t=s;
    char u[999]="";
    for(int i=0;i<S(s);i++){
        for(int j=i+1;j>0;j--){
            sprintf(u+S(u),"%c",*t);
        }
        t++;
    }
    printf("%s\n",u);
    if(S(s)>1)p(s+1);
}

1

加速!,150字节

期望在stdin上输入,以制表符终止。

N
Count c while _/128^c-9 {
_+N*128^(c+1)
}
Count i while _-9 {
Count j while _/128^j-9 {
Count k while j+1-k {
Write _/128^j%128
}
}
Write 10
_/128
}

说明

对于Acc来说,这实际上是一项相当不错的任务,因为它只需要读取一个字符串并使用一些嵌套循环对其进行迭代。我们将字符串读入累加器,将其视为基数为128的序列,第一个字符在低端。在开Count c环之后,累加器值可以像这样被概念化(xyz用作示例输入):

128^   3  2  1  0
     tab  z  y  x

(此示例的实际累加器值为9*128^3 + 122*128^2 + 121*128 + 120= 20888824。)

然后,我们可以通过迭代增加的128的幂来遍历字符串。并且可以通过在每次迭代后将累加器除以128,截取一个字符来遍历后缀。

带有缩进和注释:

# Initialize the accumulator with the first input character
N
# Loop until most recent input was a tab (ASCII 9)
Count c while _/128^c - 9 {
    # Input another character and add it at the left end (next higher power of 128)
    _ + N * 128^(c+1)
}

# Loop over each suffix, until only the tab is left
Count i while _ - 9 {
    # Loop over powers of 128 until the tab
    Count j while _/128^j - 9 {
        # Loop (j+1) times
        Count k while j + 1 - k {
            # Output the j'th character
            Write _ / 128^j % 128
        }
    }
    # Output a newline
    Write 10
    # Remove a character
    _/128
}
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.