Student Locker puzzle - c

/* There are 100 students and 100 lockers. Student 1 opens all, student 2 closes every second one, student 3 changes every third
locker(closes if open, opens if close), Student 4 changes every forth locker and so on for all 100 students.
Which locker will be left open? */
Here is my code thus far:
#include <stdio.h>
int main(void)
{
int locker[100], i, closed = 0, opened = 0;
for(i=0; i<100; i++) locker[i] = 1;//0 means closed locker, 1 means open locker
for(i=1; i<101; i++) if(i % 2 == 0) locker[i-1] = 0; // every second locker is closed by second student...(2,4,6,7)
for(i=3; i<101; i++){ // i means student no. i
if(locker[i-1] == 0) locker[i-1] = 1;
if(locker[i-1] == 1) locker[i-1] = 0;
if I substitute "if(locker[i-1] == 1)" with "else" why the program doesn't work? Correct result is opened 1 closed 99. If I use 'else' result becomes opened 50 and closed 50
}
for(i=0; i<100; i++){
if(locker[i] == 0) closed = closed + 1;
else opened = opened + 1;
}
printf("opened locker %d\nclosed locker %d", opened, closed);
return 0;
}
This is my first post in stack overflow. Correct me if I've done anything wrong.

I'll give you a few hints to help you out.
The answer is that 10 lockers remain open, 90 are closed.
For this particular problem, it's easier to write the code if you avoid zero-based indexing. So
declare the array as int locker[101]; and then use indexes 1 thru
100 to represent the 100 lockers.
The Nth student is supposed to change every Nth locker. So you need
two nested for loops. The outer loop keeps track of n, and the
inner loop flips lockers.
The inner loop that only affects every Nth locker should look like
this
for ( i = n; i <= 100; i += n ) // every Nth locker
locker[i] = 1 - locker[i]; // flip the locker
Note that instead of the normal i=0 and i++, we have i=n
and i+=n. So, for example, if n is 3, then the values of i
are 3,6,9,...

Though I have not checked entire code and the logic of your question is not very clear to me, these lines seem to be problematic in your code:
if(locker[i-1] == 0) locker[i-1] = 1;
if(locker[i-1] == 1) locker[i-1] = 0;
What you're doing here is if a value is 0, then you are setting it to 1, then you are checking again, if it is 1, you are setting it to 0. So, so in this case all values will be set to 0 after running through both these statements.
Instead you should be doing
if(locker[i-1] == 0) locker[i-1] = 1;
else locker[i-1] = 0;

Note that your loop is wrong because you are looping over every locker for the third student and not looping over the remainder. You should for each student (n) change every nth locker to the reverse.
Also when you have the two ifs in a row. If the first if opens a locker, the second if sees it open and closes it (which is wrong). The else is required to actually change it.
Another point is that you can use exclusive or instead of the if locker[i] ^= 1
#include <stdio.h>
int main(void)
{
int locker[100], i, k, closed = 0, opened = 0;
for(i=0; i<100; i++) {
if (i%2 == 0) locker[i] = 1; // odd lockers (base 1) stay open
else locker[i] = 0; // even lockers (base 1) are closed
//0 means closed locker, 1 means open locker
for(i=3; i<101; i++){ // i means student no. i
for (k=i; k<101); k+=i) { // change every ith locker
// if (locker[k-1] == 0) locker[k-1]=1
// else locker[i-1] = 0;
// use exclusive or instead of if
locker[i-1] ^= 1;
}
}
}
// Now check the number open or closed
for(i=0; i<100; i++){
if(locker[i] == 0) closed = closed + 1;
else opened = opened + 1;
}
printf("opened locker %d\nclosed locker %d", opened, closed);
return 0;
}

solution without using an array.
#include <iostream>
using namespace std;
int main()
{
int studentTotal , lockerTotal, visit, totalOpened = 0, totalClosed = 0;
cout << "Enter number of students" << endl;
cin >> studentTotal;
lockerTotal = studentTotal;
for (int locker = 1; locker <= lockerTotal; locker++ ){ // locker loop
cout << "\n\n\nLocker no." << locker << endl;
cout << " is visited by student(s) ";
visit = 0;
for (int student = 1 ; student <= studentTotal; student++) { // student loop
if( locker % student == 0) {
cout << student << ", ";
visit++;}
}//end of locker loop
cout << "\nTotal number of visits: " << visit;
if (visit % 2 == 0){
cout << " the locker will stay closed.";
totalClosed++;}
else { cout << " the locker will be opened.";
totalOpened++;}
} //end of student loop
if (lockerTotal == totalOpened + totalClosed) {
cout << "\n\n\nOf total lockers (" << lockerTotal << "), " << totalOpened << " will be left open." << "(" << totalClosed << ") " << "will be closed." << endl;
}else cout << "Error!!";
return 0;
}

