Bir dizgiyi yavaşça diğerine dönüştürün


31

Meydan okuma

İki karakter dizisi / bir karakter dizisi verildiğinde, ilk dizeyi yavaşça küçülen ve ikinci dizgiye geri genişleyen çıktı.

Dizelerin her zaman aynı karakterle başlayacağını varsayabilirsiniz.

Örnek

Input:
"Test", "Testing"

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

İlk önce ilk kelimeyi çıkardınız:

Test

Ardından, dize bir karakter uzunluğa gelene kadar bir harfi kaldırmaya devam edersiniz:

Tes
Te
T

Ardından, bitinceye kadar ikinci kelimenin bir harfini eklemeye devam edin:

Te
Tes
Test
Testi
Testin
Testing

(her iki dizenin de bir karakter uzunluğunda olması durumunda, bunlardan yalnızca bir kez çıktı verir.)

Test Kılıfları

"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

(not: boşluk / dördüncü test durumunda, S'yi boşluklarla değiştirin)

kurallar

  • Bu , bayt cinsinden en kısa cevap! Tiebreaker en çok oy alan yazı. Kazanan, 09/10/2016 tarihinde seçilecektir.

  • Standart boşluklar yasaktır.


2 sondaki yeni satıra (diziden sonra bir görünür boş satır) izin verilecek mi?
seshoumara

Yanıtlar:


11

Pyth, 9 bayt

j+_._Et._

İkinci dizeyi ve ardından ilk dizeyi STDIN'de belirtilen dizeler olarak alan ve sonucu basan bir program.

Çevrimiçi deneyin

Nasıl çalışır

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 bayt

òYp$xhòjòÄ$xhh

Çevrimiçi deneyin!

Açıklama:

ò     ò     "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.

Şimdi, tampon bu gibi görünüyor:

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0

Sadece aynı şeyi bir sonraki satır için tersine yapmamız gerekiyor:

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.

Daha ilginç alternatif çözüm :

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

3
Vim her zaman iş için doğru bir araçtır
Downgoat

@Downgoat Tam olarak. Neden en Yani sen P: V'te golf başlamak gerekir
DJMcMayhem

9

Python, 93 bayt

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)

Boş dizge ile başlar r, ekler ave bir yeni satır ve son karakteri kaldırır akadar asonra boş gerekli kısımları ekler bbir sayaç tutarak ve bir yeni satır, ien başladığı 2uzunluğu kadarb aşılana , sonra döner r. Sonunda yeni bir hattı var.

Tüm testler ideone üzerinde


2 şey. 1) Karakterleri yanlış saydığına ve aslında 93 ve 2 olduğuna inanıyorum. 2) Söylemene gerek yok r="". Basit rhala işe yarar.

@ JackBates teşekkürler. 1. Doğru ve güncellenmiş - Muhtemelen unuttum f=. Olmadan 2. r=''mevcut f('test','testing')iş değildir; evet f('test','testing',''), ama şartnamelere uymalıyız.
Jonathan Allan,

Beni affet. Sadece kodlara bakıyordum, örneklere değil.

7

05AB1E , 9 bayt

.pRI.p¦«»

açıklama

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

Çevrimiçi deneyin!


7

Retina, 50 41 26 bayt

Martin Ender'e 15 (!) Bayt tasarrufu sağladığı için teşekkür ederiz.

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

Yeni bir satırla ayrılmış iki dizeyle girdi alır:

Test
Testing

Çevrimiçi deneyin!

açıklama

M&!r`.+

İlk satır her iki kelimenin de "basamağını" oluşturur:

Testing
Testin
Testi
Test
Tes
Te
T
Test
Tes
Te
T

Meşleşme modu içindir, &çakışan eşleşmeleri göz önünde bulundurur ve !eşleşmeleri sayı yerine yazdırır. Tersine döndürülmesinin nedeni rsoldan sağa seçenektir: motor, ipin sonunda eşleşmeleri aramaya başlar ve başlangıcına doğru devam eder.

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

Bu, her şeyi doğru sıraya göre alır: Osonraki regex'in tüm eşleşmelerini listeler: Kendi satırındaki bir karakter ve bundan sonraki her karakter (yeni satırlar dahil), ikinci yarının tamamını bir yığın veya başka bir karakter dizisi ile eşleştirir Her bir satırla eşleşen. Bu eşleşmeler daha sonra kod noktasına göre sıralanır, böylece yeni satır izleyen T, önce satır, ardından uzunluk artar.

A1`

