33
\$\begingroup\$

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'
\$\endgroup\$
8
  • 2
    \$\begingroup\$ Can we assume all letters are distinct? \$\endgroup\$
    – att
    May 7, 2022 at 1:33
  • \$\begingroup\$ @att Sure, tht's fine. \$\endgroup\$
    – emanresu A
    May 7, 2022 at 2:09
  • 2
    \$\begingroup\$ 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? \$\endgroup\$ May 7, 2022 at 9:10
  • 3
    \$\begingroup\$ @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. \$\endgroup\$
    – emanresu A
    May 7, 2022 at 11:18
  • 2
    \$\begingroup\$ If a leading + were acceptable, it could be done in a one-pass regex substitution. \$\endgroup\$
    – Deadcode
    Mar 26, 2023 at 6:31

43 Answers 43

1
2
2
\$\begingroup\$

Nibbles, 8.5 bytes

*"+".,,@::`<$_"'"

Attempt This Online!

*"+".,,@::`<$_"'"
*                 Join
 "+"               with plus signs
    .              for each n in
     ,              range
      ,              length
       @              input
        :           join
         :           join
          `<$         first n characters of
             _         input
              "'"      apostrophe
                      the remaining characters
\$\endgroup\$
1
\$\begingroup\$

Burlesque, 20 bytes

JiTjiS{''IC}Z[[-'+IC

Try it online!

J      # Dup
iT     # Tails
j      # Swap
iS     # Heads
{
 ''IC  # Intercalate "'"
}Z[    # Zip together then map
[-     # Drop head
'+IC   # Intercalate "+"
\$\endgroup\$
1
\$\begingroup\$

SNOBOL4 (CSNOBOL4), 99 bytes

	I =INPUT
N	X =X + 1
	I TAB(X) . L REM . R	:F(O)
	O =O "+" L "'" R	:(N)
O	O TAB(1) REM . OUTPUT
END

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Go, 150 bytes

import."strings"
type S=string
func f(s S)S{b:=[]S{}
for i:=range s{k:=""
for j,d:=range s{k+=S(d)
if j==i{k+="'"}}
b=append(b,k)}
return Join(b,"+")}

Attempt This Online!

Using strings.Builder, 153 bytes

import."strings"
func f(s string)string{b:=Builder{}
w:=b.WriteRune
for i:=range s{w('+')
for j,d:=range s{w(d)
if j==i{w('\'')}}}
return b.String()[1:]}

Attempt This Online!

Surprised how the string builder solution is only 3 bytes logner.

\$\endgroup\$
1
\$\begingroup\$

Pyth, 10 bytes

j\+XRQ\'Sl

Test suite

Explanation:
j\+XRQ\'Sl  | Full code
j\+XRQ\'SlQ | with implicit variables
------------+--------------------------------------
    R   SlQ | For each 1-index d of the input,
   X Q\'    |  Insert "'" into the input at index d
j\+         | Join with "+"
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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

LDIA*'+sjsAp''sj

Attempt This Online!

Port of DLosc's Pip answer.

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
\$\endgroup\$
1
\$\begingroup\$

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;}
\$\endgroup\$
1
\$\begingroup\$

Arturo, 49 47 bytes

$[s][join.with:"+"map..1size s=>[insert s&"'"]]

Try it

\$\endgroup\$
1
\$\begingroup\$

Scala, 72 bytes

Golfed version. Try it online!

def f(l:String)=l.indices.map(i=>l.patch(i,s"${l(i)}'",1)).mkString("+")

Ungolfed version

object Main extends App {
  def f(l: String): String = {
    l.indices.map(i => l.patch(i, s"${l(i)}'", 1)).mkString("+")
  }

  val test = List("abc", "de", "longabcdef", "short")
  val expected = List(
    "a'bc+ab'c+abc'",
    "d'e+de'",
    "l'ongabcdef+lo'ngabcdef+lon'gabcdef+long'abcdef+longa'bcdef+longab'cdef+longabc'def+longabcd'ef+longabcde'f+longabcdef'",
    "s'hort+sh'ort+sho'rt+shor't+short'"
  )
  val checker = List("✖️", "✓")

  for ((t, e) <- test zip expected) {
    val s = f(t)
    val checkMark = checker(if (s == e) 1 else 0)
    println(s"$t -> $s $checkMark")
  }
}
\$\endgroup\$
1
\$\begingroup\$

Uiua SBCS, 21 bytes

/$"_+_"≡⍜↻(⊂@')+1⇡⊃⧻¤

Try it!

\$\endgroup\$
0
\$\begingroup\$

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!

I forgot to add "+"

+10 characters to remove a trailing '+'

\$\endgroup\$
1
  • \$\begingroup\$ slice instead of substring is shorter. \$\endgroup\$
    – m90
    May 8, 2022 at 12:39
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.