Return list with the values on odd positions - scala

Why does the following code return a empty list instead of a list with the values at odd positions ?
def f(arr:List[Int]) : List[Int] = {
def odd_concat(list_odd:List[Int], arr_index:Int) : List[Int] = {
if(arr_index == arr.size) {
list_odd
}
else if(arr_index % 2 == 0) {
odd_concat(list_odd, arr_index + 1)
}
else {
//println(arr(arr_index))
list_odd:+arr(arr_index)
odd_concat(list_odd, arr_index + 1)
}
}
odd_concat(List(), 0)
}

You are using immutable list, immutable means the object cannot be change.
Your code:
list_odd:+arr(arr_index)
It does not change the list_odd with the value of arr(arr_index) rather give a new instance of List with values added.
Try to insert that code inside the odd_concat() instead, like the following:
def f(arr:List[Int]) : List[Int] = {
def odd_concat(list_odd:List[Int], arr_index:Int) : List[Int] = {
if(arr_index == arr.size) {
list_odd
}
else if(arr_index % 2 == 0) {
odd_concat(list_odd, arr_index + 1)
}
else {
//println(arr(arr_index))
odd_concat(list_odd:+arr(arr_index), arr_index + 1)
}
}
odd_concat(List(), 0)
}

Related

Continue in Scala for loops

How do i convert below Java code to scala and use continue in for loop, this program remove minimum number of extra closed parenthesis in a given string
input : lee(t(c)o)de)
output : leet(t(c)o)de
public String minRemoveToMakeValid(String s){
StringBuilder sb =new StringBuilder();
in open =0;
for (char c : s.toCharArray()){
if(c == '('){
open++
}
else if(c == ')'){
if(open == 0) continue;
open --;
}
sb.append(c)
}
return sb
}
https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/
import util.control.Breaks._
val searchMe = "peter piper picked a peck of pickled peppers"
var numPs = 0
for (i <- 0 until searchMe.length) {
breakable {
if (searchMe.charAt(i) != 'p') {
break // break out of the 'breakable', continue the outside loop
} else {
numPs += 1
}
}
}
println("Found " + numPs + " p's in the string.")
Try it: https://scastie.scala-lang.org/R9sr95WESLyiKamCHHUVdQ
Im able to get it worked using below code
def minRemoveToMakeValid(s: String): String = {
var open = 0
val sb = new StringBuilder
for (c <- s.toCharArray) {
breakable {
if (c == '(') open += 1
else if (c == ')') {
if (open == 0)break
open -= 1
}
sb.append(c)
}
}
var result = new StringBuilder()
for(i<-sb.length()-1 to 0 by -1)
{
breakable{
open-=1
if(sb.charAt(i) == '(' && open >0) break
result.append(sb.charAt(i))
}
}
result.reverse.toString()
}

How to do parenthesis balancing using scala, recursion ,one function and one parameter for the function?

