21
6
Your company is just getting started on a project, and for the first time you decided to go use a functional programming code-style. However your boss is really diffident and doesn't want to use built-in functions, and requires you to implement yourself the main functions. In particular you need to write the functions: Map
, Nest
, Apply
, Range
, Fold
and Table
in a language on your choice. The boss is a really busy man, and he wants to have the programs as short as possible, so he doesn't waste time reading. He also would like not for you to use loops, therefore you will have a 10% reduction on the byte count for not using loops.
The detailed requirements of the functions are below:
Map
The Map
function takes two parameters: f
and list
where f
is a function and list
is a list of values. It should return the f
applied to each element of list
. Therefore it will work as such:
Map(f,{a,b,c})
returns
{ f(a), f(b), f(c) }
and
Map(f, {{a,b},{b,c}})
returns
{ f({a,b}), f({b,c})}
Nest
The Nest
function takes three parameters as well: f
, arg
, times
where f
is a function, arg
is its starting argument, and times
is how many times the function is applied. It should return an expression with f
applied times
times to arg
. Therefore it will work as such:
Nest(f, x, 3)
returns
f(f(f(x)))
and
Nest(f, {a,b}, 3)
returns
f(f(f({a,b})))
Apply
The Apply
function takes two parameters: f
and args
where f
is a function and args
a list. It should apply f
to the args
. Therefore:
Apply(f, {a,b,c})
returns
f(a,b,c)
Range
The Range
function takes one integerr
and outputs the integers up to that number. Therefore:
Range(5)
returns
{ 1, 2, 3, 4, 5}
Fold
The Fold
function takes three parameters f
, arg
, others
where f
is a function, arg
is simple parameter, and others
a list. It will work as such:
Fold(f, x, {a, b, c, d})
returns
f(f(f(f(x,a),b),c),d)
Table
The table functions should take a function f
, and a parameter called iterator
in the form: {iMin, iMax}
where iMin
and iMax
are integers. You should apply f
over the range specified. Therefore:
Table(f, {0, 5})
returns
{f(0), f(1), f(2), f(3), f(4), f(5)}
I've used the definition of these functions from the Mathematica functional programming page, so head there if you need any more guidance. Note that you will not need to implement all the version of the functions shown in that page, but only those written in this post.
Standard Loopholes are disallowed as usual.
In case your language does not allow functions to be passed as arguments, you need to implement this capability, and add it into your answer. However the byte-count of this operation will not be added to the total.
This is code golf so the shortest code wins. Good luck!!!
This is awesome! +1 However, I don't really get how
Table
works here. Is your example supposed to beTable(f, {x, 0, 5})
? I also don't get the purpose ofx
at all, since it just applies the function to the range. – kirbyfan64sos – 2015-09-24T14:05:42.837@kirbyfan64sos Thank you! Yes that was a typo, I left x in as a reference to mathematica, which uses it as symbolic feauture, however I think I can get it out – WizardOfMenlo – 2015-09-24T14:08:11.717
One more question: how do we name the functions? Do we have to give them the exact same names? Single-letter? – kirbyfan64sos – 2015-09-24T14:15:02.797
@kirbyfan64sos Since it is code-golf, I'll allow single letter names, however in your answer put a heading over each function so that we know which one it is. Also do not use colliding letters. – WizardOfMenlo – 2015-09-24T14:18:02.657
Could you be more specific about what counts as a loop? – xnor – 2015-09-24T17:59:03.817
@xnor no you can't, what I'm really interested in is the implementation of the features. As what counts for loop I think for and while loops, and the use of gotos to emulate them – WizardOfMenlo – 2015-09-24T18:01:31.653
By the way, that's the wrong fold for languages that offer infinite lists. Those languages really want
f(a, f(b, f(c, f(d, x))))
. – dfeuer – 2015-09-24T18:10:16.260Is the 10% bonus per function, i.e. a total of 60% for the whole code if no function uses loops? – nimi – 2015-09-24T19:22:14.470
@nimi originally I was going for that approach, but I think the 10% if no loops are used in all code is more adapt – WizardOfMenlo – 2015-09-24T19:29:38.760
You use
Map(f, {{a,b},{b,c}})
resulting in{ f(a, b), f(b, c) }
- is thatf
taking a single argument, the list{a, b}
? Or is itf
taking in two distinct argumentsa
andb
? – Dannnno – 2015-09-24T21:00:45.167@Dannnno it is
f
taking a single argument, a list, I wrote it wrongly, well spotted – WizardOfMenlo – 2015-09-24T21:03:09.763I assume the same for the other ones? – Dannnno – 2015-09-24T21:03:37.313
@Dannnno where exactly? As a reference I used this page, https://reference.wolfram.com/language/guide/FunctionalProgramming.html, so it should reflect those
– WizardOfMenlo – 2015-09-24T21:04:40.807Range
is for positive integers only? What happens with0
or with a negative number? – Dannnno – 2015-09-24T21:05:00.637For example,
Nest
. I would expectNest(f, {a,b}, 3)
to give mef(f(f({a, b})))
but you havef(f(f(a, b)))
– Dannnno – 2015-09-24T21:05:36.180@Dannnno Range is for positive integers indeed, Nest follows the same rule as well, so you're right – WizardOfMenlo – 2015-09-24T21:07:34.540
May I use one of the functions to implement another? – edc65 – 2015-09-24T22:11:00.247
@edc65 yes of course, just define it before its usage :) – WizardOfMenlo – 2015-09-24T22:11:29.927
My language has built-in functionality for all these, so may I just assign your names to cover-functions? – Adám – 2015-09-25T15:44:43.630
@NBZ the challenge states that built-ins are not allowed – WizardOfMenlo – 2015-09-25T15:47:15.957
What means "returns an expression"? Does this mean we should return something which needs to be evaluated later, or can we evaluate it immediately and return the result of that evaluation? – Paŭlo Ebermann – 2015-11-22T16:50:34.100
@PaŭloEbermann, it can be evaluated immediately, see other answers as guidlines, I think that the Haskell one is quite indicative. – WizardOfMenlo – 2015-11-22T16:58:16.873
@dfeuer I think you got it wrong – your version would need to iterate the whole list before starting to evaluate
f
, while the version in the question evaluatesf
during each step. – Paŭlo Ebermann – 2015-11-22T17:27:54.787If some of the functions use loops and the others not, do these others still get the 10% reduction? – Paŭlo Ebermann – 2015-11-22T19:01:07.713
@PaŭloEbermann no, to be elegible for the bonus there needs to be no looping in general – WizardOfMenlo – 2015-11-22T19:05:42.600
@Paŭlo Ebermann, I was referring to lazy lists. A lazy function passed to a right fold can be productive on an infinite list. It's possible to implement left folds in terms of right ones but not (in the infinite case) the other way around. – dfeuer – 2015-11-23T03:14:12.383
@dfeuer so you would have not just a lazy list, but also a lazy fold (i.e.
f(a, f(b, ...))
would only calculate the second parameter of the first when (an if) actually needed byf
's implementation? I guess that works. I was thinking about a non-lazy fold (maybe with side effects), i.e. an endless loop for an infinite list, which wouldn't work with right-folding. – Paŭlo Ebermann – 2015-11-23T13:21:18.543@PaŭloEbermann, take a look at how it's done in Haskell. In the latest library version, the left fold is actually defined in terms of the right:
foldl f b0 xs = foldr (\x r b -> r (f b x)) id xs b0
– dfeuer – 2015-11-23T15:07:30.090