การค้นหา“ sub-palindromes”


24

รหัสที่สั้นที่สุดที่พบว่าไม่ซ้ำกันทั้งหมด "sub-palindromes" ที่ของสตริงคือ: สตริงย่อยใด ๆ ที่มีความยาว> 1 ที่เป็น palindrome

eg.1

input: "12131331"
output: "33", "121", "131", "313", "1331"

eg.2

input: "3333"
output: "33", "333", "3333"

1
สตริงสามารถเป็นพาเนลย่อยของตัวเองได้หรือไม่? เนื่องจากสตริงเป็นสตริงย่อยของตัวเอง
JPvdMerwe

@JPvdMerwe: ใช่แน่นอน
Eelvex

ที่จริงสำคัญกว่า: สิ่งที่จะต้องมีการส่งออกของ333? ไร้เดียงสาคุณจะต้องจบการพิมพ์33สองครั้ง
JPvdMerwe

@JPvdMerwe: '333' -> '33', '333' ฉันจะแก้ไขคำถามตาม ขอบคุณ
Eelvex

เอาต์พุตถูกระบุอย่างไร? คั่นด้วยเครื่องหมายจุลภาคที่มีเครื่องหมายคำพูดล้อมรอบแต่ละช่วงย่อยตามที่คุณแสดงที่นี่? หนึ่ง sub-p ต่อบรรทัด?
Joey

คำตอบ:


11

J, 24 31 40

