How can I pad a Vector of Strings in Scala? - scala

I'd like to pad a vector of strings with a given value on all sides (i.e., top, bottom, right, left). For example, the following vector of strings:
1122
1122
3344
3344
should look like this:
000000
011220
011220
033440
033440
000000
Of course, this representation is purely for visual purposes and it is actually a Vector of strings.
I found I can accomplish this with the following code.
val v = Vector("1122", "1122", "3344", "3344")
Vector("000000") ++ (for { r <- v } yield "0" + r + "0") ++ Vector("000000")
However, I am fairly new to Scala and I feel I might be missing a better way to accomplish this. Is there a better way to pad a Vector of Strings in Scala with a given value?

Using jwvh's map approach with the * operator on String:
def repeat(len: Int, c: Char) = c.toString * len
def padLeftRight(s: String, len: Int, c: Char) = {
repeat(len - 1 - s.size, c) + s + c
}
def padSeq[S <: Seq[String]](xs: S, c: Char) = {
val len = xs.map(_.size).max + 2
val padded = repeat(len, c)
padded +: xs.map(padLeftRight(_, len, c)) :+ padded
}
Using padSeq with your example:
val v = Vector("1122", "1122", "3344", "3344")
val result = padSeq(v, '0')
gives:
Vector("000000", "011220", "011220", "033440", "033440", "000000")

Related

Stringbuilder - Replacing all instances of one character with another**

First time posting on here, let me know if I need to change my format and I will do so.
I need to extract a defined region from the buffer, and apply code that will substitute character 'x' with character 'y', which I have attempted below:
buffer.substring(lwr,upr).replace(s,t)
However that fails all of my JUNIT tests and I can't wrap my head around why.
Does anybody have any pointers? Thank you!
EDIT:
For example, given the following:
a p p r o p r i a t e (Marker position is 2, cursor position is 6)
^ ^
Doing "subChar('p', 'x') should result in this being the output:
a p x r o x r i a t e (Marker position and cursor position DO NOT CHANGE)
^ ^
If you take a string, then substring something, then invoke replace on the result, the resulting string will have nothing to do with the original string, thus your solution obviously cannot work.
The indexing scheme from the linked answer remains the same, the answer is easily generalizable to arbitrary functions that can be applied to characters:
def mapBetween(str: String, start: Int, end: Int)(f: Char => Char) = {
val (a, bc) = str.splitAt(start)
val (b, c) = bc.splitAt(end - start)
a + b.map(f) + c
}
def replaceBetween(str: String, start: Int, end: Int, what: Char, byWhat: Char): String = {
mapBetween(str, start, end){ c =>
if (c == what) byWhat else c
}
}
With the above definitions, this here:
println(replaceBetween("appropriate", 2, 6, 'p', 'x'))
produces:
apxroxriate
I think your problem is your Buffer, I created a ScalaFiddle that demonstrates it for simple String and a simple List implementation:
val str = "appropriate"
println (str.replace('p', 'x')) // axxroxriate
val list = str.toList.map{
case c if c == 'p' => 'x'
case c => c
}
println (list) // List(a, x, x, r, o, x, r, i, a, t, e)
Check your implementation or add your implementation to your question.
Here is the example with a region:
def replaceBetween(str: String, start: Int, end: Int, what: Char, byWhat: Char): String = {
val prefix = str.take(start)
val postfix = str.drop(end)
val toMap = str.drop(start).take(end-start).replace(what, byWhat)
prefix + toMap + postfix
}
println(replaceBetween("appropriate", 2, 6, 'p', 'x'))
Here you can try yourself: ScalaFiddle

Scala - Convert Seq[Int] to a single number consisting numbers in the Seq

In Scala, how can I convert a Seq[Int] to a single number consisting of the numbers in the Seq.
e.g.
Seq(2,3,45,10) to 234510 as a number
A straightforward method is
Seq(2,3,45,10).mkString.toLong
Is there a better and perhaps more performant/functional way?
Seq(2,3,45,10).reduce((x,y) => x * math.pow(10,math.floor(math.log10(y)) + 1).toInt + y)
or
Seq(2,3,45,10).map(BigDecimal(_)).reduce((x,y) => x * BigDecimal(10).pow(y.precision) + y)
But actually i think _.mkString.toLong is the most performant, only problem it will work only for decimal representaion. For arbitrary radix you could do
BigInt(Seq(0x2,0x3,0x45,0x10).map(BigInt(_).toString(16)).mkString, 16)
def toNumber(seq:Seq[Int]):Int = {
def append(scale:Int)(n:Int, m:Int):Int = if(m>=scale) append(scale*10)(n, m) else n*scale + m
seq.foldLeft(0)(append(1))
}

Refactoring a small Scala function

