# Derivative of a product

In calculus, the derivative of a mathematical function defines the rate at which it changes. The derivative of a function f(x) can be marked as f'(x), and these can sometimes be abbreviated to f and f'.

The derivative of the product of two functions fg is f'g + g'f. The derivative of three fgh is f'gh + fg'h + fgh'. In general, the derivative of a product of any number of functions is the sum of the product of all but one, multiplied by the derivative of the remaining one, for each individual function.

Your challenge is to take a string of distinct alphabetical characters and transform it into its derivative. No spacing or simplification is required, and terms separated by + may be in any order. The string will contain at least two characters.

This is , so the shortest code wins!

## Testcases

abc -> a'bc+ab'c+abc'
de -> d'e+de'
longabcdef -> l'ongabcdef+lo'ngabcdef+lon'gabcdef+long'abcdef+longa'bcdef+longab'cdef+longabc'def+longabcd'ef+longabcde'f+longabcdef'
short -> s'hort+sh'ort+sho'rt+shor't+short'

• Can we assume all letters are distinct?
– att
May 7, 2022 at 1:33
• @att Sure, tht's fine. May 7, 2022 at 2:09
• Is output with a leading + acceptable? May 7, 2022 at 5:12
• do the functions in each term need to remain in the original order? In other words, is aabc'+bca'+cab' an acceptable output for abc? May 7, 2022 at 9:10
• @DominicvanEssen That's a tricky one... I'm gonna say no simply because it's a major part of the challenge, and pretty much all answers would have to change to remain competitive under that. May 7, 2022 at 11:18

# Japt, 10 bytes

¬£i''YÄÃq+


Try it

¬£i''YÄÃq+     :Implicit input of string
¬              :Split
£             :Map each element at 0-based index Y
i''          :  Insert a "'" in U at index
YÄ        :  Y+1
Ã       :End map
q+     :Join with "+"


# Ruby, 36 bytes

->s{s.chars.map{s.sub _1,'\&\''}*?+}


Attempt This Online!

# J-uby, 52 bytes

~(:-&(:& &:sub|(~:%&(~:+&?')|:& &:*)|:|&A)).D|~:*&?+


Attempt This Online!

# Javascript (Node.js), 114 bytes

function a(b){l=b.length;s="";for(i=1;i<=l;i++){if(i>1)s+='+';s+=b.substring(0,i)+"'"+b.substring(i,l);}return s;}


Try it online!

+10 characters to remove a trailing '+'

• slice instead of substring is shorter.
– m90
May 8, 2022 at 12:39

# Python 3, 78 bytes

d=lambda s:'+'.join([s[:i+1]+'\''+s[i+1:] for i in range(len(s)) if i<len(s)])


Try it online!

# Arturo, 49 bytes

$[s][join.with:"+"map 1..size s'i[insert s i"'"]]  Try it # Swift, 104 bytes Swift is not a good language for string manipulation. {var a="" for i in$0.indices{var c=$0 c.insert("'",at:c.index(after:i)) a+=c+"+"} a.popLast() return a}  Type is (String) -> String or (Substring) -> String. Try it online! ## Swift, 120 bytes Not as short, but I think the way that a is initialized is funny. {var a=[$0][..<0]
for i in $0.indices{var c=$0
c.insert("'",at:c.index(after:i))
a+=[c]}
return a.joined(separator:"+")}


If Array is a pair (pointer, length)*, indexing operations are like this:

• arr[i] = *(pointer + i)
• arr[i...] = (pointer + i, length - i)
• arr[..<i] = (pointer, i)
• arr[...i] = (pointer, i + 1)
• arr[i..<j] = (pointer + i, j - i)
• arr[i...j] = (pointer + i, j - i + 1)
• arr[...] = (pointer, length)**

So, arr[..<0] creates an empty collection no matter what the array is. Here, I'm applying it to the array literal [\$0], which you would never do in practice but is technically legal.

*It's actually a triplet (pointer, length, capacity), but this gets the point across.

**Yes, this exists for some reason.

# Thunno, $$\ 16 \log_{256}(96) \approx \$$ 13.17 bytes

LDIA*'+sjsAp''sj


Attempt This Online!

#### Explanation

LDIA*'+sjsAp''sj  # Implicit input
LD                # Length of input and duplicate
IA*             # Wrap input in a list and repeat length times
'+sj         # Join this list by "+"
sAp      # Split into chunks of length of input
''sj  # Join this list by "'"
# Implicit output


# Java 8, 93 bytes

s->s.chars().mapToObj(e->s.replace((char)e+"",(char)e+"'")).reduce("",(a,b)->a==""?b:a+"+"+b)


Try it online!

Another close solution not using Streams (95 bytes) :

s->{String r="";for(String c:s.split("")){r+=(s+"+").replaceAll(c+"\\+{0,1}",c+"'");}return r;}


# Rust, 123 bytes

|s|{s.chars().map(|_|s).enumerate().map(|(i,w)|{let mut t=w.repeat(1);t.insert(i+1,'\'');t}).collect::<Vec<_>>().join("+")}


Attempt This Online!