How to create an array of squared values of another array - arrays

I need to make a method square_array that takes in one argument which is going to be an array. This method needs to loop through the original array and multiply each element with itself then insert the squared value into the new array.
I'm getting an error when doing this array[i] ** 2 = output[i] I think it's because of the equals sign but I'm not sure.
def square_array(array)
i = 0
array = ('1'..'3').to_a
output = []
while i < array.length do
array[i] ** 2 = output[i]
i += 1
end
end
I expect
square_array([1,2,3])
to return
[1,4,9]

When trying to declare a variable or assign a new value to it, it should be on the left side of the equals operator. So if you have a which is 5 and you want to assign the value of a multiplied by 2 to a new variable b you would do:
b = a * 2
and not
a * 2 = b
That's why array[i] ** 2 = output[i] isn't producing the result you expect it to produce.
Looking at your method, a few other things are a bit off:
def square_array(array)
i = 0
array = ('1'..'3').to_a
output = []
while i < array.length do
array[i] ** 2 = output[i]
i += 1
end
end
You accept the array variable as an input, then you overwrite it by doing array = ('1'..'3').to_a (no need to use the single quotes ' when declaring numbers (Integers)) and lose the input value. Usually you'd declare the array outside the method and then pass the value to the method. Something like this:
array = (1..3).to_a
def square_array(array)
i = 0
output = []
while i < array.length do
output[i] = array[i] ** 2 #like explained in the first part
i += 1
end
end
But the method still doesn't return anything, so simply adding output as the last line in the method should solve the problem (remember, Ruby returns the last line of the method even without the return statement).
So something like this:
def square_array(array)
i = 0
output = []
while i < array.length do
output[i] = array[i] ** 2
i += 1
end
output
end
I should also add, there's an easier way to write this method, using the #map function (like #pjs said) for example:
def square_array(array)
array.map{|x| x**2}
end
You can then call the method by doing
square_array(array)

Here, your assignment is mistake,
array[i] ** 2 = output[i]
It should be
output[i] = array[i] ** 2

Related

Ocaml - Passing an array as an argument of a function

I have built a function in which the user will insert the array size and then proceed to insert its values
let array_builder =
let coin = Array.make (10000) 0 in
let number_coins = read_int() in
for i=0 to (number_coins-1) do
let k = read_int() in
coin.(i) <- (k);
done;
The input looks something like this:
3 ---> Array size
10 ---> coin.(0)
9 ---> coin.(1)
8 ---> coin.(2)
Is there anyway to pass the array, coin, as an argument to another function?
In OCaml array are regular value and can be passed to other function without specific syntax.
Maybe you want an example. I have created a dummy function that do like your loop.
let rec array_filler coin_array current_index size =
if current_index < size then
let k = read_int() in
let () = coin_array.(current_index) <- k in
array_filler coin_array (current_index + 1) size
else
coin_array
let array_builder =
let number_coins = read_int() in
let coin = Array.make number_coins 0 in
array_filler coin 0 number_coins
I also switched 2 lines so number_coins is available when creating the array (to not reserve more cell if the user don't need more than 10000)

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
}
}

Code is not executing the else condition in the inner most loop when matching array to array index by index?

