Backspace-dan-ketik ulang daftar kata

38

Berikut cara backspace-dan-mengetik ulang dari satu string ke yang lain:

  1. Mulai dari string pertama.
  2. Hapus karakter di bagian akhir hingga hasilnya adalah awalan dari string kedua. (Ini mungkin mengambil 0 langkah.)
  3. Tambahkan karakter di akhir hingga hasilnya sama dengan string kedua. (Ini mungkin mengambil 0 langkah juga.)

Misalnya, jalur dari fooabcke fooxyzterlihat seperti:

fooabc
fooab
fooa
foo
foox
fooxy
fooxyz

Tugas

Diberikan daftar kata-kata, tulis sebuah program yang mundur-dan-mengetik ulang jalannya dari string kosong, ke semua kata dalam daftar berturut-turut, kembali ke string kosong. Keluarkan semua string perantara.

Misalnya, mengingat daftar input ["abc", "abd", "aefg", "h"], output harus:

a
ab
abc
ab
abd
ab
a
ae
aef
aefg
aef
ae
a

h

Aturan

Anda dapat mengembalikan atau mencetak daftar string, atau string tunggal dengan beberapa pembatas pilihan. Anda dapat secara opsional menyertakan string kosong awal dan akhir. Input dijamin mengandung setidaknya satu kata, dan setiap kata dijamin hanya mengandung huruf ASCII huruf kecil ( a- z). Sunting: string berturut-turut dalam input dijamin tidak sama satu sama lain.

Ini adalah ; kode terpendek dalam byte menang.

Implementasi referensi di Python 3: Cobalah online!

Lynn
sumber
4
@ rahnema1> menulis sebuah program yang mundur-dan-mengetik ulang jalannya dari string kosong
Kritixi Lithos
3
Bagaimana hasilnya ["abc","abc"]?
Kritixi Lithos
1
@ Emigna Ups, ini persis seperti itu tetapi dalam satu lingkaran! Jadi saya akan melanjutkan dan mengatakan ini adalah duplikat dari itu.
Lynn
4
@ Lynn Ini bukan hal yang persis sama. Yang satu itu tidak termasuk mengenali awalan umum, itu selalu turun ke satu karakter.
Martin Ender
6
Test case:a,abc,abcde,abc,a,abc,abcde
Zgarb

Jawaban:

9

Perl, 43 byte

42 byte kode + -nbendera.

chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge

Untuk menjalankannya:

perl -nE 'chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge' <<< "abc
abd
aefg
h"
Dada
sumber
ini mencetak abc 3 kali
izabera
@izabera Ada spasi setelah abcmenyebabkannya dicetak 3 kali (tapi sebenarnya, pertama dan ketiga kali itu tanpa spasi). Saya menghapusnya.
Dada
5

Java 8, 144 byte

Yang ini mirip dengan implementasi referensi tetapi menggabungkan dua whileloop. Ini adalah ekspresi lambda yang menerima String[]parameter.

a->{String c="";int l=0,i;for(String w:a)while((i=w.indexOf(c))!=0||!c.equals(w))System.out.println(c=i!=0?c.substring(0,--l):c+w.charAt(l++));}

Tidak disatukan

a -> {
    String c = "";
    int l = 0, i;
    for (String w : a)
        while ((i = w.indexOf(c)) != 0 || !c.equals(w))
            System.out.println(c = i != 0 ? c.substring(0, --l) : c + w.charAt(l++));
}

Ucapan Terima Kasih

  • -38 byte berkat saran lambda CAD97
