Trouble exiting 2D Array in C - c

I'm tyring to create a frequency counter. Basically, there's an array (testArray) with a bunch of numbers. I need to process those numbers and insert them in another array (probabilityArray). probabilityArray is also 2D array with the 1st row being the unique elements from the test array, the 2nd row being how many times a unique number occurs (Ex. probabilityArray[2][5] represents how often the number at probabilityArray[1][5] occurs). I'm having trouble exiting the rows for loop and I have no idea why.
#include <stdio.h>
#include <stdlib.h>
int histogram() {
}
int entropy() {
}
int main() {
int i, j, k, found = 0, currentPosition = 0, l = 0, x = 0, y = 0;
int testArray[10][10] = {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
{11, 12, 13, 14, 15, 16, 17, 18 ,19, 20},
{11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
{11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30},
{21, 22, 23, 24, 25, 26, 27, 28, 29, 30}};
int row = sizeof(testArray) / sizeof(testArray[0]);
int col = sizeof(testArray[0]) / sizeof(testArray[0][0]);
int elements = (row * col);
printf("Elements: %d\n", elements);
//printf("Rows: %d\nCols: %d\n", row, col);
int probabilityArray[3][elements];
for(x = 0; x < 3; x++) {
for(y = 0; y < elements; y++) {
//printf("X: %d\tY: %d\t", x, y);
probabilityArray[x][y] = 0;
}
//printf("\n");
}
//printf("Got here\n");
for (i = 0; i < row; i++) {
for (j = 0; j < col; j++) {
printf("%d\n", l);
l++;
int temp = testArray[i][j];
for (k = 0; k < currentPosition; k++) {
if (probabilityArray[1][k] == temp) {
//Element is not unique, increase occurance counter
printf("NOT UNIQUE: %d\n", temp);
probabilityArray[2][k]++;
found = 1;
break;
}
}
if (found == 0) {
//Element is unique, add it to array
printf("FOUND: %d\n", temp);
probabilityArray[1][currentPosition] = temp;
probabilityArray[2][currentPosition]++;
currentPosition++;
printf("Current Position: %d\n", currentPosition);
}
found = 0;
}
printf("I: %d\tC: %d\n", i, j);
}
for (i = 0; i < currentPosition; i++) {
probabilityArray[3][i] = (int)((probabilityArray[2][i] / elements) * 100);
}
for (i = 0; i < currentPosition; i++) {
printf("ELEMENT: %d\t\tFREQUENCY: %d\t\tPROBABILITY:%d\n", probabilityArray[1][i], probabilityArray[2][i], probabilityArray[3][i]);
}
}
Any help is appreciated!

You are using indices 1, 2, and 3, where you probably meant to use 0, 1, and 2.
Here:
if (probabilityArray[1][k] == temp) { // Should it be 0??
//Element is not unique, increase occurance counter
printf("NOT UNIQUE: %d\n", temp);
probabilityArray[2][k]++; // Should it be 1??
and here:
probabilityArray[1][currentPosition] = temp; // Should it be 0??
probabilityArray[2][currentPosition]++; // Should it be 1??
and here:
probabilityArray[3][i] = (int)((probabilityArray[2][i] / elements) * 100);
// Should it be 2 and 1 ??
and here:
printf("ELEMENT: %d\t\tFREQUENCY: %d\t\tPROBABILITY:%d\n",
probabilityArray[1][i], probabilityArray[2][i], probabilityArray[3][i]);
// Should be be 0, 1, and 2
Fixing those might fix your problems.

Related

Backtracking Algorithm Sudoku using C

I am working on a sudoku exercise using the backtracking algorithm using C. It prints the gameboard with the first solution it finds, however it does not stop there and continues the recursion by removing the fields of the gameboard and creates a new solution. The problem is somewhere in the solve function. Here is my approach:
#include "sudoku.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
int field[SIZE][SIZE];
int initial[SIZE][SIZE];
/* Initializes the sudoku array.
* The field initial keeps the original start value for
* figuring out if a value is fixed or can be changed. */
void init(int begin[SIZE][SIZE]) {
memcpy(field, begin, SIZE * SIZE * sizeof(int));
memcpy(initial, begin, SIZE * SIZE * sizeof(int));
}
/* Retrieves the solution. NEEDED FOR AUTO-TESTING PURPOSES. */
void getResult(int result[SIZE][SIZE]){
memcpy(result, field, SIZE * SIZE * sizeof(int));
}
/* pretty prints the sudoku array */
void print() {
int row, col;
// print the first line
printf("||");
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("===++");
else
printf("===+");
}
printf("===||\n");
// loop through all rows of the array
for (row = 0; row < SIZE; row++) {
// print the line with field values
for (col = 0; col < SIZE; col++) {
if (col % SQRT_SIZE == 0)
printf("|| ");
else
printf("| ");
if (field[row][col] == 0)
printf(" ");
else
printf("%d ", field[row][col]);
}
// print the separation line;
// depending on the result of the modulo operation
// print a single or double line
printf("||\n||");
if (row % SQRT_SIZE == SQRT_SIZE - 1) {
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("===++");
else
printf("===+");
}
printf("===||\n");
}
else {
for (col = 0; col < SIZE - 1; col++) {
if (col % SQRT_SIZE == SQRT_SIZE - 1)
printf("---++");
else
printf("---+");
}
printf("---||\n");
}
}
}
/* Checks if the value is valid and can be set into the field.
* The function returns false if the value is already present or
* has been one of the initial values. */
int checkValueInField(int value, int row, int col) {
int i, r, c;
int squareRow;
int squareCol;
// checks for initial values
if (initial[row][col] != 0) {
if (initial[row][col] == value)
return 1;
else
return 0;
}
// check horizontally
for (i = 0; i < SIZE; i++) {
if (field[row][i] == value) return 0;
}
// check vertically
for (i = 0; i < SIZE; i++) {
if (field[i][col] == value) return 0;
}
// check square
squareRow = row / SQRT_SIZE;
squareCol = col / SQRT_SIZE;
for (r = squareRow * SQRT_SIZE; r < squareRow * SQRT_SIZE + SQRT_SIZE; r++) {
for (c = squareCol * SQRT_SIZE; c < squareCol * SQRT_SIZE + SQRT_SIZE; c++) {
if (field[r][c] == value) return 0;
}
}
return 1;
}
/* Set a value in the sudoku field if the field is empty.
* The method returns false if the field contains a fixed number. */
int setValueInField(int value, int row, int col) {
if (initial[row][col] == 0) {
field[row][col] = value;
return 1;
}
else if (initial[row][col] == value)
return 1;
return 0;
}
/* Removes a value in the sudoku field if it doesn't contain an initial value.
* The method returns false if the field contains a fixed number and cannot be
* removed. */
int removeValueFromField(int row, int col) {
if (initial[row][col] == 0) {
field[row][col] = 0;
return 1;
}
return 0;
}
/* Returns the value in the field */
int getValueFromField(int row, int col) {
return field[row][col];
}
/* Return true after a valid solution for the sudoku has been found. */
int solve(int row, int col) {
print();
bool isSet = false;
if (row == 0 && col == 0) {
for (int i = 1; i <= SIZE; i++) {
if (checkValueInField(i, row, col) && getValueFromField(row, col) == 0) {
isSet = setValueInField(i, row, col);
if (isSet) {
solve(row, col);
}
if (row == SIZE - 1 && col == SIZE - 1) {
return 1;
}
else {
removeValueFromField(row, col);
}
}
}
}
if (row == SIZE - 1 && col == SIZE - 1) {
//Here is the solution, but then it continues after returning 1
for (int r = 1; r <= SIZE; r++) {
for (int c = 1; c <= SIZE; c++) {
if (getValueFromField(r, c) != 0) {
return 1;
}
}
}
}
if (row == SIZE - 1) {
row = 0;
col = col++;
}
else {
row = row++;
}
for (int i = 1; i <= SIZE; i++) {
if (checkValueInField(i, row, col) == 1) {
isSet = setValueInField(i, row, col);
solve(row, col);
if (row == SIZE - 1 && col == SIZE == -1) {
return 1;
}
else {
removeValueFromField(row, col);
}
}
}
return 1;
}
This is my header file:
#ifndef _SUDOKU_H_
#define _SUDOKU_H_
#define SIZE 9
#define SQRT_SIZE 3
void init(int begin[SIZE][SIZE]);
void getResult(int result[SIZE][SIZE]);
void print();
int checkValueInField(int value, int row, int col);
int setValueInField(int value, int row, int col);
int removeValueFromField(int row, int col);
int getValueFromField(int row, int col);
int solve(int row, int col);
This is the initial gameboard and its solution:
int initial[SIZE][SIZE] = {
{0, 1, 0, 0, 0, 9, 0, 5, 0},
{0, 9, 0, 0, 0, 0, 4, 8, 0},
{0, 6, 0, 1, 0, 4, 0, 0, 0},
{0, 0, 5, 0, 0, 0, 9, 3, 0},
{0, 0, 0, 7, 0, 2, 0, 0, 0},
{0, 2, 1, 0, 0, 0, 8, 0, 0},
{4, 0, 0, 0, 8, 0, 6, 0, 9},
{0, 0, 0, 0, 6, 0, 5, 0, 3},
{2, 0, 0, 0, 3, 0, 0, 0, 0},
};
int expected[SIZE][SIZE] = {
{3, 1, 4, 8, 7, 9, 2, 5, 6},
{5, 9, 7, 3, 2, 6, 4, 8, 1},
{8, 6, 2, 1, 5, 4, 3, 9, 7},
{7, 4, 5, 6, 1, 8, 9, 3, 2},
{9, 3, 8, 7, 4, 2, 1, 6, 5},
{6, 2, 1, 5, 9, 3, 8, 7, 4},
{4, 7, 3, 2, 8, 5, 6, 1, 9},
{1, 8, 9, 4, 6, 7, 5, 2, 3},
{2, 5, 6, 9, 3, 1, 7, 4, 8},
};
This is my testcase:
TEST_CASE("Test2", "Sudoku")
{
int result = 0;
int actual[SIZE][SIZE];
int initial[SIZE][SIZE] = {
{0, 1, 0, 0, 0, 9, 0, 5, 0},
{0, 9, 0, 0, 0, 0, 4, 8, 0},
{0, 6, 0, 1, 0, 4, 0, 0, 0},
{0, 0, 5, 0, 0, 0, 9, 3, 0},
{0, 0, 0, 7, 0, 2, 0, 0, 0},
{0, 2, 1, 0, 0, 0, 8, 0, 0},
{4, 0, 0, 0, 8, 0, 6, 0, 9},
{0, 0, 0, 0, 6, 0, 5, 0, 3},
{2, 0, 0, 0, 3, 0, 0, 0, 0},
};
int expected[SIZE][SIZE] = {
{3, 1, 4, 8, 7, 9, 2, 5, 6},
{5, 9, 7, 3, 2, 6, 4, 8, 1},
{8, 6, 2, 1, 5, 4, 3, 9, 7},
{7, 4, 5, 6, 1, 8, 9, 3, 2},
{9, 3, 8, 7, 4, 2, 1, 6, 5},
{6, 2, 1, 5, 9, 3, 8, 7, 4},
{4, 7, 3, 2, 8, 5, 6, 1, 9},
{1, 8, 9, 4, 6, 7, 5, 2, 3},
{2, 5, 6, 9, 3, 1, 7, 4, 8},
};
init(initial);
result = solve(0,0);
getResult(actual);
INFO("Test Case: valid Sudoku board failed.");
REQUIRE(memcmp(actual, expected, sizeof(initial)) == 0);
INFO("Test Case: return value not correct.");
REQUIRE(result == 1);
}

