การกำหนดสตริง


30

บทนำ

สำหรับคนที่ไม่ทราบว่า palindrome คือเมื่อสตริงเท่ากับสตริงย้อนหลัง (ยกเว้น interpunction, ช่องว่าง, ฯลฯ ) ตัวอย่างของ palindrome คือ:

abcdcba

หากคุณย้อนกลับมาคุณจะพบกับ:

abcdcba

ซึ่งเป็นแบบเดียวกัน ดังนั้นเราจึงเรียกสิ่งนี้ว่า palindrome เมื่อต้องการ palindromize สิ่งลองมาดูตัวอย่างของสายอักขระ:

adbcb

นี่ไม่ใช่ palindrome เพื่อให้เป็นไปตามนี้เราต้องรวมสตริงที่กลับด้านเข้าไปในสตริงเริ่มต้นที่ด้านขวาของสตริงเริ่มต้นโดยปล่อยให้ทั้งสองเวอร์ชันไม่เป็นอันตราย ยิ่งสั้นยิ่งดี

สิ่งแรกที่เราลองได้คือ:

adbcb
bcbda
^^ ^^

ไม่ใช่อักขระทุกตัวที่ตรงกันดังนั้นจึงไม่ใช่ตำแหน่งที่ถูกต้องสำหรับสตริงที่กลับด้าน เราไปทางขวาหนึ่งก้าว:

adbcb
 bcbda
 ^^^^

สิ่งนี้ยังไม่ตรงกับอักขระทั้งหมด เราไปอีกขั้นทางขวา:

adbcb
  bcbda

เวลานี้ตัวละครทุกตัวตรง เราสามารถผสานสตริงทั้งสองออกเหมือนเดิม ผลลัพธ์สุดท้ายคือ:

adbcbda

นี่คือสตริง palindromized


งาน

กำหนดสตริง (มีอย่างน้อยหนึ่งตัว) ที่มีเพียงตัวอักษรตัวพิมพ์เล็ก (หรือพิมพ์ใหญ่ถ้าพอดีกับที่ดีกว่า) เอาท์พุทสตริง palindromized


กรณีทดสอบ

Input     Output

abcb      abcba
hello     hellolleh
bonobo    bonobonob
radar     radar
hex       hexeh

นี่คือดังนั้นการส่งที่มีจำนวนไบต์น้อยที่สุดจะชนะ!



6
คุณควรระบุว่าสตริงที่ตรงกันข้ามจะต้องถูกรวมเข้ากับสตริงเดิมด้วยสตริงที่กลับด้านขวา หากไปทางซ้ายobonoboจะเป็นวิธีแก้ปัญหาที่ดีกว่าสำหรับกรณีทดสอบ
เลเวลริเวอร์เซนต์


2
@LevelRiverSt 1 เพียงเพราะ "obonobo" ดังกล่าวเป็นคำที่น่าตื่นตาตื่นใจ
นาธาเนียล

1
@ นาธาเนียลขอบคุณ แต่bono b o nobเป็นประโยคทั้งหมด ความแตกต่างระหว่างพระเจ้ากับ Bono คืออะไร? พระเจ้าไม่ได้เดินเล่นรอบ ๆ ดับลินแสร้งทำเป็น Bono ;-)
เลเวลริเวอร์เซนต์

คำตอบ:


5

เยลลี่11 10 ไบต์

ṫỤfU$Ḣœ^;U

ลองออนไลน์!

มันทำงานอย่างไร

ṫỤfU$Ḣœ^;U  Main link. Argument: s (string)

 Ụ          Yield all indices of s, sorted by their corr. character values.
ṫ           Tail; for each index n, remove all characters before thr nth.
            This yields the list of suffixes of s, sorted by their first character,
            then (in descending order) by length.
    $       Combine the two links to the left into a chain:
   U        Upend; reverse all suffixes.
  f         Filter; only keep suffixes that are also reversed suffixes.
            This gives the list of all palindromic suffixes. Since all of them
            start with the same letter, they are sorted by length.
     Ḣ      Head; select the first, longest palindromic suffix.
      œ^    Multiset symmetric difference; chop the selected suffix from s.
         U  Upend; yield s, reversed.
        ;   Concatenate the results to the left and to the right.

15

Pyth (กระทำ b93a874), 11 ไบต์

.VkI_IJ+zbB

ชุดทดสอบ

