Паліндромізація струн


30

Вступ

Для тих, хто не знає, паліндром - це коли рядок дорівнює рядку назад (за винятком інтерпункції, пробілів тощо). Прикладом паліндром є:

abcdcba

Якщо ви скасуєте це, ви отримаєте:

abcdcba

Який же. Тому ми називаємо це паліндром. Щоб паліндромізувати речі, розглянемо приклад рядка:

adbcb

Це не паліндром. Щоб паліндромізувати це, нам потрібно об'єднати повернутий рядок у початковий рядок праворуч від початкової рядки , залишивши недоторканими обидві версії. Чим коротше, тим краще.

Перше, що ми можемо спробувати, це наступне:

adbcb
bcbda
^^ ^^

Не всі символи відповідають, тому це не правильне положення для зворотного рядка. Ми йдемо один крок вправо:

adbcb
 bcbda
 ^^^^

Це також не відповідає всім персонажам. Ми робимо ще один крок вправо:

adbcb
  bcbda

Цього разу всі персонажі відповідають . Ми можемо об'єднати обидва рядки, залишивши недоторканими . Кінцевий результат:

adbcbda

Це паліндромізована струна .


Завдання

Давши рядок (щонайменше з одним символом), що містить лише малі літери (або великі регістри , якщо це краще підходить), виведіть паліндромізований рядок .


Тестові справи

Input     Output

abcb      abcba
hello     hellolleh
bonobo    bonobonob
radar     radar
hex       hexeh

Це , тому подання з найменшою кількістю байтів виграє!



6
Вам слід вказати, що повернутий рядок повинен бути об'єднаний у початковий рядок із зворотним рядком праворуч. Якщо це може йти зліва, obonoboбуло б кращим рішенням тестового випадку.
Рівень Св. Св.


2
@LevelRiverSt +1 лише тому, що "обонобо" таке дивовижне слово
Натаніел

1
@Nathaniel Спасибі, але bono b o nobце ціле речення. Яка різниця між Богом і Боно? Бог не блукає по Дубліну, роблячи вигляд, що є Боно ;-)
Level River St

Відповіді:


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.

Як ви придумали такий код? Це ледве читабельний і абсолютно не зрозумілий тому, хто не знайомий з Пітом. Яке призначення такої мови.
anukul

5
@momo Метою мови є написання короткого коду для розваги. Це рекреаційна діяльність. Я можу це написати тому, що в мене багато практики, і тому, що я винайшов мову. Я знаю, що це не зрозуміло тому, хто не знає мови, саме тому я включив пояснення.
isaacg

13

Пітон, 46 байт

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

Якщо рядок є паліндром, поверніть її. В іншому випадку простеліть першу букву навколо рекурсивного результату на залишок рядка.

Приклад розбивки:

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]

Якщо рядок є паліндром, поверніть її. Інакше бутерброд першої літери навколо рекурсивного результату для хвоста струни.

Рядок sрозбивається на h:tдругий захист, уникаючи наповнювача 1>0для цього випадку. Це коротше, ніж робити s@(h:t)для введення.



5

Брахілог , 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

Зворотне розповсюдження робить це таким чином, що перше дійсне значення для Aнього буде найкоротшим, яке ви можете приєднати до Input, щоб зробити його паліндром.

Черговий розчин, 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

Спробуйте в Інтернеті!

Велика подяка Мартіну за 11 байт збережених!

Це просто створює зворотну копію рядка і згладжує їх. Єдиною дійсно фантазійною частиною цього є метод реверсування:, 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

Луа, 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))

неозорий

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можна видалити?
Leaky Nun

@LeakyNun впевнений, що вони можуть ^^
Katenkyo

Не можете i=i+1end?
Ерік Аутгольфер

1
@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ На жаль, я не можу. Це спробують оцінити 1endяк шістнадцяткове число. Як правило, ви не можете користуватися [abcdef]безпосередньо після числа, не вважаючи його шістнадцятковим. Є ще один виняток 0x.
Katenkyo

3

Пролог, 43 байти

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

Це очікує, що рядок коду є вхідним, наприклад, у SWI-Prolog 7: a(`hello`).

Пояснення

Це в основному порт моєї відповіді Брахілог.

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:

Це монадійне дієслово. Спробуйте тут. Використання:

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

Пояснення

Я використовую той факт, що паліндромізація S є S + зворотною (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

Хаскелл, 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створити паліндром.


Не r=reverseпотрібно йти раніше f i=...?
Ерік Аутгольфер

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ: Ні, ви можете використовувати будь-яке замовлення.
німі

Мені вдалося в 46 байт. Надіваюся, це можна зробити ще краще.
theonlygusti

@theonlygusti: див . відповідь xnor .
німі

1

MATL , 17 16 байт

Нещільно вселив CJam відповідь @ 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

Рубін, 44 байти

Ця відповідь заснований на XNOR в Python і Haskell рішень.

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

Не можете ==s?s:?
Ерік Аутгольфер

@ EʀɪᴋᴛʜᴇGᴏʟғᴇʀ irb кидає форму, якщо я спробую це. Повинно бути щось спільне з тим, як він розбирає ?між ?:потрійними та ?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);}}

Безголовки:

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

Хаскелл, 46 байт

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

Мені цікаво, чи є спосіб видалити дужки в (f$tail l)++[l!!0]...

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.