I have this function to compute the distance between two n-dimensional points using Pythagoras' theorem.
def computeDistance(neighbour: Point) = math.sqrt(coordinates.zip(neighbour.coordinates).map {
case (c1: Int, c2: Int) => math.pow(c1 - c2, 2)
}.sum)
The Point class (simplified) looks like:
class Point(val coordinates: List[Int])
I'm struggling to refactor the method so it's a little easier to read, can anybody help please?
Here's another way that makes the following three assumptions:
The length of the list is the number of dimensions for the point
Each List is correctly ordered, i.e. List(x, y) or List(x, y, z). We do not know how to handle List(x, z, y)
All lists are of equal length
def computeDistance(other: Point): Double = sqrt(
coordinates.zip(other.coordinates)
.flatMap(i => List(pow(i._2 - i._1, 2)))
.fold(0.0)(_ + _)
)
The obvious disadvantage here is that we don't have any safety around list length. The quick fix for this is to simply have the function return an Option[Double] like so:
def computeDistance(other: Point): Option[Double] = {
if(other.coordinates.length != coordinates.length) {
return None
}
return Some(sqrt(coordinates.zip(other.coordinates)
.flatMap(i => List(pow(i._2 - i._1, 2)))
.fold(0.0)(_ + _)
))
I'd be curious if there is a type safe way to ensure equal list length.
EDIT
It was politely pointed out to me that flatMap(x => List(foo(x))) is equivalent to map(foo) , which I forgot to refactor when I was originally playing w/ this. Slightly cleaner version w/ Map instead of flatMap :
def computeDistance(other: Point): Double = sqrt(
coordinates.zip(other.coordinates)
.map(i => pow(i._2 - i._1, 2))
.fold(0.0)(_ + _)
)
Most of your problem is that you're trying to do math with really long variable names. It's almost always painful. There's a reason why mathematicians use single letters. And assign temporary variables.
Try this:
class Point(val coordinates: List[Int]) { def c = coordinates }
import math._
def d(p: Point) = {
val delta = for ((a,b) <- (c zip p.c)) yield pow(a-b, dims)
sqrt(delta.sum)
}
Consider type aliases and case classes, like this,
type Coord = List[Int]
case class Point(val c: Coord) {
def distTo(p: Point) = {
val z = (c zip p.c).par
val pw = z.aggregate(0.0) ( (a,v) => a + math.pow( v._1-v._2, 2 ), _ + _ )
math.sqrt(pw)
}
}
so that for any two points, for instance,
val p = Point( (1 to 5).toList )
val q = Point( (2 to 6).toList )
we have that
p distTo q
res: Double = 2.23606797749979
Note method distTo uses aggregate on a parallelised collection of tuples, and combines the partial results by the last argument (summation). For high dimensional points this may prove more efficient than the sequential counterpart.
For simplicity of use, consider also implicit classes, as suggested in a comment above,
implicit class RichPoint(val c: Coord) extends AnyVal {
def distTo(d: Coord) = Point(c) distTo Point(d)
}
Hence
List(1,2,3,4,5) distTo List(2,3,4,5,6)
res: Double = 2.23606797749979

'let...in' expression in Scala

In OCaml, the let...in expression allows you to created a named local variable in an expression rather than a statement. (Yes I know that everything is technically an expression, but Unit return values are fairly useless.) Here's a quick example in OCaml:
let square_the_sum a b = (* function definition *)
let sum = a + b in (* declare a named local called sum *)
sum * sum (* return the value of this expression *)
Here's what I would want the equivalent Scala to look like:
def squareTheSum(a: Int, b: Int): Int =
let sum: Int = a + b in
sum * sum
Is there anything in Scala that I can use to achieve this?
EDIT:
You learn something new every day, and this has been answered before.
object ForwardPipeContainer {
implicit class ForwardPipe[A](val value: A) extends AnyVal {
def |>[B](f: A => B): B = f(value)
}
}
import ForwardPipeContainer._
def squareTheSum(a: Int, b: Int): Int = { a + b } |> { sum => sum * sum }
But I'd say that is not nearly as easy to read, and is not as flexible (it gets awkward with nested lets).
You can nest val and def in a def. There's no special syntax; you don't need a let.
def squareTheSum(a: Int, b: Int): Int = {
val sum = a + b
sum * sum
}
I don't see the readability being any different here at all. But if you want to only create the variable within the expression, you can still do that with curly braces like this:
val a = 2 //> a : Int = 2
val b = 3 //> b : Int = 3
val squareSum = { val sum = a + b; sum * sum } //> squareSum : Int = 25
There is no significant difference here between a semicolon and the word "in" (or you could move the expression to the next line, and pretend that "in" is implied if it makes it more OCaml-like :D).
val squareSum = {
val sum = a + b // in
sum * sum
}
Another, more technical, take on this: Clojure's 'let' equivalent in Scala. I think the resulting structures are pretty obtuse compared to the multi-statement form.

Updating a 2d table of counts

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.