LOCKERS is the new FIZZBUZZ.
Here's a version which uses Booleans.
/* locker problem.c
*/
#include <stdio.h>
#include <stdbool.h>
int main (void)
{
bool locker[101]; // locker open = true, closed = false
// student 1 opens all lockers
for (int i = 1; i <= 100; ++i) {
locker[i] = true;
}
// subsequent students toggle (flip) subsequent lockers
for (int i = 2; i <= 100; ++i) {
for (int j = i; j <= 100; j += i) {
locker[j] = ! locker[j];
}
}
// display results
printf("\nopen lockers:");
for (int i = 1; i <= 100; ++i) {
if (locker[i]) {
printf(" %d", i);
}
}
putchar('\n');
return 0;
}
At the conclusion of the process the open lockers are the ones with a number which is a perfect square -- a perfect square has an odd number of divisors.

Related

C, help continue..? in while loop - polynomial ADT

When the coef is 0, I used continue to not print, but only printTerm(a) comes out and the printTerm(b) part does not come out.
When I delete the (if & continue) statement, both printTerm(a) and printTerm(b) appear, so it seems that there is a problem here (if & continue) statement.
How can I solve this?
int main() {
a[0].coef = 2;
a[0].expon = 1000; // 2x^1000
a[1].coef = 1;
a[1].expon = 2; // x^2
a[2].coef = 1;
a[2].expon = 0; // 1
b[0].coef = 1;
b[0].expon = 4; // x^4
b[1].coef = 10;
b[1].expon = 3; // 10x^3
b[2].coef = 3;
b[2].expon = 2; // 3x^2
b[2].coef = 1;
b[2].expon = 0; // 1
printTerm(a);
printTerm(b);
return 0;
}
void printTerm(polynomial *p) {
int i=0;
printf("polynomial : ");
while(p[i].expon != -1) {
if(p[i].coef == 0) continue;
printf("%dx^%d", p[i].coef, p[i].expon);
i++;
if(p[i].expon != -1 && p[i].coef > 0) printf(" + ");
}
printf("\n");
}
Because you only increment i if p[i].coef is not equal to 0.
If p[i].coef == 0 it skips the increment part and function is stuck in infinite loop, always checking the same array item.
EDIT:
Way to fix this:
Instead of if(p[i].coef == 0) continue; use:
if (p[i].coef == 0)
{
i++;
continue;
}
This way while loop evaluetes next array item instead of being stuck on the same.

How can I correctly format these loops in C how my professor wants it?

