## Write a function that reduces compositions of linear operators

6

You are given two functions g(x) and h(x), each of which takes an integer x and returns the number ax + b (where a and b are integers defined in the function).

Your task is to write a function f(g, h) that takes these two functions, and returns a function k(x) = g(h(x)), but where the procedure of k(x) is also simply of the form ax + b.

For example, given g(x) = 2x + 3 and h(x) = 3x + 4, you would need to return k(x) = 6x + 11, and not k(x) = 2(3x + 4) + 3.

Yes. There is a way to extract those two constants without accessing the AST. – Joe Z. – 2013-04-04T18:04:03.837

May I suggest clarifying that the return value is of function type as well, as I'm guessing is your intent? Two of the current answers return strings. – Kevin Reid – 2013-04-04T21:31:09.017

@KevinReid Done. – Joe Z. – 2013-04-04T23:03:54.877

I'm thinking of rewarding a bounty for an answer in binary lambda calculus... – Joe Z. – 2013-11-19T22:08:26.840

1I don't understand how you want the output. If it's as a function, you could just black-box compose the inputs. Do you want the pair (a,b) for which k(x)=ax+b? A function that must be written in the form k(x)=ax+b? If the second, do a and b have to be given explicit assignments in that function? – xnor – 2014-05-22T18:07:16.983

3

### GolfScript, 414023 19 characters

{2,0+%/-{@*+}++}:k;


Thanks to Peter Taylor for pointing out this solution. Accepts two function bodies as arguments.

The following examples show how to use function k:

# As function
{2*3+} {3*4+} k         # => {11 6 @*+}

# Apply to value
5 {2*3+} {3*4+} k ~     # => 41


If one wants to retain the original output format, the following 22 character solution is possible:

{2,0+%/-{*}+\+{+}+}:k;

{2*3+} {3*4+} k         # => {6 * 11 +}


Explanation of the code:

{                       # on stack are functions g h
2,                    # build array [0 1] -> g h [0 1]
0+                    # append 0 -> g h [0 1 0]
%                     # apply function h to each element -> g [h(0) h(1) h(0)]
/                     # apply function g to each element
# and break up the array -> g(h(0)) g(h(1)) g(h(0))
-                     # subtract last two -> g(h(0)) g(h(1))-g(h(0))
{@*+}++               # append function body to these values
}:k;                    # save function to variable k


Save 4: {2,%/1$-{@*+}++}:k; or {2,0+%/-{@*+}++}:k; – Peter Taylor – 2013-04-04T23:07:53.073 Your explanation makes me never want to learn Golfscript. It would make my head explode trying to figure it out. – jdstankosky – 2013-04-05T12:57:16.073 @jdstankosky Do you mean the explanation is not clear (in which case I'd be happy to amend if you could point out what is unclear) or that GolfScript is - well - special (in which case you'll miss a lot of fun). – Howard – 2013-04-05T14:22:31.700 @Howard It's definitely interesting, incredibly confusing, and far more advanced than anything I think I'll ever be able to figure out. – jdstankosky – 2013-04-05T14:26:25.917 2 # Mathematica 15 Define g, h as pure functions g and h are defined as pure functions (awaiting a value or independent variable to be assigned) g = 2 # + 3 &; h = 3 # + 4 &; g[x] h[x]  3 + 2 x 4 + 3 x Method #1: Compose g of h directly (15 chars) g@h@x//Simplify  11 + 6 x Or, alternatively: (17 chars) g[h[x]]//Simplify  Method #2: Define f (25 chars= 13 + 10 chars for Simplify) f=Composition  f[g, h][x] f[g, h][x] // Simplify Composition[g, h][x]//Simplify f[g, h][1] Table[f[g, h][x], {x, 1, 13}]  3 + 2 (4 + 3 x) 11 + 6 x 11 + 6 x 17 {17, 23, 29, 35, 41, 47, 53, 59, 65, 71, 77, 83, 89} Your f(g, h, x) should be f(g, h)(x). – Joe Z. – 2013-04-04T19:14:09.293 Ok. I'll adjust accordingly – DavidC – 2013-04-04T19:14:40.827 2 ### Haskell, 31 (f%g)x=f(g 0)+x*(f(g 1)-f(g 0))  Version in which the function body contains only variables (equivalent at run time, but closer to the question's form), 38 characters: (f%g)x=a*x+b where h=f.g;b=h 0;a=h 1-b  Note that in both cases, since Haskell uses curried functions, there is no explicit construction of the composed function as it is implicit in % being defined with three arguments: function f, function g, value x. Example use: > ((\x -> 2*x + 3)%(\x -> 3*x + 4)) 0 11 > ((\x -> 2*x + 3)%(\x -> 3*x + 4)) 4 35  Ungolfed second form: (f % g) x = a * x + b -- equivalent: (f % g) = \x -> a * x + b where h = f . g -- use built in function composition to bootstrap b = h 0 -- constant term of composed function a = h 1 - h 0 -- linear term of composed function  1This can be shortened to f%g=f(g 0)!(f(g 1-g 0)-f 0);(z!y)x=y*x+z (40 chars) by replacing the where clause with a function call (which also gets rid of the lambda) and defining infix operators instead of plain functions. Also, I'm not sure if it's necessary to share the values of y and z, so you may be able to improve it further by inlining them as well. – hammar – 2013-04-04T23:51:57.273 @hammar I have my doubts that putting the expressions inline is in the spirit of the question (“the procedure of k(x) is also simply of the form ax + b”) but OK, I'll take the edit, unless Joe Zeng disagrees. – Kevin Reid – 2013-04-05T18:02:12.853 Either way, f(g 1)-f(g 0) is one char shorter than f(g 1-g 0)-f 0. – Peter Taylor – 2013-04-05T20:36:20.630 @PeterTaylor Good point! In fact, that made me realize I was missing a trick in the original version: I now define h = f . g and derive all results from h, saving another two characters — I was previously stuck on the notion of extracting the coefficients of each function individually. – Kevin Reid – 2013-04-05T22:22:04.887 1 ## vba, 89 Function f(g,h,x) f=Evaluate(Replace(g,"x","*("&Replace(h,"x","*"&x)&")")) End Function  usage/result ?f("2x+3","3x+4",1) 17 The functions aren't supposed to be strings. Can you evaluate the string directly with a number and get the result of the function out? – Joe Z. – 2013-04-04T19:14:42.937 @JoeZeng, I think that is more what you were after – SeanC – 2013-04-04T19:55:53.987 1 ## Lua, 87 function f(g, h)local a,b=g(h(1))-g(h(0)),g(h(0))return function(x)return a*x+b end end  1 # Ruby >=1.9, 55 f=->g,h{a=(g[1]-g[0])*(h[1]-h[0]);b=g[h[0]];->x{a*x+b}}  Less golfed: def c(f,g) f_a=f[1]-f[0] g_a=g[1]-g[0] a=f_a*g_a b=f[g[0]] ->x{a*x+b} end  You can shorten even further by inlining a: f=->g,h{->x{(g[h[1]]-b=g[h[0]])*x+b}} – Howard – 2013-04-05T08:07:36.457 I wasn't sure that'd be permitted. – histocrat – 2013-04-05T15:00:54.180 1 ## SML (60 chars) fun f g h=let val c=g(h 0)val m=g(h 1)-c in fn x=>m*x+c end;  Ungolfed: fun f g h = let val c = g (h 0) val m = g (h 1) - c in fn x => m*x + c end;  0 # PHP 72 Apparently I completely missed the point of this code-golf. I'm STILL not sure if I understand it correctly. Is no output required? Can I assume the methods of g and h? Here's a new version based off the old one: <?=$f=function($g,$h,$x){return$k=($g[0]*$h[0]*$x)+($g[0]*$h[1])+$g[1];}


