How do I give best2 this assignment as an array? - arrays

Assume that two parallel arrays have been declared and initialized : healthOption an array of type char that contains letter codes for different healthcare options and annualCost an array of type int . The i-th element of annualCost indicates the annual cost of the i-th element of healthOption. In addition, there is an char variable , best2.Write the code necessary to assign to best2 the health option with the lower annual cost, considering only the first two healthcare options.
Thus, if the values of healthOption are 'B', 'Q', 'W', 'Z' and the values of annualCost are 8430, 9400, 7050, 6400 your code would assign 'B' to best2 because 8430 is less than 9400 and is associated with 'B' in the parallel array . (We ignore 'W' and 'Z' because we are considering only the first two options.)

int[] annualCost = new int[] { 8430, 9400, 7050, 6400 }
char[] healthOption = new char[] { 'B', 'Q', 'W', 'Z' };
int[] annualCostbest2 = new int[] { annualCost[0],annualCost[1] };
//Get Minimum value from Your array
int min = annualCostbest2.Min();
//Take index of lowest price value
int index = Array.IndexOf(annualCostbest2, min);
//Get value from your 2nd array
char best2 = healthOption[index];

Related

Print Arrays and maximum recurring element

I have 1 string of alphabetical characters. Each character can
occur 1 or more times.I want to put every third character into an array like 3rd,6th,9th,12th
I want to Print the arrays and also the maximum recurring element.
Sample Input 1:
S = “abcbjjfgqaazckuccccpcp”
Sample Output:
[ c, j, g, a, k, c, c]
Maximum recurring character: c
You can get this done using the below code:
s = 'abcbjjfgqaazckuccccpcp'
#print ('[ c, j, g, a, k, c, c]') #your reference of 3rd, 6th, 9th is wrong
print (list(s[2::3]))
#store the char and count as a dictionary
d = {x:s[2::3].count(x) for x in set(s[2::3])}
#get key for max value from dictionary
mkey = max(d, key = d.get)
mval = d[mkey]
#print both key and value
print (mkey,mval)
The output will be
['c', 'j', 'q', 'z', 'u', 'c', 'c']
c 3

How can I map a character to a pointer of another type?

I have a char*. I want to parse it, character by character, and store the location of each in an int*.
With the dummy-string "abbcdc", the content should be as follows
char int*
-------------
'a' -> 0
'b' -> 1,2
'c' -> 3,5
'd' -> 4
I want this to be accessible through a char* containing the entire alphabet, so that each character in the alphabet-pointer points to each separate integer-pointer. This is where I'm lost.
I know I can point to a pointer using the double-asterisk syntax
int **a = &aLocations;
But I don't really know how to refer to the locations-pointer by using a character as a reference. I am pretty new to C, so all pointers (pun intended) are appreciated.
Update 1:
int *aLocations = malloc(3*sizeof(int));
aLocations[0] = 13;
aLocations[1] = 9;
aLocations[2] = 57;
int **a = &aLocations;
This seems to work as expected, but a obviously remains an integer, not a char. I was thinking of writing a function something along the lines of
int *getCharLocations(char c) {
// returns a pointer to the stored character locations
}
but I don't know how to proceed with implementing it.
Ok then.
Although it would be possible it would be pretty ugly and complicated.
So if you do not mind i would suggest to drop char and use integers exclusively.
It is possible since char is in fact just small integer.
So first you would need to create your two dimensional alphabet array:
int *alphabet[26]; // this will create 26 element array of integer pointers
Now we will fill it:
int i = 0;
for(i = 0; i < 26; i++) {
alphabet[i] = malloc(100 * sizeof(int)); //alloc memory for 100 integers (should be enough for human language if we're talking about single words here)
alphabet[i][0] = 'a' + i; // this will put a letter as first element of the array
alphabet[i][1] = 2 // here we will keep index of first available position in our indices array
}
So now we have array like this:
'a', 2, ... // '...' means here that we have space to fill here
'b', 2, ...
...
'z', 2, ...
And you can add indices of occurences of letter to such construction like this:
alphabet[index_of_letter][alphanet[index_of_letter][1]] = index_of_letter; //put index at the end of array
alphabet[index_of_letter][1]++; // increment our index of available position
That's pretty much it.
I didn't test it so it may need some polishing but such approach should do the trick.
PS.
Someone in comments above noted uppercase letters - in such case you would need to extend array to 52 characters to store also occurences of uppercase letters (also fill first element with uppercase letter in for loop for such records). But i guess you will manage from now on

