慢慢地将一串变成另一个


31

挑战

给定两个字符串/一个字符串数组,输出第一个字符串缓慢缩小并扩展回第二个字符串。

您可以假设字符串始终以相同的字符开头。

Input:
"Test", "Testing"

Output:
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

首先,您输出第一个单词:

Test

然后,您继续删除一个字母,直到字符串长度为一个字符为止:

Tes
Te
T

然后继续添加第二个单词的一个字母,直到完成:

Te
Tes
Test
Testi
Testin
Testing

(如果两个字符串都长一个字符,则只需将其中一个输出一次。)

测试用例

"Hello!", "Hi."
Hello!
Hello
Hell
Hel
He
H
Hi
Hi.

"O", "O"

O

"z", "zz"

z
zz

".vimrc", ".minecraft"

.vimrc
.vimr
.vim
.vi
.v
.
.m
.mi
.min
.mine
.minec
.minecr
.minecra
.minecraf
.minecraft

"     ", "   "

SSSSS
SSSS
SSS
SS
S
SS
SSS

"0123456789", "02468"

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0
02
024
0246
02468

(注意:在空格/第四个测试用例中,将S替换为空格)

规则

  • 这是,因此最短答案以字节为单位!Tiebreaker是获得最高评价的职位。优胜者将于2016年10月10日入选。

  • 禁止出现标准漏洞。


是否允许2条尾随换行符(序列后的一条可见空行)?
seshoumara

Answers:


11

Pyth,9个字节

j+_._Et._

该程序将第二个字符串,然后是第一个字符串作为STDIN上的引号字符串,并打印结果。

在线尝试

怎么运行的

j+_._Et._  Program. Inputs: Q, E
   ._E     Yield prefixes of E as a list
  _        Reverse the above
       ._  Yield prefixes of Q as a list (implicit input fill)
      t    All but the first element of above
 +         Merge the two lists
j          Join on newlines
           Implicitly print

14

V,14字节

òYp$xhòjòÄ$xhh

在线尝试!

说明:

ò     ò     "Recursively:
 Yp         "  Yank the current line and paste it
   $        "  Move to the end of the current line
    x       "  Delete one character
     h      "  Move One character to the right.
            "  Because of the way loops work in V, this will throw an error if there
            "  Is only one character on the current line.

现在,缓冲区看起来像这样:

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0

我们只需要对下一行做相反的事情:

j           "Move down one line
 ò     ò    "Recursively (The second ò is implicit)
  Ä         "  Duplicate this line up
   $        "  Move to the end of the current line
    x       "  Delete one character
     hh     "  Move two characters to the right.
            "  Because of the way loops work in V, this will throw an error if there
            "  Is only two characters on the current line.

更有趣的替代解决方案

òÄ$xhòç^/:m0
ddGp@qd

3
就像vim始终是正确的工作工具
Downgoat

@Downgoat确实如此。这就是为什么需要在V开始打高尔夫球的原因。:P
DJMcMayhem

9

Python,93个字节

f=lambda a,b,r='',i=2:a and f(a[:-1],b,r+a+'\n')or(len(b)>=i and f(a,b,r+b[:i]+'\n',i+1)or r)

从空字符串开始r,添加a和换行,并从最后一个字符删除a直到a为空,然后b通过保留计数器添加的必需部分和换行,该计数器i始于2直到b超过的长度,然后返回r。尾随换行符。

所有测试均在ideone上


2件事。1)我相信您误算了字符,实际上是93和2)您不需要说r=""。简单r仍然可以。

谢谢@JackBates。1.正确且已更新-我可能忘记了f=。2.没有r=''现在f('test','testing')就行不通;是的f('test','testing',''),但是我们必须遵循规范。
乔纳森·艾伦

原谅我。我只是看代码而不是例子。

7

05AB1E,9个字节

.pRI.p¦«»

说明

.pR           # prefixes of first word
     I.p       # prefixes of second word
         ¦       # remove first prefix
          «     # concatenate
           »    # join with newlines

在线尝试!


7

视网膜,50 41 26字节

感谢Martin Ender节省了15(!)个字节。

M&!r`.+
Om`^.¶[^·]+|.+
A1`

输入两个字符串,并用换行符分隔:

Test
Testing

在线尝试!

说明

M&!r`.+

