Given a string l, find all palindromic substrings p of l (including duplicates and single character strings). Next, rearrange all sub-strings in p into a valid palindrome (there may be multiple correct answers). If it is not possible to rearrange p into a single palindrome, your program may have undefined behavior (error, stack-overflow, exiting, hanging/untimely murder of John Dvorak, etc...)
Examples
Valid Test Cases
l = anaa
p = ['a', 'n', 'a', 'a', 'aa', 'ana']
result = anaaaaana or aanaaanaa or aaananaaa
l = 1213235
p = ['1', '2', '1', '3', '2', '3', '5', '121', '323']
result = 1213235323121
l = racecar
p = ['r', 'a', 'c', 'e', 'c', 'a', 'r', 'cec', 'aceca', 'racecar']
result = racecarcecaacecracecar (there are others)
l = 11233
p = ['1', '11', '1', '2', '3', '33', '3']
result = 113323311 or 331121133
l = abbccdd
p = ['a', 'b', 'bb', 'b', 'c', 'cc', 'c', 'd', 'dd', 'd']
result = bbccddaddccbb or ccbbddaddbbcc or (etc...)
l = a
p = ['a']
result = a
Invalid Test Cases (Not Possible)
l = 123456789
p = ['1', '2', '3', '4', '5', '6', '7', '8', '9']
result = <not possible, behavior undefined>
l = hjjkl
p = ['h', 'j', 'jj', 'j', 'k', 'l']
result = <not possible, behavior undefined>
l = xjmjj
p = ['x', 'j', 'jmj', 'm', 'j', 'jj', 'j']
result = <not possible, behavior undefined>
Rules
- If the input word is a palindrome itself, it will always be valid as input.
- Only one substring should be returned, which one you choose is arbitrary as long as it's valid.
- If the input has no viable output, your code may have undefined behavior.
- Inputs will only contain ASCII-Printable characters between
0x20-0x7E. - This is code-golf, lowest byte-count is the winner.
12 Answers 12
Brachylog, 10 bytes
{s.↔}fpc.↔
Fails (i.e. prints false.) if not possible.
Explanation
{ }f Find all...
s. ...substrings of the input...
.↔ ...which are their own reverse
p Take a permutation of this list of palindromes
c. The output is the concatenation of this permutation
.↔ The output is its own reverse
JavaScript (ES6), 193 bytes
"Look Ma, no permutation built-in!" (So yes ... it's long ...)
Returns an empty array if there's no solution.
f=(s,a=[].concat(...[...s].map((_,i,a)=>a.map((_,j)=>s.slice(i,j+1)))).filter(P=s=>[...s].reverse().join``==s&&s),m=S=[])=>S=a.map((_,i)=>f(s,b=[...a],[...m,b.splice(i,1)]))>''?S:P(m.join``)||S
Demo
f=(s,a=[].concat(...[...s].map((_,i,a)=>a.map((_,j)=>s.slice(i,j+1)))).filter(P=s=>[...s].reverse().join``==s&&s),m=S=[])=>S=a.map((_,i)=>f(s,b=[...a],[...m,b.splice(i,1)]))>''?S:P(m.join``)||S
console.log(f('anaa'))
console.log(f('1213235'))
console.log(f('hjjkl'))
console.log(f('a'))
How?
Let's split the code into smaller parts.
We define P(), a function that returns s if s is a palindrome, or false otherwise.
P = s => [...s].reverse().join`` == s && s
We compute all substrings of the input string s. Using P(), we isolate the non-empty palindromes and store them in the array a.
a = [].concat(...[...s].map((_, i, a) => a.map((_, j) => s.slice(i, j + 1)))).filter(P)
The main recursive function f() takes a as input and compute all its permutations. It updates S whenever the permutation itself is a palindrome (once joined), and eventually returns the final value of S.
f = ( // given:
a, // a[] = input array
m = S = [] // m[] = current permutation of a[]
) => // and S initialized to []
S = a.map((_, i) => // for each element at position i in a[]:
f( // do a recursive call with:
b = [...a], // b[] = copy of a[] without the i-th element
[...m, b.splice(i, 1)] // the element extracted from a[] added to m[]
) // end of recursive call
) > '' ? // if a[] was not empty:
S // let S unchanged
: // else:
P(m.join``) || S // update S to m.join('') if it's a palindrome
Stax, 13 bytes
绬►Ö∞j∞:Æ╘τδ
Run test cases (It takes about 10 seconds on my current machine)
This is the corresponding ascii representation of the same program.
:e{cr=fw|Nc$cr=!
It's not quite pure brute-force, but it's just as small as the brute-force implementation I wrote. That one crashed my browser after about 10 minutes. Anyway, here's how it works.
:e Get all contiguous substrings
{cr=f Keep only those that are palindromes
w Run the rest of the program repeatedly while a truth value is produced.
|N Get the next permutation.
c$ Copy and flatten the permutation.
cr=! Test if it's palindrome. If not, repeat.
The last permutation produced will be implicitly printed.
Ruby, (削除) 131 (削除ここまで) (削除) 123 (削除ここまで) 120 bytes
->s{m=->t{t==t.reverse}
(1..z=s.size).flat_map{|l|(0..z-l).map{|i|s[i,l]}}.select(&m).permutation.map(&:join).detect &m}
A lambda accepting a string and returning a string. Returns nil when no solution exists.
-5 bytes: Replace select{|t|l[t]} with select(&l)
-3 bytes: Replace map{..}.flatten with flat_map{...}
-1 bytes: Loop over substring length and substring start, instead of over substring start and substring end
-2 bytes: Declare z at first use instead of beforehand
->s{
l=->t{t==t.reverse} # Lambda to test for palindromes
(1..z=s.size).flat_map{|l| # For each substring length
(0..z-l).map{|i| # For each substring start index
s[i,l] # Take the substring
}
} # flat_map flattens the list of lists of substrings
.select(&l) # Filter to include only palindromic substrings
.permutation # Take all orderings of substrings
.map(&:join) # Flatten each substring ordering into a string
.detect &l # Find the first palindrome
}
-
\$\begingroup\$
Jautomatically factorizes so you don't need€JjustJ; also, you're supposed to return one of the palindromes, not all. Try it online! is valid for the same byte-count. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年02月13日 15:49:10 +00:00Commented Feb 13, 2018 at 15:49 -
\$\begingroup\$ @MagicOctopusUrn Fixed, thanks ! \$\endgroup\$user2956892– user29568922018年02月13日 15:53:33 +00:00Commented Feb 13, 2018 at 15:53
-
\$\begingroup\$
Ùćcould be¤(or a number of other options) \$\endgroup\$Emigna– Emigna2018年02月13日 17:26:38 +00:00Commented Feb 13, 2018 at 17:26 -
\$\begingroup\$ @Emigna not sure why I didn't see the
Ùwasn't needed. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年02月13日 17:44:53 +00:00Commented Feb 13, 2018 at 17:44 -
\$\begingroup\$ Enigma My bad, for an unknown reason I thought we were supposed to display all of the unique palindromes, hence the original Ù. Thanks for the tip, fixed ! \$\endgroup\$user2956892– user29568922018年02月14日 09:24:45 +00:00Commented Feb 14, 2018 at 9:24
-
\$\begingroup\$ Lol I was so sure nobody else uses Pyth that I submitted my own separate answer (now deleted) prior to seeing yours. You can use
h_I#sM.p_I#.:ore_IDsM.p_I#.:for 13 bytes. \$\endgroup\$Mr. Xcoder– Mr. Xcoder2018年02月13日 16:25:44 +00:00Commented Feb 13, 2018 at 16:25 -
\$\begingroup\$ @Mr.Xcoder Oh haha :P yeah I hardly ever use Pyth, don't know why I decided to use it. Thanks! \$\endgroup\$2018年02月13日 16:51:22 +00:00Commented Feb 13, 2018 at 16:51
Python 3, 167 bytes
lambda a:g(sum(k,[])for k in permutations(g(a[i:j+1]for i in range(len(a))for j in range(i,len(a)))))[0]
g=lambda k:[e for e in k if e==e[::-1]]
from itertools import*
-2 bytes thanks to Mr. Xcoder
-
\$\begingroup\$ You can use
a[i:j+1]if you then usefor j in range(i,len(a))instead, for -2 bytes. \$\endgroup\$Mr. Xcoder– Mr. Xcoder2018年02月13日 16:41:52 +00:00Commented Feb 13, 2018 at 16:41
Husk, 12 bytes
ḟS=↔mΣPfS=↔Q
Explanation
ḟS=↔mΣPfS=↔Q Implicit input, a string.
Q List of substrings.
f Keep those
S=↔ that are palindromic (equal to their reversal).
P Permutations of this list.
mΣ Flatten each.
ḟ Find an element
S=↔ that is palindromic.
Japt, (削除) 19 (削除ここまで) 13 bytes
No longer hampered by Japt not being able to get all substrings of a string (nor, too much, by my current levels of exhaustion!).
Outputs undefined if there's no solution.
ã fêQ á m¬æêQ
ã fêQ á m¬æêQ :Implicit input of string
ã :Substrings
f :Filter by
êQ : Is palindrome
á :Permutations
m :Map
¬ : Join
æ :First element that
êQ : Is palindrome
-
1\$\begingroup\$ Is your question about a list of substring simply to remove
¬from your answer :P? \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年02月13日 18:37:24 +00:00Commented Feb 13, 2018 at 18:37 -
1\$\begingroup\$ Thought I could remove
m¬but then I would have neededæ_¬êQso it wouldn't have saved any bytes anyway! \$\endgroup\$Shaggy– Shaggy2018年02月13日 20:13:32 +00:00Commented Feb 13, 2018 at 20:13 -
\$\begingroup\$ Hahaha, I'll ensure to be wary of your byte-saving ways from now on ;). I tried removing it myself to check, but realized japt commands don't work like I think they work lol. \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年02月13日 20:28:02 +00:00Commented Feb 13, 2018 at 20:28
Explore related questions
See similar questions with these tags.
"abbccdd"is wrong: the last two letters should be"bb", not"dd". \$\endgroup\$