For my lab project I have to
For each integer 0 < n <= 100, find all of the integers between one and n which divide n without a remainder.
I have worked out the code but I am unsure how to format it in the way he wants.
Format: number(# of factors): factors
Examples:
2:( 2) 1,2
3:( 2) 1,3
4:( 3) 1,2,4
What the current output looks like:
1: 1
2: 1
2: 2
3: 1
3: 3
4: 1
4: 2
4: 4
5: 1
5: 5
6: 1
6: 2
6: 3
6: 6
7: 1
7: 7
8: 1
8: 2
8: 4
8: 8
9: 1
9: 3
9: 9
10: 1
10: 2
10: 5
10: 10
#include <stdio.h>
int main() {
int ini[100], i, j, d, n = 0;
for (i = 1; i <= 100; i++){
n = n+1;
ini[i] = n;
for (d = 1; d <= n; d++){
if (ini[i] % d == 0)
printf("%d: %d\n", ini[i], d);
}
}
}
Aw, c'mon, let's have a little fun here. Everyone else is suggesting the "usual" way. But Back In The Day (tm) we didn't have memory to waste on things like keeping track of stuff. We just used the paper as our memory! :-)
I suggest looping over the values to be tested (1 - 100), then inside the first loop have another loop which counts from from 1 to n, printing the divisor values which give a remainder of zero. At the end of the loop I'd overprint the n value and then add in the number of factors found, then loop back for the next value.
In code this looks a lot like:
#include <stdio.h>
int main()
{
int n, d, i;
int factor_count;
for (n = 1 ; n <= 100 ; n += 1)
{
printf("%3d( ): ", n);
factor_count = 0;
for (d = 1 ; d <= n ; d += 1)
{
if (n % d == 0)
{
printf("%c%d", (factor_count > 0 ? ',' : ' '), d);
factor_count += 1;
}
}
printf("\r%3d(%3d)\n", n, factor_count);
}
}
This code takes advantage of the fact that \r returns the print carriage (or the cursor on video terminals) to the left margin without advancing the roller (or the cursor - really, the cursor is far too busy and needs a rest! :-) to the next line, in order to avoid having to keep an array to store the factors in. It would be a lot of fun to watch run on an old ASR-33 Teletype - anybody got one to test with?
:-)
Before adapting your solution to generate the desired output, it would help to see the wood for the trees by removing the redundancy from your current solution:
In this solution, n == i is invariant so n is redundant, and the array ini[] is entirely redundant, because you only ever read/write ini[i] and ini[i] == i is invariant, so all instances of n and ini[i] can be replaced with i. j is just unused. Then neither i nor d are used before or after the loops they control, so can be localised by declaring them in the loop thus minimising the scope (just good practice).
Then your code reduces to the following equivalent:
int main() {
for( int i = 1; i <= 100; i++){
for( int d = 1; d <= i; d++){
if (i % d == 0)
printf("%d: %d\n", i, d);
}
}
return 0 ;
}
Now to obtain the required output, you don't know the number of factors until you have determined the list of factors, so the solution is to generate the list first while counting, then print the output.
That can be done in a second loop printing an array of stored factors, or even a second loop that recalculates the factors a second time - but those answers have already been given. Instead you could directly generate the list string as you go, then append it to the number/count output:
#include <stdio.h>
int main()
{
for( int i = 1; i <= 100; i++ )
{
char factor_list_out[80] = "" ;
int factor_count = 0 ;
int factor_out_index = 0 ;
for( int d = 1; d <= i; d++)
{
if( i % d == 0)
{
factor_count++ ;
factor_out_index += sprintf( &factor_list_out[factor_out_index], "%d,", d ) ;
}
}
factor_list_out[factor_out_index - 1] = 0 ; // remove trailing comma
printf( "%3d:(%2d) %s\n", i, factor_count, factor_list_out ) ;
}
return 0 ;
}
Output:
1:( 1) 1
2:( 2) 1,2
3:( 2) 1,3
4:( 3) 1,2,4
5:( 2) 1,5
6:( 4) 1,2,3,6
7:( 2) 1,7
8:( 4) 1,2,4,8
9:( 3) 1,3,9
10:( 4) 1,2,5,10
11:( 2) 1,11
12:( 6) 1,2,3,4,6,12
13:( 2) 1,13
14:( 4) 1,2,7,14
15:( 4) 1,3,5,15
16:( 5) 1,2,4,8,16
17:( 2) 1,17
18:( 6) 1,2,3,6,9,18
19:( 2) 1,19
20:( 6) 1,2,4,5,10,20
21:( 4) 1,3,7,21
22:( 4) 1,2,11,22
23:( 2) 1,23
24:( 8) 1,2,3,4,6,8,12,24
25:( 3) 1,5,25
26:( 4) 1,2,13,26
27:( 4) 1,3,9,27
28:( 6) 1,2,4,7,14,28
29:( 2) 1,29
30:( 8) 1,2,3,5,6,10,15,30
31:( 2) 1,31
32:( 6) 1,2,4,8,16,32
33:( 4) 1,3,11,33
34:( 4) 1,2,17,34
35:( 4) 1,5,7,35
36:( 9) 1,2,3,4,6,9,12,18,36
37:( 2) 1,37
38:( 4) 1,2,19,38
39:( 4) 1,3,13,39
40:( 8) 1,2,4,5,8,10,20,40
41:( 2) 1,41
42:( 8) 1,2,3,6,7,14,21,42
43:( 2) 1,43
44:( 6) 1,2,4,11,22,44
45:( 6) 1,3,5,9,15,45
46:( 4) 1,2,23,46
47:( 2) 1,47
48:(10) 1,2,3,4,6,8,12,16,24,48
49:( 3) 1,7,49
50:( 6) 1,2,5,10,25,50
51:( 4) 1,3,17,51
52:( 6) 1,2,4,13,26,52
53:( 2) 1,53
54:( 8) 1,2,3,6,9,18,27,54
55:( 4) 1,5,11,55
56:( 8) 1,2,4,7,8,14,28,56
57:( 4) 1,3,19,57
58:( 4) 1,2,29,58
59:( 2) 1,59
60:(12) 1,2,3,4,5,6,10,12,15,20,30,60
61:( 2) 1,61
62:( 4) 1,2,31,62
63:( 6) 1,3,7,9,21,63
64:( 7) 1,2,4,8,16,32,64
65:( 4) 1,5,13,65
66:( 8) 1,2,3,6,11,22,33,66
67:( 2) 1,67
68:( 6) 1,2,4,17,34,68
69:( 4) 1,3,23,69
70:( 8) 1,2,5,7,10,14,35,70
71:( 2) 1,71
72:(12) 1,2,3,4,6,8,9,12,18,24,36,72
73:( 2) 1,73
74:( 4) 1,2,37,74
75:( 6) 1,3,5,15,25,75
76:( 6) 1,2,4,19,38,76
77:( 4) 1,7,11,77
78:( 8) 1,2,3,6,13,26,39,78
79:( 2) 1,79
80:(10) 1,2,4,5,8,10,16,20,40,80
81:( 5) 1,3,9,27,81
82:( 4) 1,2,41,82
83:( 2) 1,83
84:(12) 1,2,3,4,6,7,12,14,21,28,42,84
85:( 4) 1,5,17,85
86:( 4) 1,2,43,86
87:( 4) 1,3,29,87
88:( 8) 1,2,4,8,11,22,44,88
89:( 2) 1,89
90:(12) 1,2,3,5,6,9,10,15,18,30,45,90
91:( 4) 1,7,13,91
92:( 6) 1,2,4,23,46,92
93:( 4) 1,3,31,93
94:( 4) 1,2,47,94
95:( 4) 1,5,19,95
96:(12) 1,2,3,4,6,8,12,16,24,32,48,96
97:( 2) 1,97
98:( 6) 1,2,7,14,49,98
99:( 6) 1,3,9,11,33,99
100:( 9) 1,2,4,5,10,20,25,50,100
Since the requirement are to indicate the number of factors before listing them, you will need two passed - one for counting the factors, and one for printing the factors.
Also note that this implementation does not take advantage of the ini vector, which (since for every element ini[i] = i, so there is no need for many of the declared variables.
#include <stdio.h>
int main() {
for (int i = 1; i <= 100; i++){
// First Pass: Counting
int count = 0;
for (int d=1 ; d<=i ; d++) {
if ( i%d == 0 ) count++ ;
} ;
printf("%d: (%d)", i, count) ;
// Second pass: Printing
for (int d=1 ; d<=i ; d++) {
if ( i%d == 0 ) printf(" %d", d) ; ;
} ;
printf("\n") ;
}
}
Put all the divisors in an array. Then print the elements of the array in the format required. You can also count the number of divisors as you're finding them.
#include <stdio.h>
int main() {
for (int i = 1; i <= 100; i++){
int divisors[100];
int counter = 0;
for (int d = 1; d <= i; d++){
if (i % d == 0) {
divisors[counter] = d;
counter++;
}
}
printf("%d (%d): ", i, counter);
for (int j = 0; j < counter; j++) {
printf("%s%d", (j == 0 ? "" : ","), divisors[j]);
}
printf("\n");
}
}

Test result fails for my code of Inspect Bits function

Below code is for a test sample given in https://www.testdome.com/for-developers/solve-question/9780
The question is: Implement the inspect_bits function that checks if given number contains 2 or more consecutive ones in its binary representation. If it does, the function should return 1. Otherwise, it should return 0.
For example, inspect_bits(13) should return 1 as it contains 2 consecutive ones in its binary representation (1101).
My code is:
#include <stdlib.h>
#include <stdio.h>
int inspect_bits(unsigned int number)
{
unsigned int ref = 1;
int comp;
for (int i = 0; i< sizeof(number) * 8; i++)
{
int a = number& (ref << i);
printf("%d: a is %d\n", i, a);
int b = number& (ref << (i + 1));
printf("%d: b is %d\n", i, b);
if ((a != 0) && (b != 0))
{
return 1;
}
}
return 0;
}
#ifndef RunTests
int main()
{
printf("%d", inspect_bits(13));
}
#endif
The result seems ok, but the system tells:
Various numbers: Wrong answer
Can you help to modify my code?
Regards
To be honest, I think it's an issue with the test site itself. Your code returns the proper results for each test case given to it, and I even modified the code as such:
int inspect_bits(unsigned int number)
{
for (int i = 0; i < sizeof(number) * 8; ++i) {
if (((number & (1 << i)) != 0) && ((number & (1 << (i + 1))) != 0)) {
return 1;
}
}
return 0;
}
The test cases return 1 where there are 2 binary values together and works for 3 and above; however, running this code on the test site and it gives the error that the Various Numbers test fails.
Interestingly, using this code:
int inspect_bits(unsigned int number)
{
while (number >= 3) {
if ((number & 3) == 3) { return 1; }
number >>= 1;
}
return 0;
}
Which does basically the same thing, only using bit-shifting on a single number, and the test passes 100% ..
You could submit an e-mail explaining the error; but beyond that, I'm not sure what else it could be.
Hope that helps.
int flag = 0;
int inspect_bits(unsigned int number)
{
int *arr;
int i = 0;
number = convert(number);
while(number)
{
arr[i] = number % 10;
number /= 10;
i++;
}
for(int j = 0; j < i-1; j++)
{
if(arr[j] == arr[j+1])
{
flag = 1;
return flag;
}
}
return flag;
}
int convert (int num)
{
if(num == 0)
{
return 0;
}
else
{
return (num % 2 + 10 * convert(num / 2));
}
}
This is what I did and it said Various Words: Wrong Answer. It appears to be an issue with the test site. Some other questions on their site evaluates questions incorrectly. The ones that I've come across are all C programs. C++ works fine in my experience.
By my experience in testdome almost any exercise right solution has to do with efficiency of the algorithm
This code worked for me:
#include <stdlib.h>
#include <stdio.h>
int inspect_bits( unsigned int number ) {
do {
if( ( number&3 )==3 ) return 1;
} while( number>>=1 );
return 0;
}
#ifndef RunTests
int main () {
printf( "%d", inspect_bits( 13 ) );
}
#endif
In the code you posted, the for loop checks all the bits from the function's input argument 'number'. That's not enough efficient.
The point is that we don't have to wait until the complete number has been completely right shifted.
They say, we must check if there are 2 or more consecutive ones in its binary representation, in other words, function returns 1 if a minimum of 2 consecutive bits with value 1 are found, and the fewer value with 2 consecutive ones is a decimal 3 ( 3 = 0b00000011 ).
So we are able to check it comparing the number with 3 using an AND gate, and right shift to 'number' until it happens.
Let's take a different number than the example's one:
221 = 0b11011101 we just only need to compare 3 times and shift it 2 times.
0b11011101 (221)
& 0b00000011 ( 3)
------------------
= 0b00000001 ( 1)
0b11011101(221) >> 1 = 0b01101110(110)
0b01101110 (110)
& 0b00000011 ( 3)
------------------
= 0b00000010 ( 2)
0b01101110(110) >> 1 = 0b00110111(55)
0b00110111 (55)
& 0b00000011 ( 3)
------------------
= 0b00000011 ( 3) ----> FOUND! return 1

Nested for loops to make a christmas tree in c

So I have the task of creating a Christmas tree in C, I know this has been done to death but there are some conditions that have to be meet that leave me beyond confused, I don't even know where to start.
So we ask the user for the number of levels(how many lines in the layer) and then the number of layers.
Now, each line after the first in each layer will add 2 " * " one to each side of the first( which is just a line with one " * ".) And we do this until the number of levels in the layer is meet, then the next layer is started. When I new layer is started we subtract 4( 2" * " from each side, of the last level in the previous layer, and then repeat the process of adding 1 " * " to each side until the number of levels is meet( the number of levels is decided upon in the beginning and is constant.)
Finally the last part is finishing off the tree of the tree with a width 3, height 4 trunk made of " # ". I have no idea how I'm supposed to be setting up these loops, I'll post what I've done so far( not much I'm unsure how to proceed)
I will now post my code. I'm sort of stuck on where to go in the for loop that makes the first line(level) of the next layer, have 4 less stars(2 from each side) than the last level of the previous layer.
#include <stdio.h>
#include <stdlib.h>
int main()
{
int level;
int levelcount;
int layercount;
int layer;
int star;
int starcount;
int space;
int spacecount;
int spacenumber;
int i;
int printstar;
printf("How many levels should this tree have?\n");
scanf("%d[^\n]", &level);
printf("How many layers should this tree have?\n");
scanf("%d[^\n]", &layer);
for (layer = 0 ; layer <= layercount ; layercount++) {
for (level = 0 ; level < levelcount ; levelcount++) {
star = levelcount + (layer - 1) * 2;
space = levelcount + level - star;
for (spacecount = 0 ; spacecount <= spacenumber ; spacecount++)
printf(" ");
for (starcount = 0 ; star < starcount ; starcount++)
printf("%c" , '*');
printstar = i + ((level-1) * 2);
}
i = i + ((levelcount - 1) * 2) - 4;
}
return 0;
}
I am not sure this is most efficient way, but you can give it a try.
logic i have used here is:
find the mid line for the tree.
print space till mid line and star at the end.
decrement spaces by one and increment stars by 2
Once a layer is printed decrement 4 stats and increment 2 spaces
Same way print the tree trunk.
Here is a sample code using your code snippet:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int level;
int levelcount;
int layercount;
int layer;
int star;
int starcount;
int spacecount;
int space;
int length;
printf("How many layers: ");
scanf("%d", &layercount);
printf("How many levels: ");
scanf("%d", &levelcount);
printf("\n Chrismas Tree \n");
length = (layercount*levelcount);
starcount = 1;
spacecount = length;
for (layer = 1 ; layer <= layercount ; layer++) {
for (level = 1 ; level <= levelcount ; level++) {
for (space = 1 ; space <= spacecount ; space++)
printf(" ");
for (star = 1 ; star <= starcount ; star++)
printf("*");
printf("\n");
starcount += 2;
spacecount--;
}
// since starcount and spacecount are incremented
// just before level loop exit
starcount -= 2;
spacecount++;
if(levelcount <= 3){
starcount -= 2;
spacecount += 1;
}
else{
starcount -= 4;
spacecount += 2;
}
}
spacecount = length;
for (layer = 1 ; layer <= 4; layer++) {
for (space = 1 ; space <= spacecount-1 ; space++)
printf(" ");
for (star = 1 ; star <= 3 ; star++)
printf("#");
printf("\n");
}
return 0;
}
Output:
How many layers: 2
How many levels: 6
Chrismas Tree
*
***
*****
*******
*********
***********
*******
*********
***********
*************
***************
*****************
###
###
###
###
some of the mistakes in your code was, you have not properly handled any of the for loops exit condition, not incrementing layer and level variables, and using uninitialized spacenumber etc.
Do some reading on for loops it will help you to understand.

