> <> , 137 131 байт
Когда я увидел этот вызов, я подумал, что> <>, наконец, может быть хорошим выбором языка, поскольку, используя его, вы в основном можете игнорировать палиндромы; просто убедиться, что указатель остается только там, где и должен. Хотя это и правда,> <>, к сожалению, делает условия для игры в гольф мучительными (или просто для игры в гольф в целом). Я надеюсь использовать некоторые странные уловки, о которых я думал, чтобы компенсировать это, но вот «быстрый» (не на самом деле, как программный, так и творческий) ответ. Вы можете попробовать это онлайн здесь .
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
Возвращает 1 для true и -1 для false (я мог бы изменить его на 0, но длина, к сожалению, осталась бы прежней)
Как всегда, дайте мне знать, если это не сработает, и если у вас есть идеи о том, как играть в гольф. Я проверил это на нескольких тестовых примерах, но всегда может быть исключение.
Вот еще одна версия, которая, на мой взгляд, немного умнее, но, увы, на десять байтов больше. Значения Truthy / Falsey на этот раз равны 1 и ошибка ( 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<
Объяснение:
Вот код без добавленной части, чтобы сделать его палиндромом. В этом не используются «более умные» приемы, которые я пытался использовать для альтернативной версии, так что это немного проще объяснить (если кому-то интересно объяснение «приемов», я был бы рад дать один , хотя).
i:0(?v>:"Z")?vl1-:1(?v&:{:@=?v$&e0.>
;n1<^ -*48< .00~< ;n-10<
Линия 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
Вот как работает замысловатый swapping ( :{:@=?v$
) - я буду использовать тестовый пример этого стека: [5,1,8,1]
где последний символ - верхний.
:{
Вершина стека дублируется:, [5,1,8,1,1]
а стек смещен влево:[1,8,1,1,5]
:@
Верх дублируется: [1,8,1,1,5,5]
затем три верхних значения сдвигаются вправо:[1,8,1,5,1,5]
=?v
Не нужно для этой части объяснения
$
Верхнее значение [1,8,1,5]
поменяется местами еще раз , что, если вы заметите, является исходным стеком, сдвинутым один раз (как если бы {
это была единственная команда).
Итак, что это делает на английском языке («Слава Богу, он на самом деле объясняет вещи») , проверяет весь стек по верхнему значению и перемещается в точку во второй строке, если какое-либо значение равно верхнему. Эта проверка выполняется пропорционально тому, сколько значений в стеке ( l - 1
где l
длина стека), чтобы все значения сравнивались друг с другом.
Строка 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)
действительный палиндром? Аналогично для[]
,{}
и<>
(при необходимости).