Perlahan putar string menjadi yang lain


31

Tantangan

Diberikan dua string / array string, output string pertama perlahan menyusut dan berkembang kembali ke string kedua.

Anda dapat mengasumsikan string akan selalu dimulai dengan karakter yang sama.

Contoh

Input:
"Test", "Testing"

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

Pertama, Anda menghasilkan kata pertama:

Test

Kemudian Anda terus menghapus satu huruf hingga string tersebut panjangnya satu karakter:

Tes
Te
T

Kemudian terus tambahkan satu huruf dari kata kedua sampai selesai:

Te
Tes
Test
Testi
Testin
Testing

(Jika kedua string memiliki panjang satu karakter, maka cukup tampilkan satu dari mereka satu kali.)

Uji Kasus

"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

(catatan: pada ruang / test case keempat, ganti S dengan spasi)

Aturan

  • Ini , jadi jawaban tersingkat dalam byte menang! Tiebreaker adalah pos yang paling banyak dipilih. Pemenang akan dipilih pada 09/10/2016.

  • Celah standar dilarang.


Akankah 2 trailing baris baru (satu baris kosong terlihat setelah urutan) diizinkan atau tidak?
seshoumara

Jawaban:


11

Pyth, 9 byte

j+_._Et._

Sebuah program yang mengambil string kedua, dan kemudian string pertama, seperti string yang dikutip pada STDIN dan mencetak hasilnya.

Cobalah online

Bagaimana itu bekerja

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 byte

òYp$xhòjòÄ$xhh

Cobalah online!

Penjelasan:

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

Sekarang, buffer terlihat seperti ini:

0123456789
012345678
01234567
0123456
012345
01234
0123
012
01
0

Kita hanya perlu melakukan hal yang sama secara terbalik untuk baris berikutnya:

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.

Solusi alternatif yang lebih menarik :

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

3
Ini seperti vim selalu alat yang tepat untuk pekerjaan
Downgoat

@Downgoat Tepat. Itu sebabnya Anda harus mulai bermain golf di V.: P
DJMcMayhem

9

Python, 93 byte

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)

Mulai dengan string kosong r, tambah adan baris baru dan hapus karakter terakhir dari asampai akosong kemudian tambahkan bagian yang diperlukan dari bdan baris baru dengan menyimpan penghitung i,, yang dimulai pada 2sampai panjang bterlampaui, kemudian kembali r. Memiliki baris baru.

Semua tes ada di ideone


2 hal. 1) Saya percaya bahwa Anda salah menghitung karakter dan sebenarnya 93 dan 2) Anda tidak perlu mengatakannya r="". Sederhana rmasih akan bekerja.

Terima kasih @JackBates. 1. Benar, dan diperbarui - Saya mungkin lupa f=. 2. Tanpa r=''hadiah f('test','testing')tidak akan berhasil; ya f('test','testing','')mau, tapi kita harus mengikuti spesifikasinya.
Jonathan Allan

Maafkan aku. Saya hanya melihat kode dan bukan contohnya.

7

05AB1E , 9 byte

.pRI.p¦«»

Penjelasan

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

Cobalah online!


7

Retina, 50 41 26 byte

Terima kasih kepada Martin Ender untuk menghemat 15 (!) Byte.

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

Mengambil input dengan dua string yang dipisahkan oleh baris baru:

Test
Testing

Cobalah online!

Penjelasan

M&!r`.+

Baris pertama menghasilkan "langkah" dari kedua kata:

Testing
Testin
Testi
Test
Tes
Te
T
Test
Tes
Te
T

Madalah untuk mode kecocokan, &mempertimbangkan kecocokan yang tumpang tindih, dan !mencetak kecocokan alih-alih jumlahnya. Alasannya terbalik adalah opsi right-to-left: mesin mulai mencari kecocokan di akhir tali dan terus menuju awal.

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

Ini mendapatkan semuanya dalam urutan yang benar: ini Ococok dengan semua kecocokan dari regex berikutnya: Karakter pada barisnya sendiri dan setiap karakter (termasuk baris baru) setelahnya, yang cocok dengan seluruh babak kedua sebagai satu potongan, atau sebaris karakter , yang cocok dengan setiap baris individu. Pencocokan ini kemudian disortir berdasarkan titik kode, sehingga T diikuti oleh baris yang pertama, diikuti oleh garis, naik menurut panjangnya.

A1`

Sekarang kita hanya memiliki baris karakter pertama di atas sehingga kita menggunakan Amode ntigrep untuk membuang pertandingan pertama dari regex default .+.

