Array is filled with undefined values (Erlang) - arrays

Updated Question; Original below.
I am trying to create an array which represents a grid of cells, which have tuples containing the walls they are surrounded by.
I have come up with this:
rooms(Array) ->
Size = array:size(Array),
if
Size == ?HSIZE * ?VSIZE ->
Array;
true ->
HFactor = Size rem ?VSIZE,
VFactor = Size div ?HSIZE,
Room = {1+HFactor+11*VFactor,
7+HFactor+11*VFactor,
12+HFactor+11*VFactor,
6+HFactor+11*VFactor},
rooms(array:set(Size, Room, Array))
end.
When I run this with rooms(array:new()). I get the following array back:
{array,25,100,undefined,
{{{1,7,12,6},
{2,8,13,7},
{3,9,14,8},
{4,10,15,9},
{5,11,16,10},
{12,18,23,17},
{13,19,24,18},
{14,20,25,19},
{15,21,26,20},
{16,22,27,21}},
{{23,29,34,28},
{24,30,35,29},
{25,31,36,30},
{26,32,37,31},
{27,33,38,32},
{34,40,45,39},
{35,41,46,40},
{36,42,47,41},
{37,43,48,42},
{38,44,49,43}},
{{45,51,56,50},
{46,52,57,51},
{47,53,58,52},
{48,54,59,53},
{49,55,60,54},
undefined,undefined,undefined,undefined,undefined},
10,10,10,10,10,10,10,10}}
Which is quite close to the desired result, but there are two things I can't quite put my finger on (The numbers are correct). Why does it look like it is split up into multiple subarrays? What are those undefineds and 10's doing there? These are mostly due to my lack of erlang knowledge, because array:get produces the expected results, but I couldn't find anything which explains where they come from.
Original Question
rooms(Array) ->
Size = array:size(Array),
if
Size == 5 ->
Array;
Size rem 5 == 0 ->
rooms(array:set(Size, array:new(), Array));
true ->
In_Array = array:get(array:size(Array), Array),
In_Size = array:size(In_Array),
Room = {1+In_Size+11*In_Size,
7+In_Size+11*In_Size,
12+In_Size+11*In_Size,
6+In_Size+11*In_Size},
New_In = array:set(In_Size, Room, In_Array),
rooms(array:set(Size, New_In, Array))
end.
I call it with rooms(array:new()). but the result is
** exception error: bad argument
in function array:size/1 (array.erl, line 317)
in call from framework_kamer:rooms/1 (framework_kamer.erl, line 195)
Which makes sense because In_Array is not an array, but undefined. However, I can't figure out why.
Side question, is there an easier/cleaner/better way to do this?

You are (in the second call of the recursion) trying
In_Array = array:get(array:size(Array), Array),
As array is zero-indexed this will always fail, as the access will be always be off by one. Change this line to
In_Array = array:get(array:size(Array) - 1, Array),
and you are fine.
A few comments on your code:
Conventional variable naming in Erlang would be CamelCase without underscores (i.e. InArray)
Expressing a 2-dimensional array as nested arrays is almost never a good idea. Linearalise it by writing simple wrappers that recalculate a one-dimensional index from x and y as index = y * max_x + x.

Related

Shifting array to left or right OCaml