第一行生成两个单词的“步骤”:

Testing
Testin
Testi
Test
Tes
Te
T
Test
Tes
Te
T

M用于匹配模式,&考虑重叠的匹配并!打印匹配而不是匹配的数量。反转的原因是r从右向左的选项:引擎开始在字符串的末尾查找匹配项,并继续向头查找。

Om`^.¶[^·]+|.+

这样就可以按正确的顺序获取所有内容:它会O处理后续正则表达式的所有匹配项:一个字符在其自己的行上以及其后的每个字符(包括换行符),后者将整个后半部分作为一个块匹配,否则将一行字符匹配,它与每行匹配。然后,将这些匹配项按代码点进行排序,因此T紧跟换行符,然后是行,然后按长度递增。

A1`

现在我们只在第一个字符行上方,因此我们使用Antigrep模式来丢弃默认正则表达式的第一个匹配项.+

旧版

M&!r`.+
O`\G..+¶
s`(.*)¶.¶(.*)
$2¶$1
¶.$

在线尝试此版本!

说明

第一行是相同的,因此请参见上面的说明。

O`\G..+¶

这会使上半部分(第二个输入字)的行反转。它实际上是O对行进行排序,而正则表达式会限制匹配:它必须是两个或更多字符(..+)的行,后接换行符(),从最后一个中断的字符()开始\G。在上面的示例中,T中间的单曲不匹配,因此之后的任何内容都无法匹配。

Te
Tes
Test
Testi
Testin
Testing
T
Test
Tes
Te
T

现在,我们拥有正确的两个组件,但顺序错误。

