Bir dizenin ikizlerden oluşan bir karışık olup olmadığını kontrol edin


10

açıklama

İki dize, yeni bir dize oluşturmak için harflerini serpiştirerek karıştırılabilir, tek bir yığın oluşturmak için iki kart yığını karıştırılabilir.

Örneğin, dizeleri HELLOve WORLDoluşturmak için karıştırılan olabilir HWEOLRLLOD, ya da HEWORLLLDObelki de sadece veya HELLOWORLD.

Öyle değil harflerin orijinal sipariş korunmuş değilse bir karıştır. Örneğin, Diçinde WORLDher zamankinden görünemez Rkarıştırılan sonra. Bu araçlar EHLLOWRDLO, örneğin, bir shuffle değil, HELLOve WORLDhepsi orijinal harfleri içeren rağmen.

Bir dize, iki özdeş dizenin karıştırılmasıyla oluşturulabiliyorsa ikizlerin karıştırılmasıdır. Örneğin, ABACBDECDEikizlerin karıştırılmasıdır ABCDEve karıştırılarak oluşturulabilir ABCDE. DBEACBCADEikizlerin karıştırılması değildir, çünkü iki özdeş dizenin karıştırılmasıyla oluşturulamaz.

Program Ayrıntıları

Bir giriş dizesi verildiğinde 0, ikizlerin karıştırılması değilse çıktıyı ve ikizlerin karıştırılması durumunda ikiz dizelerden birini çıktılayın.

Giriş dizesinin, dört ile yirmi karakter arasında bir uzunluğa sahip olduğunu ve tamamen büyük harfli alfabetik karakterlerden oluştuğunu varsayabilirsiniz. Makul bir sürede, örneğin 10 dakikadan az bir sürede çalışabilmelidir.

Bu kod golf, bu yüzden en kısa çözüm kazanır.

Örnek G / Ç

> ABACBDECDE
ABCDE

> DBEACBCADE
0

> FFFFFF
FFF

> FFGGG
0

> ABBA
0

> AABB
AB

> AABAAB
AAB

Bir örnek (golfsuz) uygulamam var .


Örnek dize FGG that the input string has a length inclusively between four and twenty characters, iddiayı ihlal ediyor ve bana "asla kullanıcı girdisine güvenme!", "Teknik özelliklere asla güvenme!"
kullanıcı bilinmiyor

@userunknown Bu çok utanç verici! FFGGGTutarlı hale getirmek için düzenledim .
Peter Olson

1
Sadece meraktan, herhangi biri alt-üstel en kötü durum zaman karmaşıklığı ile bir çözüm bulabilir veya herhangi bir olmadığını kanıtlayabilir?
Ilmari Karonen

Yanıtlar:


4

Haskell, 114

main=getLine>>=putStrLn.f.p;f x=head$[a|(a,b)<-x,a==b]++["0"]
p[]=[([],[])];p(x:y)=do(a,b)<-p y;[(x:a,b),(a,x:b)]

Ungolfed:

main :: IO ()
main = getLine >>= putStrLn . findMatch . partitions

-- | Find the first partition where the two subsequences are
-- equal. If none are, return "0".
findMatch :: [(String, String)] -> String
findMatch ps = head $ [a | (a,b) <- ps, a == b] ++ ["0"]

-- | Return all possible partitions of the input into two
-- subsequences. Preserves the order of each subsequence.
--
-- Example:
-- partitions "AB" == [("AB",""),("B","A"),("A","B"),("","AB")]
partitions :: [a] -> [([a], [a])]
partitions []     = [([], [])]
partitions (x:xs) = do (a, b) <- partitions xs
                       [(x:a, b), (a, x:b)]

Açıklama:

İşin çoğu partitionsişlevde yapılıyor . (a, b)Liste kuyruğunun tüm bölümlerini özyinelemeli olarak oluşturarak ve ardından ilk öğeyi her birinin başına eklemek ve tüm sonuçları toplamak için liste monadını kullanarak çalışır x.

findMatchbu listeyi filtreleyerek çalışır, böylece yalnızca alt dizilerin eşit olduğu bölümler kalır. Daha sonra ilk bölümdeki ilk alt diziyi döndürür. Hiçbiri kalmazsa, liste boştur, bu nedenle "0"sonuna eklenenler döndürülür.

main sadece girişi okur, bu iki fonksiyondan besler ve yazdırır.


Haskell'i okuyamayanlar için bir açıklama yapar mısınız?
Mr.Wizard

1
@ Mr.Wizard: Düzenlemeye bakın.
hammar

Sanırım kısa olmasa da oldukça benzer bir şey buldum, ama onu tamamen başarısız yapan aptalca bir şekilde attım. Bu algoritmayı Mathematica'da uygulamamın bir sakıncası var mı?
Mr.Wizard

