Geri al ve tekrar yaz bir sözcük listesi


38

İşte nasıl bir dizeden diğerine geri almak ve yeniden yazmak için:

  1. İlk dizeden başlayın.
  2. Sonuç, ikinci dizgenin ön eki olana kadar karakterleri kaldırın . (Bu 0 adım alabilir.)
  3. Sonuç ikinci dizgiye eşit olana kadar sonuna karakter ekleyin. (Bu da 0 adım alabilir.)

Örneğin, gelen yol fooabciçin fooxyzgörünüyor gibi:

fooabc
fooab
fooa
foo
foox
fooxy
fooxyz

Görev

Kelimelerin bir listesini göz önüne alındığında, bu bir programı yazmak için geri silme-ve-retypes geri boş bir dizeye, arkaya listedeki tüm kelimelerle, boş dize gelen yolunda. Tüm ara dizeleri çıkar.

Örneğin, giriş listesi göz önüne alındığında ["abc", "abd", "aefg", "h"], çıktı şöyle olmalıdır:

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

h

kurallar

Bir dizi listesini veya bazı sınırlayıcıları içeren tek bir dize döndürebilir veya yazdırabilirsiniz. Sen olabilir isteğe ilk ve son boş dizeleri içerir. Giriş, en az bir kelime içerecek şekilde garanti edilir ve her kelimenin yalnızca küçük ASCII harfleri içereceği garanti edilir ( a- z). Düzenleme: Girişteki ardışık dizelerin birbirlerine eşit olmaması garanti edilir.

Bu ; bayt cinsinden en kısa kod kazanır.

Python 3'te referans uygulaması: Çevrimiçi deneyin!


4
@ rahnema1> boş dizeden
Kritixi Lithos

3
Çıktı nasıl olurdu ["abc","abc"]?
Kritixi Lithos,

1
@Emigna Oops, bu tam olarak böyle ama bir döngüde! Bu yüzden devam edeceğim ve bunun bir kopyası olduğunu söyleyeceğim.
Lynn

4
@Lynn Tamamen aynı şey değil. Bu, ortak öneklerin tanınmasını içermez, her zaman bir karaktere düşer.
Martin Ender

6
Test durumu:a,abc,abcde,abc,a,abc,abcde
Zgarb

Yanıtlar:



9

Perl, 43 bayt

42 bayt kod + -nbayrakları.

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

Çalıştırmak için:

perl -nE 'chop$@,say$@while!s/^$@//;s/./say$@.=$&/ge' <<< "abc
abd
aefg
h"

bu abc 3 kez basar
izabera

@izabera abc3 kez yazdırılmasına neden olduktan sonra bir boşluk vardı (ama aslında, boşluk olmadan ilk ve üçüncü kez). Kaldırdım.
Dada

5

Java 8, 144 bayt

Bu, referans uygulamasına benzer, ancak iki whiledöngüyü birleştirir . String[]Parametre kabul eden bir lambda ifadesidir .

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

Ungolfed

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

Teşekkür

  • CAD97'nin lambda önerisi sayesinde -38 bayt

class BBunun yerine kullanmak daha ucuz değil interface Bmi? Özel bir sınıftan koşabilirsiniz. Ayrıca, önceden Java8 belirttiğiniz gibi bir lambda kullanmayı düşünün.
CAD97

@ CAD97'den interface B{static void maindaha kısa class B{public static void main.
Kevin Cruijssen

@ CAD97 Buna lambda getirmenin bir yolunu düşünemedim, ama daha dün öğrendim. Herhangi bir fikir?
Jakob

1
Ah, paslıyım. Bir a->{/*your code*/}tür değişkenine atanacak olanı yapabilmelisiniz java.util.function.Consumer<String[]>. Ancak şu anda test edemiyorum.
CAD97

1
@JakobCornell PPCG varsayılan olarak tam program veya işlev gönderimlerine izin verir. Anonim işlevli diller için (lambda), anonim işlev kendi başına kabul edilebilir bir cevaptır (bu nedenle saklamak için değişkeni dahil etmeniz gerekmez). (Java başvurularında lambda türünü sağlamak naziktir.)
CAD97 18

4

Mathematica, 149 bayt

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]]&

3

Retina , 39 bayt

Bayt sayısı, ISO 8859-1 kodlamasını varsayar.

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

Çevrimiçi deneyin!

Giriş ve çıkış satır besleme ayrılmış listelerdir. Çıktı, baştaki ve sondaki boş dizgiyi içerir.


3

Jöle , 31 29 26 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

⁷;ç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.

2

Haskell , 102 93 91 90 bayt

(?)=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
(""!).(++[""])

Son satır, dizelerin listesini alan ve döndüren adsız bir işlevdir. Çevrimiçi deneyin!

açıklama

