Jelly, score 0, 366 68 bytes
LdLYYTYYJSpppppJLdLdLdLdLdLNCNCNCNCSSSSRUFNMHpOIFACHHNCHNCNCRTLrLLCN
Try it online!
Uses a New and Exciting™️ construction for obtaining the pivotal [155, 64]
constant from 91
, which just so happens to require \$O(n^5)\$ time and memory:
pppppJLdLdLdLdLdLNCNCNCNCSSSS Turn 91 into [155, 64]:
p Take the Cartesian product of [1 .. 91] with
the input (whose length I'll call L).
p Length: 91 * L.
p Do it again.
pp Length: 91 * L ** 2.
ppppp Do it a total of five times,
J using [1 .. L] once for chaining purposes.
pppppJL Take the length: 91 * L ** 5.
dL Divmod by L: [91 * L ** 4, 0].
dL Do it again: [[91 * L ** 3, 0], [0, 0]].
dL Do it a total of five times, vectorizing deeper
dL each time and creating a big old nested mess
dL of pairs totaling 32 "leaf" scalar elements
pJLdL all which are 0 except for one leftmost 91.
N Negate each leaf
C and subtract it from 1,
NC which is to say add 1 *to each leaf*,
NCNCNCNC four times.
S Sum the outermost pair
SSSS four times, leaving one remaining pair:
pJLdL [91, 0]
NCNCNCNC + (4
pppp dLdLdLdL SSSS * 2 ** 4)
pppppJLdLdLdLdLdLNCNCNCNCSSSS = [155, 64].
The Jelly interpreter as hosted on CPython absolutely is theoretically capable of running this program on itself--not the case with some of my earliest B
-based attempts! MemoryError
s and OverflowError
s don't really keep you waiting--but you really, really don't want to. Fortunately, it is trivial to reduce the degree at the cost of length, removing one p
, one dL
, and one S
to add four NC
s, then eight, and so on, and doing so a maximal four times just brings you back to the vastly more performant previous revision:
Jelly, score 0, 366 365 200 194 172 bytes
LdLYYTYYJSpJLdLNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCNCRUFNMHpOIFACHHNCHNCNCRTLrLLCN
Try it online!
-1 remembering two golfs I'd thought of then abandoned two hours ago that cancel each other's problems/incompatibilities out
-165 by remembering I can divide by 2 before adding...
-6 with a little more goofier arithmetic
-22 realizing I can take distinct cumulative sums of integers with RUFNM
, and that that's so powerful that it's worth having to go back to dividing by 2 only afterwards! (on account of the restriction to integers)
Relies extensively on the guarantee of non-empty input, allowing the length L
to serve as a consistent positive integer that can math its way into making a handful of dyads not completely useless--aside from the underwhelming builtin set overall, the biggest weakness of ASCII-letter-only Jelly is the utter lack of any data-flow control whatsoever, rendering it completely impossible to combine two intermediate values if the right-hand one would be constructed by more than one builtin. However, most of the program is just spamming NC
(negate then subtract from 1) as a vectorizing increment or CN
as a vectorizing decrement--replacing those with normal additions or subtractions, we have:
LdLYYTYYJSpLLdL+64RUFNMH Construct the range midpoints:
L The length of the input (let's call it L)
dL divmod itself: [1, 0].
Y Join on newlines: [1, '\n', 0].
Y Join on newlines again: [1, '\n', '\n', '\n', 0].
T Truthy indices: [1, 2, 3, 4].
YY Join that on newlines, for a length of 13,
JS then sum [1 .. 13]: 91.
p Take the Cartesian product of that
Sp (implicitly converted to a 1-range) with
J the range from 1 to L inclusive,
L and take the length of that: 91 * L.
dL Divmod by L: [91, 0].
+64 Add 64: [155, 64].
R Convert both to 1-ranges
U descending,
F concatenate them,
N negate every element,
M and take maximal (i.e. -1) indices: [155, 219].
H Halve: [77.5, 109.5].
pOIFACHH‘H+2RTLrLL’ Count the characters outside the ranges:
p Take the Cartesian product of the midpoints with
O the codepoints of the input,
A and take the absolute value of
IF the difference of each pair.
C Subtract the differences from 1,
HH divide by 4,
‘ increment,
H halve,
+2 add 2,
R then finally convert to 1-ranges
RT which are empty if they're less than 1.
CHH‘H+2 (21-d)/8 < 1 iff d > 13.
TL Count the nonempty ranges:
pOIFACHH‘H+2RTL the number of characters *in* [A-Za-z].
rL Take the inclusive range from that to L,
L’ and subtract 1 from the length of that.
Yes, the 13th triangular number just so happens to also be 64 less than the sum of the codepoints of A
and Z
, i.e. twice their average which is 12.5 away from both of them, and that distance rounds up to 13. Wacky.
It feels like there might still be a cleverer way to construct the range midpoints using T
or M
, but the best I could think of so far was just Y
spam that gets binary digits from the length of a list larger than the Jelly interpreter is capable of constructing, and at this point it might not beat 68.
If all Unicode characters with the Letter property counted as alphabetic, nŒsCS
would be score 0 and 5 bytes, but rely heavily on the guarantee that the only non-ASCII characters in the input are the ones in the program--it counts the characters that don't change when case-swapped, but not all letters have case variants. Constructing a Python expression to access the unicodedata
module with only letters could also be pretty entertaining itself...