文字列をゆっくりと別の文字列に変える


31

チャレンジ

2つの文字列/文字列の配列が与えられた場合、最初の文字列をゆっくりと縮小し、2番目の文字列に戻します。

文字列は常に同じ文字で始まると仮定できます。

Input:
"Test", "Testing"

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

最初に最初の単語を出力します:

Test

次に、文字列の長さが1文字になるまで1文字を削除し続けます。

Tes
Te
T

次に、2番目の単語の1文字を追加し続けます。

Te
Tes
Test
Testi
Testin
Testing

(両方の文字列が1文字の長さである場合、どちらか一方を一度だけ出力します。)

テストケース

"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

(注:スペース/ 4番目のテストケースでは、Sをスペースに置き換えます)

ルール

  • これはなので、バイト単位の最短回答が勝ちです!Tiebreakerは最も支持されている投稿です。勝者は2016年9月10日に選ばれます。

  • 標準的な抜け穴は禁止されています。


2つの末尾の改行(シーケンスの後の1つの空行)は許可されますか?
seshoumara

回答:


11

Pyth、9バイト

j+_._Et._

STDINで引用符付き文字列として2番目の文字列を取得し、次に最初の文字列を取得し、結果を出力するプログラム。

オンラインで試す

使い方

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まさに。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と改行を追加します。末尾に改行があります。i2br

すべてのテストはideoneで行われます


2つのこと。1)キャラクターの数を間違えたと思いますが、実際は93であり、2)言う必要はありませんr=""。シンプルでrも動作します。

@JackBatesに感謝します。1.修正、更新-おそらく忘れましたf=。2. r=''現在なしでf('test','testing')は機能しません。はいf('test','testing','')、そうですが、仕様に従う必要があります。
ジョナサンアラン

私を許して。サンプルではなくコードを見ているだけです。


7

網膜、50 41 26バイト

15(!)バイトを節約してくれたMartin Enderに感謝します。

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

改行で区切られた2つの文字列で入力を取得します。

Test
Testing

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

説明

M&!r`.+

最初の行は、両方の単語の「ステップ」を生成します。

Testing
Testin
Testi
Test
Tes
Te
T
Test
Tes
Te
T

M一致モード用で、&重複する一致を考慮し!、一致の数ではなく一致を出力します。反転する理由は、r左から右へのオプションです。エンジンは、文字列の末尾で一致を探し始め、先頭に向かって続行します。

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

これはすべてを正しい順序で取得します:O後続の正規表現のすべての一致をrtsします:独自の行の文字とその後のすべての文字(改行を含む)。 、個々の行に一致します。次に、これらの一致はコードポイントでソートされるため、Tの後に改行が続き、次に行が続き、長さが昇順になります。

A1`

これで最初の文字行が先頭にあるので、Antigrepモードを使用して、デフォルトの正規表現の最初の一致を破棄します.+

古いバージョン

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

このバージョンをオンラインでお試しください!

説明

最初の行は同じなので、上記の説明を参照してください。

