Pairable dizeleri


28

Bir dizedir pairable iki kez arka arkaya tekrarlanan bir dize her biri subtrings, bölünebilir eğer. Örneğin, aabaaababbbabaşu şekilde pairable:

aaba aaba
b b
ba ba

Boş olmayan bir as ve s dizesi verildiğinde b, eğer pauylu ise bir Truthy değeri ve eğer değilse falsey değeri verin.

Pairable:

aa
abaaba
bbababbb
aabaaababbbaba
babababa
bbbbbbbbbbbb
aaababbabbabbbababbaabaabaababaaba
aaaabaab

Çekilebilir değil:

a
ba
baab
abaabaaba
bbbbbbbbbbbbbbb
baababbabaaaab
aaaaabbaaaaa

Dilinizde halihazırda daha kısa bir regex cevabı olsa bile regex'e dayalı olmayan çözümler bulmanızı tavsiye ederim. Bunları "regex yok" olarak işaretleyebilirsiniz. Regex ile, dahili bir dize deseni eşleşen alt sistemi kastediyorum.


Liderler Sıralaması:


Başka bir şey kullanabilir miyiz ab?
Outgolfer Erik

Eğer bbababbb pairable ise, neden baab ve aaaaabbaaaaa değil?
rnso

@ rnso Anladığım kadarıyla, bbabbb 3 çift olarak dökülebilir: bb, abab ve bb, bu sırada orijinal dizgiyi oluşturacak şekilde birleştirir, diğer ikisi ise yapamaz.
Sunny Pun

"Her biri (alt dize) birbirini iki kez tekrar eden bir dizedir" sorusuyla ve bu bbababbbdan memnun değildir. Aksi takdirde, baab ayrıca baab'a ve aaaaabbaaaaa'ya aaaaa bb aaaaa'ya bölünebilir.
rnso

@rnso Orada ne demek istediğinden emin değilim. Ardışık olarak, iki tekrarın yan yana olduğunu kastediyorum. "Baa b" de, iki b, a ile ayrılır, bu yüzden işe yaramaz.
Xnor

Yanıtlar:


11

Python 2, 68 63 bayt

f=lambda s,n=1:s==2*s[:n]or''<s[n:]>-f(s,n+1)<f(s[n:])*f(s[:n])

Doğru veya Yanlış döndürür . İdeone üzerinde test et .


4
Bu, hem çiftin merkezi hem de merkezin bölümlenmesi için endeksi kullanan gerçekten temiz bir özyinelemeydi. Doğruluk bir şeyden daha az olarak kontrol edilmesi komik. Bazı iyileştirmeler görüyorum ...
xnor

8

Retina , 11 bayt

^((.+)\2)+$

Tüm test durumlarını dene. İlk iki bayt, çok satırlı kılar.

Kuralların oldukça gerçek bir şekilde yorumlanması, tüm Retina programlarının yapacağı gibi açıkçası regex kullanıyor.


2
Dangit, bunu göndermek için 3 haftadır bekliyorum ...
ETHproductions

2
Martin de bekliyordu .
xnor

5
Tüh! Ben de onu sadece 10 saniye yenerim ... Eminim bir Hexagony cevabı yazarsam beni affeder!
FryAmTheEggman

5
@FryAmTheEggman Bekliyorum. :)
Martin Ender

2
Perl ile tamamen aynı:perl -pE '$_=/^((.+)\2)+$/'
Dada

8

Jöle , 10 bayt

ẆŒPẋ€€2F€ċ

Tam olarak verimli değil ... Çevrimiçi deneyin!

Nasıl çalışır

ẆŒPẋ€€2F€ċ  Main link. Argument: s (string)

Ẇ           Window, generate the array of all substrings of s.
 ŒP         Powerset; generate all subarrays of substrings of s.
   ẋ€€2     Repeat each substring in each subarray twice.
            For example, ["ab", "a", "b"] becomes ["abab", "aa", "bb"].
       F€   Flatten the subarrays by concatenating their strings.
         ċ  Count how many times s appears in the generated strings.

Bu ... verimsiz görünüyor. Bu ne kadar girdiyi makul bir zaman diliminde ele alabilir?
John Dvorak

1
Son derece verimsiz ( O (2 ^ n ^ 2) , sanırım). Yerel olarak kontrol etmem gerekir. TIO, 6 uzunluğundaki dizeler için belleği yetersiz tutar .
Dennis

