I tried doing:
for (int i=0; i<matrix.length; i++) {
for (int j=0; j<matrix[].length; j++) {
but that doesn't work :(
Just index into the matrix using your current row.
for (int i=0; i<matrix.length; i++) {
for (int j=0; j<matrix[i].length; j++) {
// code
}
}
This even factors in the possibility of a jagged array (i.e., a matrix with an inconsistent number of rows in the column).
for (int i=0; i<matrix.length; i++) {
for (int j=0; j<matrix[i].length; j++) {
for (int i=0; i<matrix.length; i++) {
for (int j=0; j<matrix[i].length; j++) {
Notice the i I added.
However, it's best to cache both lengths while looping to avoid re-evaluation on each loop, which saves time at the only cost of one more int in memory (the fix still applies):
for (int i=0, il=matrix.length; i<il; i++) {
for (int j=0, jl=matrix[i].length; j<jl; j++) {
Related
I have a 3x5 matrix that acts as a game reel. First, I search through the game symbols that I am interested in (let's call them wild clones) and then I search through their children (to locate the game object that has the animation) and then I activate those animations.
private IEnumerator EnableWilds(float delayBetweenWildsAppear)
{
WildSymbol[] wilds = FindObjectsOfType<WildSymbol>();
GameObject[] symbols = new GameObject[wilds.Length];
for (int i = 0; i < wilds.Length; i++)
{
symbols[i] = wilds[i].gameObject;
}
for (int i = 0; i < symbols.Length; i++)
{
if ( symbols[i].name.Contains("(Clone)") )
{
int reelIndex = symbols[i].GetComponentInParent<GameReel>().ReelIndex;
int indexOnReel = symbols[i].GetComponent<WildSymbol>().IndexOnReel;
// ??
for (int j = 0; j < symbols[i].transform.childCount; j++)
{
if ( symbols[i].transform.GetChild(j).gameObject.name.Contains("MM_wild") )
{
symbols[i].transform.GetChild(j).gameObject.SetActive(true);
yield return new WaitForSeconds(delayBetweenWildsAppear);
}
}
}
}
}
I started thinking about how I can activate those wilds starting from the top left corner, and coming down the reel and moving on to the next reel and animating the wilds from top to bottom, etc...
So, I realized I need to get each symbol's reel index (i.e. column number) and index on reel (i.e. position on the reel) so I go Reel1 and then wild clone 1 and 2 and 3, and then Reel2 followed by wild clone 1 and 2 and 3, and so on...
I am trying to do this where I have put a // ?? but at this point, I am a bit lost, conceptually. I cannot figure out how to perform tghis traversal.
Could someone please help me with this?
Here is how I solved it myself, and then simplified it:
private IEnumerator DisableWilds(float delayBetweenWildsDisappear)
{
WildSymbol[] wilds = FindObjectsOfType<WildSymbol>();
wilds = wilds.Where( (item, index) => item.name.Contains("(Clone)") )
.OrderBy( x => x.GetComponent<WildSymbol>().IndexOnReel )
.OrderBy( x => x.GetComponentInParent<GameReel>().ReelIndex )
.ToArray();
for (int i = 0; i < wilds.Length; i++)
{
for (int j = 0; j < wilds[i].transform.childCount; j++)
{
if (wilds[i].transform.GetChild(j).gameObject.name.Contains("MM_wild"))
{
wilds[i].transform.GetChild(j).gameObject.SetActive(false);
yield return new WaitForSeconds(delayBetweenWildsDisappear);
}
}
}
}
I need to do this to persist operations on the matrix as well. Does that mean that it needs to be passed by reference?
Will this suffice?
void operate_on_matrix(char matrix[][20]);
C does not really have multi-dimensional arrays, but there are several ways to simulate them. The way to pass such arrays to a function depends on the way used to simulate the multiple dimensions:
1) Use an array of arrays. This can only be used if your array bounds are fully determined at compile time, or if your compiler supports VLA's:
#define ROWS 4
#define COLS 5
void func(int array[ROWS][COLS])
{
int i, j;
for (i=0; i<ROWS; i++)
{
for (j=0; j<COLS; j++)
{
array[i][j] = i*j;
}
}
}
void func_vla(int rows, int cols, int array[rows][cols])
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i][j] = i*j;
}
}
}
int main()
{
int x[ROWS][COLS];
func(x);
func_vla(ROWS, COLS, x);
}
2) Use a (dynamically allocated) array of pointers to (dynamically allocated) arrays. This is used mostly when the array bounds are not known until runtime.
void func(int** array, int rows, int cols)
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i][j] = i*j;
}
}
}
int main()
{
int rows, cols, i;
int **x;
/* obtain values for rows & cols */
/* allocate the array */
x = malloc(rows * sizeof *x);
for (i=0; i<rows; i++)
{
x[i] = malloc(cols * sizeof *x[i]);
}
/* use the array */
func(x, rows, cols);
/* deallocate the array */
for (i=0; i<rows; i++)
{
free(x[i]);
}
free(x);
}
3) Use a 1-dimensional array and fixup the indices. This can be used with both statically allocated (fixed-size) and dynamically allocated arrays:
void func(int* array, int rows, int cols)
{
int i, j;
for (i=0; i<rows; i++)
{
for (j=0; j<cols; j++)
{
array[i*cols+j]=i*j;
}
}
}
int main()
{
int rows, cols;
int *x;
/* obtain values for rows & cols */
/* allocate the array */
x = malloc(rows * cols * sizeof *x);
/* use the array */
func(x, rows, cols);
/* deallocate the array */
free(x);
}
4) Use a dynamically allocated VLA. One advantage of this over option 2 is that there is a single memory allocation; another is that less memory is needed because the array of pointers is not required.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
extern void func_vla(int rows, int cols, int array[rows][cols]);
extern void get_rows_cols(int *rows, int *cols);
extern void dump_array(const char *tag, int rows, int cols, int array[rows][cols]);
void func_vla(int rows, int cols, int array[rows][cols])
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array[i][j] = (i + 1) * (j + 1);
}
}
}
int main(void)
{
int rows, cols;
get_rows_cols(&rows, &cols);
int (*array)[cols] = malloc(rows * cols * sizeof(array[0][0]));
/* error check omitted */
func_vla(rows, cols, array);
dump_array("After initialization", rows, cols, array);
free(array);
return 0;
}
void dump_array(const char *tag, int rows, int cols, int array[rows][cols])
{
printf("%s (%dx%d):\n", tag, rows, cols);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%4d", array[i][j]);
putchar('\n');
}
}
void get_rows_cols(int *rows, int *cols)
{
srand(time(0)); // Only acceptable because it is called once
*rows = 5 + rand() % 10;
*cols = 3 + rand() % 12;
}
(See srand() — why call it only once?.)
Easiest Way in Passing A Variable-Length 2D Array
Most clean technique for both C & C++ is: pass 2D array like a 1D array, then use as 2D inside the function.
#include <stdio.h>
void func(int row, int col, int* matrix){
int i, j;
for(i=0; i<row; i++){
for(j=0; j<col; j++){
printf("%d ", *(matrix + i*col + j)); // or better: printf("%d ", *matrix++);
}
printf("\n");
}
}
int main(){
int matrix[2][3] = { {0, 1, 2}, {3, 4, 5} };
func(2, 3, matrix[0]);
return 0;
}
Internally, no matter how many dimensions an array has, C/C++ always maintains a 1D array. And so, we can pass any multi-dimensional array like this.
I don't know what you mean by "data dont get lost". Here's how you pass a normal 2D array to a function:
void myfunc(int arr[M][N]) { // M is optional, but N is required
..
}
int main() {
int somearr[M][N];
...
myfunc(somearr);
...
}
2D array:
int sum(int array[][COLS], int rows)
{
}
3D array:
int sum(int array[][B][C], int A)
{
}
4D array:
int sum(int array[][B][C][D], int A)
{
}
and nD array:
int sum(int ar[][B][C][D][E][F].....[N], int A)
{
}
This is Code I reached. What I don't understand is how do I put a condition to display the first 20 numbers where I wrote the condition for i to be less than 20. I know that my code is completely wrong.
for(int i=1; i<=20; i++)
{
if(i%7==0)
{
Console.WriteLine(i);
}
}
You're close. use a counter variable:
int counter = 0; // counter variable
for(int i=1; ; i++) // removed condition
{
if (counter > 20) break; // time to stop the iteration
if(i%7==0)
{
counter++;
Console.WriteLine(i);
}
}
This can be improved to:
for(int i = 7, counter = 0; counter <= 20; i += 7)
{
Console.WriteLine(i);
counter++;
}
The first 20 integers that are divisible by 7 are easily written as 7,2*7,3*7,4*7,...,20*7. This in your loop you can do:
for(int i = 1; i<=20; i++) {
Console.WriteLine(7*i);
}
Can’t you just go up in sevens?
for (int multiple = 7, int count = 0; count < 20; multiple += 7, count++)
{
Console.WriteLine(multiple);
}
You can try bellow code that will give you first 20 numbers that will covered the condition i%7==0 ........
public static void Main(string[] args)
{
int i=0, count = 0;
while(count < 20)
{
if (i % 7 == 0)
{
Console.WriteLine("Position {0} number is = {1}", count+1, i,"\n");
count++;
}
i++;
}
Console.ReadKey();
}
I am trying to implement a Dijkstra's algorithm into a fork/join threadpool (consists the main threadpool with a global task queue and N threads with its own task queue) based on Dijkstra's Solution of a problem in concurrent programming control and Frigo's and Leiserson's and Randall's The implementation of the cilk-5 multithreaded language.
But, it seems too complicated. So, I used Filter Lock from Art of Multiprocessor Programming as following:
Book's implementation
class Filter implements Lock {
int[] level;
int[] victim;
public Filter(int n) {
level = new int[n];
victim = new int[n]; // use 1..n-1
for (int i = 0; i < n; i++) {
level[i] = 0;
}
}
public void lock() {
int me = ThreadID.get();
for (int i = 1; i < n; i++) { //attempt level 1
level[me] = i;
victim[i] = me;
// spin while conflicts exist
while ((∃k != me) (level[k] >= i && victim[i] == me)) {};
}
}
public void unlock() {
int me = ThreadID.get();
level[me] = 0;
}
}
My implementation in threadpool
static int* flag;
static int* victim;
const int MAX = 1e9;
int ans = 0;
int nthreads = 10;
struct pt
{
int id;
pthread_t thread;
};
static bool existK(int j, int i, int nthreads){
for (int k = 0; k < nthreads ; k++){
if (flag[k] >= j && k != i)
{
return true;
}
}
return false;
}
void lock_init(void)
{
flag = (int *) calloc(nthreads, sizeof(int));
victim = (int *) calloc(nthreads, sizeof(int));
}
// Executed before entering critical section
void lock(int i)
{
for (int j = 1; j < nthreads; j++){
flag[i] = j;
victim[j] = i;
while (existK(j, i, nthreads) && victim[j] == i);
}
}
// Executed after leaving critical section
void unlock(int i)
{
flag[i] = 0;
}
// in main()
void* func(void *pw)
{
while (true) {
lock(threadID);
// working on its own queue if there is a task and
// after it finishes this task, call unlock(threadID) and call continue;
//if the global queue has tasks left, work on it and call unlock and continue
//if the other worker queue has tasks left, work on it and call unlock and continue
}
}
// Driver code
int main()
{
struct pt** ptr;
lock_init();
ptr = ((struct pt **)malloc(sizeof(struct pt *) * nthreads));
for (int i = 0; i < nthreads; i++){
ptr[i] = malloc(sizeof(struct pt));
(ptr[i])->id = i;
pthread_create(&(ptr[i])->thread, NULL, func, ptr[i]);
}
for (int i = 0; i < nthreads; i++){
pthread_join((ptr[i])->thread, NULL);
}
return 0;
}
However, with my implementation, the main loop is much slower than just using the pthread_mutex_lock and pthread_mutex_unlock. I am not sure if I use the algorithm in a wrong place or my algorithm is wrong at this point.
Additionally, I am wondering how to stealing tasks to work on from the
other workers’ queues in an efficient way (locating the worker with available tasks)
Can anyone tell me why I am getting these errors? And if so, how do i fix them?
Bingo.java:176: ']' expected
private static void makeCard(int[][] card, int[picks])
^
Bingo.java:176: ')' expected
private static void makeCard(int[][] card, int[picks])
^
Bingo.java:176: illegal start of type
private static void makeCard(int[][] card, int[picks])
^
Bingo.java:176: <identifier> expected
private static void makeCard(int[][] card, int[picks])
^
Bingo.java:177: ';' expected
{
^
Bingo.java:178: illegal start of type
System.out.println("Current Number Picks: \n");
^
Bingo.java:178: ';' expected
System.out.println("Current Number Picks: \n");
^
Bingo.java:178: invalid method declaration; return type required
System.out.println("Current Number Picks: \n");
^
Bingo.java:178: illegal start of type
System.out.println("Current Number Picks: \n");
^
Bingo.java:181: illegal start of type
for (int i=0; i<count; i++){
^
Bingo.java:181: ')' expected
for (int i=0; i<count; i++){
^
Bingo.java:181: illegal start of type
for (int i=0; i<count; i++){
^
Bingo.java:181: <identifier> expected
for (int i=0; i<count; i++){
^
Bingo.java:181: ';' expected
for (int i=0; i<count; i++){
^
Bingo.java:181: > expected
for (int i=0; i<count; i++){
^
Bingo.java:181: '(' expected
for (int i=0; i<count; i++){
^
Bingo.java:189: class, interface, or enum expected
private static void announceWin(int winFound, int numPicks)
^
Bingo.java:192: class, interface, or enum expected
}
^
Bingo.java:196: class, interface, or enum expected
for (int i = 0; i < numPicks; i++){
^
Bingo.java:196: class, interface, or enum expected
for (int i = 0; i < numPicks; i++){
^
Bingo.java:198: class, interface, or enum expected
return true;}
^
Bingo.java:202: class, interface, or enum expected
}
^
22 errors
Here is the code:
import java.util.*;
import java.io.*;
import java.util.Arrays;
public class Bingo
{
public static final int ROWS = 5;
public static final int COLS = 5;
public static final int VERTICAL = 1;
public static final int DIAGONAL = 2;
public static final int HORIZONTAL = 3;
public static int winFound;
public static int currPick = 0;
public static int randomPick;
public static int WinFound;
public static void main(String[] args)
{
int Totcards;
int[][] card = new int[ROWS][COLS];
fillCard (card);
printCard(card);
playGame(card);
printCard(card);
}
private static void fillCard (int[][] card)
{
// FileReader fileIn = new FileReader("Bingo.in");
// Bufferreader in = new Bufferreader(fileIn);
try {
Scanner scan = new Scanner(new File("bingo.in"));
for (int i=0; i<card.length; i++){
for (int j=0; j<card[0].length; j++){
card[i][j] = scan.nextInt();
}
}
} catch(FileNotFoundException fnfe) {
System.out.println(fnfe.getMessage());
}
}
private static void printCard (int[][] card)
{
System.out.println("\n\tYOUR BINGO CARD : ");
System.out.println("\n\tB I N G O");
System.out.println("\t----------------------");
for (int i=0; i<card.length; i++){
for (int j=0; j<card[0].length; j++){
System.out.print("\t" + card[i][j]);
}
System.out.print("\n");
}
}
private static void playGame (int[][] card)
{
int numPicks = 0;
while (true)
{
markCard (card); // Generate a random num & zero-it out
winFound = checkForWin(card); // Look for zero sums
numPicks++;
if (winFound != 0)
{
announceWin (winFound, numPicks);
return;
}
}
}
private static void markCard (int[][] card)
{
int randomPick = (int) (Math.random() * 74) + 1;
for (int j = 0; j < ROWS; j++){
for (int k = 0; k < COLS; k++){
if (card[j][k]==randomPick)
card[j][k] = 0;}
System.out.print(" " + randomPick);
}
}
private static int checkForWin(int[][] card)
{
int sum=0;
for (int i = 0; i < ROWS; i++)
{
sum = 0;
for (int j = 0; j < COLS; j++)
sum += card[i][j];
if (sum == 0)
return HORIZONTAL;
}
for (int j = 0; j < COLS; j++)
{
sum = 0;
for (int i = 0; i < ROWS; i++)
sum += card[i][j];
if (sum == 0)
return VERTICAL;
}
sum = 0;
for (int i = 0; i < ROWS; i++)
sum += card[i][ROWS-i-1];
if (sum == 0)
return DIAGONAL;
sum = 0;
for (int i = 0; i < ROWS; i++)
sum += card[i][i];
if (sum == 0)
return DIAGONAL;
return WinFound;
}
private static void makeCard(int[][] card, int[picks])
{
System.out.println("Current Number Picks: \n");
int count = 100;
int currPick = 0;
for (int i=0; i<count; i++){
currPick = (int)(Math.random() * 74) + 1;
System.out.print(" " + currPick + "\n");
picks[i] = currPick;
System.out.print("i: " + i);
}
}
private static void announceWin(int winFound, int numPicks)
{
System.out.println("winFound: " + winFound + "numpicks: " + numPicks);
}
private static boolean duplicate (int currPick, int[picks], int numPicks)
{
for (int i = 0; i < numPicks; i++){
if (picks[i] == currPick){
return true;}
}
return false;
}
}
You're accepting an int array parameter incorrectly.
You have int [picks] where it should be int[] picks
import java.util.*;
import java.io.*;
import java.util.Arrays;
public class Bingo
{
public static final int ROWS = 5;
public static final int COLS = 5;
public static final int VERTICAL = 1;
public static final int DIAGONAL = 2;
public static final int HORIZONTAL = 3;
public static int winFound;
public static int currPick = 0;
public static int randomPick;
public static int WinFound;
public static void main(String[] args)
{
int Totcards;
int[][] card = new int[ROWS][COLS];
fillCard (card);
printCard(card);
playGame(card);
printCard(card);
}
private static void fillCard (int[][] card)
{
// FileReader fileIn = new FileReader("Bingo.in");
// Bufferreader in = new Bufferreader(fileIn);
try {
Scanner scan = new Scanner(new File("bingo.in"));
for (int i=0; i<card.length; i++){
for (int j=0; j<card[0].length; j++){
card[i][j] = scan.nextInt();
}
}
} catch(FileNotFoundException fnfe) {
System.out.println(fnfe.getMessage());
}
}
private static void printCard (int[][] card)
{
System.out.println("\n\tYOUR BINGO CARD : ");
System.out.println("\n\tB I N G O");
System.out.println("\t----------------------");
for (int i=0; i<card.length; i++){
for (int j=0; j<card[0].length; j++){
System.out.print("\t" + card[i][j]);
}
System.out.print("\n");
}
}
private static void playGame (int[][] card)
{
int numPicks = 0;
while (true)
{
markCard (card); // Generate a random num & zero-it out
winFound = checkForWin(card); // Look for zero sums
numPicks++;
if (winFound != 0)
{
announceWin (winFound, numPicks);
return;
}
}
}
private static void markCard (int[][] card)
{
int randomPick = (int) (Math.random() * 74) + 1;
for (int j = 0; j < ROWS; j++){
for (int k = 0; k < COLS; k++){
if (card[j][k]==randomPick)
card[j][k] = 0;}
System.out.print(" " + randomPick);
}
}
private static int checkForWin(int[][] card)
{
int sum=0;
for (int i = 0; i < ROWS; i++)
{
sum = 0;
for (int j = 0; j < COLS; j++)
sum += card[i][j];
if (sum == 0)
return HORIZONTAL;
}
for (int j = 0; j < COLS; j++)
{
sum = 0;
for (int i = 0; i < ROWS; i++)
sum += card[i][j];
if (sum == 0)
return VERTICAL;
}
sum = 0;
for (int i = 0; i < ROWS; i++)
sum += card[i][ROWS-i-1];
if (sum == 0)
return DIAGONAL;
sum = 0;
for (int i = 0; i < ROWS; i++)
sum += card[i][i];
if (sum == 0)
return DIAGONAL;
return WinFound;
}
private static void makeCard(int[][] card, int[] picks)
{
System.out.println("Current Number Picks: \n");
int count = 100;
int currPick = 0;
for (int i=0; i<count; i++){
currPick = (int)(Math.random() * 74) + 1;
System.out.print(" " + currPick + "\n");
picks[i] = currPick;
System.out.print("i: " + i);
}
}
private static void announceWin(int winFound, int numPicks)
{
System.out.println("winFound: " + winFound + "numpicks: " + numPicks);
}
private static boolean duplicate (int currPick, int[] picks, int numPicks)
{
for (int i = 0; i < numPicks; i++){
if (picks[i] == currPick){
return true;}
}
return false;
}
}
Compiles for me