s`(.*)¶.¶(.*)
$2¶$1

¶.¶与中间的唯一T匹配,我们不需要,但将两个部分分开。这两行(.*)捕获了前后的所有内容,包括single-line模式在内的换行符。这两个捕获以正确的顺序替换,中间是换行符。

现在我们完成了,除非输入字符串的长度为一个字符,在这种情况下,输入没有改变。为了消除重复项,我们将¶.$(字符串的最后一行是单个字符)替换为空。


4

Python 2,88 82字节

x,y=input(),input()
for i in x:print x;x=x[:-1]
s=y[0]
for i in y[1:]:s+=i;print s

接受两个输入,每个输入都用引号引起来。

感谢@JonathanAllan保存了一些字节并指出了一个错误。


1
因为负偏移切片有效len(x)x=x[:len(x)-1]所以不需要in-您可以编写x=x[:-1]。唯一的问题是您的代码无法" ", " "很好地处理测试用例。
乔纳森·艾伦

1
您可以删除第二个,input()并使用输入格式,例如"<str1>", "<str2>"
LevitatingLion

您可以将第二行更改为for i in range(x):print x[-i:],第四行更改为for i in range(1,y):print y[:-i]。不过,不确定它是否会工作。
clismique

4

Perl,34个 28个字节

包括+2用于-0n

在STDIN的不同行上运行字符串:

perl -M5.010 -0n slow.pl
Test
Testing
^D

slow.pl

/(^..+|
\K.+?)(?{say$&})^/

让正则表达式回溯来完成这项工作...



3

Brachylog,32个字节

:1aLtT,Lhbr:Tc~@nw
:2fb
~c[A:B]h

在线尝试!

说明

Brachylog没有内置的前缀,因此我们将通过使用concatenate(请参见谓词2)获得前缀:Sis 的前缀(P如果P连接到Q(无论是什么)则导致)S

  • 主要谓词:

    :1aL                  L is all prefixes of both elements of the input (see predicate 1)
       LtT,               T is the second element of L
           Lhbr           Remove the first prefix of the first list of L and reverse it
               :Tc        Concatenate with T
                  ~@n     Join with newlines
                     w    Write to STDOUT
    
  • 谓词1:

    :2f                   Find all prefixes of the input string (see predicate 2)
       b                  Remove the first one (empty string)
    
  • 谓词2:

    ~c[A:B]               Input is the result of concatenating A to B
           h              Output is A
    

3

Javascript,103 81字节

f=(x,y,n=1)=>x?`
`+x+f(x.slice(0,-1),y):n++<y.length?`
`+y.slice(0,n)+f(x,y,n):''

例: f("Test", "Testing")

输出:

Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

原始答案

f=(x,y,n=1)=>x?(console.log(x),f(x.slice(0,-1),y)):n++<y.length?(console.log(y.slice(0,n)),f(x,y,n)):''

3

爪哇188 179字节

interface E{static void main(String[]a){int i=a[0].length();while(i>1)System.out.println(a[0].substring(0,i--));while(i<=a[1].length())System.out.println(a[1].substring(0,i++));}}

更新资料

  • 删除了s变量,节省了9个字节

Ungolfed

interface E {

    static void main(String[] a) {
        int i = a[0].length();
        while (i > 1) {
            System.out.println(a[0].substring(0, i--));
        }
        while (i <= a[1].length()) {
            System.out.println(a[1].substring(0, i++));
        }
    }
}

用法

$ java E 'test' 'testing'
test
tes
te
t
te
tes
test
testi
testin
testing

3

Haskell,54 53 47字节

t[]=[]
t x=x:t(init x)
(.reverse.t).(++).init.t

用法示例: ((.reverse.t).(++).init.t) "Hello" "Hi!" -> ["Hello","Hell","Hel","He","H","Hi","Hi!"]

一些无意义的魔术。与在f x y = (init(t x))++reverse (t y)其中t列出所有初始子字符串的位置相同,例如t "HI!"-> ["H","HI","HI!"]


t=reverse.tail.inits
Bergi 2016年

@Bergi:当然可以,但是inits需要import Data.List
nimi 2013年


3

GNU sed,57 45 + 2(rn个标志)= 47个字节

:;1{/../p};2G;2h;s/.(\n.*)?$//;/./t;g;s/.$//p

跑:

echo -e "Test\nTesting" | sed -rnf morphing_string.sed

输入应该是用换行符分隔的两个字符串。该代码由sed为每一行运行。

循环:从字符串末尾删除一个字符。与第一个字符串相关的输出将直接打印,但第一个字符除外1{/../p}2G;2h在删除期间,第二个字符串的输出以相反的顺序()存储在保持空间中,并在最后打印。


3

C(gcc)102 97 95 93字节

n;f(char*a,char*b){for(n=strlen(a);n;puts(a))a[n--]=0;for(a=b+1;*a++;*a=n)n=*a,*a=0,puts(b);}

在线尝试!

第一个循环从结尾开始覆盖0字节的字符串,并使用 puts()打印字符串。第二个循环不能只是从头开始覆盖,它必须存储旧值,以便可以将其放回原处。0字节正朝结尾走去。

感谢@homersimpson和@ceilingcat每次减少2个字节!


1
您可以通过声明n为全局整数来节省几个字节,例如:n;f(char*a,char*b){n=strlen(a)...。您可能可以n=*a=0在for循环的主体中作为链式分配来执行。
homersimpson

谢谢@homersimpson。但是n = * a = 0与n = * a,* a = 0不同。
G. Sliepen '16

2

Python 3,104个字节

n='\n';lambda x,y:x+n+n.join(x[:-i]for i in range(1,len(x)-1))+n+n.join(y[:i]for i in range(1,len(y)+1))

感谢@DJMcMayhem打高尔夫球21字节。

伊迪恩!


1
如果这样做n='\n',您可以占用5个字节,并使用n代替'\n'。如果您使用lambda而不是打印,则可以再n='\n';lambda x,y:n.join(x+n+n.join(x[:-i]for i in range(1,len(x)-1))+n+n.join(y[:i]for i in range(1,len(y)+1)))
减去

2

REPL / Javascript,109字节

使用错误的字符串减少原始字符串

滥用具有较大数字的子字符串来增加第二个字符串,在其要打印与上次相同的单词时停止。

(a,b)=>{l=console.log;z='substring';for(c=a.length;d=a[z](0,c--);){l(d)}for(c=2;d!=(n=b[z](0,c++));){l(d=n)}}

演示:

> ((a,b)=>{l=console.log;z='substring';for(c=a.length;d=a[z](0,c--);){l(d)}for(c=2;d!=(n=b[z](0,c++));){l(d=n)}})("asdf","abcd")
[Log] asdf
[Log] asd
[Log] as
[Log] a
[Log] ab
[Log] abc
[Log] abcd

1
它的执行时间要短1个字节,a=>b=>...并使用(a)(b)调用函数
Zwei

2

Brainfuck,38 55字节

>++++++++++>,[>,]<[<]>>[[.>]<[-]<[<]>.>],.[[<]>.>[.>],]

编辑:输出中包含换行符


我无法让您的代码正常工作。输入是否用新行分隔?您正在使用哪个口译员?
acrolith's

2

Dyalog APL20 13 字节

↑(⌽,\⍞),1↓,\⍞

熟化

(⌽,\⍞)字符输入()的反向()累积级联,\

, 前置于

1↓ 从中删除一个元素

,\⍞ 字符输入的累积级联

在线尝试APL!


2

球拍193字节

(define(f l)
(let*((s(list-ref l 0))
(x(string-length s)))
(for((n x))
(println(substring s 0(- x n))))
(set! s(list-ref l 1))
(for((n(range 1(string-length s))))
(println(substring s 0(add1 n))))))

测试:

(f(list "Test" "Testing"))

"Test"
"Tes"
"Te"
"T"
"Te"
"Tes"
"Test"
"Testi"
"Testin"
"Testing"


(f(list "Hello!" "Hi."))

"Hello!"
"Hello"
"Hell"
"Hel"
"He"
"H"
"Hi"
"Hi."

它应该从输入字符串中删除最后一个字符,而不是第一个。
agilob

2

小花,69字节

a,b=L.J
c=1
NZ(a)!=1:z(a);a=a[:-1]
z(a)
NZ(a)!=Z(b):c+=1;a=b[:c];z(a)

这是一个开始。接受来自STDIN的输入。

测试用例

Input: Test Testing
Output:
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Input: O O
Output: O

1

JavaScript(ES6),92个字节

(s,t)=>s.replace(/./g,`
$\`$&`).split`
`.slice(2).reverse().join`
`+t.replace(/./g,`
$\`$&`)

