İki yönlü Palindromik Kapatma Jeneratörü


24

Giriş

Bir giriş dizesinin bir palindromik kapatılması, son palindromun giriş dizesiyle başladığı girdi dizisinden oluşturulabilecek en kısa palindromdur.

Bu zorluk için, iki yönlü bir palindromik kapanmayı düşüneceğiz.

  • Sol Palindromik Bir giriş dizisinin kapatılması , giriş dizesiyle başlayan en kısa palindromdur.
  • Sağ Palindromik Bir giriş dizisinin kapatılması , giriş dizesiyle biten mümkün olan en kısa palindromdur.
  • Bir giriş dizisinin iki yönlü Palindromik Kapanması , giriş dizesinin Sol veya Sağ Palindromik Kapanmasından daha kısadır.

Görev

Göreviniz basit. Bir dize verildiğinde (yalnızca yazdırılabilir ASCII, yeni çizgiler ve beyaz boşluklardan oluşan), o dizenin iki yönlü palindromik kapatılmasını sağlar. Beraberlik durumunda, sol veya sağ palindromik kapaklardan biri geçerli çıktıdır.

STDIN (veya en yakın alternatif), komut satırı argümanı veya işlev argümanı yoluyla giriş alarak ve sonucu STDOUT (veya en yakın alternatif) olarak yazdırarak veya bir dize olarak döndürerek bir program veya işlev yazabilirsiniz.

Girişin hiçbir zaman boş bir dize olmayacağını varsayabilirsiniz.

Birkaç örnek:

<Input>   -> <Output>
"abcdef"  -> "abcdefedcba"  (or "fedcbabcdef")
"abcba"   -> "abcba"
"abcb"    -> "abcba"
"cbca"    -> "acbca"

İlk Fikir kredisi, Martin ve Zgarb'ın yardımıyla nihai fikir VisualMelon'a gidiyor

Palindromik kapanma, sol-pallindromik kapanma ve sağ-palindromik kapanma terimleri ilk önce bu makale tarafından kullanılmış ve tanımlanmıştır .


1
Palindromik bir çözüm görmek istiyorum ...
mardo

2
@ojdo Bunu bir bonus olarak eklemeyi düşündüm, ancak cevapların çoğunun sadece palindromu oluşturmak için yorumları kullanacağından eminim. Bazı cevaplar gerçekten de bir palindrom olabiliyorsa, yorumlara güvenmeden, bu cevap için lütuf bırakacağım!
Doktor

Yanıtlar:


11

Pyth, 22 19

hfq_TTsm,+z_d+_dzyz

Çevrimiçi deneyin .

açıklama

İki yönlü palindromik kapama formunun, ya olduğu AXya da XAburada, Xgiriş dize ve Ade bir alt X. Aslında Xbir form için bir ön ek, diğer form için bir ek olan bitişik bir alt dize olmalıyım . Ama bu varsayılanları umursamıyorum. Bir alt dize (bitişik ya da değil) Pyth'ta tek ihtiyacım olan şey.

                        Implicit: z = raw_input() // Read a string
                 yz     A list with all substrings (contiguous or not) of z
       m                For each of these substrings d, build
        ,                  a pair of two strings:
         +z_d              ( z + inveres(d) ,
             +_dz            inverse(d) + z )
      s                 Sum (put all created pairs into a list)
 fq_TT                  filter elements T, where inverse(T) == T (Palindrom)
h                          Take the first element

Düzenle

Eski versiyon dizeleri uzunluğa göre filtrelemeden sonra emretti .olN.... Az önce fark ettim ki, bu yuzunluğa göre sıralanmış alt dizileri döndürür. Yani bu palindromlar zaten sıralanmıştır.


6

Klips , 40

