Index out of range? - arrays

Below are two 2D objects, Array and Vector. As you can see the information described in both is identically. My game works flawlessly using the Array object, but with Vector is throws the following error:
[Fault] exception, information=RangeError: Error #1125: The index 10 is out of range 10.
var _platformMap:Array = [
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
[00, 00, 10, 10, 10, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 10, 00, 00, 00, 10],
[10, 10, 10, 00, 00, 10, 10, 10, 10, 10],
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
[10, 10, 00, 00, 00, 00, 00, 10, 10, 10],
[10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
[00, 00, 00, 00, 00, 00, 00, 00, 00, 00]
];
var _platformMap:Vector.<Vector.<int>> = Vector.<Vector.<int>>(
[
Vector.<int>([10,10,10,10,10,10,10,10,10,10]),
Vector.<int>([00,00,10,10,10,10,10,10,10,10]),
Vector.<int>([10,10,10,10,01,01,01,10,10,10]),
Vector.<int>([10,10,10,00,10,10,10,10,01,10]),
Vector.<int>([10,10,10,00,10,10,01,01,01,00]),
Vector.<int>([10,10,10,10,01,01,01,01,01,10]),
Vector.<int>([00,00,00,00,00,10,10,10,10,10]),
Vector.<int>([00,00,00,00,00,00,00,00,00,00])
]
);
I read about that Vector objects have runtime range checking (or fixed-length checking) besides Arrays. Could this be the problem?
public class TileCollisionController
{
private var _softPlatformOpen:Boolean = true;
private var _elevatorOpen:Boolean = true;
public function TileCollisionController()
{}
public function platformCollision(gameObject:TileModel, platformMap:Vector.<Vector.<int>>, maxTileSize:uint, platform:uint):void
{
var overlapX:Number;
var overlapY:Number;
//check top-left corner
if (platformMap[gameObject.top][gameObject.left] == platform)
{
overlapX = gameObject.xPos % maxTileSize;
overlapY = gameObject.yPos % maxTileSize;
if (overlapY >= overlapX)
{
if (gameObject.vy < 0 && platformMap[gameObject.bottom][gameObject.left] != platform)
{
//Collision on top side of the object
gameObject.setY = gameObject.mapRow * maxTileSize;
gameObject.vy = 0;
}
}
else
{
//Collision on left side of the object
gameObject.setX = gameObject.mapColumn * maxTileSize;
gameObject.vx = 0;
}
}
//check top-right corner
if (platformMap[gameObject.top][gameObject.right] == platform)
{
overlapX = maxTileSize - ((gameObject.xPos + gameObject.width) % maxTileSize);
overlapY = gameObject.yPos % maxTileSize;
if (overlapY >= overlapX)
{
if (gameObject.vy < 0 && platformMap[gameObject.bottom][gameObject.right] != platform)
{
gameObject.setY = (gameObject.mapRow * maxTileSize);
gameObject.vy = 0;
}
}
else
{
//Collision on right
gameObject.setX = (gameObject.mapColumn * maxTileSize) + ((maxTileSize - gameObject.width) - 1);
gameObject.vx = 0;
}
}
//check bottom-left corner
if (platformMap[gameObject.bottom][gameObject.left] == platform)
{
overlapX = gameObject.xPos % maxTileSize;
overlapY = maxTileSize - ((gameObject.yPos + gameObject.height) % maxTileSize);
if (overlapY >= overlapX)
{
if (gameObject.vy > 0 && platformMap[gameObject.top][gameObject.left] != platform)
{
//trace("Collision on bottom");
//Collision on bottom
gameObject.setY = (gameObject.mapRow * maxTileSize) + (maxTileSize - gameObject.height);
gameObject.vy = 0;
gameObject.jumping = false;
}
}
else
{
//trace("Collision on bottom left");
//Collision on left
gameObject.setX = gameObject.mapColumn * maxTileSize;
gameObject.vx = 0;
}
}
//check bottom-right corner
if (platformMap[gameObject.bottom][gameObject.right] == platform)
{
overlapX = maxTileSize - ((gameObject.xPos + gameObject.width) % maxTileSize);
overlapY = maxTileSize - ((gameObject.yPos + gameObject.height) % maxTileSize);
if (overlapY >= overlapX)
{
if (gameObject.vy > 0 && platformMap[gameObject.top][gameObject.right] != platform)
{
//trace("Collision on bottom right");
//Collision on bottom
gameObject.setY = (gameObject.mapRow * maxTileSize) + (maxTileSize - gameObject.height);
gameObject.vy = 0;
gameObject.jumping = false;
}
}
else
{
//trace("Collision on right");
//Collision on right
gameObject.setX = (gameObject.mapColumn * maxTileSize) + ((maxTileSize - gameObject.width) - 1);
gameObject.vx = 0;
}
}
}
}
}
See example
public function platformCollision(gameObject:TileModel, platformMap:Vector.<Vector.<int>>, maxTileSize:uint, platform:uint):void
{
var overlapX:Number;
var overlapY:Number;
if(gameObject.bottom < platformMap.length && gameObject.right < platformMap[0].length)
{
//check top-left corner
//...
Example after updates

There is nothing wrong with the code you posted, but neither of those have an object at index 10? Maybe you should be looking at index 9 as it starts at 0?
Could you show how you are accessing the array/vector? I think that is where the error is coming from.

Try this code
var platformMap:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(2);(
[
Vector.<int>([10,10,10,10,10,10,10,10,10,10]),
Vector.<int>([00,00,10,10,10,10,10,10,10,10]),
Vector.<int>([10,10,10,10,01,01,01,10,10,10]),
Vector.<int>([10,10,10,00,10,10,10,10,01,10]),
Vector.<int>([10,10,10,00,10,10,01,01,01,00]),
Vector.<int>([10,10,10,10,01,01,01,01,01,10]),
Vector.<int>([00,00,00,00,00,10,10,10,10,10]),
Vector.<int>([00,00,00,00,00,00,00,00,00,00])
]);

the vectors length is 10, so you can access from 0 to 9.
the vectors contain vectors, what also have a len.
try
trace("maxnumallowed", platformMap.length-1)
and note, that you can only access platformMap[n], if n is between 0 and platformMap.length-1

Related

Two-dimensional Arrays (matrices) in C

I'm writing code that checks if m2 matrix is a sub-matrix of m1.
Currently I have created a method that receives matrix m1 and matrix m2 of fixed size.
First of all I check that m1 is larger than m2 otherwise m2 cannot be a sub-matrix of m1. Then I have the variable result which indicates 1 if m2 is sub-matrix, or indicates 0 if it is not.
I can't find the right technique to check this thing out. I have started scanning the rows and columns of the arrays, but I don't know how to correctly structure the code to verify it correctly.
This is the code:
void CheckSubMatrix (int rows, int cols, int m1[][cols], int m2[2][2]){
int rowsm2=2;
int colsm2=2;
int result=1;
if(rows >= rowsm2 && cols >= colsm2){
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
if(m1[i][j] != m2[i][j]
result=0;
}
}
} else {
result = 0;
if (result)
printf("Is a Sub-Matrix");
else
printf("Is not a Sub-Matrix");
I'm a beginner and I'm trying to understand how two-dimensional arrays and matrices work in order to understand even the simplest one-dimensional arrays.
Thanks to those who will help me.
Note:
example of sub-matrix: image
EDIT:
I know that the code if(m1[i][j] != m2[i][j] result=0; doesn't work, because the program will take the values of i and j at the last for loop. But I just didn't know how to be able to implement it.
Making judicious use of functions makes the code easier, I think. Using VLA notation for all array arguments means that the code can handle your three test cases, plus a couple of extras with non-square matrices. (The use of void CheckSubMatrix (int rows, int cols, int m1[][cols], int m2[2][2]){ in the code in the question prevents any of the sample tests from working; that checking function only accepts 2x2 sub-matrices). Since the code is only checking the matrices, the matrices should be specified with the const qualifier.
#include <stdio.h>
#include <assert.h>
static int SubMatrixHere(int r, int c,
int rows1, int cols1, const int m1[rows1][cols1],
int rows2, int cols2, const int m2[rows2][cols2])
{
assert(r + rows2 <= rows1 && c + cols2 <= cols1);
for (int i = 0; i < rows2; i++)
{
for (int j = 0; j < cols2; j++)
{
if (m1[r+i][c+j] != m2[i][j])
return 0;
}
}
return 1;
}
static int CheckSubMatrix(int rows1, int cols1, const int m1[rows1][cols1],
int rows2, int cols2, const int m2[rows2][cols2])
{
if (rows1 < rows2 || cols1 < cols2)
return 0;
int ub_rows = rows1 - rows2 + 1;
int ub_cols = cols1 - cols2 + 1;
for (int i = 0; i < ub_rows; i++)
{
for (int j = 0; j < ub_cols; j++)
{
/* The test for m1[i][j] == m2[0][0] is a big saving */
if (m1[i][j] == m2[0][0] &&
SubMatrixHere(i, j, rows1, cols1, m1, rows2, cols2, m2))
return 1;
}
}
return 0;
}
static void dump_matrix(const char *tag, int rows, int cols, const int matrix[rows][cols])
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
const char *pad = "";
int length = 0;
for (int j = 0; j < cols; j++)
{
length += printf("%s%d", pad, matrix[i][j]);
if (length > 60)
{
putchar('\n');
length = 0;
pad = "";
}
else
pad = ", ";
}
if (length > 0)
putchar('\n');
}
putchar('\n');
}
static void test_submatrix(const char *t1, int r1, int c1, const int m1[r1][c1],
const char *t2, int r2, int c2, const int m2[r2][c2])
{
dump_matrix(t1, r1, c1, m1);
dump_matrix(t2, r2, c2, m2);
if (CheckSubMatrix(r1, c1, m1, r2, c2, m2))
printf("%s is a sub-matrix of %s\n", t2, t1);
else
printf("%s is not a sub-matrix of %s\n", t2, t1);
putchar('\n');
}
int main(void)
{
int m1[4][4] =
{
{ 1, 4, 6, 8 },
{ 2, 5, 7, 0 },
{ 3, 6, 9, 0 },
{ 4, 5, 8, 1 },
};
int m2[3][3] =
{
{ 1, 4, 6 },
{ 2, 5, 7 },
{ 3, 6, 9 },
};
int m3[3][3] =
{
{ 5, 7, 0 },
{ 6, 9, 0 },
{ 5, 8, 1 },
};
int m4[3][3] =
{
{ 1, 4, 6 },
{ 2, 5, 7 },
{ 3, 6, 2 },
};
test_submatrix("m1", 4, 4, m1, "m2", 3, 3, m2);
test_submatrix("m1", 4, 4, m1, "m3", 3, 3, m3);
test_submatrix("m1", 4, 4, m1, "m4", 3, 3, m4);
const int m5[6][4] =
{
{ 68, 59, 61, 70 },
{ 65, 86, 44, 9 },
{ 23, 55, 24, 31 },
{ 51, 21, 10, 99 },
{ 19, 99, 43, 95 },
{ 64, 25, 79, 67 },
};
const int m6[2][3] =
{
{ 55, 24, 31 },
{ 21, 10, 99 },
};
const int m7[4][2] =
{
{ 44, 9 },
{ 24, 31 },
{ 10, 99 },
{ 43, 96 },
};
test_submatrix("m5", 6, 4, m5, "m6", 2, 3, m6);
test_submatrix("m5", 6, 4, m5, "m7", 4, 2, m7);
return 0;
}
Output:
m1 (4x4):
1, 4, 6, 8
2, 5, 7, 0
3, 6, 9, 0
4, 5, 8, 1
m2 (3x3):
1, 4, 6
2, 5, 7
3, 6, 9
m2 is a sub-matrix of m1
m1 (4x4):
1, 4, 6, 8
2, 5, 7, 0
3, 6, 9, 0
4, 5, 8, 1
m3 (3x3):
5, 7, 0
6, 9, 0
5, 8, 1
m3 is a sub-matrix of m1
m1 (4x4):
1, 4, 6, 8
2, 5, 7, 0
3, 6, 9, 0
4, 5, 8, 1
m4 (3x3):
1, 4, 6
2, 5, 7
3, 6, 2
m4 is not a sub-matrix of m1
m5 (6x4):
68, 59, 61, 70
65, 86, 44, 9
23, 55, 24, 31
51, 21, 10, 99
19, 99, 43, 95
64, 25, 79, 67
m6 (2x3):
55, 24, 31
21, 10, 99
m6 is a sub-matrix of m5
m5 (6x4):
68, 59, 61, 70
65, 86, 44, 9
23, 55, 24, 31
51, 21, 10, 99
19, 99, 43, 95
64, 25, 79, 67
m7 (4x2):
44, 9
24, 31
10, 99
43, 96
m7 is not a sub-matrix of m5
Use the correct types for sizes (size_t)
You need more loops
int issubmatrix(size_t hrows, size_t hcols, int (*haystack)[hcols],
size_t nrows, size_t ncols, int (*needle)[ncols])
{
int itis = 0;
int exitloop = 0;
if(haystack && needle && ncols <= hcols && nrows <= hrows)
{
for(size_t start_row = 0; start_row <= hrows - nrows; start_row++)
{
for(size_t start_col = 0; start_col <= hcols - ncols; start_col++)
{
exitloop = 0;
for(size_t row = 0; row < nrows; row++)
{
for(size_t col = 0; col < ncols; col++)
{
if(haystack[start_row + row][start_col + col] != needle[row][col])
{
exitloop = 1;
break;
}
if(exitloop) break;
}
if(exitloop) break;
}
if(!exitloop) itis = 1;
}
if(itis) break;
}
}
return itis;
}
int main(void)
{
int haystack[][4] = {
{1,4,6,8},
{2,5,7,0},
{3,6,9,0},
{4,5,8,1},
};
int needle1[][3] =
{
{1,4,6},
{2,5,7},
{3,6,9},
};
int needle2[][3] =
{
{5,7,0},
{6,9,0},
{5,8,1},
};
int needle3[][3] =
{
{1,4,6},
{2,5,7},
{3,6,2},
};
printf("%d\n", issubmatrix(4,4, haystack, 3,3, needle1));
printf("%d\n", issubmatrix(4,4, haystack, 3,3, needle2));
printf("%d\n", issubmatrix(4,4, haystack, 3,3, needle3));
}
https://godbolt.org/z/YTMfWP8ca

How do I finish this method which finds largest integer in an array passed as a parameter?

I'm stuck with this method which should "find the largest integer in an array passed as a parameter and also output the count of the maximum value", not sure what I'm doing wrong.
Thanks
public class q3 {
public static void main(String[] args) {
int[] arraY = {20, 20, 10, 19, 1, 4, 25, 19, 1, 11, 15, 11, 29, 27, 7, 22, 14, 26, 2, 6, 18};
findMax(arraY);
}
public static void findMax(int[] arraY) {
int max_value = arraY[0];
int countMax = 0;
for (int i = 1; i < arraY.length; i++) {
if (arraY[i] > max_value) {
max_value = arraY[i];
}
for (i = 0; i < arraY.length; i++) {
if (arraY[i] == max_value) {
//System.out.println(array[i]);
//System.out.println(max_value);
countMax++;
}
}
}
System.out.println("The maximum value is: " + max_value);
System.out.println("The count is: " + countMax);
}
}
edit: was an issue with scope, have rearranged the formatting and it now returns the correct result
code updated below
public class q3 {
public static void main(String[] args) {
int[] arraY = {20, 20, 10, 19, 1, 4, 25, 19, 1, 11, 15, 11, 29, 27, 7, 22, 14, 26, 2, 6, 18};
//int[] arraY = {30, 9, 20, 9};
findMax(arraY);
}
public static void findMax(int[] arraY) {
int max_value = arraY[0];
int countMax = 0;
for (int i = 1; i < arraY.length; i++) {
//System.out.println(arraY[i]);
if (arraY[i] > max_value) {
max_value = arraY[i];
}
}
for (int i = 0; i < arraY.length; i++) {
if (arraY[i] == max_value) {
//System.out.println(arraY[i]);
//System.out.println(max_value);
countMax++;
}
}
System.out.println("The maximum value is: " + max_value);
System.out.println("The count is: " + countMax);
}
}

i get alway an exception INDEX OUT OF RANGE at mat[i][j] = matrix[i+1][j+1]

Why am I getting index out of range in mat[i][j] = matrix[i+1][j+1]?
On the functions below I'm trying to count the determiner of a matrix.
Function eraze is to erase one line and one column so when I am filling the new matrix (array). Exception shows 'index out of range'.
func det2(matrix :[[Int]] ) -> Int {
var p : Int
p = matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]
return p
}
func det(matrix :[[Int]] , fo : Int ) -> Int {
var p2 : Int = 0
if (fo == 2) {
p2 = det2(matrix: matrix)
} else {
for j in 0..<fo {
p2 = matrix[j][0] * det(matrix: eraze(matrix: matrix, nb: j, dim: fo), fo: fo-1)
}
}
return p2
}
func eraze(matrix : [[Int]] , nb: Int , dim : Int) -> [[Int]] {
var mat = [[Int]]()
for i in 0..<dim-1 {
for j in 0..<dim-1 {
if (i == nb ) || (i>nb) {
mat[i][j] = matrix[i+1][j+1]
} else if (i<nb) {
mat[i][j] = matrix[i][j+1]
}
}
}
return mat
}
Your first issue is that in eraze(), you aren't initializing mat. In Swift you can't index into an empty array.
Replace:
var mat = [[Int]]()
with:
var mat = [[Int]](repeating: Array(repeating: 0, count: dim - 1), count: dim - 1)
With that change, your code no longer crashes, but it produces incorrect results.
You forgot to sum up the values of the expansion and when you do that you need to alternate the sign of the values:
func det(matrix :[[Int]] , fo : Int ) -> Int {
func sign(_ n: Int) -> Int {
return n % 2 == 0 ? 1 : -1
}
var p2 : Int = 0
if (fo == 2) {
p2 = det2(matrix: matrix)
} else {
for j in 0..<fo {
p2 += (sign(j) * matrix[j][0] * det(matrix: eraze(matrix: matrix, nb: j, dim: fo), fo: fo-1))
}
}
return p2
}
Test
det(matrix: [[1, 4, 7, 3, -6], [2, 5, 8, 4, -3], [3, 6, 10, -5, 14], [1, -2, 3, 4, 5], [6, -5, 4, -3, 2]], fo: 5)
13090
which agrees with Wolfram Alpha

Simplifying a switch/case statement in C

I wrote a code to read 20 different values from 20 different addresses in C. My problem is that I only know how to do it in switch/case statement. Is there a way to simplify this code? Writing 20+ cases will make it very long.
float32 Voltage_Selection[20] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
bool Stat[20] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19 ,20 }; //20 status in an array
static uint8_t read = No_read;
uint16_t = answer;
void V_Read(void)
{
typedef enum
{
No_read = 0, read_1, read_2, read_3, read_4, read_5, read_6, read_7, read_8, read_9, read_10, read_11, read_12, read_13, read_14, read_15, read_16, read_17, read_18, read_19, read_20;
} read;
switch (read)
{
case No_read;
Read_function(NULL, Address_0)
break;
case read 1;
answer = Read_function(&Voltage_Selection, Address_1)
if(answer)
stat[1] = false;
else
stat[1] = true;
break;
case read 2;
answer = Read_function(&Voltage_Selection, Address_2)
if(answer)
stat[2] = false;
else
stat[2] = true;
break;
case read 3;
answer = Read_function(&Voltage_Selection, Address_3)
if(answer)
stat[3] = false;
else
stat[3] = true;
break;
//*** all the way till case 20 ***//
case read 20;
answer = Read_function(&Voltage_Selection, Address_20)
if(answer)
stat[20] = false;
else
stat[20] = true;
break;
default;
break;
if(read >= read_20)
{
read = read_1;
}
}
}
}