Versi lama

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

Coba versi ini secara daring!

Penjelasan

Baris pertama sama, jadi lihat penjelasannya di atas.

O`\G..+¶

Ini membalikkan baris bagian pertama (kata input kedua). Ini sebenarnya Obaris, dan regex membatasi pertandingan: itu harus menjadi garis dua atau lebih karakter ( ..+) diikuti oleh baris baru ( ) yang dimulai di mana yang terakhir tinggalkan ( \G). Pada contoh di atas, single Tdi tengah tidak cocok, jadi tidak ada hasilnya.

Te
Tes
Test
Testi
Testin
Testing
T
Test
Tes
Te
T

Sekarang kita memiliki dua komponen yang benar, tetapi dalam urutan yang salah.

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

¶.¶cocok dengan satu-satunya T di tengah, yang tidak kita butuhkan tetapi memisahkan dua bagian. Keduanya (.*)menangkap semuanya sebelum dan sesudah, termasuk baris baru berkat smode ingle-line. Dua tangkapan diganti dalam urutan yang benar dengan baris baru di antaranya.

Sekarang kita sudah selesai, kecuali string input panjangnya satu karakter, dalam hal ini input tidak berubah. Untuk menghilangkan duplikat, kami mengganti ¶.$(ketika baris terakhir dari string karakter tunggal) dengan apa-apa.


4

Python 2, 88 82 byte

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

Mengambil dua input, masing-masing dikelilingi oleh tanda kutip.

Terima kasih @JonathanAllan untuk menyimpan beberapa byte dan menunjukkan bug.


1
Tidak perlu len(x)masuk x=x[:len(x)-1]karena mengiris mengimbangi negatif bekerja - Anda hanya dapat menulis x=x[:-1]. Satu-satunya masalah adalah kode Anda tidak akan menangani " ", " "test case dengan sangat baik.
Jonathan Allan

1
Anda dapat menghapus yang kedua input()dan menggunakan format input seperti"<str1>", "<str2>"
LevitatingLion

Anda dapat mengubah baris kedua menjadi for i in range(x):print x[-i:], dan baris keempat menjadi for i in range(1,y):print y[:-i]. Tapi tidak yakin itu akan berhasil.
clismique

4

Perl, 34 28 byte

Termasuk +2untuk-0n

Jalankan dengan string pada baris terpisah di STDIN:

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

slow.pl:

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

Biarkan regex mundur melakukan pekerjaan ...


3

Cheddar , 76 byte

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

Sedikit lebih lama dari yang saya sukai. Saya akan segera menambahkan penjelasan

Cobalah online!


Apa yang |>harus dilakukan
Cyoce

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

3

Brachylog , 32 byte

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

Cobalah online!

Penjelasan

Brachylog tidak memiliki awalan built-in, oleh karena itu kami akan mendapatkan awalan dengan menggunakan concatenate(Lihat predikat 2): awalan Sadalah Pjika Pdigabungkan dengan Q(apa pun itu) menghasilkan S.

  • Predikat utama:

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

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

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

3

Javascript, 103 81 byte

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

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

Keluaran:

Test
Tes
Te
T
Te
Tes
Test
Testi
Testin
Testing

Jawaban asli

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 byte

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

Memperbarui

  • Variabel yang dihapus, disimpan 9 byte

Tidak Terkumpul :

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

Penggunaan :

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

3

Haskell, 54 53 47 byte

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

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

Beberapa sihir pointfree. Ini sama dengan di f x y = (init(t x))++reverse (t y)mana tmembuat daftar semua substring awal mis t "HI!"- - ["H","HI","HI!"].


Hm t=reverse.tail.inits,?
Bergi

@Bergi: pasti, tapi initsperlu import Data.List.
nimi


3

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

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

Menjalankan:

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

Input harus berupa dua string yang dipisahkan oleh baris baru. Kode dijalankan oleh sed untuk setiap baris.

Loop :menghapus satu karakter dari ujung string secara iteratif. Output yang berhubungan dengan string pertama dicetak langsung, kecuali karakter pertama: 1{/../p}. Output untuk string kedua disimpan dalam ruang tunggu dalam urutan terbalik ( 2G;2h) selama penghapusan dan dicetak di akhir.


3

C (gcc) , 102 97 95 93 byte

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

Cobalah online!

Loop pertama menimpa string dengan 0 byte mulai dari akhir, dan digunakan puts()untuk mencetak string. Loop kedua tidak bisa hanya menimpa dari awal, ia harus menyimpan nilai lama sehingga dapat mengembalikannya; 0 byte hanya berjalan menuju akhir.

Terima kasih kepada @homersimpson dan @ceilingcat untuk setiap pengurangan 2 byte!


1
Anda dapat menyimpan beberapa byte dengan menyatakan nsebagai int global seperti: n;f(char*a,char*b){n=strlen(a).... Dan Anda mungkin bisa melakukan n=*a=0tugas berantai di tubuh for for loop Anda.
homersimpson

Terima kasih @homersimpson. Tetapi n = * a = 0 tidak sama dengan n = * a, * a = 0.
G. Sliepen

2

Python 3, 104 byte

Ah.

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

Terima kasih kepada @DJMcMayhem untuk bermain golf 21 byte.

Ide itu!


1
Anda dapat mengambil 5 byte jika Anda melakukannya n='\n'dan menggunakan n sebagai gantinya '\n'. Anda bisa melepas 8 lagi jika menggunakan lambda alih-alih mencetak: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

Menggunakan string palsu untuk memotong string asli

Pelanggaran substring dengan angka yang lebih besar untuk menumbuhkan yang kedua, berhenti ketika akan mencetak kata yang sama seperti terakhir kali.

(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
itu 1 byte lebih pendek untuk dilakukan a=>b=>...dan memanggil fungsi dengan (a) (b)
Zwei

2

Brainfuck, 38 55 byte

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

Sunting: termasuk baris baru dalam output


Saya tidak dapat mengaktifkan kode Anda. Apakah input dipisahkan oleh baris baru? Juru bahasa apa yang Anda gunakan?
acrolith

2

Dyalog APL , 20 13 byte

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

matrify

(⌽,\⍞)terbalik ( ) gabungan kumulatif ( ,\) dari input karakter ( )

, ditambahkan ke

1↓ satu elemen jatuh dari

,\⍞ gabungan kumulatif input karakter

TryAPL online!


2

Racket 193 byte

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

Pengujian:

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

Seharusnya menghapus karakter terakhir dari string input, bukan yang pertama.
agilob

2

Floroid , 69 byte

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)

Ini awal. Mengambil input dari 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 byte

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

The replacepernyataan membangun sebuah segitiga string, yang persis apa yang diperlukan untuk paruh kedua output, namun babak pertama perlu dibalik dan duplikat baris-karakter dihapus. Catatan: menampilkan baris baru terkemuka jika string pertama adalah satu karakter. Jika ini tidak diinginkan maka untuk byte tambahan versi ini selalu menampilkan baris tambahan:

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

1

C, 142 byte

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

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


1

TI-Basic, 56 byte

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

Contoh penggunaan

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 byte

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

Program tes tidak digabungkan

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 byte

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

Lebih mudah dibaca, tetapi dua byte lebih panjang:

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


Keluaran:

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

1

J, 18 byte

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

Tidak Disatukan:

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

Ini adalah kereta 7:

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

Kereta terdalam [: |. ]\@[terdiri dari topi [:di sebelah kiri, jadi kami menerapkan |.(mundur) ke hasil ]\@[, yaitu ]\(awalan) di atas[ (argumen kiri).

Inilah yang terlihat pada testing, testinput:

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

Ini memberi kita porsi pertama, hampir. 5-kereta di luar itu adalah ([: }: ([: |. ]\@[)), yang berlaku }:(betail, hapus elemen terakhir) dengan ungkapan di atas:

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

(Ini karena kami tidak dapat memiliki titik tengah rangkap.)

Bagian luar akhirnya:

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

Ini terdiri dari ]\@](awalan argumen kiri) dan ,~(tambahkan apa ke kiri dengan apa ke kanan), meninggalkan kita dengan hasil yang diinginkan:

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

Uji kasus

   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

Anda dapat mengatur ulang menjadi 14 byte menggunakan(,~}:@|.)&(]\)
miles

1

PHP, 117 109 byte

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 byte (tidak bekerja dengan string yang mengandung 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 byte

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

Tes tidak serigala

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

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

Coba di sini

Input mengambil dua string yang dipisahkan oleh umpan baris.

Program pertama dengan brianfuck dan kode golf pertama jadi saya yakin ada banyak optimasi yang harus dilakukan. Bersenang-senang melakukannya.

Tidak disatukan

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

Selamat datang di PPCG! Pos pertama yang mengesankan!
R
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.