If this is still wrong, I give up.

# PHP 176

The requirements are kind of confusing, but here's what I think you meant:

<?=f($argv);function f($a){$x=$a[3];$g=explode("x",$a[1]);$h=explode("x",$a[2]);return$k=($g[0]*$h[0])."*$x+".(($g[0]*$h[1])+$g[1])."=".(($g[0]*$h[0]*$x)+($g[0]*$h[1])+$g[1]);}  Usage: php f.php 2x+3 3x+4 5 Output: 6*5+11=41 Another Example Usage: php f.php 4x-7 3x+4 2 Output: 12*2+9=33 # Method As you described, we can't simply output the answer with g(h(x)), we had to create function f(g,h) which determines what both the functions would be together, and return that as a new function: k(x). Is this what OP meant? Ungolfed <?php function f($a) {
$x=$a[3];
$g=explode("x",$a[1]);
$h=explode("x",$a[2]);
$k =$g[0]*$h[0];$k .= "*";
$k .=$x;
$k .= "+";$k .= ($g[0]*$h[1])+$g[1];$k .= " = ";
$k .= ($g[0]*$h[0]*$x) + ($g[0]*$h[1])+$g[1]; return$k;
}

echo f(\$argv);


In PHP terminology, the requirements are asking for a function which takes two callbacks as arguments and returns a callback. As an implementation note, I would expect to see a couple of calls to call_user_func and probably a call to create_function. – Peter Taylor – 2013-04-05T08:50:01.173

0

Erlang 54:

1> F = fun(G,H)->B=G(H(0)),A=G(H(1))-B,fun(X)->A*X+B end end.
2> (F(fun(X) -> 2*X+3 end, fun(X) -> 3*X + 4 end))(0).
11
3> (F(fun(X) -> 2*X+3 end, fun(X) -> 3*X + 4 end))(1) - v(2).
6


0

Common Lisp (108)

(defun f(g h)(let*((d(g 0))(c(-(g 1)d))(z(h 0))(e(-(h 1)z))(a(* c e))(b(+(* c z)d)))(lambda(x)(+(* a x)b))))


It could be shorter if I assumed expressions would have constants folded...but I didn't make that assumption to make sure I met the spec. Also, I have implemented Clojure's literal anonymous function syntax as a read macro. I decided against using that as well.

0

## Postscript, 120

/f{1 index 0 get dup
2 index 0 get mul exch
3 2 roll 2 get mul


Ungolfed and commented with testing.

/g{2 mul 3 add}def

/f{
1 index 0 get % g h g[0]
dup 2 index 0 get mul % g h g[0] g[0]*h[0]
exch 3 2 roll 2 get mul % g g[0]*h[0] g[0]*h[2]
3 2 roll 2 get add % g[0]*h[0] g[0]*h[2]+g[2]
[ 3 1 roll /mul cvx exch /add cvx ] cvx
}def

//g //h f ==


Output:

GPL Ghostscript 9.10 (2013-08-30)