For the entirety of this article:
+
is the concatenation operator.const is_p = <T,>(ls: T[]) => eq(ls, ls.toReversed())
## Anti
Anti-P is a str that when reversed, its normalized (relative) [HD](https://en.wikipedia.org/wiki/Hamming_distance) is `1` with respect to the original str. Example: "abcd" => "dcba". Another (more algorithmically efficient) definition, is that every entry-wise pair must be different.
Algorithm in Rust and TS, respectively:
```rust
use core::iter::zip;
fn anti_p<T: Eq>(ls: &[T]) -> bool {
zip(ls, ls.iter().rev())
.all(|(v, r)| v != r)
}
const anti_p = <T,>(ls: T[]) =>
ls.every((v, i) => v !== ls[ls.length - 1 - i])
Co-P (AKA “mutually-palindromic pair”), is a pair of strs that become P when concatenated in some arbitrary way, and are said to be “copalindromic”. Note that each aren’t necessarily P independently.
If A and B are co-P, then it can be safely assumed that they are at least weakly co-P:
const ord_co_p = <T,>(a: T[], b: T[]) =>
is_p(a.concat(b))
const weak_co_p = <T,>(a: T[], b: T[]) =>
ord_co_p(a, b) || ord_co_p(b, a)
Ordinal co-p. These are order-specific:
/** both orders */
const biord_co_p = <T,>(a: T[], b: T[]) =>
ord_co_p(a, b) && ord_co_p(b, a)
/** only 1 specific order */
const monord_co_p = <T,>(a: T[], b: T[]) =>
ord_co_p(a, b) && !ord_co_p(b, a)
/** any exclusive order */
const xord_co_p = <T,>(a: T[], b: T[]) =>
ord_co_p(a, b) != ord_co_p(b, a)
A pair of Ps that are also bi-ordinal co-P:
const strong_co_p = <T,>(a: T[], b: T[]) =>
is_p(a) && is_p(b) && biord_co_p(a, b)
Is a pair where each str has the same length. Example: “abcd” & “dcba” become “abcddcba” or “dcbaabcd”, which are both Ps, so the original pair is SCP.
Is a pair where each string has different lengths. Example: “abc” & “ddcba” become “abcddcba” or “ddcbaabc”, such that only the former is P, therefore the original pair is ACP.
Note that it’s possible for an ACP to have both concats be P: “0” + “00” => “000” (regardless of order). This is a trivial case.
A sub-P is a str which contains at least 1 substring of length>1 that is P. The substring must be a slice
, that is, each item must be adjacent (no gaps). Strs of len<=1 are never sub, by definition.
Every P is also a strong sub-P, because every P can be sliced in such a way that the result is also P, so SSP doesn’t deserve its own category.
A fully sub-P has all of its possible slices being P.
A str which has at least 1 permutation that is P.
A str where all permutations are P.