count number of groups of certain element - scala

I have a list, I need to count the number of groups of certain elements(1 or 0).
(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1)
val count1Grp = daysSequence.foldLeft(List[Int]()){(acc, elem) =>
if(acc.isEmpty) elem :: acc else if(acc.head == elem) acc else elem :: acc
}
.count(_ == 1)
val count0Grp = daysSequence.foldLeft(List[Int]()){(acc, elem) =>
if(acc.isEmpty) elem :: acc else if(acc.head == elem) acc else elem :: acc
}
.count(_ == 0)
I fold similar neighbour elements and then do a count of what is left. And get
count1Grp = 1
count0Grp = 1
Another example. Both rows same result.
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
(-1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
count1Grp = 1
count0Grp = 2
But how should I do it if I needed 2 or more similar elements together to quantify as a group? In the first case 0 wouldn't fit the criteria and should result in
count1Grp = 1
count0Grp = 0

Why not get a Map with a count of every group in the collection? Then only one traversal is needed.
def groupCount[A](xs : Seq[A]
,grpSize : Int = 1
,acc : Map[A,Int] = Map[A,Int]()
): Map[A,Int] = xs match {
case Seq() => acc
case hd +: _ =>
val (grp,rest) = xs.span(_ == hd)
if (grp.size < grpSize)
groupCount(rest, grpSize, acc)
else
groupCount(rest, grpSize, acc + (hd -> (acc.getOrElse(hd,0)+1)))
}
Here's a Scastie session with a few usage examples.

Related

Remove zero rows from a list of list in Scala

I have a list of list in Scala such as:
val lst = List(List(60, 0, 1, 2, 3, 28, 0, 0, 0, 0), List(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), List(47, 0, 1, 1, 2, 28, 0, 0, 0, 0))
and I want to remove all zero rows and the result should be like:
List(List(60, 0, 1, 2, 3, 28, 0, 0, 0, 0), List(47, 0, 1, 1, 2, 28, 0, 0, 0, 0))
Does Scala list have any built-in method to remove these rows?
You can use filter to keep only items (lists) matching a predicate; The predicate can use exists to check for non-zero elements:
lst.filter(_.exists(_ != 0))
#Tzach Zohar answer is perfectly fine but here is another way to approach it.
scala> lst.filterNot(xs => xs.forall(_ == 0))
res0: List[List[Int]] = List(
List(60, 0, 1, 2, 3, 28, 0, 0, 0, 0),
List(47, 0, 1, 1, 2, 28, 0, 0, 0, 0)
)

Wrong layout of tiles

I create a level an array of int's. This is the code:
using UnityEngine;
using System.Collections;
public class Level1 : MonoBehaviour
{
int[][] level = new int[][]
{
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
new int[] { 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16}
};
public Transform tile00;
public Transform tile16;
public Transform tile38;
int rows = 12;
int cols = 32;
void Start ()
{
BuildLevel ();
}
void BuildLevel(){
int i, j;
GameObject dynamicParent = GameObject.Find ("DynamicObjects");
for(i=0; i<rows; i++)
{
for(j=0; j<cols; j++)
{
Transform toCreate = null;
Debug.Log (i + " , " + j + " " + level[i][j]);
if (level[i][j] == 0)
toCreate = tile00;
if (level[i][j] == 83)
toCreate = tile38;;
if (level[i][j] == 16)
toCreate = tile16;
Vector3 v3 = new Vector3(16-j, 6-i, 0);
Transform newObject = Instantiate(toCreate, v3, Quaternion.identity) as Transform;
newObject.parent = dynamicParent.transform;
}
}
}
}
The output screen is like that:
The tiles are 50 X 50. I changed the dimensions of tiles, I changed the positions on X and Y. I tried everything but I found no solution.Could you give me an ideea, please ?
For the horizontal tiles the layout I want to obtain is (the image is processed with paint) :
The most likely answer is because of this line
Vector3 v3 = new Vector3(16-j, 6-i, 0);
You say that your images are 50 x 50 px each. Assuming that you haven't changed the pixels to units property of your sprite, this would make each of these image occupy a space of 0.5 Unity units on both the X & Y axes.
Now, in your calculation, here's what is happening.
Iteration 1 - (i = 0, j = 0). Position = Vector3(16, 6, 0)
Iteration 2 - (i = 0, j = 1). Position = Vector3(15, 6, 0)...
Iteration 33 -(i = 1, j = 0). Position = Vector3(16, 5, 0)
Now, the difference in the X values between Iteration 1 & Iteration 2 is 1 Unity unit. We've already established earlier that these Sprites will occupy only 0.5 Unity unit due to their size.
Same thing along the Y axis for Iteration 1 & Iteration 33. A difference of 1 unit, with each image occupying only 0.5 units.
So, either change the image to be 100 x 100 px, or change the pixels to units

How to carry out a counter number in parallel_for_each

1)Why the variable length in my sample code are not 62 after calculate ? It's
seems every time the condition is satisfied,but enter the condition,
the number "length not be added every single time.
2)If I don't use concurrency::array length(1, 1, &V[0]); to save counter
but using tile_static int, the length is also wrong.
//if my 8 x 8 local data are:
//cache[TS][TS]
//{
// -69, 0, 0, 1, 0, 0, 0, 0,
// 0, 0, 0, 0, 0, 0, 0, 0,
// 0, 0, 0, 0, 0, 0, 0, 0,
// 0, 0, 0, 0, 0, 0, 0, 0,
// 0, 0, 0, 0, 0, 0, 0, 0,
// 0, 0, 0, 0, 0, 0, 0, 0,
// 0, 0, 0, 0, 0, 0, 0, 0,
// 0, 0, 0, 0, 0, 0, 0, 0
//}
My sample code:
void sample()
{
std::vector<int> V;
V.push_back(0);
concurrency::array<int, 2> length(1, 1, &V[0]);
const int TS = 8;
concurrency::parallel_for_each(data.extent.tile<TS, TS>(), [=, &length](tiled_index<TS, TS> index) restrict(amp)
{
const int row = index.local[0];
const int col = index.local[1];
//tile_static int length; ---------2)
tile_static int cache[TS][TS];
cache[row][col] = data[index.global];
index.barrier.wait();
if (cache[row][col] == 0)
{
//length++; -------------------2)
length[0][0] = length[0][0] + 1;
}
});
}
std::vector<int> V;
for (int i = 0; i < 256; i++)
V.push_back(0);
concurrency::array_view<int, 1> AC_count(256, &V[0]);
const int TS = 8;
concurrency::parallel_for_each(data.extent.tile<TS, TS>(), [=, &length](tiled_index<TS, TS> index) restrict(amp)
{
const int row = index.local[0];
const int col = index.local[1];
tile_static int cache[TS][TS];
cache[row][col] = data[index.global];
index.barrier.wait();
if (cache[row][col] == 0)
{
atomic_fetch_add(&AC_count[0], 1);
}
});
}