8
Bir dizi 6 , makinemde 3:20 dakika sürer ve 6 GB bellek gerektirir.
Dennis

1
@Dennis O zaman bir uzunluk 100 giriş yapmayalım , çünkü her şey çökecek. Evet, hatta TIO.
Outgolfer Erik

@EriktheGolfer Bu, TIO'yu diğer kullanımlar için gereksiz yere yavaşlattıracağı için iyi bir fikirdir, ancak çökmez. Sistemin belleği biter bitmez, işlem sadece OOM tarafından öldürülür.
Dennis

5

Haskell, 72 69 bayt (düzenli ifade yok)

g(a:b:c)|a==b=g c
g x=x==[]
any(g.words.concat).mapM(\c->[[c],c:" "])

Bir kaba kuvvet yaklaşımı. Ideone'da dene .

-3 bayt için BlackCap'e teşekkürler.

açıklama

Yardımcı işlev gbir dize listesi alır ve benzer dizelerin çiftlerinden oluştuğunu kontrol eder ["aa","aa","bba","bba","ab","ab"]. (Anonim) ana işlevi bir dizgiyi mümkün olan her yolla böler ve en az bir bölmenin sonuç gkabul eden bir listede sonuçlandığını kontrol eder.

g(a:b:c)                                  g on list with elements a, b and tail c,
        |a==b                              in the case that a==b,
             =g c                          recurses to the tail c.
g x=                                      g on any other list x
    x==[]                                  checks that x is empty.
                                           This includes the case where a is not equal
                                           to b, resulting in False.
any(g.words.concat).mapM(\c->[[c],c:" "]) The main function:
                    mapM(\c->[[c],c:" "])  Replace each letter c with either "c" or "c "
                                           in all possible ways, return list of results.
any(              ).                       Check that at least one result satisfies this:
            concat                          Concatenate the 1- or 2-letter strings,
      words.                                split again at each space,
    g.                                      apply g.

Sen yerini alabilir or.mapileany
blackcap

@ BlackCap Tabii ki, teşekkürler! Başlangıçta vardı any g.map(words.concat)ve "hey, ben can golf düşünce anyiçin or..."
Zgarb

5

Python 2,60 bayt

f=lambda s,t='':''<s>f(s[1:],t+s[0])|f(t and s)*f(t)>-(s==t)

Umarım bu doğrudur. Oldukça yavaş çalışıyor ve en anduygun görünmüyor.


1
Dizeleri kullanmayı denedim, ancak dizin tabanlı puanıma yakın hiçbir yerde bulamadım. Zeki andolan orada.
Dennis,

Tebrikler! Bölümde tekrar etmek aklımdaki numaraydı.
xnor 23

4

Jöle , 12 bayt

ŒṖµœs€2ZEµ€S

İki uzun bayt benim diğer yanıt , ancak bu yaklaşım çok daha verimli ve kolları tüm ama test durumları biridir.

Çevrimiçi deneyin!

Nasıl çalışır

ŒṖµœs€2ZEµ€S  Main link. Argument: s (string)

ŒṖ            Generate all partitions of s.
  µ      µ€   Map the monadic chain between the µ's over the partitions.
   œs€2         Split each string in the partition into two chunks of equal length.
       Z        Zip/transpose, collecting the first halves in one array and the
                second halves in another.
        E       Test the arrays of halves for equality.
           S  Return the sum of the results, counting the number of different
              ways s can be paired.

3

Pyth - Düzenli İfade Yok - 13 12 bayt

Bölümlerden birinin, ikiye bölündüğünde birbirine eşit olan tüm dizgilerden oluşup oluşmadığını kontrol eder.

sm.AqMcL2d./

Test Takımı .


3

Brachylog , 14 bayt (düzenli ifade yok)

lye~l:1j@2zcc?

Çevrimiçi deneyin!

Bu, bazı test durumları için çok yavaş

açıklama

ly                  The list [0, …, length(Input)]
  e~l               A list whose length is an element of the previous list
     :1j            Append itself to this list
        @2zc        Split in half, zip and concatenate so that the list contains pairs of
                      consecutive identical elements
            c?      The concatenation of that list must result in the Input

3

JavaScript (ES6), düzenli ifade yok, 75 74 bayt

