10
\$\begingroup\$

Definition

The chain rule with two functions state that:

D[f(g(x))] = f'(g(x)) * g'(x)

Or, alternatively:

D[f1(f2(x))] = f1'(f2(x)) * f2'(x)

The chain rule with three functions state that:

D[f(g(h(x)))] = f'(g(h(x))) * g'(h(x)) * h'(x)

Or, alternatively:

D[f1(f2(f3(x)))] = f1'(f2(f3(x))) * f2'(f3(x)) * f3'(x)

Et cetera.

Task

  • Given an integer between 2 and 21, output the chain rule with that many functions, either in the first form or in the second form.
  • Please specify if you are using the second form.

Specs

  • The format of the string must be exactly that stated above, with:
    1. all the spaces kept intact
    2. a capitalized D
    3. a square bracket immediately following D
    4. the asterisk kept intact
  • One extra trailing space (U+0020) is allowed.
  • Leading zeros in the function names in the second form (e.g. f01 instead of f1) is allowed.

Testcases

If you use the first form:

input output
2 D[f(g(x))] = f'(g(x)) * g'(x)
3 D[f(g(h(x)))] = f'(g(h(x))) * g'(h(x)) * h'(x)

If you use the second form:

input output
2 D[f1(f2(x))] = f1'(f2(x)) * f2'(x)
3 D[f1(f2(f3(x)))] = f1'(f2(f3(x))) * f2'(f3(x)) * f3'(x)

Leaderboard

var QUESTION_ID=86652,OVERRIDE_USER=48934;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>

asked Jul 26, 2016 at 21:57
\$\endgroup\$
2
  • \$\begingroup\$ Do function names have to be lowercase? \$\endgroup\$ Commented Jul 26, 2016 at 23:21
  • \$\begingroup\$ @betseg Yes of course. \$\endgroup\$ Commented Jul 26, 2016 at 23:22

7 Answers 7

6
\$\begingroup\$

Python 2, 79 bytes

f=lambda n:0**n*"D[x] ="or f(n-1).replace("x","f%d(x)"%n)+1%n*" *"+" f%d'(x)"%n

Outputs with numbered functions.

Builds the output by repeatedly replacing each x with fn(x), then appending * fn'(x). The * is omitted for n==1.

Compare to the iterate program (92 bytes):

r="D[x] = ";n=0
exec'n+=1;r=r.replace("x","f%d(x)"%n)+"f%d\'(x) * "%n;'*input()
print r[:-3]

96 bytes:

n=input();r='';s='x'
while n:s='f%d(%%s)'%n%s;r=" * f%d'"%n+s[2:]+r;n-=1
print"D[%s] = "%s+r[3:]

Outputs with numbered functions.

Accumulates the nested function f1(f2(f3(x))) in s and the right-hand-side expression in r. The string formatting is clunky; f-strings from 3.6 would do better.

answered Jul 27, 2016 at 0:56
\$\endgroup\$
6
\$\begingroup\$

Sesos, 49 bytes