Most efficient way to select elements in 2d array in Ruby

Let's say I have 2d array (or matrix) like,
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
And, I've to select all elements in eight directions of a certain element matrix[i][j], so I know,
up and down elements will have same j
left and right elements will have same i
back-inclined diagonal (\) elements will have same diff i-j
front-inclined diagonal (/) elements will have same sum i+j
How to select those elements, easily and efficiently? Any direct method?
For example, if my element is 4, then my selection should yield, [1, 7, 5, 6, 2, 8]. If it is, 5, then selection should be all except 5.
Edit: I've coded any solution yet, as I thought it'll be very poor, but here is my idea. Try it online!
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
res = []
i = 0
j = 1
# let [i,j] be index of my element
matrix.each_with_index{|row,r| row.each_with_index{|col,c|
res << col if c == j || r == i || r+c == i+j || r-c == i-j
}}
p res
m is the matrix you have taken from a user that is a symmetric or non-symmetric 2-dimensional array.
# inputs
m = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]
p, q = 1, 0 # co-ordinate of number 4
# code for output
i, j, result = m.size, m[0].size, []
i.times { |r| result.push(m[r][q]) if r != p }
j.times { |c| result.push(m[p][c]) if c != q }
i.times do |r|
j.times do |c|
result.push(m[r][c]) if [p,q] != [r,c] && (p-r).abs == (q-c).abs
end
end
> result
=> [1, 7, 5, 6, 2, 8]
Note: if the order of output is not needed to be preserved, we can manage with only 2 loops
Code
def extract(matrix, row, col)
last_row = matrix.size-1
last_col = matrix.first.size-1
diag_sum = row + col
diag_first_row = diag_sum - [diag_sum, last_col].min
diag_last_row = [last_row, diag_sum].min
ante_diag_diff = row - col
ante_diag_first_row = [ante_diag_diff, 0].max
ante_diag_last_row = ante_diag_diff +
[last_col, last_row - ante_diag_diff].min
arr = []
(0..last_col).each { |j| arr << matrix[row][j] unless j == col }
(0..last_row).each { |i| arr << matrix[i][col] unless i == row }
(diag_first_row..diag_last_row).each do |i|
arr << matrix[i][diag_sum - i] unless i == row
end
(ante_diag_first_row..ante_diag_last_row).each do |i|
arr << matrix[i][i - ante_diag_diff] unless i == row
end
arr
end
Example
matrix = Array.new(5) { Array.new(5) { rand(10..99) } }
#=> [[52, 29, 61, 35, 27],
# [68, 99, 67, 18, 67],
# [79, 10, 73, 15, 36],
# [49, 94, 28, 24, 53],
# [37, 26, 65, 65, 43]]
(0..4).each do |i|
(0..4).each do |j|
puts "#{i}, #{j}: #{extract(matrix,i,j)}"
end
end
i j
----------------------------------------------------------------------
0, 0: [29, 61, 35, 27, 68, 79, 49, 37, 99, 73, 24, 43]
0, 1: [52, 61, 35, 27, 99, 10, 94, 26, 68, 67, 15, 53]
0, 2: [52, 29, 35, 27, 67, 73, 28, 65, 99, 79, 18, 36]
0, 3: [52, 29, 61, 27, 18, 15, 24, 65, 67, 10, 49, 67]
0, 4: [52, 29, 61, 35, 67, 36, 53, 43, 18, 73, 94, 37]
1, 0: [99, 67, 18, 67, 52, 79, 49, 37, 29, 10, 28, 65]
1, 1: [68, 67, 18, 67, 29, 10, 94, 26, 61, 79, 52, 73, 24, 43]
1, 2: [68, 99, 18, 67, 61, 73, 28, 65, 35, 10, 49, 29, 15, 53]
1, 3: [68, 99, 67, 67, 35, 15, 24, 65, 27, 73, 94, 37, 61, 36]
1, 4: [68, 99, 67, 18, 27, 36, 53, 43, 15, 28, 26, 35]
2, 0: [10, 73, 15, 36, 52, 68, 49, 37, 61, 99, 94, 65]
2, 1: [79, 73, 15, 36, 29, 99, 94, 26, 35, 67, 49, 68, 28, 65]
2, 2: [79, 10, 15, 36, 61, 67, 28, 65, 27, 18, 94, 37, 52, 99, 24, 43]
2, 3: [79, 10, 73, 36, 35, 18, 24, 65, 67, 28, 26, 29, 67, 53]
2, 4: [79, 10, 73, 15, 27, 67, 53, 43, 24, 65, 61, 18]
3, 0: [94, 28, 24, 53, 52, 68, 79, 37, 35, 67, 10, 26]
3, 1: [49, 28, 24, 53, 29, 99, 10, 26, 27, 18, 73, 37, 79, 65]
3, 2: [49, 94, 24, 53, 61, 67, 73, 65, 67, 15, 26, 68, 10, 65]
3, 3: [49, 94, 28, 53, 35, 18, 15, 65, 36, 65, 52, 99, 73, 43]
3, 4: [49, 94, 28, 24, 27, 67, 36, 43, 65, 29, 67, 15]
4, 0: [26, 65, 65, 43, 52, 68, 79, 49, 27, 18, 73, 94]
4, 1: [37, 65, 65, 43, 29, 99, 10, 94, 67, 15, 28, 49]
4, 2: [37, 26, 65, 43, 61, 67, 73, 28, 36, 24, 79, 94]
4, 3: [37, 26, 65, 43, 35, 18, 15, 24, 53, 68, 10, 28]
4, 4: [37, 26, 65, 65, 27, 67, 36, 53, 52, 99, 73, 24]
Explanation
First observe that if the target element is in row i and column j, the elements [p,q] on the diagonal that passes through that point have the property that p+q == i+j. Similarly, the elements [p,q] on the ante-diagonal that passes through that point have the property that p-q == i-j
Suppose
row = 1
col = 2
then
last_row = matrix.size-1
#=> 4
last_col = matrix.first.size-1
#=> 4
diag_sum = row + col
#=> 3
diag_first_row = diag_sum - [diag_sum, last_col].min
#=> 0
diag_last_row = [last_row, diag_sum].min
#=> 3
ante_diag_diff = row - col
#=> -1
ante_diag_first_row = [ante_diag_diff, 0].max
#=> 0
ante_diag_last_row = ante_diag_diff +
[last_col, last_row - ante_diag_diff].min
#=> 3
The remaining calculations are straightforward.
Here's a variant of the above that uses less code and may be slightly less efficient.
def extract(matrix, row, col)
row_range = 0..matrix.size-1
col_range = 0..matrix.first.size-1
diag_sum = row + col
ante_diag_diff = row - col
arr = []
col_range.each { |j| arr << matrix[row][j] unless j == col }
row_range.each do |i|
next if i == row
arr << matrix[i][col]
j = diag_sum - i
arr << matrix[i][j] if col_range.cover?(j)
j = i - ante_diag_diff
arr << matrix[i][j] if col_range.cover?(j)
end
arr
end
Here is sample code, you can modify/simplify it further
class Matrix
attr_reader :arr, :ele
def initialize(arr, ele)
#arr = arr
#ele = ele
end
def find_elements
position = arr.flatten.index(ele)
len = arr.length
x = position % len
y = position / len
horizontal_elements(y) + vertical_elements(x, y, len) + remaining_elements(x, y, len)
end
def horizontal_elements y
arr[y] - [ele]
end
def vertical_elements x, y, len
rows = (0..(len-1)).to_a - [y]
rows.map{|row| arr[row][x] }
end
def remaining_elements(x, y, len)
rows = []
rows << y + 1 if y + 1 < len
rows << y - 1 if y - 1 >= 0
c_rows = []
c_rows << x + 1 if x + 1 < len
c_rows << x - 1 if x - 1 >= 0
rows.map{|row| c_rows.map{|c_row| arr[row][c_row] } }.flatten
end
end
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
ele = 4
(1..9).each do |i|
puts '*' * 20
puts "For #{i}"
puts Matrix.new(matrix, i).find_elements.inspect
puts '*' * 20
end
O/P will be something like following
Desktop $ ruby something.rb
********************
For 1
[2, 3, 4, 7, 5]
********************
********************
For 2
[1, 3, 5, 8, 6, 4]
********************
********************
For 3
[1, 2, 6, 9, 5]
********************
********************
For 4
[5, 6, 1, 7, 8, 2]
********************
********************
For 5
[4, 6, 2, 8, 9, 7, 3, 1]
********************
********************
For 6
[4, 5, 3, 9, 8, 2]
********************
********************
For 7
[8, 9, 1, 4, 5]
********************
********************
For 8
[7, 9, 2, 5, 6, 4]
********************
********************
For 9
[7, 8, 3, 6, 5]
********************
A recursive way
I'd like to propose a different approach, not tested if it is more or less efficient but can provide some control on order and more.
Lets start with this matrix, where elements tell their indexing:
mat = [
['00', '01', '02'],
['10', '11', '12'],
['20', '21', '22'],
['30', '31', '32']
]
And define an helper method just to get the shape of the matrix and to check which is well formed:
def shape(mat)
raise 'Out of shape' if mat.map(&:size).uniq.size > 1
return mat.size, mat[0].size
end
Implementation
Now, let's define a method that takes as input the starting point, the limits of the matrix (shape) and the direction.
def walk(i_0, j_0, i_max, j_max, direction, res=[])
d_i, d_j = direction
next_step = [i_0 + d_i, j_0 + d_j]
if [-1, i_max].include?(next_step[0]) || [-1, j_max].include?(next_step[1])
return res
end
res << next_step
i_0, j_0 = next_step
walk(i_0, j_0, i_max, j_max, direction, res)
end
The method returns the list of indexes starting from the origin and walking along the direction.
Usage examples
Example 1
i_0, j_0 = [2, 0]
i_max, j_max = shape(mat)
direction = [-1, 1]
walk(i_0, j_0, *shape(mat), direction)
#=> [[1, 1], [0, 2]]
Example 2
You can use it to extract the indexes given a list of directions.
It's possible to arrange the list of directions to give a scan order (clockwise, cclockwise) or just skip some directions, as you will.
directions = [[1, 0], [-1, 0], [0, 1], [0, -1], [1, 1], [1, -1], [-1, 1], [-1, -1]]
i_0, j_0 = [2, 0]
directions = [[1, 0], [-1, 0], [0, 1], [0, -1], [1, 1], [1, -1], [-1, 1], [-1, -1]]
directions.flat_map { |direction| walk(i_0, j_0, *shape(mat), direction) }
#=> [[3, 0], [1, 0], [0, 0], [2, 1], [2, 2], [3, 1], [1, 1], [0, 2]]
Example 3
(Which is an extension of example 2)
You can directly get the elements from the matrix:
res = directions.flat_map do |direction|
walk(i_0, j_0, *shape(mat), direction).map do |coords|
i, j = coords
mat[i][j]
end
end
res
#=> ["30", "10", "00", "21", "22", "31", "11", "02"]
It can be possible to use a longer step (eg. direction = [2, 2]) upgrading the walk method.

