Suppose you're working in a language with variable length arrays (e.g. with A[i] for all i in 1..A.length) and have to write a routine that takes n (n : 1..8) variable length arrays of items in a variable length array of length n, and needs to call a procedure with every possible length n array of items where the first is chosen from the first array, the second is chosen from the second array, and so forth.
If you want something concrete to visualize, imagine that your routine has to take data like:
[ [ 'top hat', 'bowler', 'derby' ], [ 'bow tie', 'cravat', 'ascot', 'bolo'] ... ['jackboots','galoshes','sneakers','slippers']]
and make the following procedure calls (in any order):
try_on ['top hat', 'bow tie', ... 'jackboots']
try_on ['top hat', 'bow tie', ... 'galoshes']
:
try_on ['derby','bolo',...'slippers']
This is sometimes called a chinese menu problem, and for fixed n can be coded quite simply (e.g. for n = 3, in pseudo code)
procedure register_combination( items : array [1..3] of vararray of An_item)
for each i1 from items[1]
for each i2 from items[2]
for each i3 from items[3]
register( [ii,i2,i3] )
But what if n can vary, giving a signature like:
procedure register_combination( items : vararray of vararray of An_item)
The code as written contained an ugly case statement, which I replaced with a much simpler solution. But I'm not sure it's the best (and it's surely not the only) way to refactor this.
How would you do it? Clever and surprising are good, but clear and maintainable are better--I'm just passing through this code and don't want to get called back. Concise, clear and clever would be ideal.
Edit: I'll post my solution later today, after others have had a chance to respond.
Teaser: I tried to sell a recursive solution, but they wouldn't go for it, so I had to stick to writing fortran in a HLL.
The answer I went with, posted below.
Either the recursive algorithm
procedure register_combination( items )
register_combination2( [], items [1:] )
procedure register_combination2( head, items)
if items == []
print head
else
for i in items[0]
register_combination2( head ++ i, items [1:] )
or the same with tail calls optimised out, using an array for the indices, and incrementing the last index until it reaches the length of the corresponding array, then carrying the increment up.
Recursion.
Or, better yet, trying to eliminate recursion using stack-like structures and while statements.
For your problem you stated (calling a function with variable arguments) it depends entirely on the programming language you're coding in; many of them allow for passing variable arguments.
Since they were opposed to recursion (don't ask) and I was opposed to messy case statements (which, as it turned out, were hiding a bug) I went with this:
procedure register_combination( items : vararray of vararray of An_item)
possible_combinations = 1
for each item_list in items
possible_combinations = possible_combinations * item_list.length
for i from 0 to possible_combinations-1
index = i
this_combination = []
for each item_list in items
item_from_this_list = index mod item_list.length
this_combination << item_list[item_from_this_list]
index = index div item_list.length
register_combination(this_combination)
Basically, I figure out how many combinations there are, assign each one a number, and then loop through the number producing the corresponding combination. Not a new trick, I suspect, but one worth knowing.
It's shorter, works for any practical combination of list lengths (if there are over 2^60 combinations, they have other problems), isn't recursive, and doesn't have the bug.
Related
I'm trying to write up some examples to explain when a while loop should be used, and when a for loop should be used.
When looking for 'interesting' cases to show young and novice programmers, I realized that the vast majority of textbook examples for while loops will look something like this:
i = 0
while i < 10:
do something
i = i + 1
'do something' might be printing the odd numbers, squaring i, etc... However all these are obviously easier written with a for loop!
I'm looking for more interesting examples. They would have to be:
Suitable for younger programmers (e.g. not too much math such as numerical root finding or the sequence in Collatz conjecture)
Easier (or more intuitive) to be solved with while loops rather than for.
Have some real use to it (e.g. I could do while random() < 0.95, but what's a real use for this?)
The only example I could come up with is when getting a list input from the user one-by-one (e.g. numbers to be summed), but the user will have to terminate it with a special input, and also this seems pointless as the user could just say in advance how many entries there will be in the sequence.
The fundamental difference between a FOR loop and a WHILE loop is that for a FOR loop, the number of iterations is bounded by a constant that is known before the loop starts, whereas for a WHILE loop, the number of iterations can be unbounded, unknown, or infinite.
As a result, a language offering only WHILE loops is Turing-complete, a language offering only FOR loops is not.
So, the first obvious thing that only a WHILE loop can do, is an infinite loop. Things that are easily modeled as infinite loops are, for example, a web server, a Netflix client, a game loop, a GUI event loop, or an operating system:
WHILE (r = nextHttpRequest):
handle(r)
END
WHILE (p = nextVideoStreamPacket):
frame = decode(p)
draw(frame)
END
WHILE (a = playerAction):
computeNextFrame(a)
END
WHILE (e = nextEvent):
handle(e)
END
WHILE (s = sysCall):
process(s)
END
A good example where the loop is not infinite, but the bound is not known in advance, is (as you already mentioned in your question) asking for user input. Something like this:
WHILE (askBoolean("Do you want to play again?")):
playGame()
END
Another good example is processing a C-like string, where the length of the string is unknown but finite. This is the same situation for a linked list, or for any data structure where there is a notion of "next", but not a notion of "size", instead there is some sentinel value that marks the end (e.g. NUL-terminated strings in C) or a way to check whether there is a next element (e.g. Iterator in Java):
WHILE ((element = getNext()) != END_MARKER):
process(element)
END
WHILE (hasNextElement):
process(getNext())
END
There are also situations that can be handled with a FOR loop, but a WHILE loop is more elegant. One situation I can think of, is that the bound for the number of iterations is known in advance, it is constant, but the known bound is ridiculously large, and the actual number of iterations required is significantly less than the bound.
Unfortunately, I cannot come up with a good real-life example of this, maybe someone else can. A FOR loop for this will then typically look like this, in order to skip the iterations from the actual number of iterations up to the upper bound:
FOR (i FROM 1 TO $SOME_LARGE_UPPER_BOUND):
IF (terminationConditionReached):
NOOP()
ELSE:
doSomethingInteresting()
END
END
Which would much better be expressed as
WHILE (NOT terminationConditionReached):
doSomethingInteresting()
END
Using the FOR loop could make sense in this situation, if the value of i is of interest:
FOR (i FROM 1 TO $SOME_LARGE_UPPER_BOUND):
IF (terminationConditionReached):
NOOP()
ELSE:
doSomethingInterestingWithI(i)
END
END
A last situation I can think of, where a WHILE loop is more appropriate than a FOR loop, even though the number of iterations is bounded by a known constant, is if that constant is not "semantically interesting" for the loop.
For example, a game loop for Tic-Tac-Toe only needs at most 9 moves, so it could be modeled as a FOR loop:
FOR (i FROM 1 TO 9):
IF (player1Won OR player2Won):
NOOP
ELSE:
makeMove()
END
END
But, the number "9" is not really interesting here. It's much more interesting whether one player has one or the board is full:
WHILE (NOT (player1Won OR player2Won OR boardFull)):
makeMove()
END
[Note: at least if playing against a child, this is also an example of the second-to-last situation, namely that the upper bound is known to be 9, but a lot of games will be shorter than 9 moves. However, I would still like to find an example for that, which is not also an example of a semantically un-interesting termination condition.]
So, we have two classes of situations here: one, where a FOR loop simply cannot be used (when the bound is unknown, non-existant, or infinite), and one, where a FOR loop can be used, but a WHILE loop is more intention-revealing.
I have to write my own List.map function using 'for elem in list' and tail/non-tail recursive. I have been looking all around Google for some tips, but didn't find much. I am used to Python and it's pretty hard to not think about using its methods, but of course, these languages are very different from each other.
For the first one I started with something like:
let myMapFun funcx list =
for elem in list do
funcx elem::[]
Tail recursive:
let rec myMapFun2 f list =
let cons head tail = head :: tail
But anyway, I know it's wrong, it feels wrong. I think I am not used yet to F# strcture. Can anyone give me a hand?
Thanks.
As a general rule, when you're working through a list in F#, you want to write a recursive function that does something to the head of the list, then calls itself on the tail of the list. Like this:
// NON-tail-recursive version
let rec myListFun list =
match list with
| [] -> valueForEmptyList // Decision point 1
| head :: tail ->
let newHead = doSomethingWith head // Decision point 2
newHead :: (myListFun tail) // Return value might be different, too
There are two decisions you need to make: What do I do if the list is empty? And what do I do with each item in the list? For example, if the thing you're wanting to do is to count the number of items in the list, then your "value for empty list" is probably 0, and the thing you'll do with each item is to add 1 to the length. I.e.,
// NON-tail-recursive version of List.length
let rec myListLength list =
match list with
| [] -> 0 // Empty lists have length 0
| head :: tail ->
let headLength = 1 // The head is one item, so its "length" is 1
headLength + (myListLength tail)
But this function has a problem, because it will add a new recursive call to the stack for each item in the list. If the list is too long, the stack will overflow. The general pattern, when you're faced with recursive calls that aren't tail-recursive (like this one), is to change your recursive function around so that it takes an extra parameter that will be an "accumulator". So instead of passing a result back from the recursive function and THEN doing a calculation, you perform the calculation on the "accumulator" value, and then pass the new accumulator value to the recursive function in a truly tail-recursive call. Here's what that looks like for the myListLength function:
let rec myListLength acc list =
match list with
| [] -> acc // Empty list means I've finished, so return the accumulated number
| head :: tail ->
let headLength = 1 // The head is one item, so its "length" is 1
myListLength (acc + headLength) tail
Now you'd call this as myListLength 0 list. And since that's a bit annoying, you can "hide" the accumulator by making it a parameter in an "inner" function, whose definition is hidden inside myListLength. Like this:
let myListLength list =
let rec innerFun acc list =
match list with
| [] -> acc // Empty list means I've finished, so return the accumulated number
| head :: tail ->
let headLength = 1 // The head is one item, so its "length" is 1
innerFun (acc + headLength) tail
innerFun 0 list
Notice how myListLength is no longer recursive, and it only takes one parameter, the list whose length you want to count.
Now go back and look at the generic, NON-tail-recursive myListFun that I presented in the first part of my answer. See how it corresponds to the myListLength function? Well, its tail-recursive version also corresponds well to the tail-recursive version of myListLength:
let myListFun list =
let rec innerFun acc list =
match list with
| [] -> acc // Decision point 1: return accumulated value, or do something more?
| head :: tail ->
let newHead = doSomethingWith head
innerFun (newHead :: acc) tail
innerFun [] list
... Except that if you write your map function this way, you'll notice that it actually comes out reversed. The solution is to change innerFun [] list in the last line to innerFun [] list |> List.rev, but the reason why it comes out reversed is something that you'll benefit from working out for yourself, so I won't tell you unless you ask for help.
And now, by the way, you have the general pattern for doing all sorts of things with lists, recursively. Writing List.map should be easy. For an extra challenge, try writing List.filter next: it will use the same pattern.
let myMapFun funcx list =
[for elem in list -> funcx elem]
myMapFun ((+)1) [1;2;3]
let rec myMapFun2 f = function // [1]
| [] -> [] // [2]
| h::t -> (f h)::myMapFun f t // [3]
myMapFun2 ((+)1) [1;2;3] // [4]
let myMapFun3 f xs = // [6]
let rec g f xs= // [7]
match xs with // [1]
| [] -> [] // [2]
| h::t -> (f h)::g f t // [3]
g f xs
myMapFun3 ((+)1) [1;2;3] // [4]
// [5] see 6 for a comment on value Vs variable.
// [8] see 8 for a comment on the top down out-of-scopeness of F#
(*
Reference:
convention: I've used a,b,c,etc refer to distinct aspects of the numbered reference
[1] roughly function is equivalent to the use of match. It's the way they do it in
OCaml. There is no "match" in OCaml. So this is a more compatible way
of writing functions. With function, and the style that is used here, we can shave
off a whole two lines from our definitions(!) Therefore, readability is increased(!)
If you end up writing many functions scrolling less to be on top
of the breadth of what is happening is more desirable than the
niceties of using match. "Match" can be
a more "rounded" form. Sometimes I've found a glitch with function.
I tend to change to match, when readability is better served.
It's a style thing.
[1b] when I discovered "function" in the F# compiler source code + it's prevalence in OCaml,
I was a little annoyed that it took so long to discover it + that it is deemed such an
underground, confusing and divisive tool by our esteemed F# brethren.
[1c] "function" is arguably more flexible. You can also slot it into pipelines really
quickly. Whereas match requires assignment or a variable name (perhaps an argument).
If you are into pipelines |> and <| (and cousins such as ||> etc), then you should
check it out.
[1d] on style, typically, (fun x->x) is the standard way, however, if you've ever
appreciated the way you can slot in functions from Seq, List, and Module, then it's
nice to skip the extra baggage. For me, function falls into this category.
[2a] "[]" is used in two ways, here. How annoying. Once it grows on you, it's cool.
Firstly [] is an empty list. Visually, it's a list without the stuff in it
(like [1;2;3], etc). Left of the "->" we're in the "pattern" part of the partern
matching expression. So, when the input to the function (lets call it "x" to stay
in tune with our earliest memories of maths or "math" classes) is an empty list,
follow the arrow and do the statement on the right.
Incidentally, sometimes it's really nice to skip the definition of x altogether.
Behold, the built in "id" identity function (essentially fun (x)->x -- ie. do nothing).
It's more useful than you realise, at first. I digress.
[2b] "[]" on the right of [] means return an empty list from this code block. Match or
function symantics being the expression "block" in this case. Block being the same
meaning as you'll have come across in other languages. The difference in F#, being
that there's *always* a return from any expression unless you return unit which is
defined as (). I digress, again.
[3a] "::" is the "cons" operator. Its history goes back a long way. F# really only
implements two such operators (the other being append #). These operators are
list specific.
[3b] on the lhs of "->" we have a pattern match on a list. So the first element
on the lhs of :: goes into the value (h)ead, and the rest of the list, the tail,
goes into the (t)ail value.
[3c] Head/tail use is very specific in F#. Another language that I like a lot, has
a nicer terminology for obviously interesting parts of a list, but, you know, it's
nice to go with an opinionated simplification, sometimes.
[3d] on the rhs of the "->", the "::", surprisingly, means join a single element
to a list. In this case, the result of the function f or funcx.
[3e] when we are talking about lists, specifically, we're talking about a linked
structure with pointers behind the scenes. All we have the power to do is to
follow the cotton thread of pointers from structure to structure. So, with a
simple "match" based device, we abstract away from the messy .Value and .Next()
operations you may have to use in other languages (or which get hidden inside
an enumerator -- it'd be nice to have these operators for Seq, too, but
a Sequence could be an infinite sequence, on purpose, so these decisions for
List make sense). It's all about increasing readability.
[3f] A list of "what". What it is is typically encoded into 't (or <T> in C#).
or also <T> in F#. Idiomatically, you tend to see 'someLowerCaseLetter in
F# a lot more. What can be nice is to pair such definitions (x:'x).
i.e. the value x which is of type 'x.
[4a] move verbosely, ((+)1) is equivilent to (fun x->x+1). We rely on partial
composition, here. Although "+" is an operator, it is firstmost, also a
function... and functions... you get the picture.
[4b] partial composition is a topic that is more useful than it sounds, too.
[5] value Vs variable. As an often stated goal, we aim to have values that
never ever change, because, when a value doesn't change, it's easier to
think and reason about. There are nice side-effects that flow from that
choice, that mean that threading and locking are a lot simpler. Now we
get into that "stateless" topic. More often than not, a value is all you
need. So, "value" it is for our cannon regarding sensible defaults.
A variable, implies, that it can be changed. Not strictly true, but in
the programming world this is the additional meaning that has been strapped
on to the notion of variable. Upon hearing the word variable, ones mind might
start jumping through the different kinds of variable "hoops". It's more stuff
that you need to hold in the context of your mind. Apparently, western people
are only able to hold about 7 things in their minds at once. Introduce mutability
and value in the same context, and there goes two slots. I'm told that more uniform
languages like Chinese allow you to hold up to 10 things in your mind at once.
I can't verify the latter. I have a language with warlike Saxon and elegant
French blended together to use (which I love for other reasons).
Anyway, when I hear "value", I feel peace. That can only mean one thing.
[6] this variation really only achieves hiding of the recursive function. Perhaps
it's nice to be a little terser inside the function, and more descriptive to
the outside world. Long names lead to bloat. Sometimes, it's just simpler.
[7a] type inference and recursion. F# is one of the nicest
languages that I've come across for elegantly dealing with recursive algorithms.
Initially, it's confusing, but once you get past that
[7b] If you are interested in solving real problems, forget about "tail"
recursion, for now. It's a cool compiler trick. When you get performance conscious,
or on a rainy day, it
might be a useful thing to look up.
Look it up by all means if you are curious, though. If you are writing recursive
stuff, just be aware that the compiler geeks have you covered (sometimes), and
that horrible "recursive" performance hole (that is often associated with
recursive techniques -- ie. perhaps avoid at all costs in ancient programming
history) may just be turned into a regular loop for you, gratis. This auto-to-loop
conversion has always been a compiler geek promise. You can rely on it more though.
It's more predictable in F# as to when "tail recursion" kicks in. I digress.
Step 1 correctly and elegantly solve useful problems.
Step 2 (or 3, etc) work out why the silicon is getting hot.
NB. depending on the context, performance may be an equally important thing
to think about. Many don't have that problem. Bear in mind that by writing
functionally, you are structuring solutions in such a way that they are
more easily streamlineable (in the cycling sense). So... it's okay not to
get caught in the weeds. Probably best for another discussion.
[8] on the way the file system is top down and the way code is top down.
From day one we are encouraged in an opinionated (some might say coerced) into
writing code that has flow + code that is readable and easier to navigate.
There are some nice side-effects from this friendly coercion.
I have this code:
let sumfunc(n: int byref) =
let mutable s = 0
while n >= 1 do
s <- n + (n-1)
n <- n-1
printfn "%i" s
sumfunc 6
I get the error:
(8,10): error FS0001: This expression was expected to have type
'byref<int>'
but here has type
'int'
So from that I can tell what the problem is but I just dont know how to solve it. I guess I need to specify the number 6 to be a byref<int> somehow. I just dont know how. My main goal here is to make n or the function argument mutable so I can change and use its value inside the function.
Good for you for being upfront about this being a school assignment, and for doing the work yourself instead of just asking a question that boils down to "Please do my homework for me". Because you were honest about it, I'm going to give you a more detailed answer than I would have otherwise.
First, that seems to be a very strange assignment. Using a while loop and just a single local variable is leading you down the path of re-using the n parameter, which is a very bad idea. As a general rule, a function should never modify values outside of itself — and that's what you're trying to do by using a byref parameter. Once you're experienced enough to know why byref is a bad idea most of the time, you're experienced enough to know why it might — MIGHT — be necessary some of the time. But let me show you why it's a bad idea, by using the code that s952163 wrote:
let sumfunc2 (n: int byref) =
let mutable s = 0
while n >= 1 do
s <- n + (n - 1)
n <- n-1
printfn "%i" s
let t = ref 6
printfn "The value of t is %d" t.contents
sumfunc t
printfn "The value of t is %d" t.contents
This outputs:
The value of t is 7
13
11
9
7
5
3
1
The value of t is 0
Were you expecting that? Were you expecting the value of t to change just because you passed it to a function? You shouldn't. You really, REALLY shouldn't. Functions should, as far as possible, be "pure" -- a "pure" function, in programming terminology, is one that doesn't modify anything outside itself -- and therefore, if you run it twice with the same input, it should produce the same output every time.
I'll give you a way to solve this soon, but I'm going to post what I've written so far right now so that you see it.
UPDATE: Now, here's a better way to solve it. First, has your teacher covered recursion yet? If he hasn't, then here's a brief summary: functions can call themselves, and that's a very useful technique for solving all sorts of problems. If you're writing a recursive function, you need to add the rec keyword immediately after let, like so:
let rec sumExampleFromStackOverflow n =
if n <= 0 then
0
else
n + sumExampleFromStackOverflow (n-1)
let t = 7
printfn "The value of t is %d" t
printfn "The sum of 1 through t is %d" (sumExampleFromStackOverflow t)
printfn "The value of t is %d" t
Note how I didn't need to make t mutable this time. In fact, I could have just called sumExampleFromStackOverflow 7 and it would have worked.
Now, this doesn't use a while loop, so it might not be what your teacher is looking for. And I see that s952163 has just updated his answer with a different solution. But you should really get used to the idea of recursion as soon as you can, because breaking the problem down into individual steps using recursion is a really powerful technique for solving a lot of problems in F#. So even though this isn't the answer you're looking for right now, it is the answer you're going to be looking for soon.
P.S. If you use any of the help you've gotten here, tell your teacher that you've done so, and give him the URL of this question (http://stackoverflow.com/questions/39698430/f-how-to-call-a-function-with-argument-byref-int) so he can read what you asked and what other people told you. If he's a good teacher, he won't lower your grade for doing that; in fact, he might raise it for being honest and upfront about how you solved the problem. But if you got help with your homework and you don't tell your teacher, 1) that's dishonest, and 2) you'll only hurt yourself in the long run, because he'll think you understand a concept that you maybe haven't understood yet.
UPDATE 2: s952163 suggests that I show you how to use the fold and scan functions, and I thought "Why not?" Keep in mind that these are advanced techniques, so you probably won't get assignments where you need to use fold for a while. But fold is basically a way to take any list and do a calculation that turns the list into a single value, in a generic way. With fold, you specify three things: the list you want to work with, the starting value for your calculation, and a function of two parameters that will do one step of the calculation. For example, if you're trying to add up all the numbers from 1 to n, your "one step" function would be let add a b = a + b. (There's an even more advanced feature of F# that I'm skipping in this explanation, because you should learn just one thing at a time. By skipping it, it keeps the add function simple and easy to understand.)
The way you would use fold looks like this:
let sumWithFold n =
let upToN = [1..n] // This is the list [1; 2; 3; ...; n]
let add a b = a + b
List.fold add 0 upToN
Note that I wrote List.fold. If upToN was an array, then I would have written Array.fold instead. The arguments to fold, whether it's List.fold or Array.fold, are, in order:
The function to do one step of your calculation
The initial value for your calculation
The list (if using List.fold) or array (if using Array.fold) that you want to do the calculation with.
Let me step you through what List.fold does. We'll pretend you've called your function with 4 as the value of n.
First step: the list is [1;2;3;4], and an internal valueSoFar variable inside List.fold is set to the initial value, which in our case is 0.
Next: the calculation function (in our case, add) is called with valueSoFar as the first parameter, and the first item of the list as the second parameter. So we call add 0 1 and get the result 1. The internal valueSoFar variable is updated to 1, and the rest of the list is [2;3;4]. Since that is not yet empty, List.fold will continue to run.
Next: the calculation function (add) is called with valueSoFar as the first parameter, and the first item of the remainder of the list as the second parameter. So we call add 1 2 and get the result 3. The internal valueSoFar variable is updated to 3, and the rest of the list is [3;4]. Since that is not yet empty, List.fold will continue to run.
Next: the calculation function (add) is called with valueSoFar as the first parameter, and the first item of the remainder of the list as the second parameter. So we call add 3 3 and get the result 6. The internal valueSoFar variable is updated to 6, and the rest of the list is [4] (that's a list with one item, the number 4). Since that is not yet empty, List.fold will continue to run.
Next: the calculation function (add) is called with valueSoFar as the first parameter, and the first item of the remainder of the list as the second parameter. So we call add 6 4 and get the result 10. The internal valueSoFar variable is updated to 10, and the rest of the list is [] (that's an empty list). Since the remainder of the list is now empty, List.fold will stop, and return the current value of valueSoFar as its final result.
So calling List.fold add 0 [1;2;3;4] will essentially return 0+1+2+3+4, or 10.
Now we'll talk about scan. The scan function is just like the fold function, except that instead of returning just the final value, it returns a list of the values produced at all the steps (including the initial value). (Or if you called Array.scan, it returns an array of the values produced at all the steps). In other words, if you call List.scan add 0 [1;2;3;4], it goes through the same steps as List.fold add 0 [1;2;3;4], but it builds up a result list as it does each step of the calculation, and returns [0;1;3;6;10]. (The initial value is the first item of the list, then each step of the calculation).
As I said, these are advanced functions, that your teacher won't be covering just yet. But I figured I'd whet your appetite for what F# can do. By using List.fold, you don't have to write a while loop, or a for loop, or even use recursion: all that is done for you! All you have to do is write a function that does one step of a calculation, and F# will do all the rest.
This is such a bad idea:
let mutable n = 7
let sumfunc2 (n: int byref) =
let mutable s = 0
while n >= 1 do
s <- n + (n - 1)
n <- n-1
printfn "%i" s
sumfunc2 (&n)
Totally agree with munn's comments, here's another way to implode:
let sumfunc3 (n: int) =
let mutable s = n
while s >= 1 do
let n = s + (s - 1)
s <- (s-1)
printfn "%i" n
sumfunc3 7
I have bumped into this problem several times on the type of input data declarations mathematica understands for functions.
It Seems Mathematica understands the following types declarations:
_Integer,
_List,
_?MatrixQ,
_?VectorQ
However: _Real,_Complex declarations for instance cause the function sometimes not to compute. Any idea why?
What's the general rule here?
When you do something like f[x_]:=Sin[x], what you are doing is defining a pattern replacement rule. If you instead say f[x_smth]:=5 (if you try both, do Clear[f] before the second example), you are really saying "wherever you see f[x], check if the head of x is smth and, if it is, replace by 5". Try, for instance,
Clear[f]
f[x_smth]:=5
f[5]
f[smth[5]]
So, to answer your question, the rule is that in f[x_hd]:=1;, hd can be anything and is matched to the head of x.
One can also have more complicated definitions, such as f[x_] := Sin[x] /; x > 12, which will match if x>12 (of course this can be made arbitrarily complicated).
Edit: I forgot about the Real part. You can certainly define Clear[f];f[x_Real]=Sin[x] and it works for eg f[12.]. But you have to keep in mind that, while Head[12.] is Real, Head[12] is Integer, so that your definition won't match.
Just a quick note since no one else has mentioned it. You can pattern match for multiple Heads - and this is quicker than using the conditional matching of ? or /;.
f[x:(_Integer|_Real)] := True (* function definition goes here *)
For simple functions acting on Real or Integer arguments, it runs in about 75% of the time as the similar definition
g[x_] /; Element[x, Reals] := True (* function definition goes here *)
(which as WReach pointed out, runs in 75% of the time
as g[x_?(Element[#, Reals]&)] := True).
The advantage of the latter form is that it works with Symbolic constants such as Pi - although if you want a purely numeric function, this can be fixed in the former form with the use of N.
The most likely problem is the input your using to test the the functions. For instance,
f[x_Complex]:= Conjugate[x]
f[x + I y]
f[3 + I 4]
returns
f[x + I y]
3 - I 4
The reason the second one works while the first one doesn't is revealed when looking at their FullForms
x + I y // FullForm == Plus[x, Times[ Complex[0,1], y]]
3 + I 4 // FullForm == Complex[3,4]
Internally, Mathematica transforms 3 + I 4 into a Complex object because each of the terms is numeric, but x + I y does not get the same treatment as x and y are Symbols. Similarly, if we define
g[x_Real] := -x
and using them
g[ 5 ] == g[ 5 ]
g[ 5. ] == -5.
The key here is that 5 is an Integer which is not recognized as a subset of Real, but by adding the decimal point it becomes Real.
As acl pointed out, the pattern _Something means match to anything with Head === Something, and both the _Real and _Complex cases are very restrictive in what is given those Heads.
Here is a function I would like to write but am unable to do so. Even if you
don't / can't give a solution I would be grateful for tips. For example,
I know that there is a correlation between the ordered represantions of the
sum of an integer and ordered set partitions but that alone does not help me in
finding the solution. So here is the description of the function I need:
The Task
Create an efficient* function
List<int[]> createOrderedPartitions(int n_1, int n_2,..., int n_k)
that returns a list of arrays of all set partions of the set
{0,...,n_1+n_2+...+n_k-1} in number of arguments blocks of size (in this
order) n_1,n_2,...,n_k (e.g. n_1=2, n_2=1, n_3=1 -> ({0,1},{3},{2}),...).
Here is a usage example:
int[] partition = createOrderedPartitions(2,1,1).get(0);
partition[0]; // -> 0
partition[1]; // -> 1
partition[2]; // -> 3
partition[3]; // -> 2
Note that the number of elements in the list is
(n_1+n_2+...+n_n choose n_1) * (n_2+n_3+...+n_n choose n_2) * ... *
(n_k choose n_k). Also, createOrderedPartitions(1,1,1) would create the
permutations of {0,1,2} and thus there would be 3! = 6 elements in the
list.
* by efficient I mean that you should not initially create a bigger list
like all partitions and then filter out results. You should do it directly.
Extra Requirements
If an argument is 0 treat it as if it was not there, e.g.
createOrderedPartitions(2,0,1,1) should yield the same result as
createOrderedPartitions(2,1,1). But at least one argument must not be 0.
Of course all arguments must be >= 0.
Remarks
The provided pseudo code is quasi Java but the language of the solution
doesn't matter. In fact, as long as the solution is fairly general and can
be reproduced in other languages it is ideal.
Actually, even better would be a return type of List<Tuple<Set>> (e.g. when
creating such a function in Python). However, then the arguments wich have
a value of 0 must not be ignored. createOrderedPartitions(2,0,2) would then
create
[({0,1},{},{2,3}),({0,2},{},{1,3}),({0,3},{},{1,2}),({1,2},{},{0,3}),...]
Background
I need this function to make my mastermind-variation bot more efficient and
most of all the code more "beautiful". Take a look at the filterCandidates
function in my source code. There are unnecessary
/ duplicate queries because I'm simply using permutations instead of
specifically ordered partitions. Also, I'm just interested in how to write
this function.
My ideas for (ugly) "solutions"
Create the powerset of {0,...,n_1+...+n_k}, filter out the subsets of size
n_1, n_2 etc. and create the cartesian product of the n subsets. However
this won't actually work because there would be duplicates, e.g.
({1,2},{1})...
First choose n_1 of x = {0,...,n_1+n_2+...+n_n-1} and put them in the
first set. Then choose n_2 of x without the n_1 chosen elements
beforehand and so on. You then get for example ({0,2},{},{1,3},{4}). Of
course, every possible combination must be created so ({0,4},{},{1,3},{2}),
too, and so on. Seems rather hard to implement but might be possible.
Research
I guess this
goes in the direction I want however I don't see how I can utilize it for my
specific scenario.
http://rosettacode.org/wiki/Combinations
You know, it often helps to phrase your thoughts in order to come up with a solution. It seems that then the subconscious just starts working on the task and notifies you when it found the solution. So here is the solution to my problem in Python:
from itertools import combinations
def partitions(*args):
def helper(s, *args):
if not args: return [[]]
res = []
for c in combinations(s, args[0]):
s0 = [x for x in s if x not in c]
for r in helper(s0, *args[1:]):
res.append([c] + r)
return res
s = range(sum(args))
return helper(s, *args)
print partitions(2, 0, 2)
The output is:
[[(0, 1), (), (2, 3)], [(0, 2), (), (1, 3)], [(0, 3), (), (1, 2)], [(1, 2), (), (0, 3)], [(1, 3), (), (0, 2)], [(2, 3), (), (0, 1)]]
It is adequate for translating the algorithm to Lua/Java. It is basically the second idea I had.
The Algorithm
As I already mentionend in the question the basic idea is as follows:
First choose n_1 elements of the set s := {0,...,n_1+n_2+...+n_n-1} and put them in the
first set of the first tuple in the resulting list (e.g. [({0,1,2},... if the chosen elements are 0,1,2). Then choose n_2 elements of the set s_0 := s without the n_1 chosen elements beforehand and so on. One such a tuple might be ({0,2},{},{1,3},{4}). Of
course, every possible combination is created so ({0,4},{},{1,3},{2}) is another such tuple and so on.
The Realization
At first the set to work with is created (s = range(sum(args))). Then this set and the arguments are passed to the recursive helper function helper.
helper does one of the following things: If all the arguments are processed return "some kind of empty value" to stop the recursion. Otherwise iterate through all the combinations of the passed set s of the length args[0] (the first argument after s in helper). In each iteration create the set s0 := s without the elements in c (the elements in c are the chosen elements from s), which is then used for the recursive call of helper.
So what happens with the arguments in helper is that they are processed one by one. helper may first start with helper([0,1,2,3], 2, 1, 1) and in the next invocation it is for example helper([2,3], 1, 1) and then helper([3], 1) and lastly helper([]). Of course another "tree-path" would be helper([0,1,2,3], 2, 1, 1), helper([1,2], 1, 1), helper([2], 1), helper([]). All these "tree-paths" are created and thus the required solution is generated.