This will turn into a series involving other aspects of calculus, including using the "derivative" of a string to find "stationary points" etc, as well as "integration" of sentences
Introduction
If y'all have ever studied calculus, you'll most likely know that differentiation is limited to differentiable functions.
Not that there's anything wrong with that, but have you ever wondered what it'd be like to take the first (or second) derivative of a word? Or how about a sentence? You probably haven't, so let me explain my theory of string based differentiation.
The Basics
If you already know how differentiation works, feel free to skip this part
When being introduced to the concept of differential calculus, most beginners are taught about the concept of differentiation from first principles. This is based on the concept of finding the gradient of a tangent to a curve via the gradient formula:
$$ m = \frac{y_2 - y_1}{x_2 - x_1} $$
On the tangent, we say that we have two points: \$(x, f(x))\$ and \$(x + h, f(x + h))\$, where \$h\$ is an infinitesimal number. Plugging this into the gradient formula gives:
$$ m = \frac{f(x+h)-f(x)}{x+h-x} = \frac{f(x+h) - f(x)}{h} $$
In order to eliminate any inaccuracies from the tangent's gradient, we take the limit of the above equation as \$h\$ approaches 0
, giving us:
$$ \frac{d}{dx}(f(x)) = \lim_{h\to 0}\left(\frac{f(x+h)-f(x)}{h}\right) $$
Now, you may be asking "how on earth does that apply to string calculus? First-principles uses functions and numbers, not characters!"
Well, for this challenge, I've devised a slightly modified version of the first principles concept. The "formula" we'll be using is:
$$ \frac{d}{dx}(y) = \sum_{h=-1}^{1}\left(h\left[y\left[x+h\right]-y\left[x\right]\right]\right) = y\left[x+1\right]-y\left[x-1\right] $$
The Formula Explained
One of the major differences here is that there is no longer a limit being taken of the equation. That's because it doesn't quite make sense having something approaching 0 for the whole string. Rather, we use a \$\sum\$ to inspect the characters to the left and right of the character in question.
Also, inside the sum, the first \$y\$ is now being multiplied by the \$h\$. This is to ensure that the result is balanced, as without it, the results weren't very reflective of the string.
To evaluate this formula for a certain index \$x\$, you:
- Evaluate \$-y[x-1] + y[x]\$
- Evaluate \$0\$
- Evaluate \$y[x+1] - y[x]\$
- Summate the above three items.
Essentially, you are calculating the following:
$$ y[x+1]-y[x-1] $$
Note that when subtracting things, the ordinal values are used. E.g. c - a
= 99 - 97
= 2
If any position becomes negative, it starts indexing from the back of the string (like python does). If any position becomes greater than the length of the string, the character is ignored.
Applying Differentiation to the Whole String
By now, you may have noticed that the first principles formula only works on individual characters, rather than the whole string. So, in this section, we will develop a more generalised approach to using the formula.
To apply the formula to the whole string, we get the derivative of each character in the string, convert those numbers to characters based on code point conversion (like python's chr()
function) and concatenate the results into a single string. Now, the problem here is that results may sometimes be negative. To solve this problem, we will introduce a second string to store information: the sign string.
This string will consist of a combination of any two letters of your choice, representing whether or not a character is positive.
Worked Example
Let's take a look at what would happen with the word Code
:
- We start at position
0
(C
). The three parts for this character are-(e + C)
,0
ando - c
. These evaluate to-34
,0
and44
. The sum of these is10
and the sign is+
. So a newline is added to the main string, and a+
is added to the sign string. - We then move to position
1
(o
). The three parts are:-(o + C)
,0
andd - o
. These evaluate to44
,0
and-11
. The sum of these is33
, so a!
is added to the main string and a+
is added to the sign string. - We then move to position
2
(d
). The three parts are:-(o + d)
,0
ande - d
. These evaluate to-11
,0
and1
. The sum of these is-10
, so a new line is added to the main string and a-
is added to the sign string. - We finally move to position
3
(e
). The position3 + 1
is longer than the length of the string, so therefore, the process ends.
Therefore, the final result is ["\n!\n", "++-"]
Test Cases
Format is input
, newline, output
. These test cases were generated using Python, and uses UTF-8.
Code
('\n!\n', 'ppn')
Code Golf
('\t!\nD\x1eO%\t', 'ppnnnppn')
Cgcc
('\x04 \x04', 'ppn')
Lyxal
('\r,\x18\x0c', 'ppnn')
3 - 3 = 0
('\x10\x06\x00\x06\x00\n\x00\r', 'nnpppppn')
Lim x -> 0
('9!I\x0b\x00K\x1e\r\x0e', 'ppnppnpnn')
lim x -> 0
('9\x01I\x0b\x00K\x1e\r\x0e', 'ppnppnpnn')
('', '')
afanfl;aknsf
('\x00\x00\x08\x05\x02+\x0b0\r\x08\x08', 'ppppnnnpppn')
nlejkgnserg
('\x05\t\x02\x06\x03\x03\x0c\t\x01\x02', 'pnnpnppnnp')
38492
('\x06\x01\x01\x02', 'pppn')
abcdefghijklmnopqrstuvwxy
('\x17\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02', 'nppppppppppppppppppppppp')
KLJBFD
('\x08\x01\n\x04\x02', 'pnnnp')
::::::::::::
('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'ppppppppppp')
aaa
('\x00\x00', 'pp')
aaaaa
('\x00\x00\x00\x00', 'pppp')
Rules
- Input will be restricted to printable ASCII
- You can use any codepage you like for the output, just so long as it is consistently used. This means that UTF-8, CP437, etc. are fair game.
- Input can be taken in any convenient and reasonable format
- Output can be given in any convenient and reasonable format. Suggested formats include: a list of both strings, each string on a newline, both strings joined together. It's up to you really how you want to output the result.
- Unicode sequences (like
\x00
or\x05
) can be used in the output if wanted. In other words, both real representations and Unicode control sequences are valid output given they are applied consistently. - You can use any two characters for the string sign. That's right! It doesn't have to be
+
and-
... it could bep
andn
or3
and'
. It really doesn't matter as long as you use two distinct characters. - For this challenge,
0
is considered positive.- Both full programs and functions are allowed.
Scoring
Of course, this is code-golf, so the shortest answer wins!
Reference Program
Special Thanks
I'd just like to say a huge thanks to @xnor and @FryAmTheEggman for showing me that my original model of string differentiation was not the best way of doing things. I'm much happier with this new method that you see here!
-(e + C) = -34
do you mean-e + C
\$\endgroup\$