f=s=>!s|[...s].some((_,i)=>i&&s[e='slice'](0,i)==s[e](i,i+=i)&&f(s[e](i)))

İade 1aksi pairable için 0. Düzenleme: @ edc65 sayesinde 1 bayt kaydedildi.


Güzel! substrDeğiştirmeden kullanarak aynı sayma i. Ancak slice3 kez tekrarlanırsa, 1 byte aliasing kaydedebilirsiniz
edc65

@ edc65 Değişiklik yapmadan aynı sayıyı nasıl elde edersiniz i? Bunun s.substr(i,i+i)aynı olduğunu s.slice(i,i+=i)ancak daha sonra değiştirdiğim değeri kullandığımı farkettim i...
Neil

öyle s.substr(i,i)2 byte az sonra s.slice(i+i)2 byte daha
edc65

@ edc65 Oh tabii ki, daha fazla kahveye ihtiyacım var ...
Neil

3

Python, 58 bayt

f=lambda s,p='':s>''and(f(p)>-(s==p)<f(s))|f(s[1:],p+s[0])

Bu Dennis'in özyinelemeli yöntemine dayanıyor . Boolean olumsuzlama hilesi de buradan alınır.

Yeni fikir, ilk karakterin son karakteri olmak üzere ilk karakterini baştan ve tekrar tekrar hareket ettirerek (p,s)orijinal dizginin bölümlerini ('',s)tekrarlamaktır . Bu, parçaların dize dilimleme olmadan doğrudan yönlendirilmesine izin verir. Ancak, bölüm boşla başladığından , sonsuz çağrı döngüsünden kaçınmak için dikkatli olmalıyız .sppf(s)f(s)


2

JavaScript (ES6), 24 bayt

x=>/^((.+)\2)+$/.test(x)

Muhtemelen bundan daha kısa olamaz.


Olmamalı mıydı \2?
Neil

@Neil Nedense, onunla çalıştığını düşündüm \1, ama aabgeri döndü true... düzeltme için teşekkürler.
ETHProductions

2

PHP, 40 Bayt

false için 0, true için 1 yazdırır

<?=preg_match("#^((.+)\\2)+$#",$argv[1]);

2

Python, 66 64 bayt

-1 bayt için teşekkürler @Zgarb!

f=lambda x,s=1:x>x[:s]and(x==2*x[:s])|f(x[:s])&f(x[s:])|f(x,s+1)

TrueVeya döndürür False.

Çevrimiçi deneyin!

Bu golf herhangi bir yardım seviniriz.


1

Raket 230 bayt

(let((sl string-length)(ss substring))(if(odd?(sl s))(printf ".~n")(begin(let p((s s))(if(equal? s "")(printf "!")
(for((i(range 1(add1(/(sl s)2)))))(when(equal?(ss s 0 i)(ss s i(* 2 i)))(p(ss s(* 2 i)(sl s)))))))(printf ".~n"))))

'!' Yazdırır dizenin çiftlenebildiği her yol için. Bir 'yazdırır.' sonunda.

Ungolfed:

(define (f s)
  (let ((sl string-length)                              ; create short names of built-in fns
        (ss substring))
    (if (odd? (sl s))  (printf ".~n")                   ; odd length strings cannot be pairable; end here.
        (begin
          (let loop ((s s))                             ; start testing here
            (if (equal? s "") (printf "!")              ; if no remaining string, it must be pairable
                (for ((i (range 1 (add1 (/(sl s)2)))))  ; ch lengths varying from 1 to half of string length
                  (when (equal? (ss s 0 i)              ; ch if substrings are same
                                (ss s i (* 2 i)))
                    (loop (ss s (* 2 i) (sl s) ))))))   ; if yes, loop to check remaining string.
          (printf ".~n")))))                            ; End of testing.

Test yapmak:

(println "Following should be pairable")
(f "bbaabbaa")            ; should produce 2 '!' since 2 ways are possible.
(f "aa")
(f "abaaba")
(f "bbababbb")
(f "aabaaababbbaba")
(f "babababa")                    ; should be pairable in 2 ways.
(f "bbbbbbbbbbbb")                ; should be pairable in many ways.
(f "aaababbabbabbbababbaabaabaababaaba")
(f "aaaabaab")
(println "Following should be unpairable")
; (f "a")
(f "ba")
(f "baab")
(f "abaabaaba")
(f "bbbbbbbbbbbbbbb")
(f "baababbabaaaab")
(f "aaaaabbaaaaa")

