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:
- all the spaces kept intact
- a capitalized
D - a square bracket immediately following
D - the asterisk kept intact
- One extra trailing space (U+0020) is allowed.
- Leading zeros in the function names in the second form (e.g.
f01instead off1) 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>
-
\$\begingroup\$ Do function names have to be lowercase? \$\endgroup\$betseg– betseg2016年07月26日 23:21:54 +00:00Commented Jul 26, 2016 at 23:21
-
\$\begingroup\$ @betseg Yes of course. \$\endgroup\$Leaky Nun– Leaky Nun2016年07月26日 23:22:26 +00:00Commented Jul 26, 2016 at 23:22
7 Answers 7
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.
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..
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
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`
-
1\$\begingroup\$ Why don't you put the 73-byte version as your main? \$\endgroup\$Leaky Nun– Leaky Nun2016年07月26日 23:02:03 +00:00Commented 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\$Value Ink– Value Ink2016年07月26日 23:21:23 +00:00Commented Jul 26, 2016 at 23:21 -
2\$\begingroup\$ @KevinLau-notKenny Bah, I always forget to do that. \$\endgroup\$Neil– Neil2016年07月27日 00:09:35 +00:00Commented Jul 27, 2016 at 0:09
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)"}
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.
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.).
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;
};
-
\$\begingroup\$ Change
strintos. \$\endgroup\$Leaky Nun– Leaky Nun2016年07月26日 23:25:39 +00:00Commented Jul 26, 2016 at 23:25 -
\$\begingroup\$ Ok, I forgot to change it. Lol \$\endgroup\$Drew Christensen– Drew Christensen2016年07月26日 23:27:24 +00:00Commented Jul 26, 2016 at 23:27
-
\$\begingroup\$ Change
for(j=i;j<=n;j++)s+=")";tos+=")".repeat(n-i+1);\$\endgroup\$Leaky Nun– Leaky Nun2016年07月27日 00:30:01 +00:00Commented Jul 27, 2016 at 0:30
Explore related questions
See similar questions with these tags.