(sl`f[a=ava}+m[i+v+ixx}Rlxm[i+xvu0ix}Rlx

Örnek

Documents>java -jar Clip4.jar palindrome.clip
abcb
abcba

açıklama

(sl`                                        .- The shortest                     -.
    f[a=ava}                                .- palindrome                       -.
            +                               .- among the following two sets:    -.
             m[i      }Rlx                  .- For each number up to length(x)  -.
                +                           .- combine                          -.
                 v+ix                       .- the last i chars of x, reversed  -.
                     x                      .- and x.                           -.
                          m[i       }Rlx    .- For each number up to length(x)  -.
                             +              .- combine                          -.
                              x             .- x and                            -.
                               vu0ix        .- the first i chars of x, reversed.-.

6

CJam, 30 bayt

Şimdiye dek bir CJam cevabı görmeyi umuyordum .. Yani işte burada: P

q:Q,{)QW%/(Q+Q@+s}%{,}${_W%=}=

{,}$Buradaki bloktan gerçekten nefret ediyorum , ancak kullandığım üretim algoritması nedeniyle sıralanmamış olası palindromların bir listesini alıyorum.

Kod açıklaması

q:Q,{            }%             "Read the input string, store in Q, take length and";
                                "run the code block that many times";
     )QW%                       "Increment the iteration index and Put reversed Q on stack";
         /                      "Split reversed Q into parts of incremented iteration index";
          (Q+                   "Take out the first part and prepend it to Q";
             Q@+s               "Take the rest of the parts and append them to Q";
                   {,}$         "At this point, we have all possible prepended and appended";
                                "sequences of the input string. Sort them by length";
                       {_W%=}=  "Take the first sequence which is a palindrome";

Burada çevrimiçi deneyin


6
{,}$Oradaki bloktan da gerçekten nefret ediyorum ! Şaka yapıyorum, CJam'da hiçbir şeyin ne yaptığı hakkında hiçbir fikrim yok.
Alex A.

4

Python 2, 115 113 109 105 96 bayt

f=lambda x:[x for x in sum([[x[:~i:-1]+x,x+x[i::-1]]for i in range(len(x))],[])if x==x[::-1]][0]

Umarım daha aşağı golf olabilir. Muhtemelen dikkate değer bitler:

  • Birinde iki liste kavrama için toplam kullanmak
  • Min ihtiyacını önlemek için sıralı olarak terimler oluşturmak (@Jakube tarafından önerilen)

1
Öğeler tam olarak sıralanmamıştır, bu nedenle bu gibi dizgiler için başarısız olur a.
Sp3000 17-15

4

Mathematica, 96 bayt

Bundan daha zarif bir yol olmalı ...

""<>#&@@SortBy[r=Reverse;#/.{b___,a__/;r@{a}=={a}}:>{b,r@{b,a}}&/@{r@#,#}&@Characters@#,Length]&

Bu, bir dize alan ve sonucu döndüren adsız bir işlevi tanımlar.

Temel fikir

  • Dizeyi içine bölün Characters.
  • Bu liste ve tersini içeren bir dizi oluşturun.
  • Her birinin doğru palindromisini bulmak için desen eşleştirmeyi kullanın:

    {b___,a__/;r@{a}=={a}}:>{b,r@{b,a}}
    

    Bunun aslında düz bir liste döndürmediğini unutmayın. Örneğin {a,b,c}alacağın için

    {a,b,{c,b,a}}
    
  • İki sonucu boyuna göre sıralayın.

  • Daha kısa olanı seçin ve tekrar bir dizgeye ekleyin ""<>#&@@.

Bu çıktılar abacabagirişi olduğunda abac. Doğru cevap cabac. Uzunluğa göre sıralamadan önce bunları düzleştirmeniz gerektiğini düşünüyorum.
alephalpha

1
@alephalpha Kod boyutunu değiştirmeyi gerektirmeyen daha iyi bir düzeltme buldu (ve aslında niyetimde sıralama yapmamamı sağladı).
Martin Ender

2

Brachylog (2), 6 bayt, dil kayıt sonrası mücadelesi

~{↔?a}

Çevrimiçi deneyin!

Brachylog için her zaman olduğu gibi, bu tam bir program değil, bir fonksiyondur.

açıklama

~{↔?a}
~{   }   Find a value that produces {the input} upon doing the following:
  ↔        reversing it;
   ?       asserting that we still have the same value;
    a      and taking either a prefix, or a suffix.

Bildiğim kadarıyla (bu benim dilim değil, fakat olası görünmüyor), abu zorluk için Brachylog'a eklenmedi, ancak burada gerçekten kullanışlı oluyor. Bulduğumuz değerin bir palindrom olduğunu iddia etmek için "ters ve değişmediğini iddia etme" yöntemini kullanıyoruz.

Bunun neden en kısa palindromu ürettiğine gelince , Prolog'un (ve dolayısıyla Brachylog'un) değerlendirme sırası, değerlendirdiği ilk şeyden büyük ölçüde etkilenir. Bu durumda, bu bir "reverse" komutudur ve (çoğu liste işlemi gibi) sonuçta ortaya çıkan listenin boyutunu en aza indirmeyi amaçlayan bir değerlendirme sırası belirler. Bu, çıktının boyutuyla aynı olduğu için, program tamamen doğru olanı en aza indirgeyerek sona erer, yani açık bir ipucu eklememe gerek kalmaz.