Benim çözümüm özyinelemelidir. İlk olarak, ?bir yardımcı infix fonksiyonudur: a?bİlk verir length aait karakterleri b, ya bütün bhalinde adaha uzundur. Daha sonra bir infix işlevi tanımlayacağım !. Fikir olmasıdır a!xnerede abir dize ve bir xdize listesidir, gelen yolunu üretir ailk dizeye xve kuyruğuna recurses x. Son satırda boş dizgeyi ekleyen isimsiz bir işlev tanımlarım, daha sonra !boş dizgeye ve girişe uygulanır.

Açıklaması !:

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.

2

Python 2, 118 107 103 97 93 92 bayt

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

Giriş ['abc', 'abcdef', 'abcfed'], veya olarak verilir "abc", "abcdef", "abcfed"].

Revizyon 1: -11 bayt. Credit, Python golf ipuçlarındaki yazısı için @xnor'a ve benim için bahşişi bulmak için @ Lynn'e ve akıllı olduğum için bana gider. İki değişiklik yapıldı: Yerine not s.startswith(i), kullandım s.find(i)ve yerine i!=skullandım i>s.

2. revizyon: -4 bayt. Kredi bana aptalca bir hata yaptığımı fark etti. Tek-sekmeli ve çift-sekmeli girinti kullanmak yerine, tek-boşluk ve tek-sekme girinti kullandım.

Revizyon 3: -6 bayt. Kredi, while'ları tek bir satıra koymayı önerdiği için @ mbomb007'ye gidiyor. Ben de değiştirerek bir hata düzeltildi s.find(i)için i.find(s).

Revizyon 4: -4 bayt. Credit, girdiyi bir değişkende saklamak zorunda olmadığımı fark etmek için @xnor'a gider.

Revizyon 5: -1 bayt. Kredi , girdiye eklerken olduğu ['']gibi aynı şey olduğunun farkına varıyor [s].


Put whiletek bir satırda s her. Ayrıca <1yerine kullanabilirsiniz not.
mbomb007

Güzel cevap! Kaçınılması gerekenstartswith konusunda xnor tarafından güzel bir ipucu var .
Lynn

@Lynn Oh, bağlantı için teşekkürler! Gerçekten çok yararlı buldum!
HyperNeutrino

@ mbomb007 Üzgünüm, whiles'yi tek bir satıra koyarak ne demek istediğinizi anlamadım . Gibi while s.find(i):s=s[:-1];print smi demek istiyorsun Ayrıca, öneriniz için teşekkürler <1, ancak xnor'ın Python ipuçlarındaki ipuçlarından biri sayesinde daha da kısa bir şeye geçtim.
HyperNeutrino

@AlexL. Evet, süreyi böyle yap.
mbomb007

1

GNU M4, 228 veya 232 bayt

(¹ dosyayı sonlandırıp sonlandırmamaya bağlı olarak — dnl\ngolf ve M4'te hala yeniyim)

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),$@)')

Ayrıca, 3 bayt için ikinci argüman değiştirerek kaydedilmiş olabilir substrgelen 0boş bir dizeye, ama bu, standart hataya uyarıların çok üretecektir.

Ungolfed:

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

Kullanımı:

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

1

PHP, 116 111 101 83 bayt

Not: Windows-1252 kodlamasını kullanır.

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

Bu şekilde koş:

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

açıklama

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.

Düzenlemeler

  • Yer trim($c^$w,"\0")altlığı eşleşmesini kontrol etmek için kullanarak 5 bayt kaydedildi $c&&strpos($w,$c)!==0.
  • ~ÿBir NUL baytı olan bir dize elde etmek için kullanılarak 2 bayt kaydedildi"\0"
  • Bir sonraki char ile $c=$c.ÿ&$wson ekini kullanarak 8 bayt kaydedildi$c$w
  • 2 iç döngünün mantığını bir ilmek halinde birleştirerek büyük bir 18 bayt kaydetti
  • Yorumlardan testisli bir hata düzeltildi, bayt sayısında değişiklik olmadı

1

Toplu iş, 296 291 bayt

@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

Ortak öneki hesaplamak hantaldı.


0

PHP, 153 bayt

çok uzun :(

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

İle koş php -nr '<ode>' <text1> <text2> ....


0

JavaScript (ES6), 135 bayt

İlginç bir meydan okuma! Kullanımı: g(["abc", "abd", "aefg", "h"]). Bunu bir işlev olarak yazarak herhangi bir baytı kurtarmayı başaramadım, bu yüzden iki. Bayt sayısına dahil edilmeyen satırlar.

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

Bunun daha fazla azaltılabileceğine eminim. Sonra ungolfed sürümünü ekleyecektir.


0

Javascript, 98 bayt

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

Jakob'un Java cevabı limanı

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.