4

R, 113 karakter

l=length(x<-charToRaw(scan(,'')));max(apply(combn(l,l/2),2,function(i)if(all(x[i]==x[-i]))rawToChar(x[i])else 0))

Ungolfed (ve bunun yerine dizeyi alan bir işlev):

untwin <- function(x) {
  x <- charToRaw(x)
  indMtx <- combn(length(x),length(x)/2)
  res <- apply(indMtx, 2, function(i) {
    if (all(x[i]==x[-i]))
      rawToChar(x[i])
    else
      0
  })
  max(res)
}

untwin("ABACBDECDE") # "ABCDE"
untwin("DBEACBCADE") # 0

Çözüm, combntüm indeks kombinasyonlarını bir matristeki sütunlar olarak üreten fonksiyona dayanır . applydaha sonra 2matristeki her sütuna (boyut ) bir işlev uygular ve bir dize veya sıfır vektörü döndürür. maxsonra en büyük dizgiyi bulun (0 değerini koyar).

R'deki harika bir özellik, bir indeks vektörü verilen bir vektörün alt kümesini seçme ve daha sonra endeksleri reddederek bu alt kümenin tamamlayıcısını seçme yeteneğidir :x[i] == x[-i]


Bazı artımlı iyileştirmeler yaptı ve karakter sayısını azalttı.
Tommy

3

Mathematica, 87

Bu doğrudan hammar'ın görevine dayanmaktadır, ancak umarım gönderimi hak edecek kadar farklıdır.

<<Combinatorica`

f=Catch[Cases[Characters@#~KSetPartitions~2,{x_,x_}:>Throw[""<>x]];0]&

Ölçek:

f /@ {"ABACBDECDE", "DBEACBCADE", "FFFFFF", "FGG", "ABBA", "AABB", "AABAAB"}
{"ABCDE", 0, "FFF", 0, 0, "AB", "AAB"}

1

D

string c(string in,string a=[],string b=[]){
    if(in.length==0)return a==b?a;"0";
    auto r=c(in[1..$],a~in[0],b);
    return r=="0"?c(in[1..$],a,b~in[0]):r;
}
void main(){writeln(c(readline));}

derinliği ilk özyinelemeli arama kullanarak

Bir int i = min(a.length,b.length);if(a[0..i]!=b[0..i])return "0";koruma maddesi ile daha hızlı yapabilirim


IDEONE üzerinde, programı başlatmak için başarısız oldu void main(){writeln(c("ABCADABCAD"));}- sadece farklı bir D sürümü, benim hatam, başka bir şey? "ABCABCA" ne olacak?
kullanıcı bilinmiyor

std.stdio dosyasını içe aktarmanız gerekir; IO için
cırcır ucube

1

Ruby, 89 karakter

s=->a,x,y{a=="\n"?x==y ?x:?0:[s[b=a[1..-1],x+c=a[0],y],s[b,x,y+c]].max}
$><<s[gets,'','']

Bu kod, düz bir özyinelemeli arama algoritması uygular. Giriş STDIN'de verilmelidir.


1

Perl, 68 karakter

/^((.+)(?{local($x,$,)=($,,$x.$^N)}))+$(?(?{$o=$,eq$x&&$,})|x)/?$o:0

$_Değişken içinde olduğu varsayılan girdi dizgisi , çıktı ifadenin değeridir. Girişteki sondaki yeni satırlar yoksayılır. Bunu komut satırından şu şekilde çalıştırabilirsiniz:

perl -lne 'print /^((.+)(?{local($x,$,)=($,,$x.$^N)}))+$(?(?{$o=$,eq$x&&$,})|x)/?$o:0'

Bu kod , geri izlemeyi yapmak için Perl'in normal ifade motorunu (ve özellikle gömülü kod yürütme özelliğini) kullanır. Temel olarak, giriş dizesini regexp ile eşleştirir ve ^((.+))+$tek ve çift numaralı alt eşleşmeleri $xve içinde izler ve $,ikisi eşit değilse eşleşmeyi sonunda reddeder.


Bunun için doğru sonuç var mı AABAAB?
Peter Olson

Evet öyle. (Aslında, AABAABbu çözüm için kolay bir durumdur, çünkü dış grubun sadece iki kez eşleşmesi gerekir. AABBDoğru işlemek için çok daha uzun
sürdüm

1

Python, 168 karakter

def f(s):
 c=s[0]
 d=i=r=0
 if s==c+c:r=c
 while i+1 and i<=len(s)/2 and not r:
  if i:d=f(s[1:i]+s[i+1:])
  if d:r=c+d
  i=s.find(c,i+1)
 return r
print f(raw_input())
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.