code for finding duplicates in an array, Scala - arrays

I'm trying to build a algorithm that can find duplicates in an array, without Using any pre-implemented functions such as "sort" etc.
I have no error but my function does not work… Do you have any idea why? (I'm just starting Scala programming)
def duplicate(s: Array[Int], length: Int): Boolean = {
var i = 0 // start counting at value 0
var j = 0
var result:Boolean = false
var isDupli:Boolean = false
while(j < length && result == false) {
if (s(i) == s(j)) {
isDupli = true
result = true
}
j += 1
}
result
}
var myArray = Array(2,2,2,2)
duplicate(Array(2,2), 2)
I found some code online but people are Using the function sort. My goal is to scroll through the array to find for any duplicates...

Some observations on your code:
You only look at the first (0th) element, and never increment i, so you don't check any of the subsequent elements for duplication.
The length argument is redundant, since we can discover the length of the Array, s, via its .length (or .size) attribute. Using the .length attribute is safer, because it is always valid. For example, duplicate(Array(1, 2, 3, 4, 5, 3), 10) causes an exception (java.lang.ArrayIndexOutOfBoundsException) since the array doesn't have 10 members.
You initialize j to have the same value as i, and then compare s(i) == s(j), so you're always going to get a duplicate on the first element, even if there's no duplication in the array.
You return result (which indicates whether you've found a result), rather than isDupli (which indicates whether you found a duplicate). Fortunately, we only need one of these, since finding a result is the same as finding a duplicate.
Here's another version that fixes these problems, and simplifies some code:
def duplicate(s: Array[Int]): Boolean = {
val length = s.length
var i = 0 // start counting at value 0
var foundDuplicate = false // Type inference means Scala knows this is Boolean
// Loop through each member until we've found a duplicate.
//
// Note that "!foundDuplicate" is the same as "foundDuplicate == false"
while(i < length && !foundDuplicate) {
// Now compare to each of the remaining elements. Start at the element above i.
var j = i + 1
// Loop through each of the remaining elements.
while(j < length && !foundDuplicate) {
// If we find a match, we're done.
if (s(i) == s(j)) {
foundDuplicate = true
}
// Look at the next j
j += 1
}
// Look at the next i
i += 1
}
// Return the result. If we didn't find anything, this will still be false.
foundDuplicate
}
val myArray1 = Array(1, 2, 3, 4, 5, 6, 2, 8, 9)
val myArray2 = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
duplicate(myArray1) // Returns true
duplicate(myArray2) // Returns false
However, while this is perfectly OK procedural code, in Scala we can use a much better functional style. (Procedural code uses vars, while loops, etc. which is frowned upon in Scala.)
import scala.annotation.tailrec
def duplicate(s: Array[Int]): Boolean = {
// Helper function to search the array for matches to element at i
#tailrec // Indicates function is tail recursive.
def matchElement(i: Int): Boolean = {
// Helper function to search for a match in remainder of array.
#tailrec
def matchRem(j: Int): Boolean = {
// If j has reached the end of the array, we had no match.
if(j >= s.length) false
// Otherwise, does this element match the target? Match found.
else if (s(i) == s(j)) true
// Otherwise, look at the next element after j.
else matchRem(j + 1) // Recursive call
}
// If this is the last character of the array, then we can't have a match.
if(i >= s.length - 1) false
// Otherwise did we find a duplicate in the remainder of this array?
else if(matchRem(i + 1)) true
// Otherwise, perform another iteration looking at the next element.
else matchElement(i + 1) // Recursive call
}
// Start the ball rolling by looking at for duplicates of the first character.
matchElement(0)
}
This might look rather complex, at first glance, but note that it doesn't have any var declarations or while loops. Of course, this a roll-your-own solution. There are far simpler methods of achieving this using other Array functions.

In your code the variable isDupli of no use because anyway you are returning result Boolean variable. Also, you are not incrementing variable i. You can use for loop as below:
def duplicate(s: Array[Int], length: Int): Boolean ={
var result:Boolean = false; val r = Range(0,length)
for(i<-r;j<-(i+1) until length; if(s(i)==s(j))) result = true
result
}
In Scala REPL:
scala> duplicate(Array(2,2),2)
res4: Boolean = true
scala> duplicate(Array(2,3),2)
res5: Boolean = false
scala> duplicate(Array(2,3,2),3)
res6: Boolean = true
scala> duplicate(Array(2,3,4),3)
res7: Boolean = false

Related

Kotlin - Find minimum value in an IntArray within range of indices

I am refactoring some older Java code over to Kotlin. There is a function that returns the index of the minimum value held by an element in a Kotlin IntArray within the range [a, b]. The range values default to 0 and the size of the array - 1.
I would like to do something along the lines of...
return data.minOf().indexOf()
...but while only iterating between the a and b indices of data.
Here is the function:
// data is the IntArray property that I'm looping through.
fun absMinIndex(a: Int = 0, b: Int = (data.size - 1)) : Int {
var minVal = data[a]
var minIndex = 0
for (i in (a + 1)..b) {
val e = data[i]
if (e < minVal) {
minVal = e
minIndex = i
}
}
return maxIndex
}
This [for loop] solves the issue nicely by never visiting indices out of range, and by not generating a copied array/sub-array. I'm wondering if it could be done 'prettier'.
Question
Is there a more idiomatic Kotlin approach to iterating through an array within a range that would not negatively impact the performance of my current solution?
Edited some code for clarity.
I believe this approach would be more idiomatic:
Use IntRange as an input parameter
Define extension method for IntArray providing custom iterator to traverse the list in the desired range wrapping values into IndexedValue:
fun IntArray.withIndexInRange(range: IntRange = 0..lastIndex) = Iterable {
require(range.first >= 0 && range.last <= lastIndex)
object : Iterator<IndexedValue<Int>> {
private var index = range.first
override fun hasNext() = index <= range.last
override fun next() = IndexedValue(index, this#withIndexInRange[index++])
}
}
Use minByOrNull method from stdlib to find minimal value or wrap it into another extension method for convenience:
fun <T : Comparable<T>> Iterable<IndexedValue<T>>.indexOfMinOrNull() = minByOrNull { it.value }?.index
Usage:
data.withIndexInRange(a..b).indexOfMinOrNull()
Note, that this will have some performance penalties (creation and GC of N extra objects), but as Donald Knuth says:
Premature optimization is the root of all evil
So, I believe better readability worth it.
As Tenfour04 suggested, not much you can do without loosing performance. But as per your idea with changing the way you call it, you can make it an extension function.
fun IntArray.findIndexOfMinInRange(a: Int = 0, b: Int = this.size - 1): Int {
var maxVal = get(a)
var maxIndex = 0
for (i in (a + 1)..b) {
if (get(i) < maxVal) {
maxVal = get(i)
maxIndex = i
}
}
return maxIndex
}
//and call it like this:
data.findIndexOfMinInRange(0, 15) //or without anything in the parentheses for the default values
One thing that I would change is the variable names inside the function, we are searching for the minimum value, not max, and also for the index of the minimum, not the maximum index. Also maybe (big maybe) creating a val of data[it] instead of accessing it twice might be better (honestly not sure, we would be trading a .get for a few bytes of memory).
So all in all, I'd probably leave it at this:
fun IntArray.findIndexOfMinInRange(fromIndex: Int = 0, toIndex: Int = this.size - 1): Int {
var min = get(fromIndex)
var indexOfMin = fromIndex
for(i in (fromIndex + 1)..toIndex){
val current = get(i)
if (current < min) {
min = current
indexOfMin = i
}
}
return indexOfMin
}
//would be called in the same way the one above
Also, a note of caution, if you create an IntArray of a certain size, and do not populate it in full, the default values it will hold for the non populated ones is 0. If you do:
val data = IntArray(6)
data[0] = 10
data[1] = 11
data[2] = 100
data[3] = 9
data[4] = 50
Then the actual array is [10, 11, 100, 9, 50, 0].

Scala - How do I modify an input array passed to a method by reference?

Problem Statement
I will try to elaborate the case by means of a scenario. Lets take this question for instance.
Link to question: https://leetcode.com/problems/remove-element/
Given an array nums and a value target, remove all instances of
that value in-place and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
Example: Given nums = [0,1,2,2,3,0,4,2], target = 2; the output =
5 (number of elements not equal to target) and modify the array to
[0,1,3,0,4]
The order of elements can be changed. It doesn't matter what you leave
beyond the new length.
My Approach
Step-1: Identify all the elements which are equal to the given target and move them to right hand side of the array while maintaining a counter.
Step-2: Drop all the elements from right.
Step-3: return (n - counter), where n is the array length and counter is the number of elements equal to target.
Below is the implementation of the same:
object RemoveElement {
// Link to question: https://leetcode.com/problems/remove-element/
def main(args: Array[String]): Unit = {
var nums = Array(3,2,2,3)
val target = 3
val result = removeElement(nums, target)
// nums = nums.dropRight(_.equals(target)) // POINT 1
println(s"Result: ${result}, Modified Array: [${nums.mkString(", ")}]")
}
def removeElement(nums: Array[Int], target: Int): Int = {
val n = nums.length
var left, counter = 0
var right = n - 1
while(left < right){
if(nums(left) != target){
left += 1
}
else {
// Find position of the elements which is not equal to target
if(nums(right) == target){
counter += 1
right -= 1
}
else{
// Swap the elements
counter += 1
val temp = nums(left)
nums(left) = nums(right)
nums(right) = temp
left += 1
right -= 1
}
}
}
// nums.dropWhile(_.equals(target)) // POINT 2
// nums = nums.dropRight(_.equals(target)) // POINT 3
return (n - counter)
}
}
POINT - 1: Makes absolute sense as the array nums is in the scope of main method, therefore, the statement would work as charm.
POINT - 2: These lines has no impact to the array nums.
POINT - 3: Gives error. I understand that the input argument (array nums) is of type val (i.e. passed by reference, and hence immutable within the scope of the method removeElement).
If I had an option of creating a new array, there wouldn't be any issue. But if I am required to return the modified array by adding/removing the elements (like in this question) to the calling method, how do I achieve that in Scala?
To make the case more generic, what is the way by which we can modify the input collections (passed as arguments) in Scala methods?
P.S.: If I do not remove elements from the input array itself, LeetCode fails my submission with below message:
How do I modify an input array passed to a method by reference?
Scala does not support pass-by-reference. The default is pass-by-value (or more precisely, a special case of pass-by-value which is sometimes known as call-by-object, call-by-sharing, or call-by-object-sharing). Scala also supports call-by-name.
So, you simply cannot pass an array to a method by reference in Scala. You will have to use another language which supports pass-by-reference such as C# (with the ref keyword) or C++. (Note that Java also doesn't support pass-by-reference.)
Something like this
object Solution {
def removeElement(nums: Array[Int], `val`: Int): Int = {
var p: Int = 0
nums.foreach(v => {
if (v != `val`) {
nums(p) = v
p += 1
}
})
p
}
}

Delete occurrences of an element if it occurs more than n times - my own code

function deleteNth(arr,n){
let a = [];
let num_string;
arr.forEach(function(num) {
for (let i = 0; i < arr.length; i++) {
if (num === arr[i]) {
num_string++;
}
if (num_string < n+1) {
a.push(num);
}
}
});
return a;
a.length = 0;
}
I have to created a program that returns a new array without the array variable and that returns more than n times. The computer returns an error.
I believe this would solve your problem. I included some comments, please reply if you would like further clarifications.
function filterOccurrences(arr, n) {
// Object to store occurrences of values
const occ = {};
// Return array after filter
return arr.filter(val => {
// If occurances object already contains current value
if (occ[val]) {
// Add +1 count to number of occurances of value
occ[val]++;
} else {
// Else add key with count 1
occ[val] = 1;
}
// Return boolean whether to include current value or not
return occ[val] <= n;
});
}
const sample = [1, 2, 2, 3, 3, 3, 3, 3, 3];
console.log(filterOccurrences(sample, 2));
// => [ 1, 2, 2, 3, 3 ]
There are a few problems with the code you have provided, for example a.length = 0; will never be reached because it's below the return statement.
Explanation
occ is a javascript object that stores values by named keys, if your unsure of how they work, read more here.
Filter is a method that loops through each value of an array and expects to be returned either true or false for each value. If the result is true, the value will be kept, else ignored.
So when we loop through each value, we first check if occ has a key by name of that value. For example, for value 1 we would check if occ.1 exists, but since the value is in an array we access it by wrapping the array in brackets, as occ[val]. If it does not exist, we give the occurrences object a key by that name and assign it a value of 1, since it's the first occurrence. But if we found that the value already has a key in the occ object, we instead increase that value by 1 with the ++ operator. So a second occurrence would increase the count to 2, third to 3, etc.
Lastly we return the result of testing if the count of occurrences are less then or equal to n (the max occurrences allowed). If above, will return false and the value will be not be kept in the array.

Give an O(N) algorithm to rearrange a list of true/false so that all false elements precede the true

I have an array of N elements containing only two distinct keys, true and false. I am trying to write an O(N) algorithm to rearrange the list so that all false elements precede the true elements. A specific requirement for this algorithm is that I can only traverse the array once (meaning I can NOT make two traversals over the array; once to count the number of true/false's and another time to assign values into the array). I am also not allowed to create an external temporary array.
Originally I wanted to use counting sort, but realized I could not do this since the requirement for this assignment is that I cannot create an external/temporary array.
Then, since there are only two possible values, I wanted to iterate through once and count them. Then Iterate through a second time and set the ordering (do the sort). However, I cannot do this either because I am only allowed to do one iteration.
So I am on my own trying to implement an algorithm that will iterate only once through the array and sort at the same time. So far what I have come up with is below (this is just an idea written more or less as pseudocode)
array = T T T T F F F F
int len = length of array.
counter = 0
For item in array
counter += 1
If counter <= len/2
if T change to F
else
if F change to T
Right as I completed this, I realized that this only works when all the T values are on one side of the array, and all the F values are on the other.
My question is, can somebody tell me which O(n) sorting algorithm I can use to sort through each item in the array and arrange it so that all of the false elements precede the true?
You can try the idea of the quick sort: walk through the array from the start and the end at the same time, and swap elements that have incorrect order. I.e. if you found true in the left half of the array, swap it with false in the right half.
Cause you have only 2 different values it's enough the single pass.
Example:
bool[] array = ...;
int low = 0;
int high = array.Length - 1;
do
{
while (array[low] == false)
low++;
while (array[high] == true)
high--;
if (low <= high)
{
bool temp = array[low];
array[low] = array[high];
array[high] = temp;
}
}
while (low < high);
This gives you exactly single pass, i.e. O(N).
Keep an index (lastFalseIdx) where to insert a False element. So, initially it is 0. Traverse the array from left to right, and if False found, swap it with element at lastFalseIdx, and increment the index.
Python (almost pseudo-code):
arr = [True, True, False, False, False, True]
print arr
lastFalseIdx = 0
for idx, val in enumerate(arr):
if val == False:
arr[lastFalseIdx], arr[idx] = arr[idx], arr[lastFalseIdx] # swap elements
lastFalseIdx = lastFalseIdx + 1
print arr
Demo
Here is a partial solution that constructs the correct output in a separate array. You can infer an inline implementations by observing what happens when you initialize output = input instead.
#!/usr/bin/python
input = [False, True, False, False, True, True, False, True, False]
def sort2(input):
i_false = 0
i_true = len(input) - 1
output = [None] * len(input)
for (i, val) in enumerate(input):
if val:
output[i_true] = True
i_true -= 1
else:
output[i_false] = False
i_false += 1
return output
print sort2(input)
After a single forward pass through the array, you have the desired output.
Concisely:
swap = 0
for index in range(len(list)):
if list[index] != true:
list[index], list[swap] = list[swap], list[index]
swap += 1
hope the below answer helps.
internal void ArrangeBooleanArray()
{
bool[] inputArray = {false, true, true, false};
int arrayLength = inputArray.Length;
bool[] outputArray = new bool[arrayLength];
int trueCount = 0;
int falseCount = 0;
foreach (var item in inputArray)
{
if (item == true)
{
trueCount++;
outputArray[arrayLength - trueCount] = item;
}
else
{
outputArray[falseCount] = item;
falseCount++;
}
}
}

scala searching nested arrays

I'm trying to search a nested array of characters for a specific character, and then return the indices of the character from the array.
Code Snippet
def search(target: Char, arr:Array[Array[Char]]): List[Int] = {
for (i <- 0 until arr.length) { //search through first layer of array
for (j <- 0 until arr(i).length) { //search through second layer of array
if (arr(i)(j) == target) {
val x = List(i,j)
return x
} }}}
However, I'm getting an error from compilation, that says this function is returning the two type signature. Error message:
error: type mismatch;
found : Unit
required: List[Int]
for (i <- 0 until arr.length) { //search through first layer of array
^
I've found two similar threads here: found Unit: required Int. Why is the error not obvious?
and found: Unit required: Int - How to correct this?
but they don't solve the problem i'm facing: I am trying to return the List, but the compiler is getting stuck at the for loop..
Seems like there are a lot of answers already, but I think that this is the most idiomatic way to approach the problem:
The Code
def search(target: Char, arr: Array[Array[Char]]): List[(Int, Int)] = {
val indices = for{
(a, i) <- arr.iterator.zipWithIndex
(c, j) <- a.iterator.zipWithIndex
if( c == target )
} yield i -> j
indices.toList
}
The Explanation
In scala, for-comprehensions are nestable, so you can take care of any degree of nested arrays by simply adding another x <- y line. You can introduce filtering with an if statement inside of the for{...}.
In the comprehension, a is the ith array inside arr, where i is the first index. c is the jth character inside a, where j is the second index. I use iterator so that indices can be evaluated on the fly, without needing to copy the arrays behind the scenes because of the for-comprehension. At the end, I call toList to evaluate the results of the indices iterator into a list.
The return type, List[(Int, Int)] is a list of pairs. It makes more sense to return List( (1,2), (3,4) ) if you found your target at i=1, j=2 and i=3, j=4 than to return List(1,2,3,4).
General Thoughts
Try to avoid using return in scala. You can usually handle your collections with an iterator-like approach, using yield, and then evaluate the result by calling a toList or toMap or toWhatever.
The scala collections API is very helpful for many of these cases, too. In the case where you just want the first item that matches a condition, you can use myCollection.find(...). Explore the scala docs to see the huge variety of convenient functions that are already available to you.
I would suggest using a less Java-like approach altogether. I'm not entirely sure what your function is supposed to do, but if you want a list of all (x, y) indices of the match within the nested array, you could do something like this:
def search(target: Char, array: Array[Array[Char]]): Seq[(Int, Int)] = {
array.zipWithIndex.filter(_._1.contains(target)).map { xa =>
xa._1.zipWithIndex.filter(_._1 == target).map(xb => (xa._2, xb._2)).toSeq
}.flatten.toSeq
}
which behaves like this:
val t = Array(
Array('a', 'b', 'c'),
Array('b'), Array('c', 'a'),
Array('a', 'a', 'x', 'a')
)
println(search('a', t))
=> ((0,0), (2,1), (3,0), (3,1), (3,3))
Here is my solution to find the first index of a element in a two-dimension array:
(replace collectFirt to collect, if you wan to find all indexes)
def search[T](target: T, arr: Array[Array[T]]): List[Int] =
arr.indices.collectFirst{
case k if arr(k).contains(target) =>
List(k, arr(k).indexWhere(_ == target))
}.getOrElse(Nil)
Test:
scala> val t = Array(
| Array('a', 'b', 'c'),
| Array('b'),
| Array('c', 'a'),
| Array('a', 'a', 'x', 'a')
| )
scala> println(search('a', t))
List(0, 0)
scala> println(search('x', t))
List(3, 2)
scala> println(search('e', t))
List()
You only return a List if a particular condition is met (arr(i)(j) == target). You have to define a return value for the case that the for comprehensions run through. E.g.
def search(target: Char, arr:Array[Array[Char]]): List[Int] = {
for (i <- 0 until arr.length) { //search through first layer of array
for (j <- 0 until arr(i).length) { //search through second layer of array
if (arr(i)(j) == target) {
val x = List(i,j)
return x
}
}
}
Nil // not found
}
The for loop itself would return Unit if the second array is empty or the if expression evaluates to false. You could rewrite it so it returns null if it nevers gets to the code after the if-expression.
I would leave out the assignment of x too, there's really no point.
def search(target: Char, arr:Array[Array[Char]]): List[Int] =
{
for (i <- 0 until arr.length)
{ //search through first layer of array
for (j <- 0 until arr(i).length)
{ //search through second layer of array
if (arr(i)(j) == target)
{
return List(i,j)
}
}
}
Nil
}
Btw this could probably be rewritten with a more functional approach but that goes beyond the scope of this question.

Resources