I am builing a little method for parenthesis balancing using scala and recursion.
I came out this code which surprisingly doesn't work.
object Test{
def balance(chars: List[Char]): Boolean=
{
var opening_index: Int = -1
var closing_index: Int = -1
opening_index = chars.indexOf('(')
closing_index = chars.indexOf(')')
println(opening_index)
println(closing_index)
if ( chars.size == 0 ) true
if ((opening_index == -1) & (closing_index== -1))
{
true
}
if (closing_index> -1 & opening_index> -1)
{
if (closing_index< opening_index) return(false)
else
{
balance(chars.filter(_!=chars(closing_index)).filter(_!=chars(opening_index)))
}
}
else
return (false)
}
val lst:List[Char] = List('(',')' ,'3','4')
balance(lst)
}
I am aware that there are other similar posts but I am more interested in using this approach than the other ones.
You probably wanted to filter by index, not by character. As it is, your code erases all parentheses in the first round.
This here works with zipWithIndex, and compares the index with opening_index and closing_index:
def balance(chars: List[Char]): Boolean = {
val opening_index = chars.indexOf('(')
val closing_index = chars.indexOf(')')
if ( chars.size == 0 ) {
true
} else if ((opening_index == -1) && (closing_index== -1)) {
true
} else if (closing_index > -1 && opening_index > -1) {
if (closing_index < opening_index) {
false
} else {
balance(
chars.zipWithIndex.filterNot{
case (c, i) => i == opening_index || i == closing_index
}.map(_._1)
)
}
} else {
false
}
}
println(balance("()34".toList))
println(balance("()34)".toList))
println(balance("(x)(y(z))".toList))
println(balance("(x)(y(z)".toList))
Output:
true
false
true
false
You can use below solution to check balance parenthesis.
object Driver extends App{
def balance(chars: List[Char]): Boolean=
{
if (chars.mkString("").length() == 0) {
return true;
}
if (chars.mkString("").contains("()")) {
return balance(chars.mkString("").replaceFirst("\\(\\)", "").toCharArray.toList);
}
if (chars.mkString("").contains("[]")) {
return balance(chars.mkString("").replaceFirst("\\[\\]", "").toCharArray.toList);
}
if (chars.mkString("").contains("{}")) {
return balance(chars.mkString("").replaceFirst("\\{\\}", "").toCharArray.toList);
} else {
return false;
}
}
println(balance(List('(','{','}')))
println(balance(List('(','{','}',')')))
}
There are two main (functional) problems with this code.
Firstly, this test does nothing because the result is thrown away
if ((opening_index == -1) & (closing_index== -1))
{
true
}
You probably meant return true
Secondly, the recursive call is wrong
balance(chars.filter(_ != chars(closing_index)).filter(_ != chars(opening_index)))
These two calls to filter are removing all the parentheses from the list, so the call to balance will always succeed even if the rest of the list is unbalanced.
You probably want to use three slice calls to remove the specific parentheses at opening_index and closing_index.

How to claculate adjacent data with spark/scala

I hava a RDD,the RDD type is Tuple2(value,timestamp),value is 1 or 0 , timestamp is a sequential, and a variable limitTime=4. When I map the RDD, if the value is 1 the output value from current timestamp to (timestamp +limitTime) is 1 ,else current value is 0, I call it is period. But there is a special case,when the value is 1 and its timestamp is in period,then it is ignored, the current value of output is 0
input : (0,0),(1,1),(0,3),(0,5),(0,7),(0,8),(0,10),(1,12),(0,14),(0,15)
expected output :(0,0),(1,1),(1,3),(1,5),(0,7),(0,8),(0,10),(1,12),(1,14),(1,15)
special input2: (0,0),(1,1),(0,3),(1,5),(0,7),(1,8),(0,10),(1,12),(0,14),(0,15)
expected output2:(0,0),(1,1),(1,3),(1,5),(0,7),(1,8),(1,10),(1,12),(0,14),(0,15)
this is my try:
var limitTime=4
var startTime= -limitTime
val rdd=sc.parallelize(List((0,0),(1,1),(0,3),(1,5),(0,7),(1,8),(0,10),(1,12),(0,14),(0,15)),4)
val results=rdd.mapPartitions(parIter => {
var resultIter = new ArrayBuffer[Tuple2[Int,Int]]()
while (parIter.hasNext) {
val iter = parIter.next()
if(iter._1==1){
if(iter._2<=startTime+limitTime&&iter._2!=0&&iter._2>=startTime){
resultIter.append(iter)
}else{
resultIter.append(iter)
startTime=iter._2
}
}else{
if(iter._2<=startTime+limitTime&&iter._2!=0&&iter._2>=startTime){
resultIter.append((1,iter._2))
}else{
resultIter.append(iter)
}
}
}
resultIter.toIterator
})
results.collect().foreach(println)
it's so inefficient,how can I get the same result without array?
Following code should work for both of your cases.
var limitTime=3
var first = true
var previousValue = 0
val rdd=sc.parallelize(List((0,0),(1,1),(0,3),(0,5),(0,7),(0,8),(0,10),(1,12),(0,14),(0,15)), 4)
val tempResult = rdd.collect.map(pair => {
if(first){
first = false
previousValue = pair._1
(pair._1, pair._2)
}
else {
if ((pair._1 == 1 || previousValue == 1) && limitTime > 0) {
limitTime -= 1
previousValue = 1
(1, pair._2)
}
else {
if (limitTime == 0) limitTime = 3
previousValue = pair._1
(pair._1, pair._2)
}
}
})
tempResult.foreach(print)
If it doesn't please let me know

