Have object holds three values of doubles. Two objects are equal if all three values are equal in any possible combination. Need a function to determine number of "unique" objects in array.
I think about make Set from array and return count, but conforming to Hashable protocol requires hashValue function...
Coding on Swift but algorithm on any language (except alien) would be appreciated :)
So I need hashValue of three doubles (order of values doesn't matter) or any other solution of determining number unique objects in array
UPDATE: "Unique" means not equal. As I said above equal of two objects with double values (a, b, c for example) is equal of all three values in any possible combinations. For example:
obj1 = (a: 1, b: 2, c: 3)
obj2 = (a: 3, b: 2, c: 1)
// obj1 is equal obj2
Here is an example of making a class holding 3 Doubles Hashable so that you can use Set to determine how many unique ones are held in an array:
class Triple: Hashable {
var a: Double
var b: Double
var c: Double
// hashValue need only be the same for "equal" instances of the class,
// so the hashValue of the smallest property will suffice
var hashValue: Int {
return min(a, b, c).hashValue
}
init(a: Double, b: Double, c: Double) {
self.a = a
self.b = b
self.c = c
}
}
// Protocol Hashable includes Equatable, so implement == for type Triple:
// Compare sorted values to determine equality
func ==(lhs: Triple, rhs: Triple) -> Bool {
return [lhs.a, lhs.b, lhs.c].sorted() == [rhs.a, rhs.b, rhs.c].sorted()
}
let t1 = Triple(a: 3, b: 2, c: 1)
let t2 = Triple(a: 1, b: 2, c: 3)
let t3 = Triple(a: 1, b: 3, c: 2)
let t4 = Triple(a: 3, b: 3, c: 2)
let arr = [t1, t2, t3, t4]
// Find out how many unique Triples are in the array:
let set = Set(arr)
print(set.count) // 2
Discussion: A better hashing function
As #PatriciaShanahan noted in the comments, using min in the computation of hashValue has a couple of drawbacks:
min can be expensive since it involves comparisons.
Only considering the smallest item when computing the hashValue for Triple will result in many "common" Triples with the same hashValue. For instance, any Triple with a value of 0 and two positive values would have the same hashValue.
I chose min because I felt it was easy to understand that the min(a, b, c) would result in the same value for all orderings of a, b, and c which means we'd get the same hashValue for all orderings. That is important because since we are considering Triples to be equal independent of the orderings of the 3 values, the hashValue must be the same for any ordering of the values since a == b implies a.hashValue == b.hashValue.
I had considered other hashing functions such as:
(a + b + c).hashValue
(a * b * c).hashValue
but these are flawed. Mathematically speaking, addition and multiplication are commutative, so theoretically these would result in the same hashValue no matter the order of a, b, and c. But, in practice, changing the order of operations could result in an overflow or underflow.
Consider the following example:
let a = Int.max
let b = Int.min
let c = 5
let t1 = (a + b) + c // 4
let t2 = (a + c) + b // Overflow!
An ideal hashing function for class Triplewould:
Guarantee the same hashValue for all orderings of a, b, and c.
Be fast to compute.
Would change the result if any of a, b, or c change.
Could not overflow or underflow.
One good mathematical operation for combining numbers is the bitwise OR function ^. It combines two values by comparing them bitwise and setting the resulting bit to 0 if both bits are the same and to 1 if the bits are different.
a b result
--- --- ------
0 0 0
0 1 1
1 0 1
1 1 0
Extending this to 3 values:
a b c result
--- --- --- ------
0 0 0 0
0 0 1 1
0 1 0 1
0 1 1 0
1 0 0 1
1 0 1 0
1 1 0 0
1 1 1 1
As shown in the table above, XOR(0, 0, 0) = 0 for all orderings, XOR(1, 0, 0) = 1 for all orderings, XOR(1, 1, 0) = 0 for all orderings, and XOR(1, 1, 1) = 1 for all orderings. So using exclusive OR to combine the values meets the first criterium of providing the same result for all orderings.
Exclusive OR is a fast operation. It is implemented by a single assembly instruction. So it meets the second criterium of a good hashing function.
If any of a, b, or c changes, then the result of a ^ b ^ c would change. So exclusive OR meets the third criterium of a good hashing function.
Exclusive OR cannot overflow or underflow because it simply sets the bits. So it meets the fourth criterium of a good hashing function.
Thus, a better hashing function would be:
var hashValue: Int {
return a.hashValue ^ b.hashValue ^ c.hashValue
}
Related
I want to write a function in scala calcMod(a, b, c) where a should serve as a predicate and b and c taking the range of numbers (e.g. 3(incl.)...9(excl.)) which have to be evaluated and return a list of numbers in this range for which the predicate holds.
For example the function-call calcMod(k => k % 2 == 0, 3, 9) should evaluate in Return(4, 6, 8)
The fact that I have mod 2 == 0 makes it clear that even numbers will always be returned. I want to solve this with linear recursion.
def calcMod(a: Int => Boolean, b: Int, c: Int): List[Int] = ?
Below function will go from b until c, then apply filter with the function we got in argument.
def calcMod(a: Int => Boolean, b: Int, c: Int): List[Int] = (b until c filter a).toList
a = [ 1, 2, 3]
a
[1,2,3]
b = [ 3, 4, 5]
b
[3,4,5]
c = [a ,b]
c
[[1,2,3],[3,4,5]]
a !! 2
(Just 3)
a !! 2
(Just 3)
a !! 1
(Just 2)
c !! 2
Nothing
c !! 1
(Just [3,4,5])
c !! 1 !! 0
Error found:
in module $PSCI
at line 1, column 1 - line 1, column 11
Could not match type
Maybe
with type
Array
while trying to match type Maybe (Array Int)
with type Array t0
while checking that expression (index c) 1
has type Array t0
in value declaration it
where t0 is an unknown type
Indexing into an array returns not the plain element, but values wrapped in Maybe, because the array might not have an element at the given index. In your case, the result of c !! 1 has type Maybe (Array Int). So you have to handle that Maybe somehow.
I guess you expect the end result to be of type Maybe Int. There are different ways to do so. The perhaps most explicit one is:
case c !! 1 of
Nothing -> Nothing
(Just x) -> x !! 0
(this will return Just 3)
Because "chaining" functions like this is very common, there are abstractions that lead to the same result, e.g.:
(c !! 1) >>= (_ !! 0)
Anyways, the trick is to reach into the first result (if it was successful) and then try the second indexing. If both succeed, return the end result. If one fails, return Nothing.
I have a function to find the nth number in a fibonacci sequence, in which I am recursively calling the function. The sum is stored in a class variable and I have an extra pointer I increment every time the function gets called. This extra pointer is the gate keeper which dictates the base case of when to exit from the loop. The performance I get, using this algorithm is, O(n) linear time and with O(1) space. I get the expected answer but I am confused if this an acceptable solution from a coding interview stand point.
var x = 0
var sum = 0
func myFibonacci(of n: Int, a: Int, b:Int) -> Int {
x+=1
if (x == n) {
return sum
} else {
sum = a+b
return myFibonacci(of: n, a: b, b: sum)
}
}
let finalAns = myFibonacci(of: 9, a: 0, b: 1)
print("The nth number in Fibonacci sequence is \(finalAns)")
Output: 34
Time complexity: O(n) linear time
Space complexity O(1)
Is this an acceptable solution for a coding interview?
I have recently been playing around on HackerRank in my down time, and am having some trouble solving this problem: https://www.hackerrank.com/challenges/functional-programming-the-sums-of-powers efficiently.
Problem statement: Given two integers X and N, find the number of ways to express X as a sum of powers of N of unique natural numbers.
Example: X = 10, N = 2
There is only one way get 10 using powers of 2 below 10, and that is 1^2 + 3^2
My Approach
I know that there probably exists a nice, elegant recurrence for this problem; but unfortunately I couldn't find one, so I started thinking about other approaches. What I decided on what that I would gather a range of numbers from [1,Z] where Z is the largest number less than X when raised to the power of N. So for the example above, I only consider [1,2,3] because 4^2 > 10 and therefore can't be a part of (positive) numbers that sum to 10. After gathering this range of numbers I raised them all to the power N then found the permutations of all subsets of this list. So for [1,2,3] I found [[1],[4],[9],[1,4],[1,9],[4,9],[1,4,9]], not a trivial series of operations for large initial ranges of numbers (my solution timed out on the final two hackerrank tests). The final step was to count the sublists that summed to X.
Solution
object Solution {
def numberOfWays(X : Int, N : Int) : Int = {
def candidates(num : Int) : List[List[Int]] = {
if( Math.pow(num, N).toInt > X )
List.range(1, num).map(
l => Math.pow(l, N).toInt
).toSet[Int].subsets.map(_.toList).toList
else
candidates(num+1)
}
candidates(1).count(l => l.sum == X)
}
def main(args: Array[String]) {
println(numberOfWays(readInt(),readInt()))
}
}
Has anyone encountered this problem before? If so, are there more elegant solutions?
After you build your list of squares you are left with what I would consider a kind of Partition Problem called the Subset Sum Problem. This is an old NP-Complete problem. So the answer to your first question is "Yes", and the answer to the second is given in the links.
This can be thought of as a dynamic programming problem. I still reason about Dynamic Programming problems imperatively, because that was how I was taught, but this can probably be made functional.
A. Make an array A of length X with type parameter Integer.
B. Iterate over i from 1 to Nth root of X. For all i, set A[i^N - 1] = 1.
C. Iterate over j from 0 until X. In an inner loop, iterate over k from 0 to (X + 1) / 2.
A[j] += A[k] * A[x - k]
D. A[X - 1]
This can be made slightly more efficient by keeping track of which indices are non-trivial, but not that much more efficient.
def numberOfWays(X: Int, N: Int): Int = {
def powerSumHelper(sum: Int, maximum: Int): Int = sum match {
case x if x < 1 => 0
case _ => {
val limit = scala.math.min(maximum, scala.math.floor(scala.math.pow(sum, 1.0 / N)).toInt)
(limit to 1 by -1).map(x => {
val y = scala.math.pow(x, N).toInt
if (y == sum) 1 else powerSumHelper(sum - y, x - 1)
}).sum
}
}
powerSumHelper(X, Integer.MAX_VALUE)
}
Suppose I want a Scala data structure that implements a 2-dimensional table of counts that can change over time (i.e., individual cells in the table can be incremented or decremented). What should I be using to do this?
I could use a 2-dimensional array:
val x = Array.fill[Int](1, 2) = 0
x(1)(2) += 1
But Arrays are mutable, and I guess I should slightly prefer immutable data structures.
So I thought about using a 2-dimensional Vector:
val x = Vector.fill[Int](1, 2) = 0
// how do I update this? I want to write something like val newX : Vector[Vector[Int]] = x.add((1, 2), 1)
// but I'm not sure how
But I'm not sure how to get a new vector with only a single element changed.
What's the best approach?
Best depends on what your criteria are. The simplest immutable variant is to use a map from (Int,Int) to your count:
var c = (for (i <- 0 to 99; j <- 0 to 99) yield (i,j) -> 0).toMap
Then you access your values with c(i,j) and set them with c += ((i,j) -> n); c += ((i,j) -> (c(i,j)+1)) is a little bit annoying, but it's not too bad.
Faster is to use nested Vectors--by about a factor of 2 to 3, depending on whether you tend to re-set the same element over and over or not--but it has an ugly update method:
var v = Vector.fill(100,100)(0)
v(82)(49) // Easy enough
v = v.updated(82, v(82).updated(49, v(82)(49)+1) // Ouch!
Faster yet (by about 2x) is to have only one vector which you index into:
var u = Vector.fill(100*100)(0)
u(82*100 + 49) // Um, you think I can always remember to do this right?
u = u.updated(82*100 + 49, u(82*100 + 49)+1) // Well, that's actually better
If you don't need immutability and your table size isn't going to change, just use an array as you've shown. It's ~200x faster than the fastest vector solution if all you're doing is incrementing and decrementing an integer.
If you want to do this in a very general and functional (but not necessarily performant) way, you can use lenses. Here's an example of how you could use Scalaz 7's implementation, for example:
import scalaz._
def at[A](i: Int): Lens[Seq[A], A] = Lens.lensg(a => a.updated(i, _), (_(i)))
def at2d[A](i: Int, j: Int) = at[Seq[A]](i) andThen at(j)
And a little bit of setup:
val table = Vector.tabulate(3, 4)(_ + _)
def show[A](t: Seq[Seq[A]]) = t.map(_ mkString " ") mkString "\n"
Which gives us:
scala> show(table)
res0: String =
0 1 2 3
1 2 3 4
2 3 4 5
We can use our lens like this:
scala> show(at2d(1, 2).set(table, 9))
res1: String =
0 1 2 3
1 2 9 4
2 3 4 5
Or we can just get the value at a given cell:
scala> val v: Int = at2d(2, 3).get(table)
v: Int = 5
Or do a lot of more complex things, like apply a function to a particular cell:
scala> show(at2d(2, 2).mod(((_: Int) * 2), table))
res8: String =
0 1 2 3
1 2 3 4
2 3 8 5
And so on.
There isn't a built-in method for this, perhaps because it would require the Vector to know that it contains Vectors, or Vectors or Vectors etc, whereas most methods are generic, and it would require a separate method for each number of dimensions, because you need to specify a co-ordinate arg for each dimension.
However, you can add these yourself; the following will take you up to 4D, although you could just add the bits for 2D if that's all you need:
object UpdatableVector {
implicit def vectorToUpdatableVector2[T](v: Vector[Vector[T]]) = new UpdatableVector2(v)
implicit def vectorToUpdatableVector3[T](v: Vector[Vector[Vector[T]]]) = new UpdatableVector3(v)
implicit def vectorToUpdatableVector4[T](v: Vector[Vector[Vector[Vector[T]]]]) = new UpdatableVector4(v)
class UpdatableVector2[T](v: Vector[Vector[T]]) {
def updated2(c1: Int, c2: Int)(newVal: T) =
v.updated(c1, v(c1).updated(c2, newVal))
}
class UpdatableVector3[T](v: Vector[Vector[Vector[T]]]) {
def updated3(c1: Int, c2: Int, c3: Int)(newVal: T) =
v.updated(c1, v(c1).updated2(c2, c3)(newVal))
}
class UpdatableVector4[T](v: Vector[Vector[Vector[Vector[T]]]]) {
def updated4(c1: Int, c2: Int, c3: Int, c4: Int)(newVal: T) =
v.updated(c1, v(c1).updated3(c2, c3, c4)(newVal))
}
}
In Scala 2.10 you don't need the implicit defs and can just add the implicit keyword to the class definitions.
Test:
import UpdatableVector._
val v2 = Vector.fill(2,2)(0)
val r2 = v2.updated2(1,1)(42)
println(r2) // Vector(Vector(0, 0), Vector(0, 42))
val v3 = Vector.fill(2,2,2)(0)
val r3 = v3.updated3(1,1,1)(42)
println(r3) // etc
Hope that's useful.