Swift using eratosthenes method to get prime numbers

I want to use eratosthenes method
to get prime numbers with swift. I create first function to return new array without those numbers that can be divided for specific multiplier, then create second function to create new array every time with new P multiplier. I wonder why its not work (look like it somehow pass old array, i dont know why). It should print new array of prime numbers at the end:
var simpleArr : [Int] = []
for i in 2...100 {
simpleArr.append(i)
}
func arrayEcludingDivingByP (p: Int, arrToCheck : [Int]) -> Array<Int>{
var tmp : [Int] = []
for (ob, index) in arrToCheck.enumerated() {
var isDividible : Bool = ob % p == 0 ? true : false
if (!isDividible){
tmp.append(ob)
}
}
return tmp
}
var p : Int = 2
func getSimpleNumbersArrayFromArray (p : Int, arrPassed : [Int]) -> Array <Int>{
var tmp : [Int] = []
var newArr = arrayEcludingDivingByP(p: p, arrToCheck: arrPassed)
if (newArr.isEmpty){
// No more p availible, just return tmp
} else {
let newP = p + 1
getSimpleNumbersArrayFromArray(p: newP, arrPassed: newArr)
tmp = newArr
print("tmp array? \(tmp)")
}
return tmp
}
getSimpleNumbersArrayFromArray(p: p, arrPassed: simpleArr)
In console it prints:
tmp array? [1]
tmp array? [1, 2]
tmp array? [1, 2, 3]
tmp array? [1, 2, 3, 4]
tmp array? [1, 2, 3, 4, 5]
tmp array? [1, 2, 3, 4, 5, 6]
tmp array? [1, 2, 3, 4, 5, 6, 7]
tmp array? [1, 2, 3, 4, 5, 6, 7, 8]
tmp array? [1, 2, 3, 4, 5, 6, 7, 9, 10, 11]
tmp array? [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13]
tmp array? [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17]
tmp array? [1, 2, 3, 4, 6, 7, 8, 9, 11, 12, 13, 14, 16, 17, 18, 19, 21, 22, 23]
tmp array? [1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, 17, 18, 19, 21, 22, 23, 25, 26, 27, 29, 30, 31]
tmp array? [1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17, 19, 20, 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 37, 38, 40, 41, 43, 44, 46, 47]
tmp array? [1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 83, 85, 87, 89, 91, 93, 95, 97]
But it suppose to print final iteration with tmp filled with prime numbers. What did i wrong?
You are using newArr to represent the values in the sieve that remain. Your tmp array should be the primes found so far. Also you are using a recursive call which is confusing. I suggest simply grabbing the first value out of newArr which is a prime, add that prime to your list of primes, and then call arrayEcludingDividingByP to filter out the non-primes divisible by that prime. Repeat until newArr isEmpty which will happen when the conditional binding statement while let newP = newArr.first fails and the loop ends:
func getPrimes(arrPassed: [Int]) -> [Int] {
var primes: [Int] = []
var newArr = arrPassed
while let newP = newArr.first {
primes.append(newP)
newArr = arrayEcludingDivingByP(p: newP, arrToCheck: newArr)
}
return primes
}
print(getPrimes(arrPassed: Array(2...100)))
This can be further optimized because once newP * newP is greater than the largest number in newArr (newArr.last!) you are done and you can simply append newArr to primes and set newArr to [].
Also, arrayEcludingDivingByP(p: newP, arrToCheck: newArr) can be replaced by newArr.filter { $0 % newP != 0 }