Printing to output: integer as sum of powers of 2

I had an exam, and I've been struggling ever since.
You have an array of integers(ex. 13, 6, 21, 4), and I need to make an output that looks like:
13 = 2^3 + 2^2 + 2^0
6 = 2^2 + 2^1
21 = 2^4 + 2^2 + 2^0
4 = 2^2
here's what i've got so far.
#include <stdio.h>
#define MAX 100
int main() {
int niz[MAX], nizb, n, i, ones, k;
while(1) {
printf("Array length: ");
scanf("%d", &n);
if (n<=0 || n>MAX) break;
printf("Array elements: ");
for(i=0;i<n;i++){
scanf("%d", &niz[i]);
if (niz[i] <=0) {
printf("Error! Wrong value. Enter new one: ");
scanf("%d", &niz[i]);
}
}
for(i=0;i<n;i++) {
nizb = niz[i];
ones = 0;
for(k=0; k < 16; k++) {
//What should i do here?
}
}
}
}
I'm stuck here. I dont know how many bits should i use, and how does C sees those bits of integer. I'm using var 'k' to add to a string that is in format '2^3 + 2^2 ...', where k is the value of 'for' iteration. I have made an assumption that length of the integer is 16, but im really not sure since we do this on a sheet of paper.
I want to say BIG THANKS TO EVERYONE!!!
You can calculate how many bits to use by using the sizeof operator and CHAR_BIT:
int bitsPerInt = sizeof(int) * CHAR_BIT;
CHAR_BIT is definied in limits.h.
After you have that limit, you can use the bitwise & operator to extract each bit:
for (k = bitsPerInt - 1; k >= 0; k--)
{
if (nizb & (1U << k))
// output
else
// don't
}
I'll leave the details up to you.
Aside: It looks like you're trying to use niz as an array, but you haven't declared it as one. Does this code even compile? Also, the return value of main should be int.
Not sure what this has to do with twos-complement (which is a particular way of representing negative numbers). What you are trying to do is express an integer as a sum of powers of 2, apparently. Here's the way I'd do it, which isn't necessarily better or worse than the other answers...
void powersum(int n)
{ int powers[sizeof(int) << 3];
int i;
char *sep = "";
printf("%d = ", n);
powers[0] = 0;
for (i = 0; n; n >>= 1, ++i)
powers[i] = n & 1;
while (--i >= 0)
{ if (powers[i])
{ printf("%s2^%d", sep, i);
sep = " + ";
}
}
printf("\n");
}
EDIT: Here's another version that doesn't use the stack-allocated array, but as a tradeoff has to go around the loop more (once for each bit, as opposed to only looping until the highest 1-bit is found):
void powersum2(int n)
{ int i = (sizeof(int) << 3) - 2;
int m = 1 << i;
char *sep = "";
printf("%d = ", n);
while (m)
{ if (n & m)
{ printf("%s2^%d", sep, i);
sep = " + ";
}
m >>= 1;
--i;
}
printf("\n");
}
This is complete conjecture, since I'm not really good with math, but I think I'd go about it like this:
int potency = 0, base = 1;
while(base < NumberInQuestion) {
base *= 2;
++potency;
}
After the loop finishes, you'll know the highest potency which still fits into 'Number'.
Number -= base/2; //Removes the base you just calculated from the number.
printf("2^%d", potency);
Rinse and repeat, until Number falls to 0, which should be at 2^0 at latest.
For your use-case, the code may look somewhat like this:
for(i=0; i < n; ++i) {
int Number = niz[i];
while(Number > 0) {
int potency = 0, base = 1;
do { //Executes at least once, making a number of '1' possible.
base *= 2;
++potency;
} while(base < Number);
Number -= base/2; //Reverts the last step you made, making the 'base' smaller than 'Number'.
printf("2^%d", potency);
}
}
There's a possible alternative, which can give you a more complete picture of things and will save you iterations. For this we use a two-step process.
for(i=0; i < n; ++i) {
int Number = niz[i];
int potency = 0, base = 1;
do { //Executes at least once, making a number of '1' possible.
base *= 2;
++potency;
} while(base < Number);
base /= 2; //Reverses the last iteration.
//At this point, we know the maximum potency, which still fits into the number.
//In regards of base 2, we know the Most Significant Bit.
while(base > 0) {
Number -= base; //Removes the MSD (Most significant digit)
printf("2^%d", potency); //Prints your '1'.
while(base > Number) { //Executes at least once.
base /= 2; //Goes back one potency. (Ends at '0' latest.)
--potency; //For each potency (except for first), it's a '0'.
}
}
}
quotient = niz[i];
int k=0,c[MAX];
while(quotient!=0){
binaryNumber[i++]= quotient % 2; //this will convert your numbers to binary form
quotient = quotient / 2; //and store in reverse in array
}
for(j = 0 ;j<i;j++)
{
if(binaryNumber[j]==1) */e.g binary of 4 is stored in array as 001 ie 1 atpos2*/
{ c[k]=j;
k++;}
}
while(k--)
printf("2^%d +",c[k]);
If you can tolerate a GCC-dependency, a hack on #twalberg's solution get's really nice and small ;)
void powersum(int n)
{
char *sep = "";
printf("%d = ", n);
while (n) {
int pos = 31 - __builtin_clz(n);
printf("%s2^%d", sep, pos);
sep = " + ";
n ^= 1 << pos;
}
printf("\n");
}

Resources