Jakob
sumber
Bukankah lebih murah untuk digunakan, class Bbukan interface B? Anda dapat menjalankan dari kelas paket-pribadi. Juga, pertimbangkan untuk menggunakan lambda karena Anda telah menentukan Java8.
CAD97
@ CAD97 interface B{static void mainlebih pendek dariclass B{public static void main .
Kevin Cruijssen
@ CAD97 Saya tidak bisa memikirkan cara untuk membawa lambdas ke dalam ini, tapi saya baru tahu tentang mereka kemarin. Ada ide?
Jakob
1
Ah, saya berkarat. Anda harus bisa melakukannyaa->{/*your code*/} , yang akan menetapkan ke variabel tipe java.util.function.Consumer<String[]>. Namun, saya tidak dapat menguji saat ini.
CAD97
1
@JakobCornell Secara default PPCG memungkinkan pengiriman program atau fungsi penuh. Untuk bahasa dengan fungsi anonim (lambda), fungsi anonim sendiri adalah jawaban yang dapat diterima (sehingga Anda tidak harus menyertakan variabel untuk menyimpannya). (Meskipun dalam pengiriman Jawa sopan untuk memberikan jenis lambda.)
CAD97
4

Mathematica, 149 byte

Reap[Fold[n=NestWhile;s=StringMatchQ;r=StringReplace;n[k=#2;Sow@r[k,#~~a_~~___:>#<>a]&,n[Sow@r[#,a___~~_:>a]&,#,!s[k,#~~___]&],k!=#&]&,"",#]][[2,1]]&
JungHwan Min
sumber
3

Retina , 39 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1.

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

Cobalah online!

Input dan output adalah daftar yang dipisahkan oleh linefeed. Output tidak termasuk string kosong terkemuka dan tertinggal.

Martin Ender
sumber
3

Jelly , 31 29 26 byte

⁷œ|;\
ÇṚðfḢṭḟ;ḟ@ḊðÇ}
⁷;ç2\

Cobalah online!

Bagaimana itu bekerja

⁷;ç2\           Main link. Argument: A (string array)

⁷;              Prepend a linefeed to A. 
                This is cheaper than prepending an empty string.
  ç2\           Reduce all overlapping pairs by the second helper link.


ÇṚðfḢṭḟ;ḟ@ḊðÇ}  Second helper link. Arguments: s, t (strings)

Ç               Call the first helper link with argument s.
 Ṛ              Reverse the results.
            Ç}  Call the first helper link with argument t.
  ð        ð    Combine everything in between into a dyadic chain, and call it
                with the results to both sides as arguments.
                Let's call the arguments S and T.
   f            Filter; get the common strings of S and T.
    Ḣ           Head; select the first one.
      ḟ         Filterfalse; get the strings in S that do not appear in T.
     ṭ          Tack; append the left result to the right one.
        ḟ@      Filterfalse swap; get the strings in T that do not appear in S.
       ;        Concatenate the results to both sides.
          Ḋ     Dequeue; remove the first string.


⁷œ|;\           First helper link. Argument: s (string)

⁷œ|             Linefeed multiset union; prepend a linefeed to s unless it already
                has a linefeed in it (the first string does).
   ;\           Concatenate cumulative reduce; generate all prefixes of the result.
Dennis
sumber
2

Haskell , 102 93 91 90 byte

(?)=take.length
a!x@(b:c)|a==b=b!c|a/=a?b=a:init a!x|d<-'?':a=a:d?b!x
_!x=x
(""!).(++[""])

Baris terakhir adalah fungsi anonim, yang mengambil dan mengembalikan daftar string. Cobalah online!

Penjelasan

Solusi saya bersifat rekursif. Pertama, ?adalah fungsi helper infix: a?bmemberikan length akarakter pertama b, atau keseluruhan bjika alebih panjang. Selanjutnya saya mendefinisikan fungsi infiks !. Idenya adalah bahwa a!x, di mana astring dan xdaftar string, menghasilkan jalur dari ake string pertama xdan berulang ke ekor x. Pada baris terakhir saya mendefinisikan fungsi anonim yang menambahkan string kosong, lalu berlaku! untuk string kosong dan input.

Penjelasan tentang !:

a!x@(b:c)        -- a!x, where x has head b and tail c:
  |a==b          -- If a equals b,
    =b!c         -- recurse to x.
  |a/=a?b        -- If a is not a prefix of b,
    =a:          -- produce a and
    init a!x     -- continue with one shorter prefix of a.
  |              -- Otherwise a is a proper prefix of b.
   d<-'?':a      -- Let d be a with an extra dummy element,
    =a:          -- produce a and
    d?b!x        -- continue with one longer prefix of b.
_!x=x            -- If x is empty, return x.
Zgarb
sumber
2

Python 2, 118 107 103 97 93 92 byte

s=''
for i in input()+[s]:
 while i.find(s):s=s[:-1];print s
 while i>s:s+=i[len(s)];print s

Input diberikan sebagai ['abc', 'abcdef', 'abcfed'], atau sebagai [ "abc", "abcdef", "abcfed"].

Revisi 1: -11 byte. Kredit diberikan kepada @xnor untuk posnya tentang kiat golf Python, dan @Lynn karena menemukan tip untuk saya, dan bagi saya karena pintar. Dua perubahan dilakukan: Alih-alihnot s.startswith(i) , saya menggunakan s.find(i), dan bukannya i!=ssaya menggunakan i>s.

Revisi 2: -4 byte. Penghargaan bagi saya menyadari saya membuat kesalahan yang sangat bodoh. Alih-alih menggunakan indentasi tab tunggal dan tab ganda, saya menggunakan indentasi spasi tunggal dan tab tunggal.

Revisi 3: -6 byte. Credit pergi ke @ mbomb007 karena menyarankan untuk menempatkan whiles pada satu baris. Saya juga memperbaiki bug dengan mengubahs.find(i) ke i.find(s).

Revisi 4: -4 byte. Kredit pergi ke @ xnor karena menyadari bahwa saya tidak perlu menyimpan input dalam suatu variabel.

Revisi 5: -1 byte. Kredit diberikan kepada saya karena menyadari bahwa itu ['']adalah hal yang sama seperti [s]ketika menambahkannya ke input.

HyperNeutrino
sumber
Letakkan whilemasing-masing pada satu baris. Selain itu, Anda dapat menggunakannya <1sebagai gantinya not.
mbomb007
Jawaban bagus! Ada tip bagus dari xnor tentang cara menghindarinyastartswith .
Lynn
@ Lynn Oh, terima kasih untuk tautannya! Saya merasa ini sangat membantu!
HyperNeutrino
@ mbomb007 Maaf, saya tidak mengerti maksud Anda dengan meletakkan whiles pada satu baris. Maksud Anda suka while s.find(i):s=s[:-1];print s? Juga, terima kasih atas sarannya <1, tetapi saya telah mengubah sesuatu yang lebih singkat berkat salah satu tips xnor pada utas tips Python.
HyperNeutrino
@AlexL. Ya, letakkan sementara seperti itu.
mbomb007
1

GNU M4, 228 atau 232 bytes¹

(¹ tergantung pada apakah akan mengakhiri file dengan dnl\natau tidak — saya masih baru untuk bermain golf dan M4)

define(E,`ifelse(index($2,$1),0,`T($1,$2)',`$1
E(substr($1,0,decr(len($1))),$2)')')define(T,`ifelse($1,$2,,`$1
T(substr($2,0,incr(len($1))),$2)')')define(K,`ifelse($2,,$1,`E($1,$2)K(shift($@))')')define(M,`K(substr($1,0,1),$@)')

Selain itu, 3 byte dapat disimpan dengan mengganti argumen kedua substrdari0 ke string kosong, tetapi itu akan menghasilkan banyak peringatan di stderr.

Tidak Disatukan:

define(erase_til_prefix, `dnl arguments: src dst; prints src and chops one char off of it until src == dst, at which point it calls type_til_complete instead
ifelse(dnl
index($2, $1), 0, `type_til_complete($1, $2)',dnl
`$1
erase_til_prefix(substr($1, 0, decr(len($1))), $2)dnl
')')dnl
define(type_til_complete, `dnl arguments: src dst; types src, does not type `dst' itself
ifelse(dnl
$1, $2, ,dnl
`$1
type_til_complete(substr($2, 0, incr(len($1))), $2)'dnl
)')dnl
define(main_, `dnl
ifelse(dnl
$2, , $1, dnl no arguments left
`erase_til_prefix($1, $2)main_(shift($@))'dnl
)')dnl
define(main, `main_(substr($1, 0, 1), $@)')dnl

Pemakaian:

$ m4 <<<"include(\`backspace-golfed.m4')M(abc, abd, aefg, abcdefg, h)"
Film thriller
sumber
1

PHP, 116 111 101 83 byte

Catatan: menggunakan pengkodean Windows-1252.

for(;$w=$argv[++$i];)for(;$c!=$w;)echo$c=($c^$c^$w)==$c?$c.ÿ&$w:substr($c,0,-1),~õ;

Jalankan seperti ini:

php -r 'for(;$w=$argv[++$i];)for(;$c!=$w;)echo$c=($c^$c^$w)==$c?$c.ÿ&$w:substr($c,0,-1),~õ;' -- abc abd aefg h 2>/dev/null
> a
> ab
> abc
> ab
> abd
> ab
> a
> ae
> aef
> aefg
> aef
> ae
> a
>
> h

Penjelasan

for(                       # Outer loop.
  ;
  $w=$argv[++$i];          # Loops over the input words.
)
  for(                     # Second inner loop.
    ;
    $c!=$w;                # Loop until the word was output.
  )
    echo $c=
      ($c^$c^$w)==$c?      # Check if last output string is a substring
                           # match with the next word to output.
        $c.ÿ&$w:           # ... If yes, suffix the string with the next
                           # char of the word, and output the result.
        substr($c,0,-1),   # ... If not, remove a char and output.
      ~õ;                  # Output newline.

Tweaks

  • Disimpan 5 byte dengan menggunakan trim($c^$w,"\0")untuk memeriksa kecocokan substrat alih-alih $c&&strpos($w,$c)!==0.
  • Disimpan 2 byte dengan menggunakan ~ÿuntuk menghasilkan string dengan byte NUL, bukan"\0"
  • Disimpan 8 byte dengan menggunakan $c=$c.ÿ&$wsuffix $cdengan karakter selanjutnya$w
  • Menyimpan 18 byte besar dengan menggabungkan logika dari 2 loop batin dalam satu loop
  • Memperbaiki bug dengan testcase dari komentar, tidak ada perubahan dalam jumlah byte
aross
sumber
1

Batch, 296 291 byte

@echo off
set f=
set t=%1
:t
set f=%f%%t:~,1%
set t=%t:~1%
echo(%f%
if not "%t%"=="" goto t
shift
set t=%1
set s=%f%
set p=
:h
if %s:~,1%==%t:~,1% set p=%p%%t:~,1%&set s=%s:~1%&set t=%t:~1%&goto h
:b
set f=%f:~,-1%
echo(%f%
if not "%f%"=="%p%" goto b
if not "%1"=="" goto t

Menghitung awalan umum itu rumit.

Neil
sumber
0

PHP, 153 byte

sangat lama :(

for($s=$argv[$k=1];$t=$argv[++$k];){for(;$s>""&&strstr($t,$s)!=$t;$s=substr($s,0,-1))echo"$s
";for($i=strlen($s);$s<$t;$s.=$t[$i++])echo"$s
";echo"$s
";}

Jalankan dengan php -nr '<ode>' <text1> <text2> ....

Titus
sumber
0

JavaScript (ES6), 135 byte

Tantangan yang menarik! Penggunaan: g(["abc", "abd", "aefg", "h"]). Saya tidak bisa menyimpan byte dengan menulis ini sebagai satu fungsi, jadi ini dua. Baris baru tidak termasuk dalam jumlah byte.

f=a=>console.log(([,...z]=[x,y]=a)[0])||
y?f(a=(x==y.slice(0,-1))?z:([y.match(x)
?x+y[x.length]:x.slice(0,-1),...z])):1;
g=a=>f(['',...a])

Saya yakin ini bisa dikurangi lebih banyak. Akan menambahkan versi yang tidak diklik nanti.

Chris M
sumber
0

Javascript, 98 byte

a=>{c="",l=0;for(w of a)while((i=w.indexOf(c))!=0||c!=w)alert(c=i!=0?c.substring(0,--l):c+w[l++])}

Port Java Jakob menjawab

SuperStormer
sumber