Compiler dependency of searching a value in array of pointers to array of pointers in C

The following code have an array named ReadOnly[] which contains elements that are pointers to other arrays like AV_ReadOnly, BV_ReadOnly etc. Again AV_ReadOnly, BV_ReadOnly etc are pointer arrays containing elements that points to integer arrays.
The read_arrays() is a function used for printing a particular list/ accessing any particular value of the integer arrays. This approach works well on the test environment. But is there a chance for failure of this approach with a change in the platform/compiler?
#include<stdio.h>
int AV1_ReadOnly[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int AV2_ReadOnly[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
int BV1_ReadOnly[] = { 21, 22, 23, 24, 25, 26, 27, 28, 29, 30};
int BV2_ReadOnly[] = { 31, 32, 33, 34, 35, 36, 37, 38, 39, 40};
int MV1_ReadOnly[] = { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50};
int MV2_ReadOnly[] = { 51, 52, 53, 54, 55, 56, 57, 58, 59, 60};
int NC1_ReadOnly[] = { 61, 62, 63, 64, 65, 66, 67, 68, 69, 70};
int NC2_ReadOnly[] = { 71, 72, 73, 74, 75, 76, 77, 78, 79, 80};
int * AV_ReadOnly[] =
{
AV1_ReadOnly,
AV2_ReadOnly,
};
int * BV_ReadOnly[] =
{
BV1_ReadOnly,
BV2_ReadOnly,
};
int * MV_ReadOnly[] =
{
MV1_ReadOnly,
MV2_ReadOnly,
};
int * NC_ReadOnly[] =
{
NC1_ReadOnly,
NC2_ReadOnly
};
int ** ReadOnly[] =
{
AV_ReadOnly,
BV_ReadOnly,
MV_ReadOnly,
NC_ReadOnly
};
void read_arrays( int obj, int inst )
{
int ** ArrayPtr = ReadOnly[obj];
int count =0;
while( count <8 )
{
printf( "\n %d", *(ArrayPtr[inst]+count) );
count++;
}
}
void main()
{
read_arrays( 1,1 );
}
Should be OK as long as you keep the int arrays and the int* arrays in the same file.
Also, you can (should) declare them const if you have no intentions to change them.
Also, you can (should) declare them static if you have no intentions to extern them in other files.
BTW, from what you've published, it looks like you can simply use int table[8][10] instead...

What is wrong with pointer expression in c?

I am using a function that has a segment (shown below) that was used in qsort to compare variable fields that are sorted in either ascending or desending order. I added a third order (assending is 0, descending is 1 and the third order is 2) where I sort gas and oil well classifications in the NormalizeResClass function that returns a different int for the classifications.
I added the code for (typsort == 2) as shown below, but it only sorts properly when I have the reserve class as the only type of sort. If I sort with a secondary sort like by reserve class and well name it dose not sort.
The original code in the else block uses *((int *) before xval and yval and I am weak on pointers. I know that it is casting to int but the NormalizeResClass function already returns an int so I don't need the cast, and if I use it I get a segmentaion fault.
static char *Strings = NULL; // Global var
int result= 0; // local var
int ft; // local var
// ft is checked before going to this to be >= 0
if (typsort == 2)
{
// the code that I have added
result = strncmp (Strings + NormalizeResClass (xval),
Strings + NormalizeResClass (yval), ft);
}
else
{
// this code was there and the sorting was right
result = strncmp (Strings + *((int *) xval),
Strings + *((int *) yval), ft);
}
This is the Normalize Function below I might need to make sure all of these have a unique
number a few have the same.
int NormalizeResClass (char rc)
{
/
Given a reserve class string , return a reserve class number.
*/
register int i;
register char *p, *q;
static struct
{
int index;
char str;
} RCposs[] =
{
{
1, "PROVED DEVELOPED PRODUCING"},
{
2, "PROVED PRODUCING SECONDARY"},
{
3, "PROVED PRODUCING TERTIARY"},
{
1, "PROVED PRODUCING"},
{
4, "PROVED SHUT-IN"},
{
5, "PROVED DEVELOPED NON-PRODUCING"},
{
5, "PROVED NON-PRODUCING"},
{
6, "PROVED DEVELOPED BEHIND-PIPE"},
{
6, "PROVED BEHIND-PIPE"},
{
8, "PROVED UNDEVELOPED SECONDARY"},
{
9, "PROVED UNDEVELOPED TERTIARY"},
{
7, "PROVED UNDEVELOPED"},
{
1, "PROVED"},
{
10, "PROBABLE DEVELOPED PRODUCING"},
{
11, "PROBABLE PRODUCING SECONDARY"},
{
12, "PROBABLE PRODUCING TERTIARY"},
{
13, "PROBABLE SHUT-IN"},
{
10, "PROBABLE PRODUCING"},
{
14, "PROBABLE DEVELOPED NON-PRODUCING"},
{
14, "PROBABLE NON-PRODUCING"},
{
15, "PROBABLE DEVELOPED BEHIND-PIPE"},
{
15, "PROBABLE BEHIND-PIPE"},
{
17, "PROBABLE UNDEVELOPED SECONDARY"},
{
18, "PROBABLE UNDEVELOPED TERTIARY"},
{
16, "PROBABLE UNDEVELOPED"},
{
20, "PROBABLE PRIMARY/SECONDARY"},
{
21, "PROBABLE SECONDARY"},
{
19, "PROBABLE"},
{
22, "POSSIBLE DEVELOPED PRODUCING"},
{
23, "POSSIBLE PRODUCING SECONDARY"},
{
24, "POSSIBLE PRODUCING TERTIARY"},
{
25, "POSSIBLE SHUT-IN"},
{
22, "POSSIBLE PRODUCING"},
{
26, "POSSIBLE DEVELOPED NON-PRODUCING"},
{
26, "POSSIBLE NON-PRODUCING"},
{
27, "POSSIBLE DEVELOPED BEHIND-PIPE"},
{
27, "POSSIBLE BEHIND-PIPE"},
{
29, "POSSIBLE UNDEVELOPED SECONDARY"},
{
30, "POSSIBLE UNDEVELOPED TERTIARY"},
{
28, "POSSIBLE UNDEVELOPED"},
{
22, "POSSIBLE"},
{
32, "PROSPECTIVE PRIMARY/SECONDARY"},
{
33, "PROSPECTIVE SECONDARY"},
{
31, "PROSPECTIVE"},
{
34, "ANALOGY"},
{
35, "DEPLETE"},
{
36, "PROV+PROB+POSS UNDEVELOPED RESERVES"},
{
37, "PROV+PROB+POSS DEVELOPED RESERVES"},
{
38, "PROV+POSS UNDEVELOPED RESERVES"},
{
39, "PROV+POSS DEVELOPED RESERVES"},
{
40, "PROB+POSS UNDEVELOPED RESERVES"},
{
41, "PROB+POSS DEVELOPED RESERVES"},
{
42, "PROV+PROB UNDEVELOPED RESERVES"},
{
43, "PROV+PROB DEVELOPED RESERVES"},
{
44, "RISKED PROV UNDEVELOPED RESERVES"},
{
45, "RISKED PROB UNDEVELOPED RESERVES"},
{
46, "RISKED POSS UNDEVELOPED RESERVES"},
{
47, "RISKED PROV BEHIND-PIPE RESERVES"},
{
48, "RISKED PROB BEHIND-PIPE RESERVES"},
{
49, "RISKED POSS BEHIND-PIPE RESERVES"},
{
50, "PLANT PRODUCTS SALES"},
{
51, "PROBABLE PLANT PRODUCTS SALES"},
{
52, "POSSIBLE PLANT PRODUCTS SALES"},
{
53, "POTENTIAL PLANT PRODUCTS SALES"},
{
54, "PROVED GAS PIPELINE SALES"},
{
55, "PROBABLE GAS PIPELINE SALES"},
{
56, "POSSIBLE GAS PIPELINE SALES"},
{
57, "POTENTIAL GAS PIPELINE SALES"},
{
58, "PROVED OIL PIPELINE SALES"},
{
59, "PROBABLE OIL PIPELINE SALES"},
{
60, "POSSIBLE OIL PIPELINE SALES"},
{
61, "POTENTIAL OIL PIPELINE SALES"},
{
0, NULL / terminator */ }};
for (i = 0; (q = RCposs[i].str); i++)
{
p = rc;
while (*p++ == *q++)
{
if ((*q == '\0'))
return RCposs[i].index;
}
}
return (0);
}
Based on the code that you have shown, it looks like the global Strings variable is a large block of memory which contains many different strings (one per record, presumably).
The original code:
result = strncmp (Strings + *((int *) xval),
Strings + *((int *) yval), ft);
compares the string at Strings[xval] to the string at Strings[yval], with maximum length ft.
I don't know what the NormalizeResClass(x) function does, but if it is going to work the in a similar fashion to the old code, it needs to return an int which represents the location of the beginning of a string in the Strings memory block. It must not return an index which would fall outside of that memory block, otherwise the call to strncmp would start reading from who knows where.
Update:
It looks like your NormalizeResClass function returns an integer ranking for a resource class string. In that case, you should not be using strncmp() and Strings[] at all. The code should look something like this:
if (typsort == 2)
{
int xRank = NormalizeResClass (xval);
int yRank = NormalizeResClass (yval);
if (xRank == yRank) { result = 0; }
else if (xRank > yRank) { result = 1; }
else if (xRank < yRank) { result = -1; }
}

Resources