I'm having some trouble around arrays in OCaml.
Namely, I want to just shift the elements to the right or left based on a value I pass.
Example: # let a = [|1;2;3;4;5|], # shift_array a 7;;- : int array array = [|4;5;1;2;3|]
I wrote the following code but I keep getting a syntax error where the second array is formed.
let shift_array arr x =
let size = Array.length arr in
let sec_arr = Array.make size 0 in
for i = 0 to size - 1 do
if i < x
then (sec_arr.(size - x + 1) <- arr.(i))
else (sec_arr.(i-x) <- arr.(i))
done;;
I'm just not 100% sure how to print out the new array.
EDIT: fixed it by adding in to the second and third line.
The problem now is that the function has type int array -> int -> unit and the one I'm trying to get is 'a array -> int -> 'a array. Is there some way to work around that ?
It should be let size = Array.length arr in, notice the in, which you're missing.
The let expression in OCaml has the form let <var> = <expr> in <body> and should not be (but commonly is) confused with the let definition that can occur only on the top-level (as an element of a module), which has form let <name> = <body>.
In your example, you have both, the top-level definition, let shift_array = <body> and two let expressions (though, you have used the wrong syntax for them.
EDIT:
Since OP edited the post, here is the corresponding edit.
You function doesn't return anything, it creates a new array, does the cycle, but doesn't return anything but the unit value (which is the value to which the for cycle evaluates). So you have to add one more line, that will contain the expression, to which the whole function will evaluate. Hint the sequencing operator ; is what you need, when you have expression x;y;z the computer evaluates x, then y, and finally z and the value of the whole expression of x;y;z is the value of z.

What is the point of cell indexing in MATLAB

The point of indexing is mainly to get the value. In MATLAB,
for a cell array, there is content indexing ({}), and thus cell indexing (()) is only for selecting a subset from the cell array, right?
Is there anything other advanced usage for it? Like using it as
a pointer and pass it to a function?
There is a heavily simplified answer. {}-indexing returns you the content, ()-indexing creates a subcell with the indexed elements. Let's take a simple example:
>> a=x(2)
a =
[2]
>> class(a)
ans =
cell
>> b=x{2}
b =
2
>> class(b)
ans =
double
Now continue with non-scalar elements. For the ()-indexing everything behaves as expected, you receive a subcell with the elements:
>> a=x(2:3)
a =
[2] [3]
The thing really special to Matlab is using {}-indexing with non-scalar indices. It returns a Comma-Separated List with all the contents. Now what is happening here:
>> b=x{2:3}
b =
2
The Comma-Separated List behaves similar to a function with two return arguments. You want only one value, only one value is assigned. The second value is lost. You can also use this to assign multiple elements to individual lists at once:
>> [a,b]=x{2:3} %old MATLAB versions require deal here
a =
2
b =
3
Now finally to a very powerful use case of comma separated lists. Assume you have some stupid function foo which requires many input arguments. In your code you could write something like:
foo(a,b,c,d,e,f)
Or, assuming you have all parameters stored in a cell:
foo(a{1},a{2},a{3},a{4},a{5},a{6})
Alternatively you can call the function using a comma separated list. Assuming a has 6 elements, this line is fully equivalent to the previous:
foo(a{:}) %The : is a short cut for 1:end, index the first to the last element
The same technique demonstrated here for input arguments can also be used for output arguments.
Regarding your final question about pointers. Matlab does not use pointers and it has no supplement for it (except handle in oop Matlab), but Matlab is very strong in optimizing the memory usage. Especially using Copy-on-write makes it unnecessary to have pointers in most cases. You typically end up with functions like
M=myMatrixOperation(M,parameter,parameter2)
Where you input your data and return it.

How to re-arrange elements of Array after Deleting

Recently I was reading a Programming book and found this question:
I have an array :
array = [2,3,6,7,8,9,33,22];
Now, Suppose I have deleted the element at 4th position i.e. 8 .
Now I have to rearrange the array as:
Newarray = [2,3,6,7,9,33,22];
How Can I do this. And I have to also minimize the complexity.
Edit I have no choice to make another copy of it.I have to only modify it.
You can "remove" a value from an array by simply copy over the element by the next elements, that's easy to do with memmove:
int array[8] = {2,3,6,7,8,9,33,22};
memmove(&array[4], &array[5], sizeof(int) * 3);
The resulting array will be {2,3,6,7,9,33,22,22}.
And from that you can see the big problem with attempting to "remove" an element from a compile-time array: You can't!
You can overwrite the element, but the size of the array is fixed at time of compilation and can't actually be changed at run-time.
One common solution is to keep track of the actual number of valid elements in the array manually, and make sure you update that size as you add or remove elements. Either that or set unused elements to a value that's not going to be used otherwise (for example if your array can only contain positive numbers, then you could set unused elements to -1 and check for that).
If you don't want to use a library function (why not?) then loop and set e.g.
array[4] = array[5];
array[5] = array[6];
and so on.
Do this, just use these two functions and it will work fine
index=4;//You wanted to delete it from the array.
memcpy(newarray,array,sizeof(array));
memmove(&newarray[index], &newarray[index + 1], sizeof(newarray)-1);
now the newarray contains your exact replica without the character that you wished to remove
You can simply displace each element from the delIdx(deletion index) one step forward.
for(int i=delIdx; i<(arr_size-1);i++)
{
arr[i]= arr[i+1];
}
If required you can either set the last element to a non-attainable value or decrease the size of the array.

Number sequences length, element first and last indexes in array

Im beginner in programming. My question is how to count number sequences in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output integer = 3 (count one-sequences)
And how to calculate number sequences first and last indexes in input array? For example:
input array = [0,0,1,1,1,1,1,1,0,1,0,1,1,1]
output array = [3-8,10-10,12-14] (one first and last place in a sequence)
I tried to solve this problem in C with arrays. Thank you!
Your task is a good exercise to familiarize you with the 0-based array indexes used in C, iterating arrays, and adjusting the array indexes to 1-based when the output requires.
Taking the first two together, 0-based arrays in C, and iterating over the elements, you must first determine how many elements are in your array. This is something that gives new C programmers trouble. The reason being is for general arrays (as opposed to null-terminated strings), you must either know the number of elements in the array, or determine the number of elements within the scope where the array was declared.
What does that mean? It means, the only time you can use the sizeof operator to determine the size of an array is inside the same scope (i.e. inside the same block of code {...} where the array is declared. If the array is passed to a function, the parameter passing the array is converted (you may see it referred to as decays) to a pointer. When that occurs, the sizeof operator simply returns the size of a pointer (generally 8-bytes on x86_64 and 4-bytes on x86), not the size of the array.
So now you know the first part of your task. (1) declare the array; and (2) save the size of the array to use in iterating over the elements. The first you can do with int array[] = {0,0,1,1,1,1,1,1,0,1,0,1,1,1}; and the second with sizeof array;
Your next job is to iterate over each element in the array and test whether it is '0' or '1' and respond appropriately. To iterate over each element in the array (as opposed to a string), you will typically use a for loop coupled with an index variable ( 'i' below) that will allow you to access each element of the array. You may have something similar to:
size_t i = 0;
...
for (i = 0; i< sizeof array; i++) {
... /* elements accessed as array[i] */
}
(note: you are free to use int as the type for 'i' as well, but for your choice of type, you generally want to ask can 'i' ever be negative here? If not, a choice of a type that handles only positive number will help the compiler warn if you are misusing the variable later in your code)
To build the complete logic you will need to test for all changes from '0' to '1' you may have to use nested if ... else ... statements. (You may have to check if you are dealing with array[0] specifically as part of your test logic) You have 2 tasks here. (1) determine if the last element was '0' and the current element '1', then update your sequence_count++; and (2) test if the current element is '1', then store the adjusted index in a second array and update the count or index for the second array so you can keep track of where to store the next adjusted index value. I will let you work on the test logic and will help if you get stuck.
Finally, you need only print out your final sequence_count and then iterate over your second array (where you stored the adjusted index values for each time array was '1'.
This will get you started. Edit your question and add your current code when you get stuck and people can help further.

Usage of empty array allocation for custom class

Say, we have a class Car
classdef Car < handle
properties
wheels = 4;
end
methods
function obj = Car()
end
end
end
We can create ten cars like so
cars = Car.empty();
for ii = 1:10
cars(end+1) = Car;
end
However, one can make an empty array of cars first
>> cars = Car.empty(0,10)
cars =
0x10 Car array with properties:
wheels
What I do not understand: If one now puts a single car in it, the array seems to shrink to a single element
>> cars(1) = Car
cars =
Car with properties:
wheels: 4
So, does allocating such an empty array make any sense? What are the use cases?
First of all, note that your question is not directly related to custom classes - you can do this with any MATLAB variable type. For example,
>> a = double.empty(0,10)
a =
Empty matrix: 0-by-10
So your questions are
What I do not understand: If one now puts a single car in it, the array seems to shrink to a single element
Well no, it has grown to a single element. I guess there is an ambiguity here, in that you might expect it to grow not to a 1x1 array but to a 1x10 array, with the other nine elements that weren't directly assigned being set to default (i.e. zero in the case of doubles or other numbers, or to a default element in the case of a custom class). However, I think the only thing to say there is that that's not what MATLAB does.
does allocating such an empty array make any sense? What are the use cases?
The use cases are very few in general, really just edge cases. The capability of having arrays of with zero-length dimensions is obviously required to be there for consistency, but an array of 0x10 is rarely much different in behaviour from an array of 0x0.
If I have an array that may vary in height but will always be 10 wide, I might predefine it as 0x10 rather than 0x0, just to leave myself a reminder in the code of that fact.
Also note that there are differences in behaviour between [] and double.empty(0,0). For example
>> a = rand(4,2)
a =
0.83625 0.19468
0.58508 0.12698
0.44332 0.8509
0.51858 0.3673
>> a(2,:) = []
a =
0.83625 0.19468
0.44332 0.8509
0.51858 0.3673
>> a(2,:) = double.empty(0,0)
Subscripted assignment dimension mismatch.
>> a(2,:) = double.empty(0,2)
Improper assignment with rectangular empty matrix.
This is because = [] is a special piece of MATLAB syntax that is used for deleting rows, rather than literally constructing the empty array and then assigning it. So there's another use case there, i.e. preventing accidental deletion of rows.
This is not a problem related to object programming but a normal behavior which is more general in Matlab.
For instance:
>> a = NaN(0,10);
>> a(1) = 5;
>> a
a =
5
When you define an array of size 0xn Matlab does not allocate any memory to it, since there is no element. So a call to empty(0,10) should not be considered as a pre-allocation.
When you define the first element of the array, you force a resizing, and during resizing Matlab always adopts the minimal possible size for the array.
The empty syntax is useful to define an array that will be filled by aggregation in a loop with the end+1 syntax, for instance:
a = NaN(0,2);
for i = 1:10
a(end+1,:) = [i i^2];
end
Best,

Resources