a- Bu sorun için ek eklenmedi. Önek ve sonek için iyi anımsatıcılara sahip hiçbir simge kullanmamıştım, bu yüzden hem gerekse önek veya sonekleri seçmek için abonelik alabilen eke birleştim.
17'de ölüm

1

Ruby, 76 + 2 = 78

Komut satırı bayraklarıyla -pl( lgirişi nasıl yaptığınıza bağlı olarak gerekmeyebilir),

$_=[[$_,r=$_.reverse]*"\0",r+"\0#$_"].min_by{|s|s.sub!(/(.*)\0\1/){$1}.size}

Bir 'abaa' dizgisi verildiğinde, 'cbca 0 acbc' ve 'acbc 0 cbca' dizgelerini oluşturur , burada 0 , ascii kodu 0 ile yazdırılamaz karakterdir, daha sonra her birinde bulunan 0 çerçeveli en uzun tekrarlanan dizenin bir kopyasını siler , 'a' birinci ve ikinci 'cbc' ise iki kapanış için. Daha sonra en kısa sonucu verir.

Golf koduyla ilgili gerçekten garip olan şey, sıralama sırasında dizgileri kısaltmasıdır, bunları kaldırabileceğiz, çünkü min_byher öğeyi karşılaştırırken bloğu yalnızca bir kez çalıştırır (her ikisi de Schwartzian bir dönüşüm olduğundan ve yalnızca iki tane olduğundan) karşılaştırılacak elemanlar).


1

Python 3, 107 bayt


f=lambda a:[i for i in[a[:i:-1]*j+a+a[-1-i::-1]*(1-j)for i in range(len(a))for j in(0,1)]if i==i[::-1]][-1]

Test etmek için:

>>> print("\n".join(map(f, ["abcdef", "abcba", "abcb", "cbca"])))
abcdefedcba
abcba
abcba
acbca

1

Haskell, 107 bayt

import Data.List
r=reverse
f s=snd$minimum[(length x,x)|x<-map(s++)(tails$r s)++map(++s)(inits$r s),x==r x]

Ölçek:

*Main> mapM_ (putStrLn.f) ["abcdef", "abcba", "abcb", "cbca"]
abcdefedcba
abcba
abcba
acbca

1

J, 66 62 bayt

3 :'>({~[:(i.>./)(#%~[-:|.)@>),(<@([,|.@{.~)"#:i.@#"1)y,:|.y'

Oldukça açık. Kullandığım iki numara:

Sağ palindromik kapatma, ters dizinin sol palindromik kapanmasıdır.

Dize uzunluğu minimum (is_palindrome / uzunluk) ifadesiyle minimum uzunluk ve palindromity ile bulma.

   f=.3 :'>({~[:(i.>./)(#%~[-:|.)@>),(<@([,|.@{.~)"#:i.@#"1)y,:|.y'

   f 'lama'
lamal

Burada çevrimiçi deneyin.

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.