Compiling multiple reverse permutations

sorry if this isn't an appropriate question for here, it's just been melting my mind the last few hours and I'm sure I'm missing something obvious!
I've got a system set up which swaps the order of a series of entries in an array multiple times. For this I'm just using a Fisher-Yates swapping algorithm to create a corresponding array which where the corresponding index entry is to be moves to.
So what I want to be able to do is go back multiple steps. At the moment I'm trying to figure out the way of writing how I'd be able to get back from the second swap to the original order in a dynamically produced array using the two information from the swap arrays. I assume once I'm able to build one which goes back two steps in one go that I just keep applying the same approach to go back another step.
What would be the easiest approach of building an array of {'a','b','c','d'} using exclusively the information of swap[0], swap[1] and arr[1]?
The code below is pretty much pseudocode, everything is working fine in the actual program asides from generating the reverse permutation thing.
char theOriginal[4] = {'a', 'b', 'c', 'd'}; //the initial order
int swap[x][4];
char arr[x][4];
/*below code would actually be generated using functions*/
swap[0] = GetSwap(4); //eg. returns {2,3,0,1} generated using a Fisher-Yates swap
arr[0] = Swappit(theOriginal, swap[0]); //returns {'c', 'd', 'a', 'b'} permuted array produced by function which rearranged theOriginal's values to correspond with swap[0]
//all entries after the first one built in a loop
for(z=1; z<x; z++){
swap[z] = GetSwap(4); //e.g. return {1,3,2,0} another permutation built the same way
arr[z] = Swappit(arr[z-1], swap[z]); //from swap[z] applied to arr[0], we get {'d','b','a','c'}
}
If that code is too confusingly worded to give an answer to easily, here's a more stripped down one you can use:
char letters[4] = {'a', b', 'c', 'd'};
int move1[4] = {2, 3, 0, 1};
char reorder1[4] = {'c', 'd', 'a', 'b'};
int move2[4] = {1, 3, 2, 0};
char reorder2[4] = {'d', 'b', 'a', 'c'};
/**something happens here so that using move1 and move2,
a new integer array can be built which will give a third
reordering which matches letters, ie the follow outputs**/
int moveBack[4] = {2, 1, 3, 0};
char reorderBack = {'a', 'b', 'c', 'd'};
You simply have to compute the inverse permutation for each step and apply them in reverse order.
If you have a forward permutation P defined as
moveP[0] = n0
moveP[1] = n1
moveP[2] = n2
moveP[3] = n3
then you compute the corresponding inverse permutation P-1 such as
movePinv[n0] = 0
movePinv[n1] = 1
movePinv[n2] = 2
movePinv[n3] = 3
That way you have P-1(Y) = X if P(X) = Y.
In your example, if you start from array A0 and apply 2 permutations P and Q, giving the steps A1 = P(A0) and A2 = Q(A1) = Q(P(A0)), then to get back the initial array A0, you have to apply the inverse permutations in reverse order to the final array. That is A1 = Q-1(A2) then A0 = P-1(A1) = P-1(Q-1(A2)).
Note that for an improved memory usage you can definitely do this incrementally, accumulating all the inverse permutations in a single one (assuming you are only interested in retrieving the initial order but not the intermediate steps of course).
Edit : following your code, here is what the backward step could look like to. It's clearly not great if you plan to do it several times (since the inverse permutations would be computed and applied to the source array each time), but for a one-shot, it's the simplest way.
int backFrom = x - 1, backTo = 0; // for example
char state[4] = arr[backFrom];
int swapInvAux[4];
for (z = backFrom; z >= backTo; --z)
{
swapInvAux = InversePermutation(swap[z]);
state = Swappit(state, swapInvAux);
}
For better performance, parallel to the swap array you should store a chain of accumulated inverse permutations obtained by applying your Swappit function to the swap array itself. Doing so you would be able to reverse the final state to any intermediate state in a single step.

Any ideas on how to solve this matrix / 2x2D array computation?

I have 2 3x3 matrices each represented in 2D arrays.
First matrix holds elements [ I store PID so,the range of elements could be from millions Iam just simplifying it as A in my actual application it is an integer range A could be 200 and B could be 200000]
e.g., matrix element
{ A B C
B D C
C F B }
second holds weight of each location
e.g., Matrix weight
{ 9 7 5
8 6 1
7 5 4 }
so in the above example B is the heaviest element because its weight is 7+8+4 followed by C etc.,
How do I find out the top 3 highest element ?
One solution is:
Is to store the elements in a separate array A[9][2]( element, value and unique) looping the element matrix and then another loop to go through the value array and filling up the value corresponding to the element.
[ iterate to create a 9x2 key value matrix,iterate to sort, iterate to remove duplicates(since weights need to be consolidated ), - Is there a better way ? ]
Any other efficient way ? [hint : I need only 3 so i shouldnt use 9x2 ]
Let's assume you know you have only letters A-Z available and they are capitals.
char elems[3][3] = {
{ 'A', 'B', 'C' },
{ 'B', 'D', 'C' },
{ 'C', 'F', 'B' }
};
And you have similarly set up your weights...
You can keep track of counts like this:
int counts[26] = {0};
for( int i = 0; i < 3; i++ ) {
for( int j = 0; j < 3; j++ ) {
counts[elems[i][j] - 'A'] += weights[i][j];
}
}
Then it's just a case of finding the index of the three largest counts, which I'm sure you can do easily.
Forget that they're 2D arrays, and merge the two data sources into a single array (of pairs). For your example, you would get {{'A', 9}, {'B', 7}, {'C', 5}, {'B', 8}, ...}. Sort these (for example, with qsort), and then scan through the list, summing as you go -- and maintaining the top 3 scored keys you find.
[This solution always works, but only makes sense if the arrays are large, which on re-reading the question they're not].

Printing all possible words from a 2D array of characters

Stumbled upon this interview question recently,
Given a 2-dimensional array of characters and a dictionary in which a word can be searched in O(1) time. Need to print all the words from array which are present in dictionary. Word can be formed in any direction but has to end at any edge of array.(Need not worry much about the dictionary)
Input:
a f h u n
e t a i r
a e g g o
t r m l p
Output:
after
hate
hair
air
eat
tea
Note: Here "egg" is not a dictionary word because its not ending at the edge of array.
I've seen similar questions before, but was never able to think of a good algorithm to solve these kind of problems. Any help on how to approach these kind of problems (forming words from arrays of characters) will be highly helpful.
(The only way I could think of is to find all possible permutations of characters in the 2D array, and check if it ends on the edge of the array, and check if the permutation is a valid word from the dictionary in O(1) time)
Turn the array into a graph so that each cell [i,j]
has an edge shared with each one of its 4 neighbors [i+1,j], [i-1,j], [i,j+1], [i,j-1].
Then run DFS at each array-edge-cell and and keep checking the dictionary whether
the word in reverse is in it.
You did not mention anything about a character can be used only once - so without this restriction is problem of "Can we generate k (or more) different words?" is undecideable.1.
(With a constraint on the number of "visites" per element there are finite number of possibilities and the claim and proof does not hold of course).
Proof:
It is known that there is no algorithm A that can decide if a terminating algorithm B returns true for k or more different inputs. (will look for citation for this claim later if needed, trust me for now).
We will show that given an algorithm A that says if there are k or more generated words - we can decide if there are k or more different inputs that yield "true":
Let the (terminating) algorithm that decides if there are k or
more generated words be M.
Without loss of generality - assume binary alphabet (we can represent everything with it).
Let:
array = 0 1
0 1
Note we can generate any binary word while walking on this array.
Algorithm A:
input: algorithm B, natural number n
output: true if and only if algorithm B answers "true" for n or more different inputs.
The algorithm:
(1) use B(word) as the black box dictionary - if the answer is true, then word is in dictionary.
(2) use array as the array.
(3) Run M on (array,dictionary,n), and answer like it.
Note that if M answered true -> there are n or more accepted words -> there are n or more different inputs to B that yields true (definition of dictionary and since we can generate every input with array) -> the answer to the problem is true.
(if the algorithm answered false the proof is similar).
QED
Conclusion:
If we can repeat a character in the array more then a once (or to be exact - unbounded number of times) - then the problem is unsolveable without any information on the dictionary.
(1) An undecideble problem is a problem where there is no algorithm that can answer TRUE/FALSE correctly in 100% of the cases - For every algorithm, there is some case where the algorithm will get "stuck" in an infinite loop (or give a wrong answer). The most common of "undecideable" problems is the Halting Problem - which says - there is no algorithm A that can take any algorithm B and answer if B stops for some input w.
My solution is:
I suppose that I have an M*N array and there is no restriction in searching words. For example 'rood' and 'door' are 2 different words as being reversed of each other.
Start from the first letter (left, top). In this case, it is 'a'. And check adjacents if there are any words in dictionary(suppose there are words starting with 'ae' and 'af' ) Check whether they are already words or not and the index of the last letter is 0 or M-1 or N-1. If not, add them to a queue to look later. By turns, check all queued substrings like this and finish this this phase by prosessing all values in queue. Then check second letter and go on up to the last member of array. Like this, you will be able to check all possible words.
It works on one of my problems like this but Im not sure if you are looking also for complexity.
import java.util.HashSet;
import java.util.Set;
/**
* Given a 2-dimensional array of characters and a
* dictionary in which a word can be searched in O(1) time.
* Need to print all the words from array which are present
* in dictionary. Word can be formed in any direction but
* has to end at any edge of array.
* (Need not worry much about the dictionary)
*/
public class DictionaryWord {
private static char[][] matrix = new char[][]{
{'a', 'f', 'h', 'u', 'n'},
{'e', 't', 'a', 'i', 'r'},
{'a', 'e', 'g', 'g', 'o'},
{'t', 'r', 'm', 'l', 'p'}
};
private static int dim_x = matrix.length;
private static int dim_y = matrix[matrix.length -1].length;
private static Set<String> wordSet = new HashSet<String>();
public static void main(String[] args) {
//dictionary
wordSet.add("after");
wordSet.add("hate");
wordSet.add("hair");
wordSet.add("air");
wordSet.add("eat");
wordSet.add("tea");
for (int x = 0; x < dim_x; x++) {
for (int y = 0; y < dim_y; y++) {
checkAndPrint(matrix[x][y] + "");
int[][] visitedMap = new int[dim_x][dim_y];
visitedMap[x][y] = 1;
recursion(matrix[x][y] + "", visitedMap, x, y);
}
}
}
private static void checkAndPrint(String word) {
if (wordSet.contains(word)) {
System.out.println(word);
}
}
private static void recursion(String word, int[][] visitedMap, int x, int y) {
for (int i = Math.max(x - 1, 0); i < Math.min(x + 2, dim_x); i++) {
for (int j = Math.max(y - 1, 0); j < Math.min(y + 2, dim_y); j++) {
if (visitedMap[i][j] == 1) {
continue;
} else {
int[][] newVisitedMap = new int[dim_x][dim_y];
for (int p = 0; p < dim_x; p++) {
for (int q = 0; q < dim_y; q++) {
newVisitedMap[p][q] = visitedMap[p][q];
}
}
newVisitedMap[i][j] = 1;
checkAndPrint(word + matrix[i][j]);
recursion(word + matrix[i][j], newVisitedMap, i, j);
}
}
}
}
}

Resources