0000000: 2ac992 63fb92 245fb6 6c57be 255bbe 2cc9bf 6d49da *..c..$_.lW.%[.,..mI.
0000015: 025e7f fdced0 fd67f8 fcde33 b6a7b2 643d4f 65597e .^.....g...3...d=OeY~
000002a: f77a72 dd73cf fe .zr.s..

Try it online

Disassembled

set numin
add 68 ; 'D'
put
sub 7 ; '=' - 'D'
fwd 1
add 32 ; ' '
fwd 1
add 91 ; '['
put
add 2 ; ']' - '['
fwd 1
add 102 ; 'f'
fwd 1
add 40 ; '('
fwd 3
add 120 ; 'x'
rwd 2
get
jmp
 jmp
 fwd 1
 add 1
 rwd 3
 put
 add 1
 fwd 1
 put
 fwd 1
 sub 1
 jnz
 sub 1
 rwd 1
 add 1 ; ')' - '('
 fwd 3
 put
 rwd 1
 jmp
 rwd 3
 sub 1
 fwd 1
 put
 fwd 1
 add 1
 fwd 1
 sub 1
 jnz
 rwd 4
 put
 get
 add 41 ; ')'
 rwd 1
 put
 rwd 1
 put
 get
 add 42 ; '*'
 fwd 1
 put
 fwd 2
 put
 add 1
 fwd 1
 sub 2 ; '\'' - ')'
 put
 add 1 ; '(' - '\''
 put
 fwd 1
jnz
fwd 2
put
rwd 5
put
answered Jul 27, 2016 at 1:45
\$\endgroup\$
3
\$\begingroup\$

JavaScript (ES6), 89 bytes

f=n=>--n?f(n).replace(/x/g,`${c=(n+15).toString(36)}(x)`)+` * ${c}'(x)`:`D[f(x)] = f'(x)`

Or 75 bytes using the second form:

f=n=>n>1?f(n-1).replace(/x/g,`f${n}(x)`)+` * f${n}'(x)`:`D[f1(x)] = f1'(x)`

Or 82/64 bytes if I'm allowed an extra 1 * term:

f=n=>n?f(n-1).replace(/x/g,`${c=(n+14).toString(36)}(x)`)+` * ${c}'(x)`:`D[x] = 1`
f=n=>n?f(n-1).replace(/x/g,`f${n}(x)`)+` * f${n}'(x)`:`D[x] = 1`
Leaky Nun
50.6k6 gold badges115 silver badges291 bronze badges
answered Jul 26, 2016 at 22:59
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Why don't you put the 73-byte version as your main? \$\endgroup\$ Commented Jul 26, 2016 at 23:02
  • 1
    \$\begingroup\$ If you're being recursive, you need the f= or else your program won't work. \$\endgroup\$ Commented Jul 26, 2016 at 23:21
  • 2
    \$\begingroup\$ @KevinLau-notKenny Bah, I always forget to do that. \$\endgroup\$ Commented Jul 27, 2016 at 0:09
1
\$\begingroup\$

Ruby, 72 bytes

Second form. Port to Ruby from @Neil answer.

f=->n{n>1?f[n-1].gsub(?x,"f#{n}(x)")+" * f#{n}'(x)":"D[f1(x)] = f1'(x)"}
answered Jul 26, 2016 at 23:30
\$\endgroup\$
1
\$\begingroup\$

Julia, 66 bytes

!x=x>1?replace(!~-x,"x","f$x(x)")*" * f$x'(x)":"D[f1(x)] = f1'(x)"

Port of @Neil's ES6 answer. Uses the second form.

answered Jul 27, 2016 at 1:42
\$\endgroup\$
0
\$\begingroup\$

Python 2, 174 bytes

i=input()+1
a=lambda x:'('.join(['f%d'%e for e in range(x,i)])+'(x'+')'*(i-x)
print'D[%s] = %s'%(a(1),' * '.join(["f%d'%s%s)"%(e+1,'('*(i-e-2>0),a(e+2))for e in range(i-1)]))

Lots of room left to be golfed here. Uses the second form (f1, f2, etc.).

Leaky Nun
50.6k6 gold badges115 silver badges291 bronze badges
answered Jul 26, 2016 at 23:00
\$\endgroup\$
0
\$\begingroup\$

JavaScript (ES6), 194 bytes

n=>{s="D[";for(i=1;i<=n;i++)s+="f"+i+"(";s+="x";s+=")".repeat(n);s+="] = ";for(i=1;i<=n;i++){s+="f"+i+"'(";for(j=i+1;j<=n;j++)s+="f"+j+"(";s+="x";s+=")".repeat(n-i+1);if(i-n)s+=" * ";}return s;}

31 bytes saved thanks to @LeakyNun.

It's an anonymous lambda function. I'm sure there's some way to shorten this...

Ungolfed

var chain = function(n) {
 var str = "D["; // derivative symbol
 for (var i = 1; i <= n; i++) {
 str += "f"+i+"("; // put in n functions, each labeled f1(, f2(, etc.
 }
 str += "x"; // add in the function input, usually "x"
 for (var i = 0; i < n; i++) {
 str += ")"; // add in n end parentheses
 }
 str += "] = "; // add in the end bracket and the equals operator
 for (var i = 1; i <= n; i++) {
 str += "f"+i+"'("; // add in all n of the outer functions with the prime operator
 for (var j = i+1; j <= n; j++) {
 str += "f"+j+"("; // add in all of the inner functions
 }
 str += "x"; // add in the input, "x"
 for (var j = 1; j <= n; j++) {
 str += ")"; // close the parentheses
 }
 if (i !== n) {
 str += " * "; // the multiplication of all of the outer primed functions
 }
 }
 return str;
};
\$\endgroup\$
3
  • \$\begingroup\$ Change str into s. \$\endgroup\$ Commented Jul 26, 2016 at 23:25
  • \$\begingroup\$ Ok, I forgot to change it. Lol \$\endgroup\$ Commented Jul 26, 2016 at 23:27
  • \$\begingroup\$ Change for(j=i;j<=n;j++)s+=")"; to s+=")".repeat(n-i+1); \$\endgroup\$ Commented Jul 27, 2016 at 0:30

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.