><>, 137 131 Bytes
When I saw this challenge, I thought ><> might finally be a good choice of language since using it you can mostly ignore palindromes; it is simple to make sure the pointer only stays where it should. While this is true, ><> unfortunately makes golfing conditionals excruciating (or just golfing in general). I hope to use some weird tricks I thought of to compensate for this, but here's a "quick" (not actually, both program-wise and creation-wise) answer. You can try it online here.
i:0(?v>:"Z")?vl1-:1(?v&:{:@=?v$&e0.>
;n1<^ -*48< .00~< ;n-10<01-n; >~00. >84*- ^>1n;
<.0e&$v?=@:}:&v?)1:-1lv?("Z":<v?)0:i
Returns 1 for true and -1 for false (I could change it to 0 but the length would stay the same, unfortunately)
As always, let me know if this doesn't work and if you have any ideas on how to golf it down. I tested it against a few test cases, but there always could be an exception.
Here's another version, one that I think is a bit more clever, but alas is ten bytes more. Truthy/falsey values this time are 1 and an error (something smells fishy...
):
>i:0(?v>:"Z")?vl: 2(?v&{:@$:@=01-*2.
< ;n1<^ -*48<f6+0.0<
&1-:1)e*1.1*e(1:-1&
>0.0+6f>84*- ^>1n; >
.2*-10=@:$@:}&v?)2 :lv?("Z":<v?)0:i<
Explanation:
Here's the code without the part added to make it a palindrome. This one doesn't use the "more clever" tricks I attempted to use for the alternate version, so it's a bit easier to explain (if anyone is interested in an explanation for the "tricks," I'd be happy to give one, though).
i:0(?v>:"Z")?vl1-:1(?v&:{:@=?v$&e0.>
;n1<^ -*48< .00~< ;n-10<
Line 1:
i:0(?v>:"Z")?vl1-:1(?v&:{:@=?v$&e0.>
i:0(?v #Pushes input and directs down if negative
>:"Z")?v #Directs down if input is greater than "Z"
#(reduces lowercase input to uppercase)
l #Pushes length
#Main loop begins
1-:1(?v #Decrements top, and then directs down if less than 1
& #Pushes top of stack onto register (length minus 1)
:{ #Duplicates top, shifts stack to the left
:@ #Duplicates top, shifts top three values of the stack to the right
=?v #If top two values are equal, directs down
$ #Swaps top two values of the stack
& #Pushes register onto stack
e0. #Jumps back to the "1" after "?vl"
#Main loop ends
> #Makes sure when the pointer jumps back to i it goes the right way
Here's how the convoluted swapping (:{:@=?v$
) works -- I'll use a test case of this stack: [5,1,8,1]
where the last character is the top.
:{
The top of the stack is duplicated: [5,1,8,1,1]
, and the stack shifted to the left: [1,8,1,1,5]
:@
The top is duplicated: [1,8,1,1,5,5]
, then the top three values are shifted to the right: [1,8,1,5,1,5]
=?v
Unnecessary for this part of explanation
$
The top value is swapped once more yielding [1,8,1,5]
, which, if you'll note, is the original stack shifted over once (as if {
had been the only command).
So what this does in English ("Thank God, he's actually explaining things") is check the entire stack against the top value and move to a point in the second line if any value equals the top. This checking is done proportionate to how many values there are in the stack (l - 1
, where l
is the length of the stack) so that all values are checked against each other.
Line 2:
;n1<^ -*48< .00~< ;n-10<
n1< #If input is less than 0 (i.e. there is none), print 1
; #and terminate
< #If redirected because input is greater than "Z"
-*48 #Push 32, subtract (reducing lowercase to uppercase, numerically)
^ #And move back to the portion that tests if input
#is uppercase (which it will pass now)
< #If counter is less than 1 (for main loop)
.00~ #Pop the counter and jump to the beginning (i)
< #If any two values in the stack are equal
-10 #Push -1 (subtract 1 from 0)
;n #Print and terminate
(hellolleh)
a valid palindrome? Similar for[]
,{}
, and<>
(where appropriate). \$\endgroup\$asdsa
be considered equal toasd\nsa
? \$\endgroup\$