Scala: how to get random element form given list - scala

I want to pick random element from given list:
def randomAlphaNumericChar(): Char = {
val ALPHA_NUMERIC_STRING = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789".toCharArray
Gen.oneOf(ALPHA_NUMERIC_STRING)
}
So currently this now compile:
type mismatch; found : org.scalacheck.Gen[Char] required: Char
Gen.oneOf(ALPHA_NUMERIC_STRING)

def randomAlphaNumericChar(): Char = {
/*
ASCII Codes
[0-9]: (48 to 57)
[A-Z]: (65 to 90)
[a-z]: (97 to 122)
*/
val alphabet = (48 to 57) union (65 to 90) union (97 to 122)
val i = scala.util.Random.nextInt(alphabet.size)
alphabet(i).toChar
}

For
val xs = ('a' to 'z') ++ ('A' to 'Z') ++ (1 to 9)
try
xs.maxBy(_ => scala.util.Random.nextInt)
Here maxBy applies a function to each element of the collection and then selects the maximum value returned by the function applied to each element. In this case the function is a random value returned from Random.nextInt.

Something like this will work
def randomAlphaNumericChar(): Char = {
val ALPHA_NUMERIC_STRING = "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ0123456789".toList
scala.util.Random.shuffle(ALPHA_NUMERIC_STRING).head
}

Related

How to xor char within string and add to List?

In this code where I'm attempting to xor the corresponding characters of two strings :
val s1 = "1c0111001f010100061a024b53535009181c";
val s2 = "686974207468652062756c6c277320657965";
val base64p1 = Base64.getEncoder().encodeToString(new BigInteger(s1, 16).toByteArray())
val base64p2 = Base64.getEncoder().encodeToString(new BigInteger(s2, 16).toByteArray())
val zs : IndexedSeq[(Char, Char)] = base64p1.zip(base64p2);
val xor = zs.foldLeft(List[Char]())((a: List[Char] , b: (Char, Char)) => ((Char)((b._1 ^ b._2))) :: a)
produces error :
Char.type does not take parameters
[error] val xor = zs.foldLeft(List[Char]())((a: List[Char] , b: (Char, Char)) => ((Char)((b._1 ^ b._2))) :: a)
How to xor the corresponding string char values and add them to List ?
What you're doing is can be simplified.
val xor = base64p1.zip(base64p2).map{case (a,b) => (a^b).toChar}.reverse
The result of the XOR op (^) is an Int. Just add .toChar to change it to a Char value.
But it looks like what you really want to do is XOR two large hex values that are represented as strings, and then return the result as a string. To do that all you need is...
val (v1, v2) = (BigInt(s1, 16), BigInt(s2, 16))
f"${v1 ^ v2}%x" // res0: String = 746865206b696420646f6e277420706c6179
You use java casting syntax. In scalla you cast like var.asInstanceOf[Type].
Should be (b._1 ^ b._2).asInstanceOf[Char].

How do you pad a string in Scala with a character for missing elements in a Vector?

If I have a sparse list of numbers:
Vector(1,3,7,8,9)
and I need to generate a string of a fixed size which replaces the 'missing' numbers with a given character that might look like this:
1.3...789
How would I do this in Scala?
Well, I'm not sure the range of the integers. So I'm assuming that they may not fit into a char and used a string. Try this:
val v = Vector(1,3,7,8,9)
val fixedStr = ( v.head to v.last )
.map( i => if (v.contains(i)) i.toString else "." )
.mkString
If you are only dealing with single digits then you may change the strings to chars in the above.
-- edit --
ok, so I couldn't help myself and addressed the issue of sparse vector and wanted to change it to use the sliding function. Figured it does no good sitting on my PC so sharing here:
v.sliding(2)
.map( (seq) => if (seq.size == 2) seq else seq ++ seq ) //normalize window to size 2
.foldLeft( new StringBuilder )( (sb, seq) => //fold into stringbuilder
seq match { case Seq(a,b) => sb.append(a).append( "." * (b - a - 1) ) } )
.append( v.last )
.toString
One way to do this is using sliding and pattern matching:
def mkNiceString(v: Vector[Int]) = {
v.sliding(2).map{
case Seq(a) => ""
case Seq(a,b) =>
val gap = b-a;
a.toString + (if(gap>1) "." * (gap-1) else "")
}.mkString + v.last
}
In the REPL:
scala> mkNiceString(Vector(1,3,7,8,9,11))
res22: String = 1.3...789.11
If the vector is sparse, this will be more efficient than checking the range between the first and the last number.
def padVector(numbers: Vector[Int], placeHolder: String) = {
def inner(nums: Vector[Int], prevNumber: Int, acc: String) : String =
if (nums.length == 0) acc
else (nums.head - prevNumber) match {
// the difference is 1 -> no gap between this and previous number
case 1 => inner(nums.tail, nums.head, acc + nums.head)
// gap between numbers -> add placeholder x times
case x => inner(nums.tail, nums.head, acc + (placeHolder * (x-1)) + nums.head)
}
if (numbers.length == 0) ""
else inner(numbers.tail, numbers.head, numbers.head.toString)
}
Output:
scala> padVector(Vector(1,3,7,8,9), ".")
res4: String = 1.3...789