Çıktı:

"Following should be pairable"
!!.
!.
!.
!.
!.
!!.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!.
!.
!.
"Following should be unpairable"
.
.
.
.
.
.

1

Perl, 16 + 2 = 18 bayt (regex ile)

-nlBayraklarla koş . -Ebedava.

say/^((.+)\2)+$/

Olarak çalıştırmak:

perl -nlE 'say/^((.+)\2)+$/'

Eşleştirilebilirse yakalama gruplarının (bir truthy), eşleştirilemiyorsa boş dize listesini döndürür.

açıklama

-nlBayrakları bir döngüde kodunu (çalışacaktır -n(dolayı çıkarılır yeni satır firar ile giriş koyarak) -ldeğişkene) $_program el sona kadar, daha sonra her bir zaman giriş girilir kodunu değerlendirmek, her zaman. -EBayrak komut satırında kod değerlendirmek sağlar ve sağlayan saykomutu.

say/^((.+)\2)+$/

   /^((.+)\2)+$/  #The regex engine
      (.+)\2      #Find any set of at least one character, followed by itself
     (      )+    #Do this at least one time
   /^         $/  #Make sure that this matches the entire string from start to end
say               #Output the result of the regex

Bir eşleşme bulunursa (örneğin, dizge eşleştirilebilirse), o zaman regex yakalanan grupların bir listesini döndürür, bu daha sonra iletilen sayve sonradan çıkarılan bir gerçeği değerlendirir . Eşleşme bulunmazsa, regex, sonradan iletilen sayve çıktının hatalı olduğu değerlendirilen boş dizeyi döndürür .

Numune:

$ perl -nlE 'say/^((.+)\2)+$/'
aaababbabbabbbababbaabaabaababaaba
baababaababaaba                      #Truthy
baababbabaaaab
                                     #Falsy
bbababbb
bbb                                  #Truthy
aabaaababbbaba
bababa                               #Truthy
abaabaaba
                                     #Falsy

1

GNU Prolog, 49 46 bayt

Muhtemelen diğer değişkenlerde de çalışsa da, hepsi aynı şekilde dizeleri temsil etmese de; GNU Prolog'un temsili bu problem için faydalıdır.

Bunun regex kullanıp kullanmadığı sayılmaz. Herhangi bir regex benzeri özellik kullanmıyor, ancak dilin tüm anlambilimi regex'inkilerle aynı.

Yeni sürüm (diğer bazı cevaplarda görülen özyineleme numarasını kullanır):

s(X):-append(A,B,X),(A=B;A\=X,B\=X,s(A),s(B)).

Eski versiyon:

s(X):-X=[];append(A,B,X),B\=X,append(C,C,A),s(B).

Bu sbir programdır (Prolog'un bir fonksiyonun karşılığı) . Bu şekilde kullanın:

| ?- s("aa").
true ?
yes
| ?- s("aaababbabbabbbababbaabaabaababaaba").
true ?
yes
| ?- s("baababbabaaaab").
no
| ?- s("bbbbbbbbbbbbbbb").
no

Eski çözümün ilginç bir özelliği, tercümana “daha ​​fazla çözüm var mı?” Diye sorarsanız. kullanımı aracılığıyla ;en true ?hızlı, bu birkaç kez dize ifade edilebilir farklı şekillerde sayısına eşit "true" döndürür (yerine soran daha yukarıda olduğu gibi, istemi de dönüşü basarak yoluyla "herhangi bir çözüm yoktur") Verilen formda (örneğin s("aaaa")., iki kez "true" döndürür , çünkü (a a)(a a)veya as ayrıştırılabilir (aa aa)).

Prolog programlar genellikle geri dönüşümlü (izin siçin üretmek verilen özelliğiyle dizeleri listesini). Büyük olanı (sonsuz bir döngüye girer) değil, ama C'nin boş olmadığından emin olmak için kullandığım golf yöntemi yüzünden; C'yi açıkça boş olmayan olarak belirtmek için programı yeniden yazarsanız, "aa", "aabb", "aabbcc" vb. gibi dizeler oluşturur (Prolog olmak, bunları yapan karakterlerin kimliklerini belirtmez) yukarı, sadece hangi karakterlerin aynı olduğu ile ilgili bir açıklama). Yenisi "aa", "abab", "abcabc", vb. Biçiminde dizeleri oluşturur; bu kendi başına sonsuz bir döngüdür ve bu nedenle sıfır uzunluklu bir dize algılayamadığı için sıkışıp kaldığı noktaya asla ulaşmaz.