replace语句建立字符串的三角形,这正是所需要的输出下半年,但上半年需要予以转回,重复单字符行中删除。注意:如果第一个字符串是单个字符,则输出前导换行符。如果这是不希望的,那么对于额外的字节,此版本始终输出尾随换行符:

(s,t)=>s.replace(/./g,`
$\`$&\n`).split(/^/m).slice(1).reverse().join``+t.replace(/./g,`
$\`$&\n`)

1

C,142字节

#define _(x,y) while(y)printf("%.*s\n",d,x-c);
f(char*a,char*b){int c=1,d=strlen(a)+1;while(*++a==*++b)c++;_(a,--d>=c)d++;_(b,d++<strlen(b-c))}

提供f(char* str1, char* str2)


1

TI-Basic,56个字节

Prompt Str1,Str2
Str1
While 1<length(Ans
Disp Ans
sub(Ans,1,length(Ans)-1
End
For(I,1,length(Str2
Disp sub(Str2,1,I
End

用法示例

Str1=?Test
Str2=?Testing
Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Str1=?O
Str2=?O
O

Str1=?z
Str2=?zz
z
zz

1

Java,168136字节

(s,d)->{int i=s.length()+1;while(i-->1)System.out.println(s.substring(0,i));while(i++<d.length())System.out.println(d.substring(0,i));};

非高尔夫测试程序

public static void main(String[] args) {

    BiConsumer<String, String> biconsumer = (s, d) -> {
        int i = s.length() + 1;
        while (i-- > 1) {
            System.out.println(s.substring(0, i));
        }
        while (i++ < d.length()) {
            System.out.println(d.substring(0, i));
        }
    };

    biconsumer.accept("Test", "Testing123");

}

1

(Lambdabot)Haskell-41个字节

f=(.drop 2.inits).(++).reverse.tail.inits

更具可读性,但长两个字节:

a!b=(reverse.tail$inits a)++drop 2(inits b)


输出:

f "Hello" "Hi!"
["Hello","Hell","Hel","He","H","Hi","Hi!"]

1

J,18个字节

]\@],~[:}:[:|.]\@[

取消高尔夫:

]\@] ,~ [: }: [: |. ]\@[

这是7列火车:

]\@] ,~ ([: }: ([: |. ]\@[))

最里面的列[: |. ]\@[[:左侧的一个顶盖组成,因此我们将|.(反向)应用于的结果]\@[,即]\(前缀)上方的[(前缀)。

这里有一个看起来像在什么testing, test输入:

   'testing' ([: |. ]\@]) 'test'
test
tes
te
t

这几乎给了我们第一部分。外面的5列是([: }: ([: |. ]\@[)),它适用于}:(表达式,删除最后一个元素)上述表达式:

   'testing' ([: }: [: |. ]\@]) 'test'
test
tes
te

(这是因为我们不能有重复的中点。)

最后是:

]\@] ,~ ([: }: ([: |. ]\@[))

这由]\@](left参数的前缀)和,~(在左侧加上右侧的内容组成)组成,为我们提供了所需的结果:

   'testing' (]\@] ,~ ([: }: ([: |. ]\@[))) 'test'