var amazon = activeSpreadsheet.getSheetByName('Amazon');
var lastRow1 = amazon.getLastRow();
var array1 = amazon.getRange('A2:A' + lastRow1).getValues();
var source = activeSpreadsheet.getSheetByName('ProductDetails');
var lastRow2 = source.getLastRow();
var array2 = source.getRange('B2:B' + lastRow2).getValues();
n = 2;
x = 0; // match
z = 0; // non-match
for (var i = 0; i < array2.length; i++){
for (var j = 0; j < array1.length; j++){
if (array2[i] !== array1[j]){
z = z + 1;
}
else {
x = 9999
}
}
newsheet.getRange([n],[5]).setValue(z);
newsheet.getRange([n],[6]).setValue(x);
if (z > x) {
newsheet.getRange([n],[1]).setValue(array2[i]);
n == n++;
z = 0;
x = 0;
}
else if (z < x) {
z = 0;
x = 0;
}
}
My project is written in GAS (google app scripts) which is essentially, for all intents and purposes JS with variation in libraries.
Basically I am grabbing an element in the array2 and passing it through a loop to match to array1. For every time it does not match it adds 1, and when it matches (should only match once if it has any matches) it stores an arbitrary large number (larger than length of array1) and compares them.
As you can see I've written out to display these values and I always get z = 5183 (length of array1) and x = 0 (meaning no non-matches found). Therefore even if something exists in array 2 and 1 it will always write it to the cell.
What should happen is if there is a match, z= 5182 and x= 9999 (or arbitrary large number) and since 5182 < 9999 it doesn't do anything.
Is my scope wrong? Or am I not writing the If/Else correctly? Or is it something else?
Your code performs a strict comparison between the elements of two Arrays. That's fine, in general. However, for those specific Arrays those elements are also Arrays, which means strict (in)equality is checking to see if those are the exact same array object in memory. See this question for more information.
You probably wanted to do a value-based comparison, which means you need to compare the specific element of that inner array (i.e., index again). if (array2[i][0] !== array1[j][0]) {...} will check the 1st element of the inner array.
Looking at the instantiation of array1 and array2, we see that these are indeed 2D arrays from a single-column Ranges, so there will be only 1 element in each inner array. You can reduce the level of indexing necessary by flattening these arrays when you read them:
const array1 = sheet.getRange(...).getValues().map(function (row) { return row[0]; });
const array2 = ...;
I'm also not sure why you are passing in arrays to Sheet#getRange - you should pass in 1-4 arguments in manners consistent with the method signatures detailed in the Apps Script documentation.
Note that there are much better algorithms for checking if a value exists in a given array - you re-scan all of the 2nd array for every value of the first array. You should conduct thorough research into this topic before asking a new question on how to improve your algorithm.
Lastly, you should implement the best practice of using batch methods - you currently call setValue in a loop. Consider storing the results to write in an array, and then writing with Range#setValues once your loop has completed. There are many questions available for you to review on this topic.

Scala: Shift elements in an Array

I'm getting used to the various data structures in Scala and I've noticed that this function (contrived example), which is supposed to move every character in the mutable array to the right by one, has no effect on the array:
def shiftRight(str: String): Array[Char] = {
val chars = str.toCharArray
for(i <- chars.length - 1 until 0) chars(i) = chars(i - 1)
chars
}
println(shiftRight("ABCD").mkString)
which produces the result
ABCD
not the expected
AABC
Default step for range is one. See class Range here and implicit that gets you to it here.
Instead of
for(i <- chars.length - 1 until 0)...
you need:
for(i <- chars.length - 1 until 0 by -1)...

Variable dimensions in file don't match with dimension of indexing subscript if one dimension is singleton

I want to test a function func(par1,par2,par3) with all combinations of the parameters par1, par2 and par3 and store the output in a .mat file. My code looks like this at the moment:
n1 = 3;
n2 = 1;
n3 = 2;
parList1 = rand(1,n1); % n1,n2,n3 is just some integer
parList2 = rand(1,n2); % the lists are edited by hand in the actual script
parList3 = rand(1,n3);
saveFile = matfile('file.mat','Writable',true);
% allocate memory
saveFile.output = NaN(numel(parList1),numel(parList2),numel(parList3));
counter1 = 0;
for par1 = parList1
counter1 = counter1 + 1;
counter2 = 0; % reset inner counter
for par2 = parList2
counter2 = counter2 + 1;
counter3 = 0; % reset inner counter
for par3 = parList3
counter3 = counter3 + 1;
saveFile.output(counter1,counter2,counter3) = sum([par1,par2,par3]);
end
end
end
This works except if parList3 has only one item, i.e. if n3 = 1. Then the saveFile.output has singleton dimensions and I get the error
Variable 'output' has 2 dimensions in the file, this does not match the 3 dimensions in the indexing subscripts.
Is there a elegant way to fix this?
The expression in the for statement needs to be a row array, not a column array as in your example. The loops will exit after the first value with your code. Set a breakpoint on the saveFile.output command to see what I mean. With a column array, par1 will not be a scalar as desired, but the whole parList1 column. With a row array, par1 will iterate through each value of parList1 as intended
Another thing is that you need to reset your inner counters (counter2 and counter2) or your second and third dimensions will blow up larger than you expected.
The n3=1 problem is expected behavior because matfile defines the variables with fixed number of dimensions and it will treat saveFile.output as 2D. Once you have fixed those issues, you can solve the n3=1 problem by changing the line,
saveFile.output(counter1,counter2,counter3) = sum([par1,par2,par3]);
to
if n3==1, saveFile.output(counter1,counter2) = sum([par1,par2,par3]);
else saveFile.output(counter1,counter2,counter3) = sum([par1,par2,par3]);
end
By now I realized that actually in matfiles all the singleton dimensions, except for the first two are removed.
In my actual programm I decided to save the data in the file linearly and circumvent matfile's lack of linear indexing capability by using the functions sub2ind and ind2sub.

Resources