~.(#~(1<#*]-:|.)&>),<\\.

ตัวอย่างการใช้งาน:

   ~.(#~(1<#*]-:|.)&>),<\\. '12131331'
┌───┬───┬───┬────┬──┐
│121│131│313│1331│33│
└───┴───┴───┴────┴──┘
   ~.(#~(1<#*]-:|.)&>),<\\. '3333'
┌──┬───┬────┐
│33│333│3333│
└──┴───┴────┘

รับสิ่งนี้ GolfScript!


ยอมรับมันคุณเพียงแค่ถ่ายโอนข้อมูลจาก/dev/randomที่นี่เพื่อหลอกเรา ;-)
Joey

@ โจอี้ลองด้วยตัวคุณเอง p (TBH ฉันไม่เชื่อว่ามันจะทำงานได้ในตอนแรก)
JB

ฉันค่อนข้างแน่ใจว่ามันเป็นรหัสจริง ฉันใช้เวลาหนึ่งสัปดาห์ในการพยายามล้อมหัว J ไว้ แต่ล้มเหลวอย่างน่าสังเวช ถึงกระนั้นฉันก็จำรหัสได้ ฉันไม่เข้าใจว่ามันทำอะไร ;-)
Joey

2
ไม่สามารถย่อให้เหลือ~.(#~(1<#*]-:|.)&>),<\\.(24 ตัวอักษร) ได้หรือไม่
ephemient

@ephemient มันทำแน่นอน (ดูเหมือนว่าฉันติดอยู่ในความคิด "คำตอบจะต้องเป็นฟังก์ชั่น" ซึ่งไม่ได้ใช้ที่นี่.) แก้ไขขอบคุณ!
JB



3

Python - 138 136

รหัสนี้ไม่ได้ทำซ้ำ sub-palindromes

r=raw_input()
i,l=0,len(r)
j=l
a=[]
while i<l-1:
 t=r[i:j];j-=1
 if t==t[::-1]:a+=['"'+t+'"']
 if j<i+2:i+=1;j=l
print", ".join(set(a))

1
เปลี่ยน'"'+t+'"'เป็นtประหยัดบางพื้นที่แม้ว่าจะใช้เครื่องหมายคำพูดเดี่ยว
โทมัสโอ


3

Golfscript, 48 ตัวอักษร

subpalindrome.gs

{,}{(;}/{{,}{);}/}%{+}*{.,1>\.-1%=*},.&{`}%", "*

การใช้งาน:

echo "12131331" | ruby golfscript.rb subpalindrome.gs

การดำเนินการครั้งแรก{,}{(;}/เปลี่ยนสตริงเป็นรายการของส่วนท้ายท้าย การแปลงสารชั้นนำที่คล้ายกันจะถูกแมปกับผลลัพธ์ จากนั้นแผ่แบนด้วย{+}*กรองฟินด์โดยใช้เพร.,1>\.-1%=*ดิเคตคว้าค่าที่ไม่ซ้ำด้วย.&แล้วพิมพ์สวย

มันจะเป็น neater ที่จะแยกส่วนท้ายของการแปลงเป็นบล็อกและนำมันกลับมาใช้ใหม่เพื่อแทนที่ substrings ชั้นนำหลังจากย้อนกลับแต่ละสตริงย่อยท้าย แต่ฉันไม่สามารถหาวิธีรวบรัดในการทำเช่นนั้น


2

Haskell - 170 , 153

import Data.List
import Data.Set
p a=fromList$[show x|x<-subsequences a,x==reverse x,length x>1]
main=getLine>>=(\x->putStrLn$intercalate", "$toList$p x)

แทนที่ด้วยmain=getLine>>=(\x->putStrLn$intercalate", "$toList$p x) main=getLine>>=putStrLn.intercalate", ".toList.pฉันจะแทนที่การโทรpด้วยร่างกายของมัน
Yasir Arsanukaev

สตริงย่อย / = subsequences! โปรแกรมของคุณรายงาน subpalindes มากกว่าเอาต์พุตอ้างอิงเช่น 1 (ตัวอย่างเช่น "1111")
JB


2

อารัมภบท, 92

f(S,P):-append([_,X,_],S),X=[_,_|_],reverse(X,X),atom_codes(P,X).
p(S,R):-setof(P,f(S,P),R).

ตัวอย่างการใช้งาน:

?- p("12131331",R).
R = ['121', '131', '1331', '313', '33'].

?- p("3333",R).
R = ['33', '333', '3333'].

2

Windows PowerShell, 104 109 111

0..($l=($s="$input").length-1)|%{($a=$_)..$l|%{-join$s[$a..$_]}}|sort -u|?{$_[1]-and$_-eq-join$_[$l..0]}

สิ่งนี้คาดว่าอินพุตของ stdin และจะโยน palindromes ที่พบทั้งหมดหนึ่งรายการต่อบรรทัดบน stdout:

PS Home:\SVN\Joey\Public\SO\CG183> '12131331'| .\subp.ps1
33
121
131
313
1331

(เมื่อเรียกใช้จากcmdมันจะกลายเป็นecho 12131331|powershell -file subp.ps1- มันเป็นเพียงที่$inputใช้ความหมายที่แตกต่างกันเล็กน้อยขึ้นอยู่กับวิธีที่เรียกว่าสคริปต์ แต่มันสามารถ stdin เพียงไม่โต้ตอบ)

2011-01-30 13:57 (111) - ความพยายามครั้งแรก

2011-01-30 13:59 (109) - การประกาศตัวแปรแบบอินไลน์

2011-06-02 13:18 (104) - ทำการค้นหาสตริงย่อยอีกครั้งโดยการเข้าร่วมอาร์เรย์อาร์เรย์แทนการโทร.Substring()ออก


2

คำถามที่ 78

{a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}

การใช้

q){a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}"12131331"
"121"
"131"
"313"
"1331"
"33"
q){a::x;(?)(,/)b@'(&:')({x~(|:)x}'')b:-1_1_'({(sublist[;a]')x,'1+c}')c::(!)(#)a}"3333"
"33"
"333"
"3333"

2

เรติน่า , 34 27 ไบต์

&@!`(.)+.?(?<-1>\1)+(?(1)^)

ลองออนไลน์!

ชุดทดสอบจำเป็นต้องใช้Mเนื่องจากมีขั้นตอนอื่นตามมาเพื่อแทรกบรรทัดว่างระหว่างกรณีทดสอบ

คำอธิบาย

&@!`(.)+.?(?<-1>\1)+(?(1)^)

พิมพ์ ( !) ทั้งหมดไม่ซ้ำกัน ( @) ทับซ้อนกัน (& ) ตรงกับของ (.)+.?(?<-1>\1)+(?(1)^)regex สิ่งนี้ตรงกับ palindrome ของความยาว 2 หรือมากกว่าโดยใช้กลุ่มสมดุล มีข้อควรระวังสำหรับส่วน "การแข่งขันที่ทับซ้อนกันทั้งหมด": เราสามารถแข่งขันได้มากที่สุดหนึ่งนัดต่อตำแหน่งเริ่มต้น อย่างไรก็ตามหาก palindromes ที่มีความยาวต่างกันเริ่มต้นที่ตำแหน่งเดียวกัน palindrome ที่สั้นกว่าจะปรากฏขึ้นอีกครั้งในตอนท้ายของ palindrome ที่ยาวกว่า และเนื่องจากความโลภของการ+จัดลำดับความสำคัญที่ตรงกันยาวนานขึ้นเราจึงได้รับ palindromes ทั้งหมด


2

05AB1E , 11 10 ไบต์

ŒÙʒÂQ}žQSK

ลองออนไลน์!



@scottinet ล้มเหลวสำหรับคนโสด EG1234142141410010101000
Magic Octopus Urn

1
ของคุณเหมือนกัน แต่ไม่ใช่ในทางเดียวกัน o_O มีบางอย่างเกิดขึ้นที่ต้องมีการตรวจสอบ ในระหว่างนี้นี่เป็นรุ่น 10 ไบต์ที่ดูเหมือนจะใช้งานได้
scottinet

มีข้อบกพร่องที่ไม่ซ้ำกันฉันแก้ไขมัน ตอนนี้ทั้ง 11 ไบต์ของคุณตอบและ 9 ไบต์ของฉันหนึ่งงาน :-)
scottinet

@scottinet 10 byter ของคุณอาจจะเป็น 9 byter เช่นกันโดยการเปลี่ยนไป1› :)
Kevin Cruijssen


1

JavaScript (ES6), 120 ไบต์

a=>{for(b=0,c=d=a.length,e=[];b<d;--c<b+2?(b++,c=d):1)(f=a.slice(b,c))==f.split``.reverse().join``&&e.push(f);return e}

ฟังก์ชันนี้รับสตริงเป็นอินพุตและเอาต์พุตอาร์เรย์


1

Clojure, 81 ไบต์

#(set(for[i(range 2(+(count %)1))p(partition i 1 %):when(=(reverse p)(seq p))]p))

forเป็นคู่ที่สมบูรณ์แบบที่นี่ :) สามารถใช้:when(=(reverse p)p)ถ้าอินพุตเป็นรายการของตัวละครหรือสตริงเต็มไม่นับเป็น palindrome จริง ๆ แล้วในกรณีนั้นช่วงสูงสุดของiอาจจะ(count %)เป็นเช่นกัน

กรณีกะทัดรัดที่สุดสำหรับการอ้างอิง:

#(set(for[i(range 2(count %))p(partition i 1 %):when(=(reverse p)p)]p))

1

Python 83 102 ตัวอักษร

s=lambda t:(t[1:]or())and(t,)*(t==t[::-1])+s(t[1:])+s(t[:-1])
print set(s(input()))

วลี(t[1:]or())and...นี้เทียบเท่ากับ(...)if t[1:]else()และบันทึกอักขระหนึ่งตัว! ฉันภูมิใจในสิ่งนี้มากเกินไปเพราะได้รับเงิน

ตัวอย่าง:

python x
"51112232211161"
set(['11', '22', '11122322111', '161', '111', '112232211', '1223221', '22322', '232'])

1

สกาล่า 127

object p extends App{val s=args(0);print(2.to(s.size).flatMap(s.sliding(_).toSeq.filter(c=>c==c.reverse)).toSet.mkString(" "))}

เพื่อให้แอปเปิ้ลแอปเปิ้ลเปรียบเทียบกับคำตอบ Scala อื่น ๆ ฉันได้สร้างวัตถุที่ขยายแอป แทนที่จะทำซ้ำสตริงอินพุตด้วยตนเองและใช้สตริงย่อยฉันใช้ประโยชน์จากการเลื่อน () เพื่อสร้างลำดับของสตริงย่อยทั้งหมดสำหรับฉัน


1

สกาลา 156 170

object o extends App{val l=args(0).length-2;val r=for(i<-0 to l;j<-i to l;c=args(0).substring(i,j+2);if(c==c.reverse))yield c;print(r.toSet.mkString(" "))}

object o{def main(s:Array[String]){val l=s(0).length-2;val r=for(i<-0 to l;j<-i to l;c=s(0).substring(i,j+2);if(c==c.reverse)) yield c;println(r.distinct.mkString(" "))}}


สวัสดี Lalith ฉันย่อรหัสของคุณเล็กน้อย: ไม่เว้นว่างก่อนที่จะให้ผลผลิตและขยายแอพแทนการเขียนทับ main, println => print and different => toSet
ผู้ใช้ที่ไม่รู้จัก

1

Perl 6 ,  35  32 ไบต์

{unique m:ex/(.+).?<{$0.flip}>/}

ทดสอบมัน

{set m:ex/(.+).?<{$0.flip}>/}

ทดสอบมัน

ขยาย:

{  # bare block lambda with implicit parameter 「$_」

  set             # turn into a Set object (ignores duplicates)

  \             # stringify 「~」 all of these 「«」 (possibly in parrallel)
                  # otherwise it would be a sequence of Match objects

  m               # match
  :exhaustive     # in every way possible
  /
    ( .+ )        # at least one character 「$0」
    .?            # possibly another character (for odd sized sub-palindromes)
    <{ $0.flip }> # match the reverse of the first grouping
  /
}


1

เยลลี่ขนาด 9 ไบต์

ẆQŒḂÐfḊÐf

ลองออนไลน์!


ผลลัพธ์ของลิงก์ถาวรของคุณไม่ถูกต้อง
เดนนิส

@ เดนนิสเหตุใดจึงกลายเป็นเป้าหมายล่อลวงแล้ว> _> แก้ไขแล้ว
Erik the Outgolfer

7 ไบต์พร้อมเยลลี่ใหม่
user202729

1

APL (Dyalog Classic) 27 ไบต์

{∪⍵/⍨≡∘⌽¨⍨⍵}∘⊃(,/1↓⍳∘≢,/¨⊂)

ลองออนไลน์!

{∪⍵/⍨≡∘⌽¨⍨⍵}∘⊃(,/1↓⍳∘≢,/¨⊂)    Monadic train:
                                Enclose the input, '12131331'
                     ⍳∘≢          Range from 1 to length of input
                     ⍳∘≢,/¨⊂      List of list of substrings of each length
                   1            Remove the first list (length-1 substrings)
                ,/              Put the rest of the substrings into a single list.
{∪⍵/⍨≡∘⌽¨⍨⍵}                   To the result, apply this function which
                                   keeps all palindromes from a list:
      ≡∘⌽¨⍨⍵                    Boolean value of whether each (¨) string in argument
      ≡∘⌽                      is equal to its own reverse

  ⍵/⍨                           Replicate (filter) argument by those values.
                                 This yields the length >1 palindromes.
                                Remove duplicates from the list of palindromes.

เนื่องจากการเรียก OP สำหรับ "รหัส" ตัวอย่าง∪w/⍨≡∘⌽¨⍨w←⊃,/1↓(⍳∘≢,/¨⊂)จึงถูกต้อง
Adám

@ Adam ฉันคิดว่าฉันจะเก็บคำตอบนี้ไว้เพราะมาตรฐานเว็บไซต์ที่ทันสมัยโดยเฉพาะอย่างยิ่งเมื่อมันไม่ได้รับรางวัลโดยรวม
lirtosiast


1

PowerShellขนาด 99 ไบต์

$args|% t*y|%{$s+=$_
0..$n|%{if($n-$_-and($t=-join$s[$_..$n])-eq-join$s[$n..$_]){$t}}
$n++}|sort -u

ลองออนไลน์!

หักกอล์ฟ:

$args|% toCharArray|%{
    $substring+=$_
    0..$n|%{
        if( $n-$_ -and ($temp=-join$substring[$_..$n]) -eq -join$substring[$n..$_] ){
            $temp
        }
    }
    $n++
}|sort -Unique

1

Brachylogขนาด 11 ไบต์

{s.l>1∧.↔}ᵘ

ลองออนไลน์!

(ส่วนหัวในลิงค์เสียในขณะที่ทำการโพสต์ดังนั้นนี่คือคำกริยา (ฟังก์ชั่นที่เทียบเท่าใน Brachylog) ในกรณีทดสอบครั้งแรกเท่านั้นโดยwที่ท้ายจะพิมพ์ผลลัพธ์)

               The output is
{        }ᵘ    a list containing every possible unique
 s.            substring of
               the input
   l           the length of which
    >          is greater than
     1         one
      ∧        and
       .       which
        ↔      reversed
               is itself. (implicit output within the inline sub-predicate)

ฉันรู้สึกว่ามีวิธีที่สั้นกว่าในการตรวจสอบว่ามีความยาวมากกว่า 1 (หากไม่ได้กรอง palindromes เล็กน้อยมันก็จะเป็น{s.↔}ᵘเช่นนั้น)


1

APL (NARS) 65 ตัวอักษร 130 ไบต์

{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}

ทดสอบ:

  r←{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}
  o←⎕fmt
  o r '1234442'
┌2───────────┐
│┌2──┐ ┌3───┐│
││ 44│ │ 444││
│└───┘ └────┘2
└∊───────────┘
  o r '3333'
┌3───────────────────┐
│┌4────┐ ┌3───┐ ┌2──┐│
││ 3333│ │ 333│ │ 33││
│└─────┘ └────┘ └───┘2
└∊───────────────────┘
  o r  "12131331"
┌5─────────────────────────────────┐
│┌4────┐ ┌3───┐ ┌2──┐ ┌3───┐ ┌3───┐│
││ 1331│ │ 121│ │ 33│ │ 313│ │ 131││
│└─────┘ └────┘ └───┘ └────┘ └────┘2
└∊─────────────────────────────────┘
  o r '1234'
┌0─┐
│ 0│
└~─┘


{0=≢m←∪b/⍨{1≥≢⍵:0⋄∧/⍵=⌽⍵}¨b←↑∪/{x[⍵;]⊂y}¨⍳≢x←11 1‼k k⊢k←≢y←⍵:⍬⋄m}
 y←⍵  assign the argument to y (because it has to be used inside other function)
 x←11 1‼k k⊢k←≢y   assign the lenght of y to k, call the function 11 1‼k k
                   that seems here find all partition of 1 2 ..k
 {x[⍵;]⊂y}¨⍳≢      make partition of arg ⍵ using that set x
 ∪/                set union with precedent to each element of partition y (i don't know if this is ok)
 b←↑               get first assign to b
 {1≥≢⍵:0⋄∧/⍵=⌽⍵}¨ for each element of b return 1 only if the argument ⍵ is such that 
                   "∧/⍵=⌽⍵" ⍵ has all subset palindrome, else return 0
 b/⍨               get the elements in b for with {1≥≢⍵:0⋄∧/⍵=⌽⍵} return 1
 m←∪               make the set return without ripetition element, and assign to m
 0=≢               if lenght of m is 0 (void set) than 
 :⍬⋄m              return ⍬ else return m

ใครบางคนรู้ดีกว่าว่าทำไมและสามารถอธิบายสิ่งนี้ได้ดีกว่าไม่มีการเปลี่ยนแปลงทั้งหมดนี้ ... ฉันไม่แน่ใจในรหัสนี้เป็นไปได้หากตัวอย่างทดสอบมีจำนวนมากขึ้นบางสิ่งจะผิดพลาด ...



0

Java 8, 202 201 199 ไบต์

import java.util.*;s->{Set r=new HashSet();String x;for(int l=s.length(),i=0,j;i<l;i++)for(j=i;++j<=l;)if((x=s.substring(i,j)).contains(new StringBuffer(x).reverse())&x.length()>1)r.add(x);return r;}

ลองที่นี่

หากฟังก์ชั่นไม่ได้รับอนุญาตและจำเป็นต้องใช้โปรแกรมเต็มรูปแบบจะเป็น256 255 253 ไบต์แทน:

import java.util.*;interface M{static void main(String[]a){Set r=new HashSet();String x;for(int l=a[0].length(),i=0,j;i<l;i++)for(j=i;++j<=l;)if((x=a[0].substring(i,j)).contains(new StringBuffer(x).reverse())&x.length()>1)r.add(x);System.out.print(r);}}

ลองที่นี่

คำอธิบาย:

import java.util.*;      // Required import for Set and HashSet

s->{                     // Method with String parameter and Set return-type
  Set r=new HashSet();   //  Return-Set
  String t;              //  Temp-String
  for(int l=s.length(),  //  Length of the input-String
          i=0,j;         //  Index-integers (start `i` at 0)
      i<l;i++)           //  Loop (1) from `0` to `l` (exclusive)
    for(j=i;++j<=l;)     //   Inner loop (2) from `i+1` to `l` (inclusive)
      if((t=s.substring(i,j) 
                         //    Set `t` to the substring from `i` to `j` (exclusive)
         ).contains(new StringBuffer(t).reverse())
                         //    If this substring is a palindrome,
         &t.length()>1)  //    and it's length is larger than 1:
        r.add(t);        //     Add the String to the Set
                         //   End of inner loop (2) (implicit / single-line body)
                         //  End of loop (1) (implicit / single-line body)
  return r;              //  Return the result-Set
}                        // End of method

0

JavaScript (ES6), 107 ไบต์

ส่งคืนชุด

s=>new Set((g=(s,r=[...s].reverse().join``)=>s[1]?(r==s?[s]:[]).concat(g(s.slice(1)),g(r.slice(1))):[])(s))

กรณีทดสอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.