Şimdi sadece ilk karakter satırına sahibiz, bu nedenle Avarsayılan regex'in ilk eşleşmesini silmek için ntigrep modunu kullanırız .+.

Eski versiyon

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

Bu sürümü çevrimiçi olarak deneyin!

açıklama

İlk satır aynıdır, bu nedenle yukarıdaki açıklamalara bakınız.

O`\G..+¶

Bu, ilk yarıdaki (ikinci giriş kelimesi) satırlarını tersine çevirir. Aslında Osatırları sıralar ve regex eşleşmeleri sınırlar: iki veya daha fazla karakterden ..+oluşan bir satır ( ) ve ardından sonuncunun kaldığı yerden başlayan bir newline ( \G) olmalıdır. Yukarıdaki örnekte, Tortadaki tek eşleşmiyor, yani ondan sonra hiçbir şey yok.

Te
Tes
Test
Testi
Testin
Testing
T
Test
Tes
Te
T

Şimdi doğru iki bileşene sahibiz, ancak yanlış sırada.

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

¶.¶İhtiyacımız olmayan fakat iki parçayı ayıran ortadaki yalnız T ile eşleşir. İkili (.*), single-line modu sayesinde yeni satırlar da dahil olmak üzere önceki ve sonraki her şeyi yakalar . İki yaka, doğru sırayla ikisinin arasında bir yenisiyle değiştirilir.

Now we're done, unless the input strings are one character long, in which case the input hasn't changed. To get rid of the duplicate, we replace ¶.$ (when the last line of the string a single character) with nothing.


4

Python 2, 88 82 bytes

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

Takes two inputs, each surrounded by quotes.

Thanks @JonathanAllan for saving some bytes and pointing out a bug.


1
No need for the len(x) in x=x[:len(x)-1] since negative offset slicing works - you can just write x=x[:-1]. Only problem is your code wont handle the " ", " " test case very well.
Jonathan Allan

1
You can drop the second input() and use an input format like "<str1>", "<str2>"
LevitatingLion

You could change the second line to for i in range(x):print x[-i:], and the fourth line to for i in range(1,y):print y[:-i]. Not sure it would work, though.
clismique

4

Perl, 34 28 bytes

Includes +2 for -0n

Run with the strings on separate lines on STDIN:

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

slow.pl:

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

Let regex backtracking do the work...


3

Cheddar, 76 bytes

(a,b,q=s->(|>s.len).map((_,i)->s.head(i+1)))->(q(a).rev+q(b).slice(1)).vfuse

A bit longer than I'd liked. I'll add an explanation soon

Try it online!


What does |> do?
Cyoce

@Cyoce unary |> is range [0,n) binary is [a,b]
Downgoat

3

Brachylog, 32 bytes

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

Try it online!

Explanation

Brachylog has no prefix built-in, therefore we will get the prefixes by using concatenate (See predicate 2): a prefix of S is P if P concatenated to Q (whatever it is) results in S.

  • Main predicate:

    :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
    
  • Predicate 1:

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

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

3

Javascript, 103 81 bytes

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

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

Output:

Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Original answer

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 bytes

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++));}}

Update

  • Removed s variable, saved 9 bytes

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++));
        }
    }
}

Usage:

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

3

Haskell, 54 53 47 bytes

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

Usage example: ((.reverse.t).(++).init.t) "Hello" "Hi!" -> ["Hello","Hell","Hel","He","H","Hi","Hi!"].

Some pointfree magic. It's the same as f x y = (init(t x))++reverse (t y) where t makes a list of all initial substrings e.g. t "HI!" -> ["H","HI","HI!"].


Hm, t=reverse.tail.inits?
Bergi

@Bergi: sure, but inits needs import Data.List.
nimi


3

GNU sed, 57 45 + 2(rn flags) = 47 bytes

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

Run:

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

The input should be the two strings separated by a newline. The code is run by sed for each line.

The loop : deletes one character from the end of the string iteratively. The output related to the first string is printed directly, except the first character: 1{/../p}. The output for the second string is stored in hold space in reverse order (2G;2h) during deletion and printed at the end.


3

C (gcc), 102 97 95 93 bytes

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);}

Try it online!

The first loop overwrites the string with 0 bytes starting from the end, and uses puts() to print the string. The second loop can't just overwrite from the beginning, it has to store the old value so it can put it back; the 0 byte is just walking towards the end.

Thanks to @homersimpson and @ceilingcat for each shaving off 2 bytes!


1
You can save a couple bytes by declaring n as a global int like: n;f(char*a,char*b){n=strlen(a).... And you can probably do n=*a=0 as a chained assignment in the body of your for loop.
homersimpson

Thanks @homersimpson. But n=*a=0 is not the same as n=*a,*a=0.
G. Sliepen

2

Python 3, 104 bytes

Meh.

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))

Thanks to @DJMcMayhem for golfing 21 bytes off.

Ideone it!


1
You can take 5 bytes of if you do n='\n' and use n instead of '\n'. You could take another 8 off if you used a lambda instead of printing: 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 Bytes

Uses false string to whittle down the original string

Abuses substring with larger numbers to grow the second one, stops when its about to print the same word as last time.

(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)}}

Demo:

> ((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
it's 1 byte shorter to do a=>b=>... and call the function with (a)(b)
Zwei

2

Brainfuck, 38 55 bytes

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

Edit: included newlines in output


I can't get your code to work. Is the input separated by a new line? Which interpreter are you using?
acrolith

2

Dyalog APL, 20 13 bytes

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

matrify

(⌽,\⍞) reversed () cumulative concatenation (,\) of character input ()

, prepended to

1↓ one element dropped from

,\⍞ cumulative concatenation of character input

TryAPL online!


2

Racket 193 bytes

(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))))))

Testing:

(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."

It should delete last character from input string, not the first one.
agilob

2

Floroid, 69 bytes

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)

It's a start. Takes the input from STDIN.

Testcases

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

Input: O O
Output: O

1

JavaScript (ES6), 92 bytes

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

The replace statements build up a triangle of strings, which is exactly what's required for the second half of the output, however the first half needs to be reversed and the duplicate single-character line removed. Note: outputs a leading newline if the first string is a single character. If this is undesirable then for an extra byte this version always outputs a trailing newline:

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

1

C, 142 bytes

#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))}

Provide f(char* str1, char* str2).


1

TI-Basic, 56 bytes

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

Example usage

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 bytes

(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));};

Ungolfed test program

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 bytes

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

More readable, but two bytes longer:

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


Output:

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

1

J, 18 bytes

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

Ungolfed:

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

This is a 7-train:

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

The innermost train [: |. ]\@[ consists of a cap [: on the left, so we apply |. (reverse) to the result of ]\@[, which is ]\ (prefixes) over [ (left argument).

Here's what that looks like on the testing, test input:

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

This gives us the first portion, almost. The 5-train outside of that is ([: }: ([: |. ]\@[)), which applies }: (betail, remove last element) to the above expression:

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

(This is because we can't have a duplicate midpoint.)

The outer part is finally:

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

This is composed of ]\@] (prefixes of left argument) and ,~ (append what's to the left with what's to the right), leaving us with the desired result:

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

Test cases

   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

You can rearrange it to 14 bytes using (,~}:@|.)&(]\)
miles

1

PHP, 117 109 bytes

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 bytes (not working with strings containing 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 bytes

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);}

Ungolfed test

#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 bytes

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

Try it here

Input takes the two strings separated by a linefeed.

First program with brianfuck and first code golf so I'm sure there is plenty of optimization to be done. Had fun doing it though.

Ungolfed

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

Welcome to PPCG! Impressive first post!
Rɪᴋᴇʀ
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.