how would i convert this from a constant to a variable array? - arrays

Uses Graph;
Const Triangle : Array [1..3] Of PointType =
((X: 50; Y: 100),
(X: 100; Y: 100),
(X: 150; Y: 50));
Var Gd, Gm : smallint;
Begin
Gd:=Detect;
InitGraph(Gd, Gm, '');
If GraphResult <> grOk Then Halt(1);
SetFillStyle(7,0);
SetColor(14);
FillPoly(SizeOf(Triangle) Div SizeOf(PointType), Triangle);
ReadLn;
CloseGraph;
End.
I want to be able to input a value for the triangle so the user can move it arround, but it is a constant so that isn't possible unless there is a way to convert this to a variable.

For FreePascal:
Just replace "const" by "var". You can initialize global variables, even complex variables like this one, in this manner, the variable will take this value at the beginning of your program, until you change it.
For TurboPascal:
Constant arrays aren't really constants and you can modify them all you want. For instance, you can do:
Triangle[1].X := 500;
at the beginning of the program and it'll work just fine. See this related question for more details.

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.

Non-scalar enumeration in Matlab

Is it possible to have enumeration member that are non-scalar?
For example, how can I enumerate colors such that each color is a 1x3 double (as needed for plots), without using methods?
With the following class definition
classdef color
properties
R, G, B
end
methods
function c = color(r, g, b)
c.R = r;
c.G = g;
c.B = b;
end
function g = get(c)
g = [c.R, c.G, c.B];
end
end
enumeration
red (1, 0, 0)
green (0, 1, 0)
end
end
I can write color.green.get() to get [0 1 0], but I would like the same result with color.green to make the code cleaner.
A different solution may be setting color as a global struct, but it's not practical because global variables can cause confusion and I have to write global color; in each script/function.
I'm not sure exactly what you're asking here, but I think the main answer is that you're currently doing basically the right thing (although I'd suggest a few small changes).
You can certainly have non-scalar arrays of enumeration values - using your class, for example, you could create mycolors = [color.red, color.green]. You can also have an enumeration with non-scalar properties, such as the following:
classdef color2
properties
RGB
end
methods
function c = color2(r, g, b)
c.RGB = [r,g,b];
end
end
enumeration
red (1, 0, 0)
green (0, 1, 0)
end
end
and then you could just say color2.red.RGB and you'd get [1,0,0].
But I'm guessing that neither of those are really what you want. The thing that I imagine you're aiming for, and unfortunately what you explicitly can't do, is something like:
classdef color3 < double
enumeration
red ([1,0,0])
green ([0,1,0])
end
end
where you would then just type color3.red and you'd get [1,0,0]. You can't do that, because when an enumeration inherits from a built-in, it has to be a scalar.
Personally, I would do basically what you're doing, but instead of calling your method get I would call it toRGB, so you'd say color.red.toRGB, which feels quite natural (especially if you also give it some other methods like toHSV or toHex as well). I'd also modify it slightly, so that it could accept arrays of colors:
function rgb = toRGB(c)
rgb = [[c.R]', [c.G]', [c.B]'];
end
That way you can pass in an array of n colors, and it will output an n-by-3 array of RGB values. For example, you could say mycolors = [color.red, color.green]; mycolors.toRGB and you'd get [1,0,0;0,1,0].
Hope that helps!

writing methods in f#

I have a question:
There is such a method in C:
inline void ColorSet(int face, int pos,int col)
{
color[face*9+pos]=col;
}
I've tried to write it in F#;
type ColorSet =
member this.ColorSet (face: int, pos: int, col: int) =
color.[face*9+pos] = col
but I encountered with such an error:
The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints...
Could you help me to write the exact method?
Reading the comments, it seems you may be trying to do this:
let itemCount = 9
let faceCount = 6
let color : int [] = Array.zeroCreate (faceCount * itemCount)
let setColor face pos col =
color.[face * itemCount + pos] <- col
Two things to note:
The object of indeterminate type error can usually be solved with a type annotation: by declaring color as : int [], it is specified that color must be an array of integers
The operator = is a test for equality in F#. To assign to a mutable variable or an array component, use <-.
Usage might look like this:
let red = 0xFFFF0000 // Assuming ARGB (machine endianness)
setColor 0 8 red // Set the last component of the first face to red
Note that this is unusual style for F#. I do use code like this, but only if it is known to be performance critical and the compiler can't optimize it. Normally, you would use a type for color, e.g. System.Drawing.Color for compatibility, and a type for the objects iterated by the face parameter.
Edit Are you storing the colors of 6 faces of dice or cuboids interleaved in an array? Just in case someone is interested, I'll assume that and write how it might look in more typical F#. I don't know if this is relevant, but I guess it can't hurt to add it.
/// A color, represented as an int. Format, from most to least
/// significant byte: alpha, red, green, blue
type Color = Color of int
let black = Color 0xFF000000
let red = Color 0xFFFF0000
type CubeColors =
{ Top : Color; Bottom : Color
Left : Color; Right : Color
Front : Color; Back : Color }
/// Creates CubeColors where all faces have the same color
static member Uniform c =
{ Top=c; Bottom=c; Left=c
Right=c; Front=c; Back=c }
// Make an array with nine completely black cubes
let cubes = Array.create 9 (CubeColors.Uniform black)
// Change the top of the second cube to red
cubes.[1] <- { cubes.[1] with Top = red }
This uses a single-case discriminated union for the Color type and a record for the CubeColors type. This is much safer to use, and often more readable, than doing low-level array stuff.
You should define color somewhere in the class constructor.
For example if color is an array:
type ColorSet() =
let color = Array.zeroCreate 100
member this.ColorSet (face: int, pos: int, col: int) =
color.[face*9+pos] <- col

How to make dynamic array constant?

There is any way of making x array constant after the data is read from user? There is any way of making variable not modifiable after it's value is read from user (eg. y)?
program hmm;
uses crt;
var
i, y: word;
x: array of word;
begin
readln(y);
y:=y-1;
SetLength(x,y);
for i := 0 to y do begin
read(x[i]);
end;
readkey;
end.
To make y constant I tried something like this, but it won't work - y will be set as 0.
program hmm;
uses crt;
var
i: word;
x: array of word;
const
{$J+}
y:word = 0;
{$J-}
begin
{$J+}
readln(y);
y:=y-1;
{$J-}
y:=0;
SetLength(x,y);
for i := 0 to y do begin
read(x[i]);
end;
readkey;
end.
Thanks for help.
Yes. Don't change either of them in your code after you set the initial value.
Other than that, there's no way. A dynamic array by definition is changeable, and so is a variable - that's why they have dynamic and variable as names.

MATLAB min(array) gives index exceeds array dimensions [duplicate]

This question already has an answer here:
sum(Array) says index exceeds matrix dimensions [duplicate]
(1 answer)
Closed 3 years ago.
I am trying to find the minimum value of a function of two variables, and then find the value of the variables.
My method is to iterate the function through several values of the variables and then use the min function to find the lowest value.
minval = -10;
maxval = 10;
n = 1;
for x = minval:maxval
for y = minval:maxval
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
n=n+1;
end
end
f(n) = abs(x-1)+abs(y-1)+abs(x-3)+abs(y-5)+abs(x-8)+abs(y-3);
fmin = min(f)
The problem is with the last line:
fmin = min(f)
I am getting the error
??? Index exceeds matrix dimensions.
Error in ==> Lab2 at 65
fmin = min(f)
Why is this? Any help is greatly appreciated.
Don't define a variable named min. Try this:
which min
What does it tell you?
Note that functions in MATLAB can be overloaded by creating variables with the same name. When you do so, you prevent the function from being accessed by MATLAB. This is RARELY a good idea, so don't do it. The solution is
clear min
So you will delete that variable you have created. Of course, if there was something important in that variable, stuff it somewhere else first.
It does indeed look like you have declared a variable called min and so Matlab now treats it like a variable and not a function so it thinks you are trying to index the variable min with the vector f.
But just a comment on your code, leaving off whatever f(442) is you could achieve the same thing in a much more matlabesque fashion without loops like this:
minval = -10;
maxval = 10;
X = minval:maxval;
Y = X;
[xx, yy] = meshgrid(X, Y);
F = abs(xx-1) + abs(yy-1) + abs(xx-3) + abs(yy-5) +abs(xx-8) + abs(yy-3);
Your f is now equivalent to F(:)' (without the final value...), prove it to yourself like this: sum(f(1:end-1) == F(:)')
F as a matrix probably makes more sense than f as a flat vector anyway and you can find the min of F like this: min(F(:))
This code runs perfectly when I plug it into my version of Matlab.
If the error is occuring on line 65, then there must be something else going on in your program. Try and turn this part of your program into a function, so that it won't be impacted by everything else that you're working on.

Resources