I'm struggling a bit to find it on https://github.com/fsharp/fsharp
and this is very important because I need to ensure the least amount of collisions possible.
As VoroniPotato mentions, you might want to override GetHashCode yourself, but the default implemention of GetHashCode works like the following for a record. Assuming fields is a list of the value of the fields in the record, then the following steps are done:
Start with an initial value of 0.
Then for each element in field, starting from the last one defined (i.e. given the record type {a: int; b: string} we start with b), do the following:
0x9e3779b9 + fields.[i].GetHashCode() + (value <<< 6) + (value >>> 2), where value is the value from the previous iteration of the algorithm. We assume fields.[i] isn't null, otherwise its hash value is just set to 0.
Repeat step 2 for all fields.
You can see this in the source code from the code for mkRecdHashWithComparer and mkAddToHashAcc.
For the simple example record of {a: int; b: string}, the decompiled GetHashCode method is this:
[CompilerGenerated]
public sealed override int GetHashCode(IEqualityComparer comp)
{
if (this != null)
{
int num = 0;
num = -1640531527 + ((b#?.GetHashCode() ?? 0) + ((num << 6) + (num >> 2)));
return -1640531527 + (a# + ((num << 6) + (num >> 2)));
}
return 0;
}
Well I can tell you it's not going to provide the least amount of collisions possible. You may want to override GetHashCode. Some have complained that it didn't fit their hashing needs but that for backwards compatiblity it couldn't reasonably be changed. I would add an issue on the github visual fsharp repository if this a serious issue for you due to performance considerations of checking conflicted hashes.
Update, Sources:
github.com/fsharp/fslang-suggestions/issues/366
github.com/fsharp/fsharp/issues/343
github.com/Microsoft/visualfsharp/issues/1838
Our professor said that in computer logic it's important when you add a number to another so a+b and b+a are not always equal.
Though,I couldn't find an example of when they would be different and why they won't be equal.
I think it would have to do something with bits but then again ,I'm not sure.
Although you don't share a lot of context it sounds as if your professor did not elaborate on that or you missed something.
In the case that he was talking about logic in general, he could have meant that the behavior of the + operator depends on how you define it.
Example: The definition (+) a b := if (a==0) then 5 else 0 results in a + operator which is not associative, e.g. 1 + 0 would be 0 but 0 + 1 would be 5. There are many programming languages that allow this redefinition (overwriting) of standard operators.
But with the context you share, this is all speculative.
One obscure possibility is if one or other of a or b is a high-definition timer value - ticks since program start.
Due to the cpu cycle(s) consumed to pop one of the values before addition, it's possible the sum could be different dependant on the order.
One more possibility is if a and b are expressions with side effects. E.g.
int x = 0;
int a() {
x += 1;
return x;
}
int b() {
return x;
}
a() + b() will return 2 and b() + a() will return 1 (both from initial state).
Or it could be that a or b are NaN, in which case even a == a is false. Though this one isn't connected with "when you add a number to another".
Integer types in SystemVerilog, as in most languages, wrap around on overflow. I was wondering if this is also true in constraints. For example:
class Test;
rand bit [3:0] a;
rand bit [3:0] b;
constraint c { a + b <= 4'h6; }
endclass;
When randomizing an object of this class, is it possible to get a solution where a == 7 and b == 12, which would satisfy the constraint since 7 + 12 = 19 which wraps around to 3, and 3 is less than 6?
If so, would it help to formulate the constraint as
constraint c { a + b <= 6; }
where 6 is a 32-bit signed int and the sum is forced to be calculated with 32-bit precision? (This of course is not a solution if the random variables are of type int)
You are correct. Expression evaluation is identical whether you are inside a constraint or not. In addition to overflow, you also need to be concerned about truncation and sign conversion. Integral expressions are weakly typed in SystemVerilog.
This is a simple function that checks to see if the string is unique. I reason that the complexity should be N * N -> N^2. Is this correct? Even if the second N will always be smaller than the first.
func isUnique(_ str: String) -> Bool {
let charArr = Array(str.characters)
for (i1 , char) in charArr.enumerated() {
guard i1 != charArr.count - 1 else {
break
}
for (i2, char) in charArr[(i1 + 1)..<charArr.count].enumerated() {
if charArr[i1] == char {
return false
}
}
}
return true
}
Yes, There are a lot of myths behind this problem and when you analysis on Big O topic, you getting so many varying answers. And the most popular question is:
"If two nested for loops contains break statement. so still my complexity
is n*n or O(n2)?"
I think the simple answer is"
Big-O notation isn't about finding exact values given your actual parameters. It is about determining asymptotic runtime.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have the following Scala snippet. In order to solve my given problem, I "cheat" a little and use a var -- essentially a non-final, mutable data type. Its value is updated at each iteration through the loop. I've spent quite a bit of time trying to figure out how to do this using only recursion, and immutable data types and lists.
Original snippet:
def countChange_sort(money: Int, coins: List[Int]): Int =
if (coins.isEmpty || money < 0)
0
else if (coins.tail.isEmpty && money % coins.head != 0) {
0
} else if (coins.tail.isEmpty && money % coins.head == 0 || money == 0) {
1
} else {
-- redacted --
}
}
Essentially, are there any basic techniques I can use to eliminate the i and especially the accumulating cnt variables?
Thanks!!
There are lots of different ways to solve problems in functional style. Often you start by analysing the problem in a different way than you would when designing an imperative algorithm, so writing an imperative algorithm and then "converting" it to a functional one doesn't produce very natural functional algorithms (and you often miss out on lots of the potential benefits of functional style). But when you're an experienced imperative programmer just starting out with functional programming, that's all you've got, and it is a good way to begin getting your head around the new concepts. So here's how you can approach "converting" such a function as the one you wrote to functional style in a fairly uncreative way (i.e. not coming up with a different algorithm).
Lets just consider the else expression since the rest is fine.
Functional style has no loops, so if you need run a block of code a number of times (the body of the imperative loop), that block of code must be a function. Often the function is a simple non-recursive one, and you call a higher-order function such as map or fold to do the actual recursion, but I'm going to presume you need the practice thinking recursively and want to see it explicitly. The loop condition is calculated from the quantities you have at hand in the loop body, so we just have the loop-replacement function recursively invoke itself depending on exactly the same condition:
} else {
var cnt = 0
var i = 0
def loop(????) : ??? = {
if (money - (i * coins.head) > 0) {
cnt += countChange_sort(money - (i * coins.head), coins.tail)
i = i + 1
loop(????)
}
}
loop(????)
cnt
}
Information is only communicated to a function through its input arguments or through its definition, and communicated from a function through its return value.
The information that enters a function through its definition is constant when the function is created (either at compile time, or at runtime when the closure is created). Doesn't sound very useful for the information contained in cnt and i, which needs to be different on each call. So they obviously need to be passed in as arguments:
} else {
var cnt = 0
var i = 0
def loop(cnt : Int, i : Int) : ??? = {
if (money - (i * coins.head) > 0) {
cnt += countChange_sort(money - (i * coins.head), coins.tail)
i = i + 1
loop(cnt, i)
}
}
loop(cnt, i)
cnt
}
But we want to use the final value of cnt after the function call. If information is only communicated from loop through its return value, then we can only get the last value of cnt by having loop return it. That's pretty easy:
} else {
var cnt = 0
var i = 0
def loop(cnt : Int, i : Int) : Int = {
if (money - (i * coins.head) > 0) {
cnt += countChange_sort(money - (i * coins.head), coins.tail)
i = i + 1
loop(cnt, i)
} else {
cnt
}
}
cnt = loop(cnt, i)
cnt
}
coins, money, and countChange_sort are examples of information "entering a function through its definition". coins and money are even "variable", but they're constant at the point when loop is defined. If you wanted to move loop out of the body of countChange_sort to become a stand-alone function, you would have to make coins and money additional arguments; they would be passed in from the top-level call in countChange_sort, and then passed down unmodified in each recursive call inside loop. That would still make loop dependent on countChange_sort itself though (as well as the arithmetic operators * and -!), so you never really get away from having the function know about external things that don't come into it through its arguments.
Looking pretty good. But we're still using assignment statements inside loop, which isn't right. However all we do is assign new values to cnt and i and then pass them to a recursive invocation of loop, so those assignments can be easily removed:
} else {
var cnt = 0
var i = 0
def loop(cnt : Int, i : Int) : Int = {
if (money - (i * coins.head) > 0) {
loop(cnt + countChange_sort(money - (i * coins.head), coins.tail), i + 1)
} else {
cnt
}
}
cnt = loop(cnt, i)
cnt
}
Now there are some obvious simplifications, because we're not really doing anything at all with the mutable cnt and i other than initialising them, and then passing their initial value, assigning to cnt once and then immediately returning it. So we can (finally) get rid of the mutable cnt and i entirely:
} else {
def loop(cnt : Int, i : Int) : Int = {
if (money - (i * coins.head) > 0) {
loop(cnt + countChange_sort(money - (i * coins.head), coins.tail), i + 1)
} else {
cnt
}
}
loop(0, 0)
}
And we're done! No side effects in sight!
Note that I haven't thought much at all about what your algorithm actually does (I have made no attempt to even figure out whether it's actually correct, though I presume it is). All I've done is straightforwardly applied the general principle that information only enters a function through its arguments and leaves through its return values; all mutable state accessible to an expression is really extra hidden inputs and hidden outputs of the expression. Making them immutable explicit inputs and outputs, and then allows you to prune away unneeded ones. For example, i doesn't need to be included in the return value from loop because it's not actually needed by anything, so the conversion to functional style has made it clear that it's purely internal to loop, whereas you had to actually read the code of the imperative version to deduce this.
cnt and i are what is known as accumulators. Accumulators aren't anything special, they're just ordinary arguments; the term only refers to how they are used. Basically, if your algorithm needs to keep track of some data as it goes, you can introduce an accumulator parameter so that each recursive call can "pass forward" the data from what has been done so far. They often fill the role that local temporary mutable variables fill in imperative algorithms.
It's quite a common pattern for the return value of a recursive function to be the value of an accumulator parameter once it is determined that there's no more work left to do, as happens with cnt in this case.
Note that these sort of techniques don't necessarily produce good functional code, but it's very easy to convert functions implemented using "local" mutable state to functional style using this technique. Pervasive non-local use of mutability, such as is typical of most traditional OO programs, is harder to convert like this; you can do it, but you tend to have to modify the entire program at once, and the resulting functions have large numbers of extra arguments (explicitly exposing all the hidden data-flow that was present in original program).
I don't have any basic techniques to change the code you have specifically. However, here is a general tip for solving recursion algorithms:
Can you break the problem into sub-problems? In the money example, for example, if you are trying to get to $10 with a $5, that's similar to the question of getting to $5 with a $5 (having already chosen the $5 once). Try to draw it out and make rules. You'll be surprised at how much more obviously correct your solution is.
Since nobody answers your question I will try to give you some hints:
What is a loop?
Traversing each element of a collection. stop meeting a condition
What can you do with recursion:
Traversing each element of a collection. stop meeting a condition.
Start simple write a method without vars which prints each element of a collection.
Then the rest becomes simple look at your loop and what you are doing.
Instead of manipulating the variables directly(like i=i + 1), simply pass i + 1 to the recursive call of your method.
HTH