testing
testin
testi
test
tes
te
t
te
tes
test

测试用例

   k =: ]\@] ,~ ([: }: ([: |. ]\@[))
   'o' k 'o'
o
   k~ 'o'
o
   'test' k 'test'
test
tes
te
t
te
tes
test
   k~ 'test'
test
tes
te
t
te
tes
test
   '. . .' k '...'
. . .
. .
. .
.
.
..
...
   'z' k 'zz'
z
zz

您可以使用(,~}:@|.)&(]\)
miles将

1

PHP,117109字节

for($i=strlen($a=$argv[1]);$i>1;)echo" ".substr($a,0,$i--);
for(;$j<strlen($b=$argv[2]);)echo" ".$c.=$b[$j++];

for($i=strlen($a=$argv[1]);$i>1;)echo substr($a,0,$i--)." ";
for(;$i<=strlen($b=$argv[2]);)echo substr($b,0,$i++)." ";

PHP,107个字节(不适用于包含的字符串0

for($a=$argv[1];$a[$i];)echo substr($a.a,0,-++$i)." ";
for($b=$argv[2];$b[$j];)echo substr($b,0,++$j+1)." ";

1

C,111字节

f(char*a, char*b){int l=strlen(a),k=1;while(*a){printf("%s\n",a);a[--l]=0;}while(b[k]) printf("%.*s\n",++k,b);}

脱胶测试

#include <stdio.h>
#include <string.h>

f(char*a, char*b) {
  int l=strlen(a), k=1;
  while(*a) {
    printf("%s\n",a);
    a[--l]=0;
  }
  while(b[k])
    printf("%.*s\n",++k,b);
}

int main() {
  char a[10] = {0};
  char b[10] = {0};

  for (int i=0; i<5; ++i) {
    a[i] = 'a' + i;
    b[i] = 'a' + i*2;
  }

  f(&(a[0]), &(b[0]));
}

1

Brainfuck,162个字节

,[>,]++++++++++[[-<]>[->]<]++++++++++[<[+<]<[+<]>[+>]>[+>]<---]<[<]<[<]>[[.>]++++++++++.----------<[-]<[[->+<]<]>>]>[<+>-]>[[<+>-]<[<]>[.>]++++++++++.---------->]

在这里尝试

输入采用由换行符分隔的两个字符串。

brianfuck的第一个程序和golf的第一个代码,所以我确定有很多优化要做。这样做很有趣。

不打高尔夫球

,[>,] Read all input
++++++++++ Flag for 10
[                   Subtract 10 from each cell to flag space for blank
    [-<]            
    >
        [->]
        <
]
++++++++++ Flag for 10
[                   Add 10 back to each cell with value in it
    <[+<]<[+<]
    >[+>]>[+>]<---
]
<[<]<[<]>               goto first cell in first string string      

[                           Print first word subtracting one each time
    [.>]                    Print first string
    ++++++++++.----------   Print new line
    <[-]                    Kill last letter of first string
    <                       Back one
    [                       Move each first string character up one
          [->+<]
          <
    ]>>
]
>[<+>-]>                    Move to first letter of scond string back one goto second letter
[                               
    [<+>-]                  Move next letter back
    <[<]>                   Move to start of string
    [.>]                    Print string
    ++++++++++.----------   Print new line
    >
]

欢迎来到PPCG!令人印象深刻的第一篇文章!
Rɪᴋᴇʀ
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.