Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
Any idea how to do it?. i'm new into programming, and for now im stuck at this exercice.
for(i = 0; i < 9;++i) {
for(j = 0; j < 9;++j) {
printf("%d ", rand()%2);
}
printf("\n");
}
return 0;
I would
Start by creating a matrix with all 0:s.
typedef unsigned char byte;
byte m[9][9] = {0};
Add the number of 1:s you want.
void fill(byte(*arr)[9][9], unsigned count, byte value) {
for(unsigned idx = 0; idx < count; ++idx) {
(*arr)[idx / 9][idx % 9] = value;
}
}
int rnd(int min, int max) {
return rand() % (max - min + 1) + min;
}
// ...
fill(&m, rnd(5, 10), 1); // this will fill it with 5 to 10 1:s
// fill(&m, 10, 1); // alternative if you want exactly 10 1:s
Shuffle the result.
void swap(byte *a, byte *b) {
byte tmp = *a;
*a = *b;
*b = tmp;
}
void shuffle(byte(*arr)[9][9]) {
for (unsigned idx = 9*9 - 1; idx > 0; --idx) {
unsigned swno = rnd(0, idx);
swap(&((*arr)[idx / 9][idx % 9]),
&((*arr)[swno / 9][swno % 9]));
}
}
// ...
shuffle(&m);
This should result in an equal probability for each possible permutation to appear.
Demo
Another option that perhaps is easier to visualize could be to create a basket containing tickets with all the possible positions in the matrix written on them. Then randomly pick tickets from this basket.
Start by creating a matrix with all 0:s just like in the first example.
Create an array with all the positions in your matrix. This is the "basket" mentioned above. You have a 9 x 9 matrix so that's just an array with the numbers 0 to 80. I'll call the basket picklist below.
unsigned picklist[9*9];
for(unsigned idx = 0; idx < 9*9; ++idx) {
picklist[idx] = idx; // fill picklist with the values [0,80]
}
Iteratively and randomly select which position in the above picklist you should choose from, while removing the picked positions from the list and leaving only the non-picked position in it.
for(unsigned co = 1; co <= count; ++co) {
unsigned lastidx = 9*9 - co; // the last non-picked position
// here you put your hand in the basket to draw a ticket:
unsigned pickidx = rnd(0, lastidx); // randomly chosen index in the picklist
// and this is what was written on the ticket:
unsigned chosenidx = picklist[pickidx]; // the position gotten from the picklist
// Assign value to the chosen position
(*arr)[chosenidx / 9][chosenidx % 9] = value;
// Put the last non-picked position in the picklist where the position we just
// used was, leaving only non-picked positions in the lower part of picklist.
// This is equivalent to throwing the chosen ticket away.
picklist[pickidx] = picklist[lastidx];
}
This approach should also assure that all permutations have an equal chance of appearing in the final matrix. It doesn't require that you shuffle the matrix afterwards since every position you pick from the basket will be unique and random.
Demo
This will not result in perfect distribution but should be good enough for a start:
int ones_placed = 0;
// pick one of the following 2 lines. Not both!
int ones_to_place = rand()%11; // for up to 10 entries
int ones_to_place = 10; // for exactly 10 entries
while (ones_placed < ones_to_place)
{
// Get random position for the next 1;
int row = rand() % 9;
int col = rand() % 9;
// Don't count same cell twice but skip instead.
if (arr[row][col] == 0)
{
arr[row][col] = 1;
ones_placed ++;
}
}
int crt_ones = 0
for(i = 0; i < 9;++i) {
for(j = 0; j < 9;++j) {
rand_no = rand() % 2;
if (crt_ones < 9 && rand_no == 1) {
a[i][j] = rand_no;
crt_ones++;
} else a[i][j] = 0;
printf("%d ", rand()%2);
}
printf("\n");
}
return 0;
The idea is to initialise your matrix and to keep track in a variable (crt_ones in out case) how many random one's have I generated so far.
As it is an excercise, I am not writing you the code, but instead giving a hint:
Initialize the matrix all to 0. Initialize a counter to 0.
Randomly select an index into the matrix.
Check if it is 0, write 1 and increment a counter. If it is 1 skip to the next.
Repeat from 2. until the counter is 10
I have completed and submitted the easier version of the problem set for the week I'm on, I'm just interested in finishing the harder version for the learning experience, but I'm stuck on what seems like the crux of it. Basically you are supposed to implement a voting system that records all the ranks of each of the voters. So for instance let's say you have 3 candidates (A, B, and C). If the first voter chooses candidate C as their first choice, and A as their second, (B as their last), the orginal array you would have looks like this [2,0,1] signifying that the the third candidate is the first choice, the first candidate is the second choice, and the second candidate is the third choice. The code I've used for this is the following:
bool vote(int rank, string name, int ranks[])
{
for (int i = 0; i < candidate_count; i++)
{
if(strcmp(candidates[i], name) == 0)
{
ranks[rank] = i;
for( int j = 0; j < candidate_count; j++)
{
printf("%i\n", ranks[j]);
}
return true;
}
}
return false;
}
But then we are asked to convert it into a 2d array that compares each of the candidates in basically a 1vs1 battle. So in our ABC example, the array should convert from [2,0,1] to [[0,1,0],[0,0,0],[1,1,0]]
where the first array represents the first candidate and how they did against the 2nd and 3rd respectively, etc. (the first location in the first array should always be 0 because you cant compare the candidate to how many votes they had against themself, same with the middle spot in the second array and the last spot in the last array). In other words array[i][j] represents how candidate i did against candidate j. You are meant to work this function out using the array returned from the vote function.
I know that it will involve another nested loop, possibly 3 layers. I need a point in the right direction. I've made a bunch of different tweaks to a function that looks like this but I know they've all been wrong because I'm resorting to trial and error rather than logic because the logic has defeated me at this point. Maybe this forum isn't really meant for logical help but I'd still like to work this out on my own without being given the answer. Anyway here's the latest version of the function that I've been helplessly tinkering with.
void record_preferences(int ranks[])
{
printf("\n");
for (int i = 0; i < candidate_count; i++)
{
for (int j = 0; j < candidate_count; j++)
{
for (int k = 0; k < candidate_count; k++)
{
if((ranks[k] > i && ranks[k] < j) || (ranks[k] < i && ranks[k] > j))
{
preferences[i][j] += 1;
}
}
printf("%i\n", preferences[i][j]);
}
}
return;
}
Keep in mind I've already gotten my grade for this week and I don't plan on submitting this work so it's not cheating even if you do straight up tell me the answer, but I'd prefer if you didn't. I know a lot of people are of the belief that you need to work the logic out yourself otherwise you're not really learning, which I kind of get, but at the same time you can only bang your head against a wall so many times before seeking help.
Thanks.
Edit: here is a link to a more clear explanation. The function in question starts around the 7:30 mark. https://www.youtube.com/watch?v=kb83NwyYI68&t=492s&ab_channel=CS50
Using the term vote instead of ranks for consistency with the video. It is also clearer as we also need to deal with the plural form votes.
The solution is a little long but the key insight is function rank() which returns the position of candidate for a given vote. We call the rank() for candidate i and j and incrementpreferences[i][j] if i ranks higher (<) than j.
Introduced enum candidates for readability (used candidate names from the video just to have a 2nd test case; comment out definition of QUESTION). This will also give you a compile error if you misspell a candidate name.
The code assumes that all candidates are ranked. It's straight forward to decouple number of candidates and the number of candidates that are being ranked.
#include <stdio.h>
#define LEN(a) (sizeof(a) / sizeof(*a))
enum candidates {
Alice,
Bob,
Charlie
};
void preferences_print(size_t candidates_len, unsigned preferences[candidates_len][candidates_len]) {
for(size_t i = 0; i < candidates_len; i++) {
for(size_t j = 0; j < candidates_len; j++) {
printf("%u%s", preferences[i][j], j + 1 < candidates_len ? ", " : "");
}
printf("\n");
}
}
unsigned rank(size_t candidates_len, unsigned vote[candidates_len], enum candidates candidate) {
for(size_t i = 0; i < candidates_len; i++) {
if(vote[i] == candidate) return i;
}
printf("Error: skipping invalid cadidate %d", candidate);
return 0;
}
void votes_to_preferences(size_t votes_len, size_t candidates_len, enum candidates votes[votes_len][candidates_len], unsigned preferences[candidates_len][candidates_len]) {
for(size_t v = 0; v < votes_len; v++) {
for(size_t i = 0; i < candidates_len; i++) {
for(size_t j = 0; j < candidates_len; j++) {
preferences[i][j] +=
rank(candidates_len, votes[v], i) <
rank(candidates_len, votes[v], j);
}
}
}
}
int main() {
enum candidates votes[][3] = {
#define QUESTION
#ifdef QUESTION
{ Charlie, Alice, Bob },
#else // VIDEO
{ Alice, Charlie, Bob },
{ Alice, Charlie, Bob },
{ Charlie, Alice, Bob },
{ Bob, Alice, Charlie }
#endif
};
unsigned preferences[LEN(*votes)][LEN(*votes)] = { { 0 } };
votes_to_preferences(LEN(votes), LEN(*votes), votes, preferences);
preferences_print(LEN(*votes), preferences);
return 0;
}
I have an array and I need to find n tie cases in the array for example {1,2,3,3} I need the program to return both 3's
void print_winner(void)
{
// TODO
string arr[9];
string name = "";
int largest = 0;
for (int i = 0; i < voter_count; i++)
{
if (largest<candidates[i].votes)
{
largest = candidates[i].votes;
name = candidates[i].name;
}
}
// arr[0] = name;
printf("%s\n", name);
return;
}
in this code candidates is a struct with two attributes: name and votes
I need the program to print the name with the highest number of votes even if there is a 3-way tie
I was thinking I would traverse the list find the largest int and then remove that int and traverse the list again to see if any elements equal the largest element from the original list and if so add the name to the array and in the end print all the name(s)
An approach in programming that is often good is to divide the problem up and solve its separate parts.
In this case, one way of setting up the problem is to print the names of all those that have the highest score. But that problem is somewhat complex.
An alternative way of setting up the problem would be as follow:
Find the maximum score.
After having found the maximum score, print the names of all those that have the highest score.
Each of these sub-problems are easier, and should together solve the problem.
I much prefer teaching others how to fish, so I don't want to spoil or ruin your chances for learning and improving and becoming awesome by implementing the solution for you in code. You are more than welcome to ask for clarification, however, I very much like to help :).
I think u just need to loop the array again after you find the candidate with max votes, to look for if there is another candidate or more with same no. of votes.No need to remove records.
Until you passed every vote count, you do not know the largest vote count.
The currently largest's name would be needed to be corrected when a really larger largest is found. So do:
void print_winner_1(void)
{
// globals: candidates: array
// voter_count: size of array
int largest = 0;
for (int i = 0; i < voter_count; i++)
{
if (largest < candidates[i].votes)
{
largest = candidates[i].votes;
}
}
for (int i = 0; i < voter_count; i++)
{
if (largest == candidates[i].votes)
{
printf("%s\n", candidates[i].name);
}
}
}
The above could store a largest_first_i for a small speed improvement.
Collecting intermediary results in full:
void print_winner_2(void)
{
// globals: candidates: array
// voter_count: size of array
string names[9]; // Tie names.
int name_count = 0;
int largest = 0;
for (int i = 0; i < voter_count; i++)
{
if (largest < candidates[i].votes)
{
name_count = 0; // Reset list of ties.
largest = candidates[i].votes;
}
if (largest == candidates[i].votes)
{
if (name_count == 9) { // More than 9 temporary (!) ties.
print_winner_1();
return;
}
names[name_count++] = candidates[i].name;
}
}
for (int i = 0; i < name_count; i++)
{
printf("%s\n", names[i]);
}
}
I did one with two full loops, and one collecting the ties immediately.
The second solution is prone to overflow of the result array (if there are more than 9 candidates), say in the case of [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 23 23] the first intermediary tie would overflow for largest == 0.
Also the second need not be faster, as you need to store into names and for every increase of largest. Almost a case of premature optimization.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I want to find the index of largest element in a given array in C .
I have tried insertion sort algorithm to determine the largest number in array after that I compared largest value with my all previous array's element and It did not work.
void insertion_array(float array[], int n) //* insertion algorithm*//
{
int i = 1, j;
float x;
for (; i < n; i++) {
x = array[i];
j = i - 1;
while ((j >= 0) && (array[j] > x)) {
array[j + 1] = array[j];
j = j - 1;
}
array[j + 1] = x;
}
}
uint8_t Largest_Number_Finder(float arr[], uint8_t n) {
uint8_t index;
insertion_array(arr, n);
for (int i = 0; i < n; i++) {
if (arr[i] > arr[n - 1]) {
index = i;
}
}
return index;
}
I expected to take largest number index but Algorithm gives always last elements index. What should I do to make it right?
Edit=What you navigated as duplicate was to find largest element. I am aiming to find the index of largest element in array.
As "Some programmer dude" mentioned in the comment, if your purpose is to just find the index of the largest value, you don't need to implement insertion or any other algorithm to sort the array.
You can probably make a function like this.
int find_max_value(float array[], int length)
{
// set the value of index 0 as the "current max value"
float max_value = array[0];
// the same goes for the index number
int max_index = 0;
// go through the array
for(int i = 1; i < length; i++)
{
// if the next index's value is greater than the "current max value"
// update the max_value and max_index
if(array[i] > max_value)
{
max_value = array[i];
max_index = i;
}
}
return max_index;
}
and try calling that find_max_value() function with whatever input values, like
int result = find_max_value(array1, 10); // just an example supposing that you have declared an array called "array1" and its length is 10
printf("%d", result); // see what the return value of the find_max_value() function would be
The question at hand is:
Q8. Given an unsorted array A[]. The task is to print all unique pairs in the unsorted array with equal sum. Consider the Input: A[] = {6, 4, 12, 10, 22, 54, 32, 42, 21, 11}
Explain the approach of solving the above problem, and write the code in any one programming language C/C++/Python/Java. What is the time complexity of the above problem?
Here is my solution to the above problem (in C) :
#include <stdio.h>
int main(){
int arr[]={6,4,12,10,22,54,32,42,21,11};
int len=sizeof(arr)/sizeof(arr[0]);
for(int i=0;i<len;i++)
for(int j=i+1;j<len;j++)
for(int k=i+1;k<len;k++)
for(int l=k+1;l<len;l++)
if(arr[i]+arr[j]==arr[l]+arr[k])
printf("(%d,%d),(%d,%d)\n",arr[i],arr[j],arr[k],arr[l]);
return 0;
}
My logic is to take one element at a time, and take its sum with every other element, and for each such iteration, compare the sum of two other unique pair of elements to it.
For example, when i=0, j=3, arr[i]+arr[j]=16. When k=1,l=2, arr[k]+arr[l]=16. Since the pairs are unique (6,10) and (4,12) and their sum is equal, I print them.
Note that the pairs are assumed to be unordered pairs so that (a,b) is the same as (b,a) and so we don't need to repeat that, as they have to be unique.
My question is : I know that my code is almost O(n^4). How can I improve/optimise it further?
FIrst you precompute the sum of each pair and keep the result in a matrix PAIRSUM.
PAIRSUM(0, 0) = 12
PAIRSUM(0, 1) = 10 a s o
Next, you loop over the PAIRSUM and see where 2 entries are similar.
So you reduced the big problem to a smaller one, in which you check the equality of 2 numbers, not of 2 sums of numbers.
For this you keep a vector PAIR in which at index X you keep the entries in PAIRSUM where the sum was X.
For example, PAIR(10) = { {0, 1} }.
You can also consider in PAIRSUM only the matrix above the diagonal, so for which the indexes (i,j) have i>j.
It would be easier in C++, Python, or Java because those languages provide high level containers. In Python, you could use a defaultdict(list) where the key would be the sums and the value a list of pairs giving that sum.
Then you only have to process unique pairs (N2 / 2)
result = collections.defaultdict(list)
for i, a in enumerate(A):
for b in A[i+1:]:
result[a+b].append((a,b))
It will be slightly more complex in C because you do not have the high-level direct access dict. If you can waste some memory and only have small numbers like here, you can say that the highest sum will be less than twice the biggest number in the input array, and directly allocate an array of that size. That way you ensure direct access from a sum. From there, you just use a linked list of pairs and that is all. As a bonus you even get a sorted list of sums.
I you cannot assume that numbers are small you will have to build a direct access container. A hash type container using N*N/2 as size (N being the length of A) and sum%size as hash function should be enough.
For completeness, here is a possible C code not doing the small numbers assumption (this code displays all pairs not only the ones with duplicated sums):
#include <stdio.h>
#include <stdlib.h>
// a node in a linked list of pairs
struct pair_node {
int first;
int second;
struct pair_node *next;
};
// a slot for a hash type containers of pairs indexed by their sum
struct slot {
int number;
struct pair_node *nodes;
struct slot *next;
};
// utility function to find (or create) a slot for a sum
struct slot* find_slot(struct slot **slots, int size, int sum) {
struct slot *slt = slots[sum%size];
while (slt != NULL) {
if (slt->number == sum) {
return slt;
}
slt = slt->next;
}
slt = malloc(sizeof(struct slot));
slt->number = sum;
slt->nodes = NULL;
slt->next = slots[sum%size];
slots[sum%size] = slt;
return slt;
}
int main() {
int A[] = {6,4,12,10,22,54,32,42,21,11}; // the array of numbers
int N = sizeof(A) / sizeof(A[0]);
int arr_size = N * N / 2; // size of the hash table of pairs
struct slot** result = malloc(arr_size * sizeof(struct slot *));
for (int i=0; i<arr_size; i++) {
result[i] = NULL;
}
// process unique pairs
for (int i=0; i<N-1; i++) {
for (int j=i+1; j<N; j++) {
int sum = A[i] + A[j];
// allocate and initialize a node
struct pair_node *node = malloc(sizeof(*node));
node->first = A[i];
node->second = A[j];
// store the node in the hash container
struct slot *slt = find_slot(result, arr_size, sum);
node->next = slt->nodes;
slt->nodes = node;
}
}
// display the result
for (int i=0; i<arr_size; i++) {
for (struct slot* slt=result[i]; slt != NULL;) {
printf("%d :", slt->number);
struct pair_node *node = slt->nodes;
while(node != NULL) {
printf(" (%d,%d)", node->first, node->second);
node = node->next;
free(node); // free what has been allocated
}
printf("\n");
struct slot *old = slt;
slt = slt->next;
free(old);
}
}
free(result);
return EXIT_SUCCESS;
}
C code for calculating all the sums and storing the sums with indexes inside an array of structures. Then we sort the structures and print adjacent structure elements with the same sum.
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
// for debugging
#define debug(...) ((void)0) // printf(__VA_ARGS__)
// two indexes and a sum
struct is_s {
// one index inside the array
size_t i;
// the other index also inside the array
size_t j;
// no idea, must be random
int sum;
};
// used for qsoring the struct is_s
static int is_qsort_compare_sum(const void *a0, const void *b0) {
const struct is_s * const a = a0;
const struct is_s * const b = b0;
return a->sum - b->sum;
}
int unique_pairs(const size_t len, const int arr[len]) {
if (len <= 1) return 0;
// The number of unsorted combinations must be n!/(2!*(n-2)!)
const size_t islen = len * (len - 1) / 2; // #MOehm
debug("%zu\n", islen);
struct is_s * const is = malloc(islen * sizeof(*is));
if (is == NULL) {
return -ENOMEM;
}
size_t isidx = 0;
for (size_t i = 0; i < len; ++i) {
for (size_t j = i + 1; j < len; ++j) {
assert(isidx < islen); // just for safety
struct is_s * const p = &is[isidx++];
p->i = i;
p->j = j;
p->sum = arr[i] + arr[j];
debug("[%zu]=[%zu]=%d [%zu]=%d %d\n", isidx, p->i, arr[p->i], p->j, arr[p->j], p->sum);
}
}
qsort(is, islen, sizeof(*is), is_qsort_compare_sum);
for (size_t i = 0; i < islen - 1; ++i) {
debug("([%zu]=%d,[%zu]=%d)%d = ([%zu]=%d,[%zu]=%d)%d\n",
is[i].i, arr[is[i].i], is[i].j, arr[is[i].j], is[i].sum,
is[i+1].i, arr[is[i+1].i], is[i+1].j, arr[is[i+1].j], is[i+1].sum
);
if (is[i].sum == is[i + 1].sum) {
printf("(%d,%d),(%d,%d) = %d\n",
arr[is[i].i], arr[is[i].j],
arr[is[i+1].i], arr[is[i+1].j], is[i].sum);
}
}
free(is);
return 0;
}
int main(void) {
const int arr[] = {6,4,12,10,22,54,32,42,21,11};
return unique_pairs(sizeof(arr)/sizeof(*arr), arr);
}
The result I get is:
(6,10),(4,12) = 16
(10,22),(21,11) = 32
(12,21),(22,11) = 33
(22,21),(32,11) = 43
(32,21),(42,11) = 53
(12,42),(22,32) = 54
(10,54),(22,42) = 64
As I wonder if this is correct, as #Bathsheba noted, I think the worst case is O(n*n).
It can be done in O(N^2 * log(N^2) * M), where M is the maximum number of pairs(i, j) that have the same sum, so in worst case it would be O(N^3 * log(N)).
Lets iterate for every pair 0 <= i,j < N in order (increasing or decreasing), we have to save the sum of all the previous pairs(i, j) (to know which previous pairs have a certain sum) this can be done with a map with a integer key and a vector of pairs for the mapped value; then for every pair(i, j) you search in the map for it's sum (key = A[i] + A[j]), then al the pairs store in map[sum] are answers to this pair(i, j).
You don't have to worry about for the following pairs to (i, j) that have the sum because the following pairs when they be processed they will count it.
Here is a Java solution:
import java.util.*;
class Duplicate {
public static void main(String[] args) {
int [] a = {5,3,1,4,5,6,3,7,0,10,6,4,9,1};
List<Integer> li = new ArrayList<Integer>();
int p1=0, p2=0;
for(int i=0; i<a.length;i++) {
for(int j=i+1; j<a.length;j++){
if(a[i]+a[j] == 10) {
p1 = a[i];
p2 = a[j];
if(!li.contains(Math.abs(p2-p1))) {
li.add(Math.abs(p2-p1));
System.out.println("Pairs" + ":" + p1 + "," + p2);
}
}
p1=0;
p2=0;
}
}
}
}