1

Brainfuck, 177 bayt

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

biçimlendirilmiş:

+[<<<<,]
>>>>
[
  >+
  [
    >+
    [
      [>>]
      <+<[<<]
      >+>-
    ]
    <[>+<-]>
    >>,>>[>>]
    +<<[<+> >-<-]
    <[>+<-]>
    >
    [
      not equal
      ,>[-<<<<]
      <[<<<<]
      >
    ]
    <
    [
      equal
      [<<]
      >
    ]
    >>
  ]
  >>
  [
    mismatch
    [>+>>>]
    >>>[>]
    <<<<
    [
      backtrack
      >+[-<<<,<]
      <
      [
        not done yet
        <<<
        [
          [<<<<]
          >>
        ]
        <
      ]
      >
    ]
    >>
  ]
  <
  [
    match
    [->>>>]
    >>[<]
    <
  ]
  <<
]
<.

Sondaki yeni satır olmadan girişi bekler. \x00False ve \x01true için yazdırır .

Çevrimiçi deneyin.

Bu, derinlikte ilk aramayı uygular. Özellikle: geçerli sonekten başlayarak artan uzunluktaki tekrarlanan önekleri kontrol edin, ardından bir eşleşme bulunursa bir sonraki sonekine geçin, aksi takdirde geri izleme.

Başlangıçta, dize tersine çevrilir ve bir sentinel \x01sonuna yerleştirilir.

Bant 4 hücreli düğümlere ayrılmıştır. Bir düğümün hafıza düzeni:

c h x 0

ckarakter nerede , karakterin hyinelenen bir ön ekin ilk yarısında olup olmadığı xve geçerli karakter çiftinin karşılaştırılmasının izlenmesi gereken bir bayraktır. hİse bayraklar yerde kalmak xbayrakları hareketli pencere oluşturur.

Dizge eşleştirilebilirse, işaretçi ana döngünün sonundaki sentinelin yanına gelir; Aksi halde, geri izleme sırasında işaretçi dizginin sol tarafından düşer.


1

Brachylog , 5 bayt

~c~jᵐ

Çevrimiçi deneyin!

Bu algoritmanın özellikle falsey durumlarında çok uzun zaman alabileceğine dikkat edin , çünkü giriş dizesinin tüm olası bölümlerini kontrol eder.

açıklama

~c     Reversed concatenate: find a list that, when concatenated, results in the input string
       This examines all partitions of the input
  ~jᵐ  Map reversed juxtapose: for each string in that list, is it the result of concatenating
       a string to itself?

Gibi bir giriş dizesi "ababcc", ~cgelinceye kadar farklı bölümleri dener ["abab", "cc"], bu noktada ~jlistenin her iki öğesi için de başarılı olur, çıktılar ["ab", "c"]ve yüklem başarılı olur.


1

R , 31 bayt

grepl("^((.+)\\2)+$",scan(,""))

Çevrimiçi deneyin!

Retina cevabına dayanarak.

R , 129 bayt

Ve işte orjinal, regex olmayan bir cevap:

o=(y=utf8ToInt(scan(,"")))<0;for(i in 2*1:(sum(y>0)/2))for(j in 1:(i/2)){w=i:(i-j+1);v=w-j;if(all(y[w]==y[v]))o[c(v,w)]=T};all(o)

Çevrimiçi deneyin!


0

Lithp , 57 karakter

#S::((? (!= (null) (match S "^((.+)\\2)+$")) true false))

Örnek kullanım:

% pairable_strings.lithp
(
    (def f #S::((? (!= (null) (match S "^((.+)\\2)+$")) true false)))
    (print (f "aa"))
    (print (f "aabaaababbbaba"))
    (print (f "aaababbabbabbbababbaabaabaababaaba"))
    (print (f "ba"))
)

# ./run.js pairable_strings.lithp
AtomValue { value: 2, type: 'Atom', name: 'true' }
AtomValue { value: 2, type: 'Atom', name: 'true' }
AtomValue { value: 2, type: 'Atom', name: 'true' }
AtomValue { value: 3, type: 'Atom', name: 'false' }
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.