Ocaml - Passing an array as an argument of a function - arrays

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)

Related

How to create an array of squared values of another array

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

F# why arrays are not scrambled in a different way when mapping a function to scramble each array in an array

I wrote a function to scramble an array and map an array of arrays to scramble each one different but they are scrambled the same way
let rand = System.Random()
let shuffle (rand : System.Random)(array :int[] ) = let rng = new Random()
let mutable n = array.Length
while (n > 1) do
let k = rng.Next(n)
n <- n - 1
let temp = array.[n]
array.[n] <- array.[k]
array.[k] <- temp
array
let playsarray = shuffle rand
let scrambledarray = Array.map (fun x -> playsarray x )
let playsarra = fun (array : int[]) -> array |> playsarray
let smallarray = [1..10].ToArray()
let megaarray = Array.create 10 smallarray
let megarrayscrambled = megaarray |> scrambledarray
megarrayscrambled |> Seq.iter (fun y -> printfn "Ar: %A" y)
after running the code all the 10 arrays have the same order in the data ej
Ar: [|5; 1; 7; 2; 8; 10; 6; 3; 9; 4|]
Ar: [|5; 1; 7; 2; 8; 10; 6; 3; 9; 4|] and so on ...
There are two problems with your code.
First, your shuffle function takes a rand parameter but isn't actually using it: inside the function you create a new System.Random instance and use it instead of using the one passed in. The docs for the System.Random constructor mention (in the examples) that the default constructor uses the current time as a seed, so if two Random objects are created in quick succession, they would have the same seed and thus produce the same values. To fix this problem, you just need to stop creating a new Random instance in your shuffle function and instead use the one passed in (I renamed it from rand to rng so that the rest of your code wouldn't need changing). Here's your shuffle function with that change made (and with much easier-to-read indentation: you don't have to start the first line of the function on the same line as the = sign; you can put it on the next line and just indent one indentation level, four spaces):
let shuffle (rng : System.Random) (array : int[]) =
let mutable n = array.Length // The number of items left to shuffle (loop invariant).
while (n > 1) do
let k = rng.Next(n) // 0 <= k < n.
n <- n - 1 // n is now the last pertinent index;
let temp = array.[n] // swap array[n] with array[k] (does nothing if k == n).
array.[n] <- array.[k]
array.[k] <- temp
array
BUT that won't solve your issues just yet, because you've also misunderstood how Array.create works. It creates an array of a given size, where each item in the array contains the value you passed in. I.e., every entry in your megarrayscrambled array contains a reference to the same smallarray. If you did megarrayscrambled.[0].[0] <- 999 you'd see that this changed every one of the ten entries in megarrayscrambled, because they're the same array.
What you actually wanted was to use Array.init, not Array.create. Array.init takes a function and runs that function once per item it's creating in the array you're building. This means that if that function returns [1..10].ToArray(), then each time it's called it will return a different array, and you'll therefore get the results you expect. (By the way, you can create an array more simply by doing [|1..10|], and that's what I'll use in the sample code below).
So just change your let megaarray line to:
let megaarray = Array.init 10 (fun _ -> [|1..10|])
and then you should see the results you were expecting.
BTW, one more little detail: in one line you have Array.map (fun x -> playsarray x), but that is just equivalent to Array.map playsarray, which is a little simpler to read.

how to print Scala user defined Arrays

I tried below code but it ultimately prints 5 zeros after giving the user defined values to array .
the below code takes array of size 5 and gives user defined values
object printarray {
def main(args:Array[String]) {
val arr = new Array[Int](5)
println("the values of array is ")
for(i<-0 to 4) {
val arr = scala.io.StdIn.readInt()
}
arr.foreach(println)
}
}
There are a couple of things that need improvement in the code.
You allocate an array of 5 elements named arr in the scope of the main method, but you also declare an additional value with the same name, arr, inside the for comprehension scope and read an Int into it, which you discard once you exit the for scope. Then, you print the array in the outer scope, which hasn't changed at all.
The first thing you need to make this work, is index into the array instead of creating a new value named arr in the inner scope:
object printarray {
def main(args:Array[String]) {
val arr = new Array[Int](5)
println("the values of array is ")
for (i <- 0 to 4) {
arr(i) = scala.io.StdIn.readInt()
}
arr.foreach(println)
}
}
To improve things further, you use the yield Scala synax to make this more concise:
val arr = for (i <- 0 to 4) yield StdIn.readInt()
This will not return an Array[Int], but an IndexedSeq[Int] with an underlying type of Vector[Int]. If you still want an Array[Int], you'll have to explicitly call toArray:
val arr: Array[Int] = (for (i <- 0 to 4) yield scala.io.StdIn.readInt()).toArray
In your for-loop you are reassigning the variable in every iteration. You can change it to:
for(i <- 0 to 4) {
arr(i) = scala.io.StdIn.readInt()
}
As a side-note, instead of declaring the arr before the loop you can simply do:
val arr = for(i <- 0 to 4) yield scala.io.StdIn.readInt()

Converting an int to bit array in OCaml

I got an int, lets say 6 and I want to convert it to a bit array.
bArr.(0) = 1
bArr.(1) = 1
bArr.(2) = 0
Is there any function that does this for me ?
I needed it to be an array so that I can then pass it to other function that receives a boolean array.
The n-th bit of an integer x can be computed with the following function:
let nth_bit x n = x land (1 lsl n) <> 0
An array can be created and initialized with Array.init function:
let bitarray length x = Array.init length (nth_bit x)
This will create an array of booleans in a LSB (Least Significant Bit) first order. If you need an array of integers, then you can use a function nth_bit_value instead of nth_bit:
let nth_bit_value x n = if nth_bit x n then 1 else 0
I will leave it as an exercise, to get an array in the MSB-order.
let int_to_bArr i =
let rec int_to_bit acc i =
if i=0 then acc
else int_to_bit (i land 1::acc) (i lsr 1)
in
let l=int_to_bit [] i in
Array.of_list l
;;
Test
# int_to_bArr 6;;
- : int array = [|1; 1; 0|]
Or
let int_to_bArr i =
let rec int_to_bool acc i =
if i=0 then acc
else int_to_bool (((i land 1)=1)::acc) (i lsr 1)
in
let l=int_to_bool [] i in
Array.of_list l
;;
# int_to_bArr 6;;
- : bool array = [|true; true; false|]

How do I change the number in an array name based on the variable i in a for loop?

I am trying to, through standard input, get arrays of numbers. this is what the input looks like:
3
11 2 4
4 5 6
10 8 -12
The top number is the integer N, the rows of numbers are arrays. N represents N numbers in each of the N arrays. I want to get each array, and assign it. The thing is, I might not know how many arrays there are. So far, I have this:
var n = Int(readLine()!)!
var arr: [String] = []
for i in 0..<n {
if readLine()! == "\n" || arr.count == 0 {
var arr1 = readLine()!.characters.split(" ").map(String.init)
arr.append(arr1)
}
}
var firstDiag = 0
var secondDiag = 0
for i in 0..<n {
firstDiag += Int(arr[i][i])!
secondDiag += Int(arr[i][n-i-1])!
}
let dif = firstDiag - secondDiag
print(abs(dif))
What I want to change is the variable in the first for loop. Instead of arr1, I want to create an array that is based of of the variable i for that for-loop, like arr<i>, so I have an array of arrays like this:
var arr = [arr0, arr1, arr2]
And so on.
Is there a way to do this in quote, "basic Swift" (whatever that means to you)?

Resources