Now there are some words that might look like palindromes but are not. For example consider the word sheesh, sheesh is not a palindrome because its reverse is hseehs which is different, however if we consider sh to be a single letter, then it's reverse is sheesh. This kind of word we will call a semi-palindrome.

Specifically a word is a semi-palindrome if we can split up the word in to some number of chunks such that when the order of the chunks are reversed the original word is formed. (For sheesh those chunks are sh e e sh) We will also require no chunk contains letters from both halves of the word (otherwise every word would be a semi-palindrome). For example rear is not a semi-palindrome because r ea r has a chunk (ea) that contains letters from both sides of the original word. We consider the central character in an odd length word to be on neither side of the word, thus for words with odd length the center character must always be in it's own chunk.

Your task will be to take a list of positive integers and determine if they are a semi-palindrome. Your code should output two consistent unequal values, one if the input is a semi-palindrome and the other otherwise. However the byte sequence of your code must be a semi-palindrome itself.

\$\begingroup\$Why did you define semi-palindromes using strings but your inputs are arrays of integers? In addition to being confusing, this means we can't test our source code using our own program.\$\endgroup\$
– BradCOct 15 '18 at 20:59

\$\begingroup\$@BradC Palindromes and the like are often explained in terms of words, since it's a bit easier to do so.\$\endgroup\$
– Erik the OutgolferOct 15 '18 at 21:01

\$\begingroup\$@BradC Strings tend to introduce weird edge cases, particularly in terms of characters vs bytes. I choose number because they are simpler. I thought words would be easier for explanation purposes.\$\endgroup\$
– Sriotchilism O'ZaicOct 15 '18 at 21:03

2

\$\begingroup\$These types of palindromes are known as Generalized Smarandache Palindromes in the literature.\$\endgroup\$
– borribleOct 16 '18 at 8:32

1

\$\begingroup\$@RosLuP Yes, "true" palindromes are also semi-palindromes, just treat each character/integer as-is with no additional "chunking".\$\endgroup\$
– BradCOct 18 '18 at 19:40

How it works

ṖUṁ@Ƒ€ṚẸHḢŒŒHḢŒṖUṁ@Ƒ€ṚẸ Main link. Argument: A (array)
Œ Invalid token. Everything to its left is ignored.
ŒH Halve; divide A into two halves similar lengths. The middle
element (if there is one) goes into the first half.
Ḣ Head; extract the first half.
ŒṖ Generate all partitions of the first half.
U Upend; reverse each chunk of each partition.
Let's call the result C.
Ṛ Yield R, A reversed.
Ƒ€ Fixed each; for each array P in C, call the link to the left
with arguments P and R.
Return 1 if the result is P, 0 if not.
ṁ@ Mold swapped; replace the n integers of C, in reading
order, with the first n integers of R.
Ẹ Exists; check if one of the calls returned 1.

\$\begingroup\$You can get around the issue with odd-length lists with 2äøøε.œ}`, saving 6 bytes. You also seem to have left 30 unused bytes in...\$\endgroup\$
– EmignaOct 15 '18 at 20:01

\$\begingroup\$@Emigna the no-ops at the end are to comply with the challenge's restricted source requirement\$\endgroup\$
– Kamil DrakariOct 15 '18 at 21:44

\$\begingroup\$@KamilDrakari: Oh right. Forgot that part. Good news is that the 6-byte save will be 12 bytes then :)\$\endgroup\$
– EmignaOct 16 '18 at 5:49

\$\begingroup\$@Emigna Very smart with the double-zip trick. I was not happy about that part, but this is a lot better! Btw, since the Elixir rewrite the 2-byte commands can be used with € instead of ε }. :)\$\endgroup\$
– Kevin CruijssenOct 16 '18 at 6:25

This condition: The lengths of each (€g) are stored in a list, whose prefixes (η) are then summed (O), hence giving us the cumulative sums of the lengths list. Then, the ceiled halve of the maximum of that list is pushed onto the stack – but keeping the original list on it as well (Z;î) and if it occurs (å) in the cumulative sums then the function returns truthy.

εÂQ}

For each, compare (Q) a with a reversed, which are pushed separately on the stack by Â. Returns a list of 0s and 1s.

ZĀq

Maximum. If any is truthy, then 1 else 0. End execution. Everything that follows is completely ignored.

The only chunks are the ŒḂs ({3rd & 4th} vs {29th & 30th} bytes), just to allow the code to parse.

How?

All the work is performed by the right-hand side - the "Main Link":

ŒṖẈÄċṀHĊƊ$ƊƇŒḂƇẸ - Main Link: list
ŒṖ - all partitions
Ƈ - filter keep those for which this is truthy (i.e. non-zero):
Ɗ - last three links as a monad:
Ẉ - length of each
$ - last two links as a monad:
Ä - cumulative addition
Ɗ - last three links as a monad:
Ṁ - maximum
H - halve
Ċ - ceiling
ċ - count
Ƈ - filter keep those for which this is truthy:
ŒḂ - is palindrome?
Ẹ - any?

p(L,a,n) returns 0 if array a of length L is a semi-palindrome, 1 otherwise. Given that all prefixes of length >n are already checked, it compares the prefix of length n with the suffix of length n. p(L,a) is the entry point.

Big improvement this version, it actually beats most of the practical languages now. Now operates on an array of integers since the previous method had a bug.

Explanation:

@ }a1 Find the first number n > 0 such that...
¯X the first n elements
UsXn and the last n elements
e are the same
"
Ê§V?UÊ<2:ßUéV sVÑ String literal to make it a Semi-palindrome
@¯X eUsXn}a1 "
Ê§V? If n >= length of input...
UÊ<2 return true if the length is less than 2
: Otherwise...
UéV move n elements from the end of the input to the start
sVÑ remove the first 2*n elements
ß and repeat on the remaining elements

\$\begingroup\$The challenge requires that your code be a semi-palindrome as well. That's most the fun in the challenge.\$\endgroup\$
– Sriotchilism O'ZaicOct 26 '18 at 23:19

\$\begingroup\$@PostLeftGhostHunter, I added original source code into comment to satisfy the requirement. BTW, what is the fun of making source code semi palindrome? If I'm not wrong, every solution in this thread would be two times shorter without this requirement. Are you aware of any solution not like that?\$\endgroup\$
– Dr Y WitOct 29 '18 at 16:30

Your Answer

If this is an answer to a challenge…

…Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.

…Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
Explanations of your answer make it more interesting to read and are very much encouraged.

…Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.

More generally…

…Please make sure to answer the question and provide sufficient detail.

…Avoid asking for help, clarification or responding to other answers (use comments instead).