How to define count without using var

I have this simple function that return some Status:
def getStatus : String =
{
//...
}
And i want to wait until this return specific status but still count this number of calls before exit:
def wait =
{
var count = 0
while (getStatus != "smeStatus" && count < 10) {
// some code here
count++
}
}
How can i avoid of using var ?
You can use a recursive method that takes the count-so-far and returns it + 1:
def waitUntilDone(countSoFar: Int): Int = {
if (getStatus != "smeStatus" && countSoFar < 10) {
// some code here
waitUntilDone(countSoFar + 1)
} else {
countSoFar
}
}
// invoke it starting with 0:
val count = waitUntilDone(0)
def status = ""
def waiting: Unit = {
def check(count: Int): Unit = {
if(count < 10 && status != "smeStatus") {
// do something
check(count + 1)
}
}
check(0)
}

Connect-Four Game in Scala

I have to make a connect-four game using scala. I have attached the code but everytime the game runs and gets to row 3 it just continues to change the second rows entry instead of going to the next row. Any help would be appreciated. I found this code on another thread on here and couldn't figure out how to get it to work:
// makes the board
val table = Array.fill(9,8)('-')
var i = 0;
while(i < 8){
table(8)(i) = (i+'0').toChar
i = i+1;
}
// prints starting board
def printBoard(table: Array[Array[Char]]) {
table.foreach( x => println(x.mkString(" ")))
}
//player 1 moves
def playerMove1(){
val move = readInt
var currentRow1 = 7
while (currentRow1 >= 0)
if (table(currentRow1)(move) != ('-')) {
currentRow1 = (currentRow1-1)
table(currentRow1)(move) = ('X')
return (player2)}
} else {
table(currentRow1)(move) = ('X')
return (player2)
}
}
//player 2 moves
def playerMove2(){
val move = readInt
var currentRow2 = 7
while (currentRow2 >= 0)
if (table(currentRow2)(move) != ('-')) {
currentRow2 = (currentRow2-1)
table(currentRow2)(move) = ('O')
return (player1)}
} else {
table(currentRow2)(move) = ('O')
return (player1)
}
}
//player 1
def player1(){
printBoard(table)
println("Player 1 it is your turn. Choose a column 0-7")
playerMove1()
}
//player 2
def player2(){
printBoard(table)
println("Player 2 it is your turn. Choose a column 0-7")
playerMove2()
}
for (turn <- 1 to 32){
player1
player2
}
I've tried to make your code readable and compiling and also tried to fix some logic.
However, I've never worked with Scala so this is just a first sketch where you might want to continue ...
Some functions can be merged and the currentRow needed a fix. See here:
object ConnectFour{
val table = Array.fill(9,8)('-')
val currentRow = Array.fill(8)(8)
def main(args: Array[String]) {
var i = 0;
while(i < 8) {
table(8)(i) = (i+'0').toChar
i = i+1;
}
player(1)
}
def printBoard(table: Array[Array[Char]]) {
table.foreach( x => println(x.mkString(" ")))
}
def player(playerNr : Int){
printBoard(table)
println("Player " + playerNr + " it is your turn. Choose a column 0-7")
var column = readAndVerifyInt
var nextUser = 1 : Int
var symbol = 'O' : Char
if(playerNr == 1) {
symbol = 'X'
nextUser = 2
}
var curR = currentRow(column)
while (curR >= 0) {
if (table(curR)(column) != ('-')) {
curR = curR-1
currentRow(column) = curR
}
table(curR)(column) = symbol
player(nextUser)
}
}
def readAndVerifyInt() : Int = {
var column = readInt
if (column >= 0 && column <= 7) {
return column
} else {
println(" > Please try again")
return readAndVerifyInt
}
}
}