Loop over date range

In Python3, I can loop over a range of dates like this
import datetime
dt0 = datetime.datetime(2017, 1, 1, 0, 0, 0)
dt1 = datetime.datetime(2017, 1, 5, 0, 0, 0)
dt = dt0
while dt <= dt1:
print(dt.strftime("%Y-%m-%d %H:%M:%S"))
dt += datetime.timedelta(days=1)
Is there a similar way to loop over dates in Rust?
I know that I could write a nested loop over the months then the days of the month. Like this:
let days = [1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31];
let months = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
let months_30_days = [4, 6, 9, 11];
for month in months.iter() {
for day in days.iter() {
if month == &2 {
if is_leap_year(year) {
if day > &29 {
continue;
}
} else if day > &28 {
continue;
}
} else if months_30_days.contains(&month) && day > &30 {
continue;
}
print!("{:04}-{:02}-{:02} ", year, month, day);
}
}
fn is_leap_year(year: i32) -> bool {
if year % 100 == 0 {
return year % 400 == 0;
} else {
return year % 4 == 0;
}
}
Is there a more Rustic way to do it?
You could use the chrono crate for that:
extern crate chrono; // 0.4.6
use chrono::{Duration, TimeZone, Utc};
fn main() {
let dt0 = Utc.ymd(2017, 1, 1);
let dt1 = Utc.ymd(2017, 1, 5);
let mut dt = dt0;
while dt <= dt1 {
println!("{:?}", dt);
dt = dt + Duration::days(1);
}
}
This can also be wrapped into an iterator:
extern crate chrono; // 0.4.6
use chrono::{Date, Duration, TimeZone, Utc};
use std::mem;
struct DateRange(Date<Utc>, Date<Utc>);
impl Iterator for DateRange {
type Item = Date<Utc>;
fn next(&mut self) -> Option<Self::Item> {
if self.0 <= self.1 {
let next = self.0 + Duration::days(1);
Some(mem::replace(&mut self.0, next))
} else {
None
}
}
}
fn main() {
let dt0 = Utc.ymd(2017, 1, 1);
let dt1 = Utc.ymd(2017, 1, 5);
for dt in DateRange(dt0, dt1) {
println!("{:?}", dt);
}
}
There might be a crate that already provides such a functionality, but if you would like to implement this on your own, you could introduce a new data type and implement Iterator - that would be the Rust-y way to do it.
struct MyDate {
year: usize, // or allow negatives for B.C.
month: u8, // or a dedicated Month type limited to 12
day: u8 // or a dedicated Day type limited to 31
}
impl Iterator for Date {
type Item = Date;
fn next(&mut self) -> Option<Date> {
// conditions for incrementing day, month and year
}
}
Then you would be able to increment it in a loop using next().

Resources