O`\G..+¶

これにより、前半(2番目の入力ワード)の行が反転します。実際にOは行をrtsし、正規表現は一致を制限します。2文字以上の行(..+)の後に、最後の行が終わったところから始まる改行()でなければなりません(\G)。上記の例ではT、真ん中のシングルは一致しないため、その後は何も一致しません。

Te
Tes
Test
Testi
Testin
Testing
T
Test
Tes
Te
T

これで正しい2つのコンポーネントができましたが、順序は間違っています。

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

¶.¶中央の孤立したTに一致します。これは必要ありませんが、2つの部分を分離します。この2つは(.*)sイングルラインモードのおかげで改行を含む前後のすべてをキャプチャします。2つのキャプチャは正しい順序で置換され、間に改行が入ります。

入力文字列が1文字の長さでない限り、これで完了です。その場合、入力は変更されていません。重複を取り除くために、¶.$(文字列の最後の行が1文字の場合)何も置き換えません。


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

それぞれが引用符で囲まれた2つの入力を取ります。

いくつかのバイトを保存してバグを指摘してくれた@JonathanAllanに感謝します。


1
負のオフセットスライシングが機能するため、len(x)inの必要はありませんx=x[:len(x)-1]-書くだけx=x[:-1]です。唯一の問題は、コードが" ", " "テストケースをうまく処理できないことです。
ジョナサンアラン

1
あなたは第二をドロップすることができますinput()などの入力形式を使用"<str1>", "<str2>"
LevitatingLion

2行for i in range(x):print x[-i:]目をに、4行目をに変更できます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):の接頭辞がSある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

Java、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バイトを保存しました

アンゴルフド

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)where tがすべての初期部分文字列のリストを作成する場所と同じですt "HI!"- 例えば、["H","HI","HI!"]


うんt=reverse.tail.inits
ベルギ

@Bergi:確かに、しかしinits必要import Data.Listです。
nimi


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

入力は、改行で区切られた2つの文字列にする必要があります。コードは各行ごとにsedによって実行されます。

ループ:は、文字列の末尾から1文字を繰り返し削除します。最初の文字列に関連する出力は、最初の文字を除き、直接印刷されます:1{/../p}。2番目の文字列の出力は、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()印刷にします。2番目のループは、最初から上書きすることはできません。古い値を保存して、元に戻すことができます。0バイトは最後に向かって歩いています。

2バイトを削るごとに@homersimpsonと@ceilingcatに感謝します!


1
次のnようなグローバルintとして宣言することで、数バイトを節約できますn;f(char*a,char*b){n=strlen(a)...。そして、おそらくn=*a=0forループの本体で連鎖割り当てとして行うことができます。
ホーマーシンプソン

ありがとう@homersimpson。ただし、n = * a = 0はn = * a、* a = 0と同じではありません。
G.スリーペン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))

21バイトのゴルフをしてくれた@DJMcMayhemに感謝します。

できた!


1
n='\n'使用する場合は5バイトを使用でき、の代わりにnを使用できます'\n'。あなたの代わりに、印刷のラムダを使用した場合は、別の8オフを取ることができる: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)))
DJMcMayhem

2

REPL / Javascript、109バイト

偽の文字列を使用して、元の文字列を削ります

大きい数字の部分文字列を乱用して2番目の文字列を拡大し、前回と同じ単語を出力しようとすると停止します。

(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=>...()(B)との関数を呼び出すと
ツヴァイ

2

Brainfuck、38 55バイト

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

編集:出力に改行を含める


コードを機能させることができません。入力は改行で区切られていますか?どのインタープリターを使用していますか?
アクロリス16


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、168 136バイト

(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

(ラムダボット)Haskell-41バイト

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

読みやすくなっていますが、2バイト長くなっています。

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


出力:

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

1

J、18バイト

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

ゴルフをしていない:

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

これは7トレインです。

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

最も内側の列車は[: |. ]\@[キャップで構成され[:、我々が適用されますので、左の|.結果に(逆)]\@[である、]\(接頭辞)を超えます[(left argument)ます。

testing, test入力では次のようになります。

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

これにより、ほぼ最初の部分が得られます。それ以外の5トレインは([: }: ([: |. ]\@[))}:、上記の式に適用されます(つまり、最後の要素を削除します)。

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

(これは、中間点を複製できないためです。)

外側の部分は最終的に次のとおりです。

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

これは、]\@](左引数のプレフィックス)と,~(左に何を追加し、右に何を追加するか)で構成され、目的の結果を残します。

   '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

あなたは14使ってバイトにそれを並べ替えることができます(,~}:@|.)&(]\)
マイル

1

PHP、117 109バイト

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

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

ここで試してみてください

入力は、改行で区切られた2つの文字列を取ります。

brianfuckを使用した最初のプログラムと最初のコードゴルフで、最適化が十分に行われると確信しています。でもそれを楽しんでいた。

非ゴルフ

,[>,] 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ɪᴋᴇʀ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.