Synchronize on a var in Scala

The problem is to search among a few pages of text for an exclamation point concurrently and as soon as any of the threads finds it, all the other threads should stop searching.
Code:
object AntiVolatile {
val pages = for (i <- 1 to 15) yield new Page("!Na" * rand.nextInt(1000) + " Batman!", -1)
var found = Some(false)
def run(): Unit = {
for (p <- pages) yield thread {
var i = 0
var foundInThread = found.get
while (i < p.txt.length && !foundInThread)
if (p.txt(i) == '!') {
found.synchronized {
found match {
case Some(true) => foundInThread = true
case Some(false) => {
p.position = i
found = Some(true)
Thread.sleep(1)
}
case _ =>
}
}
} else i += 1
// if still not found, wait for another thread to find it.
def wait(): Unit = {
found match {
case Some(false) => wait()
case _ =>
}
}
wait()
log(s"results: ${pages.map(_.position)}")
}
}
}
It seems to work ok:
Thread-29: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-27: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-28: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-26: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-30: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-31: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-32: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-25: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-33: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-34: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-39: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-38: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-37: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-36: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
Thread-35: results: Vector(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
But then I realized that found is not a constant instance because it's reassign to a new Option object later. (Why does the code actually work?)
So I came up with a fix:
object AntiVolatile {
case class Found(var isFound: Boolean)
val pages = for (i <- 1 to 15) yield new Page("!Na" * rand.nextInt(1000) + " Batman!", -1)
val found = Found(false)
def run(): Unit = {
for (p <- pages) yield thread {
var i = 0
var foundInThread = found.isFound
while (i < p.txt.length && !foundInThread)
if (p.txt(i) == '!') {
found.synchronized {
found match {
case Found(true) => foundInThread = true
case Found(false) => {
p.position = i
found.isFound = true
Thread.sleep(1)
}
case _ =>
}
}
} else i += 1
// if still not found, wait for another thread to find it.
def wait(): Unit = {
found match {
case Found(false) => wait()
case _ =>
}
}
wait()
log(s"results: ${pages.map(_.position)}")
}
}
}
These two versions seem to behave the same, why? I would expect some bug cropping up in the first version.
Link to github repo: https://github.com/kindlychung/learnConcurrentScala/blob/master/src/main/scala/org/learningconcurrency/ch2/Ch2.scala
It is not entirely clear if you are interested in learning concurrency or if you are solving an actual problem. With that being said, I am going to assume that you are attempting to solve the problem.
Why not use Futures?
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration
import scala.concurrent.{ExecutionContext, Await, Future}
import scala.util.Random
import ExecutionContext.Implicits.global
object Main extends App {
case class Page(number: Int, text: String)
val pages = for (i <- 1 to 15) yield Page(i, "!Na" * Random.nextInt(1000) + " Batman! ")
val searchFutures = pages.map { p => Future {
val position = p.text.indexOf("!")
s"Exclamation mark found on page ${p.number} at position: $position"
}}
val firstCompleted = Future.firstCompletedOf(searchFutures)
val result = Await.result(firstCompleted, Duration(5, TimeUnit.SECONDS))
println(result)
}

Print whole result in interactive Scala console

When I type something into the Scala interactive console, the console prints the result of the statement. If the result is too long, the console crops it (scroll right to see it):
scala> Array.fill[Byte](5)(0)
res1: Array[Byte] = Array(0, 0, 0, 0, 0)
scala> Array.fill[Byte](500)(0)
res2: Array[Byte] = Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...
scala> "a"*5000
res3: String = aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
How can I print the same or equivalent output, for any given object (not just a collection or array) without the cropping occurring?
The result is not "cropped", simply println is invoking java.lang.Arrays.toString() (since scala.Array is a Java array).
Specifically, Arrays defines a toString overload that works with Object, which calls the toString implementation of java.lang.Object on every element. Such implementation prints the reference of the object, so you end up with
[Lscala.Tuple2;#4de71ca9
which is an Array containing the reference 4de71ca9 to a scala.Tuple2 object.
That has been discussed in this ticket years ago.
In the specific case of arrays, you can simply do
println(x.mkString("\n"))
or
x foreach println
or
println(x.deep)
Update
To answer your last edit, you can set the maximum lenght of the strings printed by the REPL
scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'. **
** scala.tools.nsc._ has been imported **
** global._, definitions._ also imported **
** Try :help, :vals, power.<tab> **
scala> vals.isettings.maxPrintString = Int.MaxValue
vals.isettings.maxPrintString: Int = 2147483647
try this
scala> :power
Power mode enabled. :phase is at typer.
import scala.tools.nsc._, intp.global._, definitions._
Try :help or completions for vals._ and power._
scala> vals.isettings.maxPrintString
res9: Int = 800
scala> vals.isettings.maxPrintString = 10000
vals.isettings.maxPrintString: Int = 10000
try
x map println
or
x foreach println