รหัสนี้ใช้ประโยชน์จากข้อผิดพลาดในรุ่นปัจจุบันของ Pyth การกระทำb93a874 ข้อผิดพลาดคือการที่_IJ+zbจะแยกกันราวกับว่ามันเป็นq_J+zbJ+zbซึ่งเทียบเท่ากับ_I+zb+zbเมื่อมันควร (โดยความตั้งใจออกแบบของ Pyth) สามารถแยกวิเคราะห์เป็นซึ่งเทียบเท่ากับq_J+zbJ _I+zbนี้จะช่วยให้ผมที่จะบันทึกไบต์ - .VkI_IJ+zbJBหลังจากข้อผิดพลาดได้รับการแก้ไขรหัสที่ถูกต้องจะเป็น ฉันจะอธิบายรหัสนั้นแทน

โดยพื้นฐานแล้วโค้ดเดรัจฉานจะบังคับให้ข้ามสตริงที่เป็นไปได้ทั้งหมดจนกระทั่งพบสตริงที่สั้นที่สุดที่สามารถผนวกเข้ากับอินพุตเพื่อสร้างพาเนลและส่งออกสตริงที่รวมกัน

.VkI_IJ+zbJB
                z = input()
.Vk             For b in possible strings ordered by length,
       +zb      Add z and b,
      J         Store it in J,
    _I          Check if the result is a palindrome,
   I            If so,
          J     Print J (This line doesn't actually exist, gets added by the bug.
          B     Break.

คุณคิดรหัสอย่างไร มันเป็นเรื่องที่อ่านได้ยากและไม่สามารถเข้าใจได้โดยคนที่ไม่คุ้นเคยกับ Pyth วัตถุประสงค์ของภาษาดังกล่าวคืออะไร
anukul

5
@momo วัตถุประสงค์ของภาษานี้คือการเขียนรหัสย่อเพื่อความสนุกสนาน มันเป็นกิจกรรมสันทนาการ ฉันสามารถเขียนได้เพราะมีการฝึกฝนมากมายและเพราะฉันคิดค้นภาษา ฉันรู้ว่ามันไม่สามารถเข้าใจได้สำหรับคนที่ไม่รู้จักภาษาซึ่งเป็นสาเหตุที่ฉันรวมคำอธิบายไว้
isaacg

13

Python ขนาด 46 ไบต์

f=lambda s:s*(s==s[::-1])or s[0]+f(s[1:])+s[0]

หากสตริงเป็น palindrome ให้ส่งคืน มิฉะนั้นแซนวิชตัวอักษรตัวแรกรอบผลการเรียกซ้ำสำหรับส่วนที่เหลือของสตริง

ตัวอย่างรายละเอียด:

f(bonobo)
b  f(onobo) b
b o f(nobo) o b 
b o n f(obo) n o b
b o n obo n o b

ฉันคิดว่าคุณสามารถบันทึกไบต์ได้หากคุณใช้เงื่อนไขตรงข้าม ( s!=s[::-1])
aditsu

@aditsu มันใช้งานได้ แต่การคูณจะสั้นกว่า
xnor

9

Haskell, 36 ไบต์

f s|s==reverse s=s|h:t<-s=h:f t++[h]

อ่านง่ายขึ้น:

f s
 |s==reverse s = s
 |(h:t)<-s     = h:(f t)++[h]

หากสตริงเป็น palindrome ให้ส่งคืน มิฉะนั้นแซนวิชตัวอักษรตัวแรกรอบผลซ้ำสำหรับหางของสตริง

สตริงsจะถูกแบ่งออกh:tในยามที่สองโดยการคัดแยกฟิลเลอร์1>0สำหรับกรณีนี้ สิ่งนี้สั้นกว่าs@(h:t)การป้อนข้อมูล


5

Pyth - 16 12 ไบต์

บันทึก 4 ไบต์ด้วย @FryAmTheEggman

FGITW เป็นไปได้มากในการเล่นกอล์ฟ

h_I#+R_Q+k._

Test Suite


5

Brachylog , 16 6 5 ไบต์ (ไม่แข่งขัน)

:Ac.r

ลองออนไลน์!

เมื่อฉันโพสต์คำตอบเริ่มต้นของฉันมันยังอยู่ในการใช้งานเก่าใน Java เนื่องจากฉันได้เขียนโปรแกรมใหม่ทุกอย่างใน Prolog ตอนนี้มันทำงานได้ดีเท่าที่ควร

คำอธิบาย

(?):Ac.        Output is the concatenation of Input with another unknown string A
      .r(.)    The reverse of the Output is the Output

Backpropagation ทำให้ค่าที่ใช้ได้ครั้งแรกสำหรับAมันจะสั้นที่สุดที่คุณสามารถต่อกับ Input เพื่อทำให้เป็น palindrome

โซลูชันสำรอง 5 ไบต์

~@[.r

นี่เป็นคำตอบเดียวกับข้างบนยกเว้นว่าแทนที่จะระบุ "เอาท์พุทเป็นการต่อข้อมูลที่มีสตริงA" เราระบุว่า "เอาท์พุทเป็นสตริงที่อินพุตเป็นส่วนนำหน้าของเอาท์พุท"


4

JavaScript (ES6), 92 ไบต์

(s,a=[...s],r=a.reverse().join``)=>s.slice(0,a.findIndex((_,i)=>r.startsWith(s.slice(i))))+r

คำนวณและแบ่งส่วนที่ทับซ้อนกันระหว่างสตริงเดิมและการกลับรายการ


4

จอประสาทตา 29 25

$
¶$_
O^#r`.\G
(.+)¶\1
$1

ลองออนไลน์!

ขอบคุณมากสำหรับMartin ที่บันทึกไว้ 11 ไบต์!

นี่เป็นเพียงการสร้างสำเนาที่ตรงกันข้ามของสตริงและ smooshes ด้วยกัน ส่วนที่แฟนซีเพียงอย่างเดียวของวิธีนี้คือวิธีการย้อนกลับ: O^#r`.\Gซึ่งทำได้โดยใช้โหมดเรียงลำดับ เราจัดเรียงตัวอักษรของสายอักขระที่สอง (ตัวที่ไม่ได้ขึ้นบรรทัดใหม่และต่อเนื่องกันจากจุดสิ้นสุดของสตริงขอบคุณ\G) ด้วยค่าตัวเลขซึ่งเนื่องจากไม่มีตัวเลขเป็น 0 จากนั้นเรากลับรายการ ลำดับของผลลัพธ์ของการเรียงลำดับที่เสถียรนี้พร้อม^ตัวเลือก เครดิตทั้งหมดสำหรับการใช้งานแฟนซีของ\Gมาร์ติน :)


3

CJam, 18

q__,,{1$>_W%=}#<W%

ลองออนไลน์

คำอธิบาย:

q         read the input
__        make 2 copies
,,        convert the last one to a range [0 … length-1]
{…}#      find the first index that satisfies the condition:
  1$>     copy the input string and take the suffix from that position
  _W%=    duplicate, reverse and compare (palindrome check)
<         take the prefix before the found index
W%        reverse that prefix
          at the end, the stack contains the input string and that reversed prefix

3

Lua, 89 88 ไบต์

ฉันชนะ Javascript! \ o / บันทึก 1 ไบต์ขอบคุณ @LeakyNun ^^

มันเป็นโปรแกรมที่สมบูรณ์ใช้อินพุตเป็นอาร์กิวเมนต์บรรทัดคำสั่ง

i=1s=...r=s:reverse()while s:sub(i)~=r:sub(0,#r-i+1)do i=i+1 end print(s..r:sub(#r-i+2))

ungolfed

i=1                             -- initialise i at 1 as string are 1-indexed in lua
s=...                           -- use s as a shorthand for the first argument
r=s:reverse()                   -- reverse the string s and save it into r
while(s:sub(i)~=r:sub(0,#r-i+1))-- iterate while the last i characters of s
do                              -- aren't equals to the first i characters of r
  i=i+1                         -- increment the number of character to skip
end
print(s..r:sub(#r-i+2))         -- output the merged string

ฉันเชื่อว่าวงเล็บที่อยู่ใกล้whileจะสามารถลบได้หรือไม่
Leun Nun

@LeakyNun มั่นใจว่าพวกเขาสามารถทำได้ ^^
Katenkyo

ทำไม่ได้i=i+1endเหรอ
Erik the Outgolfer

1
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀน่าเศร้าที่ฉันทำไม่ได้ มันจะพยายามประเมิน1endเป็นเลขฐานสิบหก โดยทั่วไปแล้วคุณไม่สามารถใช้งาน[abcdef]ได้โดยตรงหลังจากตัวเลขนั้นถูกพิจารณาว่าเป็นเลขฐานสิบหก 0xมีข้อยกเว้นอีกหนึ่งความเป็นอยู่คือ
Katenkyo

3

Prolog ขนาด 43 ไบต์

a(S):-append(S,_,U),reverse(U,U),writef(U).

สิ่งนี้คาดว่าสตริงรหัสเป็นอินพุตเช่นใน SWI-Prolog 7: a(`hello`).

คำอธิบาย

นี่เป็นพอร์ตของคำตอบ Brachylog ของฉัน

a(S) :-               % S is the input string as a list of codes
    append(S,_,U),    % U is a list of codes resulting in appending an unknown list to S
    reverse(U,U),     % The reverse of U is U
    writef(U).        % Write U to STDOUT as a list of codes

3

อ็อกเทฟ, 78 75 ไบต์

บันทึก 3 ไบต์ต้องขอบคุณEʀɪᴋᴛʜᴇGᴏʟғᴇʀ!

function p=L(s)d=0;while~all(diag(s==rot90(s),d++))p=[s fliplr(s(1:d))];end

ideone ยังคงล้มเหลวสำหรับฟังก์ชั่นที่มีชื่อ แต่นี่คือการทดสอบการทำงานของรหัสเป็นโปรแกรม


2

Perl, 37 ไบต์

ตามคำตอบของ xnor

รวมถึง +2 สำหรับ -lp

เรียกใช้ด้วยอินพุตบน STDIN เช่น

palindromize.pl <<< bonobo

palindromize.pl:

#!/usr/bin/perl -lp
s/.//,do$0,$_=$&.$_.$&if$_!~reverse



1

J, 20 ไบต์

,[|.@{.~(-:|.)\.i.1:

นี่คือคำกริยา monadic ลองที่นี่ การใช้งาน:

   f =: ,[|.@{.~(-:|.)\.i.1:
   f 'race'
'racecar'

คำอธิบาย

ฉันใช้ความจริงที่ว่า palindromization ของSคือS + reverse (P)โดยที่Pเป็นคำนำหน้าสั้นที่สุดของSซึ่งการลบออกในรูปพาลินโดรม ใน J มันเป็นเรื่องเล็ก ๆ น้อย ๆ ที่จะทำการค้นหาองค์ประกอบแรกของอาเรย์ที่ตรงกับคำกริยา ดังนั้นการจัดทำดัชนี

,[|.@{.~(-:|.)\.i.1:  Input is S.
        (    )\.      Map over suffixes of S:
         -:             Does it match
           |.           its reversal? This gives 1 for palindromic suffixes and 0 for others.
                i.1:  Take the first (0-based) index of 1 in that array.
 [   {.~              Take a prefix of S of that length: this is P.
  |.@                 Reverse of P.
,                     Concatenate it to S.

1

Haskell, 68 ไบต์

import Data.List
f i=[i++r x|x<-inits i,i++r x==x++r i]!!0
r=reverse

ตัวอย่างการใช้งาน: ->f "abcb""abcba"

ค้นหาinitsจากอินพุตi(เช่นinits "abcb"-> ["", "a", "ab", "abc", "abcb"]) จนกว่าคุณจะพบที่ซึ่งมีการผนวกย้อนกลับเพื่อiสร้าง palindrome


ไม่r=reverseต้องไปก่อนf i=...
Erik the Outgolfer

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ: ไม่คุณสามารถใช้คำสั่งซื้อใด ๆ
nimi

ฉันจัดการใน 46 ไบต์ ฉันพนันได้ว่าจะทำได้ดีกว่านี้
theonlygusti

@theonlygusti: เห็นคำตอบของ XNOR
nimi

1

MATL , 17 16 ไบต์

แรงบันดาลใจในการหลวมของ @ aditsu คำตอบ

`xGt@q:)PhttP=A~

ลองออนไลน์!

คำอธิบาย

`        % Do...while loop
  x      %   Delete top of stack, which contains a not useful result from the
         %   iteration. Takes input implicitly on first iteration, and deletes it
  G      %   Push input
  t      %   Duplicate
  @q:    %   Generate range [1,...,n-1], where n is iteration index. On the  first
         %   iteration this is an empty array
  )      %   Use that as index into copy of input string: get its first n elements
  Ph     %   Flip and concatenate to input string
  t      %   Duplicate. This will be the final result, or will be deleted at the
         %   beginning of next iteration
  tP     %   Duplicate and flip
  =A~    %   Compare element-wise. Is there some element different? If so, the
         %   result is true. This is the loop condition, so go there will be a 
         %   new iteration. Else the loop is exited with the stack containing
         %   the contatenated string
         % End loop implicitly
         % Display stack contents implicitly

1

Ruby, 44 ไบต์

คำตอบนี้จะขึ้นอยู่กับ XNOR ของงูหลามและHaskellการแก้ปัญหา

f=->s{s.reverse==s ?s:s[0]+f[s[1..-1]]+s[0]}

ทำไม่ได้==s?s:เหรอ
Erik the Outgolfer

@ E tryGᴏʟғᴇʀ irb ปาใส่ได้ถ้าฉันลอง ต้องเป็นสิ่งที่เกี่ยวข้องกับวิธีการแยกวิเคราะห์?ระหว่าง?:ternary และการ?x == 'x'แทนที่ที่ใช้ตั้งแต่ Ruby 1.9
Sherlock9

1

Oracle SQL 11.2, 195 ไบต์

SELECT MIN(p)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(p))FROM(SELECT:1||SUBSTR(REVERSE(:1),LEVEL+1)p FROM DUAL WHERE SUBSTR(:1,-LEVEL,LEVEL)=SUBSTR(REVERSE(:1),1,LEVEL)CONNECT BY LEVEL<=LENGTH(:1));

ยกเลิกแข็งแรงเล่นกอล์ฟ

SELECT MIN(p)KEEP(DENSE_RANK FIRST ORDER BY LENGTH(p))
FROM (
       SELECT :1||SUBSTR(REVERSE(:1),LEVEL+1)p 
       FROM   DUAL 
       WHERE  SUBSTR(:1,-LEVEL,LEVEL)=SUBSTR(REVERSE(:1),1,LEVEL)
       CONNECT BY LEVEL<=LENGTH(:1)
     );

1

อย่างจริงจัง 34 ไบต์

╩╜lur`╜╨"Σ╜+;;R=*"£M`MΣ;░p╜;;R=I.

อักขระตัวสุดท้ายเป็นช่องว่างไม่แตกหัก (ASCII 127 หรือ0x7F)

ลองออนไลน์!

คำอธิบาย:

╩╜lur`╜╨"Σ╜+;;R=*"£M`MΣ;░p╜;;R=I.<NBSP>
╩                                        push inputs to registers (call the value in register 0 "s" for this explanation)
 ╜lur                                    push range(0, len(s)+1)
     `              `M                   map (for i in a):
      ╜╨                                   push all i-length permutations of s
        "        "£M                       map (for k in perms):
         Σ╜+                                 push s+''.join(k) (call it p)
            ;;R=                             palindrome test
                *                            multiply (push p if palindrome else '')
                      Σ                  summation (flatten lists into list of strings)
                       ;░                filter truthy values
                         p               pop first element (guaranteed to be shortest, call it x)
                          ╜;;R=I         pop x, push s if s is palindromic else x
                                .<NBSP>  print and quit

1

C #, 202 ไบต์

ฉันเหนื่อย.

class P{static void Main(string[]a){string s=Console.ReadLine(),o=new string(s.Reverse().ToArray()),w=s;for(int i=0;w!=new string(w.Reverse().ToArray());){w=s.Substring(0,i++)+o;}Console.WriteLine(w);}}

Ungolfed:

class P
{
    static void Main(string[] a)
    {
        string s = Console.ReadLine(), o = new string(s.Reverse().ToArray()), w = s;
        for(int i = 0; w!=new string(w.Reverse().ToArray());)
        {
            w = s.Substring(0, i++) + o;
        }
        Console.WriteLine(w);
        Console.ReadKey();
    }

}

ทุกคนสามารถให้แนวคิดกับฉันในการจัดกลุ่มสองสายไปยัง. Reverse () ToArray () ได้หรือไม่ วิธีการแยกเป็นไบต์เพิ่มเติม


0

QBIC , 41 ไบต์

;_FA|C=A{a=a+1~C=_fC||_XC\C=A+right$(B,a)

คำอธิบาย:

;_FA|    Read A$ from the cmd line, then flip it to create B$
C=A      Set C$ to be A$
{        Start an infinite DO-loop
a=a+1    Increment a (not to be confused with A$...)
~C=_fC|  If C$ is equal to its own reversed version
|_XC     THEN end, printing C$
\C=A+    ELSE, C$ is reset to the base A$, with
right$(B the right part of its own reversal
,a)      for length a (remember, we increment this each iteration
         DO and IF implicitly closed at EOF

0

Haskell, 46 ไบต์

f l|l==reverse l=l|(h:t)<-l=l!!0:(f$tail l)++[l!!0]

ฉันสงสัยว่าถ้ามีวิธีที่จะเอาวงเล็บใน(f$tail l)++[l!!0]...

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