Scala - What type are the numbers in the List using x.toString.toList?

I have written a function in Scala that should calculate the sum of the squares of the digits of a number. Eg: 44 -> 32 (4^2 + 4^2 = 16 + 16 = 32)
Here it is:
def digitSum(x:BigInt) : BigInt = {
var sum = 0
val leng = x.toString.toList.length
var y = x.toString.toList
for (i<-0 until leng ) {
sum += y(i).toInt * y(i).toInt
}
return sum
}
However when I call the function let's say with digitSum(44) instead of 32 I get 5408.
Why is this happening? Does it have to do with the fact that in the list there are Strings? If so why does the .toInt method do not work?
Thanks!
The answer to your questions has been already covered here Scala int value of String characters, have a good read through and you will have more information than required ;)
Also looking at your code, it can benefit more from Scala expressiveness and functional features. The same function can be written in the following manner:
def digitSum(x: BigInt) = x.toString
.map(_.asDigit)
.map(a => a * a)
.sum
In the future try to avoid using mutable variables and standard looping techniques if you could.
When you do toString you're mapping the String to Chars not Ints and then to Ints later. This is what it looks like in the repl:
scala> "1".toList.map(_.toInt)
res0: List[Int] = List(49)
What you want is probably something like this:
def digitSum(x:BigInt) : BigInt = {
var sum = 0
val leng = x.toString.toList.length
var y = x.toString.toList
for (i<-0 until leng ) {
sum += (y(i).toInt - 48) * (y(i).toInt - 48) //Subtract out char base
}
sum
}

Scala Map Integer to (Integer => Integer)

How can I map over a List from 1 to 100 (inclusively) to make each item a Function1 that curries each element to partially apply (itself * _).
I tried this:
scala> val xs: List[Integer => Integer] = List.range(1,101).map { x => _ * x }
<console>:13: error: missing parameter type for expanded function ((x$1) =>
x$1.$times(x))
val xs: List[Integer => Integer] = List.range(1,101).map { x => _ * x }
Desired output:
val xs: List[Integer] = List[1,2,3,4, .., 100]
val desired: List[Integer => Integer] = List[(*1), (*2), ...]
Then, this would be expected too:
desired.get(0).apply(2) = 2 // 1 * 2
The compiler is telling you exactly what you need to fix here: "Missing parameter type". Change _ * x to (_: Integer) * x.
Incidentally, is there some reason you're using java.lang.Integer here? You probably mean scala.Int:
val fns: List[Int => Int] =
List.range(1, 101).map{x => (_: Int) * x}
Explanation:
The compiler can't infer the type of ''_''.
That is because there is no need for ''_'' to be a Integer, just because you used a List of Integers to create these functions.
With other words at this point it is not clear what kind of type should be bound to the free parameter of the partially applied function.
As stated before, this solution works for your case if the input will be Integers
(1 to 101) map ( x => x * (_:Int) )
An example:
val functions = (1 to 101) map ( x => x * (_:Int) )
This will work
functions map (_(2))
res13: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4 ...
This would fail:
functions map (_(2.5))
<console>:9: error: type mismatch;
found : Double(2.5)
required: Int
functions map (_(2.5))

Why converting '1' char to int using toInt method results to 49?

I want to convert a char to an int value.
I am a bit puzzled by the way toInt works.
println(("123").toList) //List(1, 2, 3)
("123").toList.head // res0: Char = 1
("123").toList.head.toInt // res1: Int = 49 WTF??????
49 pops up randomly for no reason.
How do you convert a char to int the right way?
For simple digit to int conversions there is asDigit:
scala> "123" map (_.asDigit)
res5: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3)
Use Integer.parseInt("1", 10). Note that the 10 here is the radix.
val x = "1234"
val y = x.slice(0,1)
val z = Integer.parseInt(y)
val z2 = y.toInt //equivalent to the line above, see #Rogach answer
val z3 = Integer.parseInt(y, 8) //This would give you the representation in base 8 (radix of 8)
49 does not pop up randomly. It's the ascii representation of "1". See http://www.asciitable.com/
.toInt will give you the ascii value. It's probably easiest to write
"123".head - '0'
If you want to handle non-numeric characters, you can do
c match {
case c if '0' <= c && c <= '9' => Some(c - '0')
case _ => None
}
You can also use
"123".head.toString.toInt