I'm quite new to Scala so apologies for the very basic question.
I have this great on liner that checks if a number is a prime. What I'm trying to do with it is allowing the function to take in an Array and spit out the out the prime numbers.
How can I best achieve this? Is it possible to do so in a one liner as well? Thanks!
def isPrime(num: Int): Boolean = (2 to num) forall (x => num % x != 0)
I'm trying to do with it is allowing the function to take in an Array and spit out the out the prime numbers
You can do the following
def primeNumbs(numbers: Array[Int]) = numbers.filter(x => !((2 until x-1) exists (x % _ == 0)) && x > 1)
and if you pass in array of numbers as
println(primeNumbs(Array(1,2,3,6,7,10,11)).toList)
You should be getting
List(2, 3, 7, 11)
I hope the answer is helpful
Note: your isPrime function doesn't work
You can use this method
def isPrime(num : Int) : Boolean = {
((1 to num).filter(e => (num % e == 0)).size) == 2
}
isPrime: (num: Int)Boolean
scala> (1 to 100) filter(isPrime(_)) foreach(e=> print(e+" "))
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
Your isPrime seems completely broken.
Even if you replace to by until, it will still return strange results for 0 and 1.
Here is a very simple implementation that returns the correct results for 0 and 1, and checks only divisors smaller than (approximately) sqrt(n) instead of n:
def isPrime(n: Int) =
n == 2 ||
(n > 1 && (2 to (math.sqrt(n).toInt + 1)).forall(n % _ > 0))
Now you can filter primes from a range (or a list):
(0 to 10000).filter(isPrime).foreach(println)
You could also write it like this:
0 to 10000 filter isPrime foreach println
But this version with explicit lambdas probably generalizes better, even though it's not necessary in this particular case:
(0 to 10000).filter(n => isPrime(n)).foreach(n => println(n))
In understand that the prime function may be the objective of your assignment/task/interest, but note that's already available in the JVM as BigInteger.isProbablePrime(). With that, and the fact that Scala can call Java transparently, try the following filter:
import java.math.BigInteger
val r = (1 to 100).filter { BigInteger.valueOf(_).isProbablePrime(25) }.mkString(", ")
// "2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97"
This works by iterating the range of numbers (or your Array, or any TraversableOnce, same syntax) and letting pass only those numbers "_" in the closure that fulfill the condition, i.e. that are prime. And instead of folding with a string concatenation, there's a convenient helper mkString that inserts a separator into a sequence and produces a String for you.
And don't worry about the "probable" prime here. For such small numbers like here, there's no probability involved, despite the method name. That kicks in for numbers with maybe 30+ digits or so.
Related
Say I have an array:
[10,12,20,50]
I can iterate though this array like normal which would look at the position at 0, then 1, 2, and 3.
What if I wanted to start an any arbritrary position in the array, and then go through all the numbers in order.
So the other permutations would be:
10,12,20,50
12,20,50,10
20,50,10,12
50,10,12,20
Is there a general function that would allow me to do this type of sliding iteration?
so looking at the index positions from the above it would be:
0,1,2,3
1,2,3,0
2,3,0,1
3,0,1,2
It would be great if some languages have this built in, but I want to know the algorithm to do this also so I understand.
Let's iterate over an array.
val arr = Array(10, 12, 20, 50)
for (i <- 0 to arr.length - 1) {
println(arr(i))
}
With output:
10
12
20
50
Pretty basic.
What about:
val arr = Array(10, 12, 20, 50)
for (i <- 2 to (2 + arr.length - 1)) {
println(arr(i))
}
Oops. Out of bounds. But what if we modulo that index by the length of the array?
val arr = Array(10, 12, 20, 50)
for (i <- 2 to (2 + arr.length - 1)) {
println(arr(i % arr.length))
}
20
50
10
12
Now you just need to wrap it up in a function that replaces 2 in that example with an argument.
There is no language builtin. There is a similar method permutations, but it will generate all permutations without the order, which doesn't really fit your need.
Your requirement can be implemented with a simple algorithm where you just concatenates two slices:
def orderedPermutation(in: List[Int]): Seq[List[Int]] = {
for(i <- 0 until in.size) yield
in.slice(i, in.size) ++ in.slice(0, i)
}
orderedPermutation(List(10,12,20,50)).foreach(println)
Working code here
excuse me, I'm a new learner of spark, now I want to print a rdd in a right format, but the result is like that:
(200412169,([Ljava.lang.String;#7515eb2d,[Ljava.lang.String;#72031368))
(200412169,([Ljava.lang.String;#7515eb2d,[Ljava.lang.String;#27ef4b52))
my rdd is
Array[(String, (Array[String], Array[String]))] =
Array(
(200412169,(Array(gavin),Array(1, 24, 60, 85, 78))),
(200412169,(Array(gavin),Array(2, 22, 20, 85, 78))),
(200412166,(Array(gavin3),Array(1, 54, 80, 78, 98))),
)
and I want to print it like that:
200412169 gavin 2 22 20 85 78
200412169 gavin 1 24 60 85 78
is someone can help me, thanks very much.
The odd-looking print is the result of calling toString on a Java Array. To get a nice tab-separated printout, you can map each record into a String formatted to your liking, something like:
rdd.map { case (a, (arr1, arr2)) => (a +: arr1) ++ arr2 } // "flatten" into single array
.map(_.mkString("\t")) // combine into Tab-separated string
.foreach(println)
// 200412166 gavin3 1 54 80 78 98
// 200412169 gavin 2 22 20 85 78
// 200412169 gavin 1 24 60 85 78
Alternatively, if you do want to keep the RDD's structure, just see a proper representation of it when printing, you can simply convert the Arrays (with their not-so-useful toString) with Scala Lists:
rdd.map { case (a, (arr1, arr2)) => (a, arr1.toList, arr2.toList) }
.foreach(println)
// (200412169,List(gavin),List(1, 24, 60, 85, 78))
// (200412166,List(gavin3),List(1, 54, 80, 78, 98))
// (200412169,List(gavin),List(2, 22, 20, 85, 78))
You are viewing the result (200412169,([Ljava.lang.String;#7515eb2d,[Ljava.lang.String;#72031368))
is only because its calling tostring but in Scala to view the result of RDDyou have to use mkString .
If you want to view the content of a RDD, one way is to use collect()
myRDD.collect().foreach(println)
when the RDD has more of lines use take() to just print few .
myRDD.take(n).foreach(println)
Example:
val input=sc.parallelize(List(1,2,3,4,5))
print(input.collect().mkString(","))
Result:
Is there any way to create a range which includes the end value when using a step which doesn't align?
For instance the following yields:
scala> Range.inclusive(0, 35, 10)
res3: scala.collection.immutable.Range.Inclusive = Range(0, 10, 20, 30)
But I would also like the end value (35) included like so:
scala> Range.inclusive(0, 35, 10)
res3: scala.collection.immutable.Range.Inclusive = Range(0, 10, 20, 30, 35)
As mentioned, not a standard semantics. A workaround,
for (i <- 0 to 35 by 10) yield if (35 % 10 != 0 && 35 - i < 10) 35 else i
where you must replace the boundary and step values as needed.
No, not with the current definition/ implementation. It would be strange behaviour to have the step the same for all intermediate elements but different from the last.
The above solution does not work because it omits the value "30". Here is a unfold-style solution that produces a list rather than a sequence.
def unfoldRange(i: Int, j: Int, s: Int): List[Int] = {
if (i >= j) List(j)
else i :: unfoldRange(i+s,j,s)
}
I think you can tackle this by extending Range with the Pimp my Library pattern as well.
object Extensions {
implicit def RichRange(value: Range) = new {
def withEnd: IndexedSeq[Int] = {
if (value.last != value.end) value :+ value.end
else value
}
}
}
although you get an IndexedSeq[Int] rather than a range. Use it like:
import Extensions._
0 to 5 by 2 withEnd // produces 0, 2, 4, 5
I have been trying to create a small method to calculate given percentile from a seq. It works.. almost. Problem is I don't know why is doesn't work. I was hoping one of your 'a bit smarter' people than me could help me with it.
What I hope the result would be is that it would return the item from the seq that n prosent of the seq is smaller than equal than returned value.
def percentile[Int](p: Int)(seq: Seq[Int]) = {
require(0 <= p && p <= 100) // some value requirements
require(!seq.isEmpty) // more value requirements
val sorted = seq.sorted
val k = math.ceil((seq.length - 1) * (p / 100)).toInt
return sorted(k)
}
So for example if I have
val v = Vector(7, 34, 39, 18, 16, 17, 21, 36, 17, 2, 4, 39, 4, 19, 2, 12, 35, 13, 40, 37)
and I call my function percentile(11)(v) return value is 2. However, 10% of the vector are smaller or equal than 2, not 11% like I am calling. percentile(11)(v) should return 4.
your error is in this row:
val k = math.ceil((seq.length - 1) * (p / 100)).toInt
and particularly here: p / 100. Being p an Int <= 100 and >= 0, p/100 will always be equal to 0 or 1 (if p == 100). If you want a floating point result, you have to widen one of the two values to double: p/100.0
val k = math.ceil((seq.length - 1) * (p / 100.0)).toInt
On a side note: you don't need the [Int] type parameter
The problem is with the part p / 100 in
val k = math.ceil((seq.length - 1) * (p / 100)).toInt
Since p is of type Int and 100 is also an Int, the division is an integer division that returns an Int. If either p or 100 is a Double, the result will be a Double.
The easiest fix would be to change that part in p / 100.0.
I'm learning Scala as my first functional-ish language. As one of the problems, I was trying to find a functional way of generating the sequence S up to n places. S is defined so that S(1) = 1, and S(x) = the number of times x appears in the sequence. (I can't remember what this is called, but I've seen it in programming books before.)
In practice, the sequence looks like this:
S = 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7 ...
I can generate this sequence pretty easily in Scala using an imperative style like this:
def genSequence(numItems: Int) = {
require(numItems > 0, "numItems must be >= 1")
var list: List[Int] = List(1)
var seq_no = 2
var no = 2
var no_nos = 0
var num_made = 1
while(num_made < numItems) {
if(no_nos < seq_no) {
list = list :+ no
no_nos += 1
num_made += 1
} else if(no % 2 == 0) {
no += 1
no_nos = 0
} else {
no += 1
seq_no += 1
no_nos = 0
}
}
list
}
But I don't really have any idea how to write this without using vars and the while loop.
Thanks!
Pavel's answer has come closest so far, but it's also inefficient. Two flatMaps and a zipWithIndex are overkill here :)
My understanding of the required output:
The results contain all the positive integers (starting from 1) at least once
each number n appears in the output (n/2) + 1 times
As Pavel has rightly noted, the solution is to start with a Stream then use flatMap:
Stream from 1
This generates a Stream, a potentially never-ending sequence that only produces values on demand. In this case, it's generating 1, 2, 3, 4... all the way up to Infinity (in theory) or Integer.MAX_VALUE (in practice)
Streams can be mapped over, as with any other collection. For example: (Stream from 1) map { 2 * _ } generates a Stream of even numbers.
You can also use flatMap on Streams, allowing you to map each input element to zero or more output elements; this is key to solving your problem:
val strm = (Stream from 1) flatMap { n => Stream.fill(n/2 + 1)(n) }
So... How does this work? For the element 3, the lambda { n => Stream.fill(n/2 + 1)(n) } will produce the output stream 3,3. For the first 5 integers you'll get:
1 -> 1
2 -> 2, 2
3 -> 3, 3
4 -> 4, 4, 4
5 -> 5, 5, 5
etc.
and because we're using flatMap, these will be concatenated, yielding:
1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 5, ...
Streams are memoised, so once a given value has been calculated it'll be saved for future reference. However, all the preceeding values have to be calculated at least once. If you want the full sequence then this won't cause any problems, but it does mean that generating S(10796) from a cold start is going to be slow! (a problem shared with your imperative algorithm). If you need to do this, then none of the solutions so far is likely to be appropriate for you.
The following code produces exactly the same sequence as yours:
val seq = Stream.from(1)
.flatMap(Stream.fill(2)(_))
.zipWithIndex
.flatMap(p => Stream.fill(p._1)(p._2))
.tail
However, if you want to produce the Golomb sequence (that complies with the definition, but differs from your sample code result), you may use the following:
val seq = 1 #:: a(2)
def a(n: Int): Stream[Int] = (1 + seq(n - seq(seq(n - 2) - 1) - 1)) #:: a(n + 1)
You may check my article for more examples of how to deal with number sequences in functional style.
Here is a translation of your code to a more functional style:
def genSequence(numItems: Int): List[Int] = {
genSequenceR(numItems, 2, 2, 0, 1, List[Int](1))
}
def genSequenceR(numItems: Int, seq_no: Int, no:Int, no_nos: Int, numMade: Int, list: List[Int]): List[Int] = {
if(numMade < numItems){
if(no_nos < seq_no){
genSequenceR(numItems, seq_no, no, no_nos + 1, numMade + 1, list :+ no)
}else if(no % 2 == 0){
genSequenceR(numItems, seq_no, no + 1, 0, numMade, list)
}else{
genSequenceR(numItems, seq_no + 1, no + 1, 0, numMade, list)
}
}else{
list
}
}
The genSequenceR is the recursive function that accumulates values in the list and calls the function with new values based on the conditions. Like the while loop, it terminates, when numMade is less than numItems and returns the list to genSequence.
This is a fairly rudimentary functional translation of your code. It can be improved and there are better approaches typically used. I'd recommend trying to improve it with pattern matching and then work towards the other solutions that use Stream here.
Here's an attempt from a Scala tyro. Keep in mind I don't really understand Scala, I don't really understand the question, and I don't really understand your algorithm.
def genX_Ys[A](howMany : Int, ofWhat : A) : List[A] = howMany match {
case 1 => List(ofWhat)
case _ => ofWhat :: genX_Ys(howMany - 1, ofWhat)
}
def makeAtLeast(startingWith : List[Int], nextUp : Int, howMany : Int, minimumLength : Int) : List[Int] = {
if (startingWith.size >= minimumLength)
startingWith
else
makeAtLeast(startingWith ++ genX_Ys( howMany, nextUp),
nextUp +1, howMany + (if (nextUp % 2 == 1) 1 else 0), minimumLength)
}
def genSequence(numItems: Int) = makeAtLeast(List(1), 2, 2, numItems).slice(0, numItems)
This seems to work, but re-read the caveats above. In particular, I am sure there is a library function that performs genX_Ys, but I couldn't find it.
EDIT Could be
def genX_Ys[A](howMany : Int, ofWhat : A) : Seq[A] =
(1 to howMany) map { x => ofWhat }
Here is a very direct "translation" of the definition of the Golomb seqence:
val it = Iterator.iterate((1,1,Map(1->1,2->2))){ case (n,i,m) =>
val c = m(n)
if (c == 1) (n+1, i+1, m + (i -> n) - n)
else (n, i+1, m + (i -> n) + (n -> (c-1)))
}.map(_._1)
println(it.take(10).toList)
The tripel (n,i,m) contains the actual number n, the index i and a Map m, which contains how often an n must be repeated. When the counter in the Map for our n reaches 1, we increase n (and can drop n from the map, as it is not longer needed), else we just decrease n's counter in the map and keep n. In every case we add the new pair i -> n into the map, which will be used as counter later (when a subsequent n reaches the value of the current i).
[Edit]
Thinking about it, I realized that I don't need indexes and not even a lookup (because the "counters" are already in the "right" order), which means that I can replace the Map with a Queue:
import collection.immutable.Queue
val it = 1 #:: Iterator.iterate((2, 2, Queue[Int]())){
case (n,1,q) => (n+1, q.head, q.tail + (n+1))
case (n,c,q) => (n,c-1,q + n)
}.map(_._1).toStream
The Iterator works correctly when starting by 2, so I had to add a 1 at the beginning. The second tuple argument is now the counter for the current n (taken from the Queue). The current counter could be kept in the Queue as well, so we have only a pair, but then it's less clear what's going on due to the complicated Queue handling:
val it = 1 #:: Iterator.iterate((2, Queue[Int](2))){
case (n,q) if q.head == 1 => (n+1, q.tail + (n+1))
case (n,q) => (n, ((q.head-1) +: q.tail) + n)
}.map(_._1).toStream