Project Euler 5 - c

2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
My solution:
#include<stdio.h>
int gcd(int m, int n);
int lcm(int a, int b);
int main()
{
int x=1, i;
for(i=1; i<20; i++)
{
x=lcm(x, i+1);
}
printf("The answer is:\t%d", x);
return 0;
}
int gcd(int m, int n)
{
while(m!=n)
{
if(m>n)
m=m-n;
else
n=n-m;
}
return m;
}
int lcm(int a, int b)
{
return ((a*b)/gcd(a, b));
}
Please tell where I am wrong? It shows only blank screen on running.

Most problems on Project Euler can be solved in three ways:
with brute-force
with an algorithm that solves a more general problem (like you do)
with a smart solution that requires pencil and paper at most
If you're interested in a nice solution rather than fixing your code, try concentrating on the last approach:
The trick is to find the smallest multiset of primes such that any number between 1 and 20 can be expressed as a product of some of these primes.
1 = 1 11 = 11
2 = 2 12 = 2*2*3
3 = 3 13 = 13
4 = 2*2 14 = 2*7
5 = 5 15 = 3*5
6 = 2*3 16 = 2*2*2*2
7 = 7 17 = 17
8 = 2*2*2 18 = 2*3*3
9 = 3*3 19 = 19
10 = 2*5 20 = 2*2*5
By "ORing" the prime factors for the numbers between 1 and 10, we get 1*2*2*2*3*3*5*7, which happens to be 2520, just as expected.
Now if we go from 1 to 20, we get 1*2*2*2*2*3*3*5*7*11*13*17*19, which is indeed accepted by Project Euler.

If there should be only one lesson that you learn from this exercise, make it this: the order in which you do your multiplications and divisions matters.
Even if it does not matter in mathematics, it often matters in your program. For example, in math there is no difference between (a*b)/gcd(a, b) and a/gcd(a, b)*b; In your program, it would make the difference between passing and failing.
(P.S. of course you need to fix the bug in your logic, too: you should not be multiplying x by lcm).
EDIT
To understand why the order makes the difference here, consider calculating lcm of 232792560 and 20. 232792560 is divisible by 20, so it is the lcm. However, when you calculate 232792560*20, you get an overflow; then you divide by 20, but you do not get 232792560 back.
Since the divisor is gcd(a,b), you can divide it out of a before multiplying by b without truncating the result by integer division. This little trick that experienced programmers use without thinking can save you hours of debugging.

A printf() would show you that you're code is getting into an infinite loop. I've added a printf() in the gcd() in the while loop.
n=n-m;
printf("m=%d n=%d\n", m, n);
}
return m;
while(m!=n) is never true for n=14. Finally the m and n overflows because x goes to a higher number which cannot be accommodated by int type!

The bug is x*=lcm(x, i+1); and here is the complete solution,
long gcd(long m, long n);
long lcm(long a, long b);
int main()
{
long x=1;
for(int i=2; i<=20; i++)
{
x=lcm(x,i);
}
cout << "The answer is: " << x << endl;
return 0;
}
long gcd(long a, long b)
{
return (b==0)?a:gcd(b,a%b);
}
long lcm(long a, long b)
{
return ((a*b)/gcd(a, b));
}

The n-1 should be n; and x =lcm(...) not x*=lcm(...). But I don't quite see (away from terminal) where your loop gets stuck.

The answer for 20 is: 232792560.
These are all answers for all numbers of which the answer fits in a long integer:
1 : 1
2 : 2
3 : 6
4 : 12
5 : 60
6 : 60
7 : 420
8 : 840
9 : 2520
10 : 2520 <=== example in Euler P5 question for division by 1 to 10 without remainder
11 : 27720
12 : 27720
13 : 360360
14 : 360360
15 : 360360
16 : 720720
17 : 12252240
18 : 12252240
19 : 232792560
20 : 232792560 <== answer for Euler Prog 5 (1 to 20 without remainder
21 : 232792560
22 : 232792560
23 : 5354228880
24 : 5354228880
25 : 26771144400
26 : 26771144400
27 : 80313433200
28 : 80313433200
29 : 2329089562800
30 : 2329089562800
31 : 72201776446800
32 : 144403552893600
33 : 144403552893600
34 : 144403552893600
35 : 144403552893600
36 : 144403552893600
37 : 5342931457063200
38 : 5342931457063200
39 : 5342931457063200
40 : 5342931457063200
41 : 219060189739591200
42 : 219060189739591200

There is no need to write a program at all for this one. My solution:
Write down all prime numbers that are not greater than the highest divisible number.
For 20 its: 2, 3, 5, 7, 11, 13, 17, 19.
Then if any of the prime numbers square root is not greater than the highest divisible number(20 in this example), you replace the original prime number with its square root.
In this example 2*2 > 20, 2*2*2 > 20, 2*2*2*2 > 20, but 2*2*2*2*2 < 20. 2*2*2*2 = 16 so new number lines is:
16, 3, 5, 7, 11, 13, 17, 19.
Same for 3: 3*3 > 20 but 3*3*3 < 20. 3*3 = 9, so new number line: 16, 9, 5, 7, 11, 13, 17, 19. 5*5 > 20, so this is final line.
Multiple all numbers int the line and you get answer: 16 * 9 * 5 * 7 * 11 * 13 * 17 * 19 = 232,792,560‬

Related

Deleting an element from an array in C

so Im supposed to make a game an assignment for class.
Essentially, I decided to re-create a heads up Poker game, running different functions such as int deal(a, b, x, y) where a and b are the hero's cards, and x and y are the villan's.
This function in particular, has me a bit stumped. Effectively, I loop through the array deck, and assign random numbers to a, b, x and y. Then, I will translate each assigned value into a real, unique card, and return that to int main().
The part that I am stuck at is "as each card is selected, it is deleted from the array. It seems that there is no easy way in C to simply remove an element from deck array.
int deal (a, b, x, y)
{
int deck[52] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52};
int heroFirst;
int heroSecond;
int villainFirst;
int villainSecond;
srand(0);
}
Any thoughts?
You don't have to delete anything.
Shuffle your deck array (using a Fisher-Yates shuffle or similar algorithm). Deal each card from the "top" of the deck:
int top = 0;
card1 = deck[top++];
card2 = deck[top++];
card3 = deck[top++];
...
etc. The top variable is the index of the next available card in the deck.
The general outline of your code will be something like
#define DECKSIZE 52
#define HANDSIZE 5
int main( void )
{
int deck[DECKSIZE] = { ... }; // initial deck;
size_t top = 0; // points to next available card
shuffle( deck, DECKSIZE );
int hero[HANDSIZE] = {0}; // 0 means no card has been drawn for
int villan[HANDSIZE] = {0}; // that element.
if ( deal( hero, HANDSIZE, deck, DECKSIZE, &top ) &&
deal( villan, HANDSIZE, deck, DECKSIZE, &top ) )
{
/**
* do stuff with hero and villan hands
*/
}
else
{
/**
* Not enough cards available in deck for two hands.
*/
}
};
Your deal function would look something like
int deal( int *hand, size_t handsize, int *deck, size_t decksize, size_t *top )
{
size_t i;
for ( i = 0; i < handsize && *top < decksize; i++ )
hand[i] = deck[(*top)++];
return i == handsize;
}
This function will return 0 if we run out of cards in deck before we've dealt the hand, in which case you'll need to do...something. Good luck!
If you want to deal a partial hand (such as to replace 3 cards), you'd do something like
if ( deal( &hero[2], 3, deck, DECKSIZE, &top) )
...
This call will overwrite hero[2] through hero[4] with three new cards drawn from deck. With each call to deal, top will be advanced to point to the next available card in the deck.
You can write a discard function that returns cards to the deck. It means keeping a separate bottom variable and updating that:
int discard( int card, int *deck, size_t decksize, size_t *top, size_t *bottom )
{
int result = *bottom < *top && *bottom < decksize;
if ( result )
deck[(*bottom)++] = card;
return result;
}
Obviously, bottom should be strictly less than the deck size and strictly less than top on a discard; otherwise, we haven't managed our deck or hands properly. With a little work, you could make your array "circular", such that top and bottom "wrap around" as necessary. If you exhaust the deck, you can reshuffle (minus the cards in hand, which will be the deck entries between bottom and top) and reset top and bottom as necessary.
Play with this on paper for a little while, and it should become obvious.
EDIT
Addressing questions here:
At which point do you assign deck[5] to a card, for instance
That happens in the deal function, in the for loop. The first time we call deal, we tell it to deal to the hero hand:
deal( hero, HANDSIZE, deck, DECKSIZE, &top )
At this point, top is 0. Assuming we're dealing 5 cards at a time, the first call to deal effectively does this:
Loop iteration 0: hero[0] = deck[0]
Loop iteration 1: hero[1] = deck[1]
Loop iteration 2: hero[2] = deck[2]
Loop iteration 3: hero[3] = deck[3]
Loop iteration 4: hero[4] = deck[4]
When the function returns, the top variable has been updated to 5. The next time we call deal, we tell it to deal to the villain hand:
deal( villain, HANDSIZE, deck, DECKSIZE, &top )
Again, assuming we're dealing 5 cards at a time, the loop effectively does this:
Loop iteration 0: villain[0] = deck[5];
Loop iteration 1: villain[1] = deck[6];
Loop iteration 2: villain[2] = deck[7];
Loop iteration 3: villain[3] = deck[8];
Loop iteration 4: villain[4] = deck[9];
After the second call to deal, top has been updated to 10.
Each time you call deal with the top variable, it will start dealing from deck at the position specified by top, and each time through the loop it will add 1 to top. The loop will exit if one of two conditions is true:
i == handsize - we've dealt all the cards necessary for this hand
*top == decksize - we've reached the end of the array, nor more cards may be dealt.
So, suppose you've dealt a number of hands, and there are only 3 cards left in the deck - if you try to deal 5 more cards, the loop will exit before you've dealt all 5 cards, and we'll return a 0 to indicate that no more cards are left in the deck.
at which point is the desk shuffled randomly?
You would call a shuffle function to do that before the first call to deal:
int deck[DECKSIZE] = { ... };
...
shuffle( deck, DECKSIZE );
...
if ( deal( hero, HANDSIZE, deck, DECKSIZE, &top ) &&
deal( villain, HANDSIZE, deck, DECKSIZE, &top ) )
{
...
}
A simplistic (and not terribly good) implementation of the shuffle function would be:
void shuffle( int *deck, size_t decksize )
{
for ( size_t i = 0; i < decksize; i++ )
{
int r = rand() % (decksize - i)
int tmp = deck[i+r];
deck[i+r] = deck[i];
deck[i] = tmp;
}
}
Basically, what this does is swap each deck[i] with a randomly chosen element from deck[i] through deck[decksize-1] (meaning the element may remain in place). Assume we have 5 cards. The first time through the loop, i points to the first card. We pick an offset from i at random and call it r:
i --> 1
2
3
4 <-- r
5
We then swap the contents of deck[i] and deck[i+r], and then advance i:
4
i --> 2
3
1
5
We pick another r at random from the remaining elements:
4
i --> 2
3
1
5 <-- r
and do another swap and advance i:
4
5
i --> 3
1
2
Lather, rinse, repeat - by the end of the loop, the array is more-or-less randomly shuffled.
No, there is no way in C to delete an element from an array. Indeed, as far as I know there is no way to delete an element from an array in C++, C# or Java either.
Now, that being the case, you have a few options. You can use a sentinel value in your code to mark an element as absent. You can resize your array to actually shrink it by one and relocate all elements backwards one place whenever an element is deleted.
In your example, either 0 or -1 should serve fine as sentinel values.
First at all, make the array deck static.
Next, introduce another static variable initially equal to the lenght of array=52.
Now when a card at a random position is dealt, it can be swapped with the last card in the deck, indexed with arraysize-1, and the arraysize being decreased.
Making these two variables static allows the function to maintain a state between calls. Of course better techniques would encapsulate these variables in a struct (allowing eg multiple games / resetting the deck).
In short, the problem you're really trying to solve isn't one of deleting an entry in an array.. Rather, it is a more encompassing issue: How to perform repeated random selection from a fixed domain without repeating selected values. The method described above is one way to do that. An example of the latter technique using a 20-slot array is below (the value 20 was chosen for short output lines (easy to read). It could just as easily be 52, 1000, etc.):
Code
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define DECK_SIZE 20
typedef struct Deck
{
int cards[DECK_SIZE];
size_t size;
} Deck;
Deck init_deck()
{
// no shuffle is needed. each selection in draw_card will
// pick a random location in the remaining cards.
Deck deck;
for (int i=0; i<DECK_SIZE; ++i)
deck.cards[i] = i+1;
deck.size = DECK_SIZE;
return deck;
}
int draw_card(Deck *deck)
{
// reset when we run out of cards.
if (deck->size == 0)
{
printf("- reset \n");
deck->size = DECK_SIZE;
}
// generate random location in remaining cards.
// note: susceptible to modulo bias
size_t idx = rand() % deck->size;
// decrement size to consume card and index where
// the card will be swap-stored.
--deck->size;
// swap with last card in remaining cards
int tmp = deck->cards[deck->size];
deck->cards[deck->size] = deck->cards[idx];
deck->cards[idx] = tmp;
// return the drawn card
return deck->cards[deck->size];
}
int main()
{
Deck deck = init_deck();
srand((unsigned)time(NULL));
// draw 300 times. this should reset 15 times, and
// each time a new set of 1..20 should result
for (int i=0; i<300; ++i)
printf("%d ", draw_card(&deck));
fputc('\n', stdout);
}
Output (obviously varies)
7 16 3 20 9 13 6 4 1 12 18 10 14 2 8 17 11 5 15 19 - reset
6 20 14 16 11 2 10 13 4 12 18 5 3 7 19 9 17 8 15 1 - reset
14 1 8 15 13 2 19 16 11 17 5 18 9 12 7 6 3 20 4 10 - reset
18 17 12 2 15 19 1 4 14 10 20 16 9 5 11 13 6 8 3 7 - reset
4 18 5 1 19 16 8 10 9 14 13 17 12 20 7 2 15 6 11 3 - reset
14 16 18 1 5 10 17 3 19 9 8 2 7 13 12 20 4 15 11 6 - reset
16 15 12 13 6 1 17 10 9 7 11 20 8 19 2 18 3 4 14 5 - reset
7 1 8 16 17 5 2 12 13 6 18 20 9 11 14 19 15 3 4 10 - reset
20 13 4 18 7 17 12 15 5 14 2 16 11 3 9 10 1 19 8 6 - reset
5 19 4 17 18 13 8 2 12 7 9 1 11 10 3 14 6 15 16 20 - reset
3 5 10 7 1 15 19 13 16 12 9 8 6 20 4 11 17 18 14 2 - reset
11 14 4 7 15 9 16 18 8 13 12 5 10 19 2 6 20 1 3 17 - reset
10 18 2 4 12 20 14 11 16 13 3 9 8 6 5 7 17 1 15 19 - reset
19 12 20 11 13 9 5 1 10 15 7 2 17 6 3 4 8 14 16 18 - reset
10 3 19 4 6 14 18 11 1 7 9 16 8 13 17 20 2 5 15 12
Notive that on each line, there are twenty selections, and each number in 1..20 appears exactly once per line. How this technique serves you is up to you. A worthy challenge will be how to enumerate the hands held by existing players when a reset (often called a deck-flip) happens. That's an interesting problem to solve, and not one that is as intuitive as it may seem.
Hope it helps.
There are a couple of solutions you could use to solve your problem:
First, is using the vector class, especially the insert and remove functions. here's a good explanation on how it works:
C++ Vectors
Second, which is also my favorite is to use numbers or booleans as indicators. for example, declare a simple boolean array of the same length as your deck. the initial value of all elements would be true. for each card, you'd like to remove from the deck simply change its value to false to indicate it's gone.

C program to check lottery numbers: why some tests fail?

This program takes as an input the following lines:
23 12 33 19 10 8
5
23 19 8 12 60 18
14 60 12 44 54 10
8 3 12 19 33 10
33 15 7 60 12 10
22 12 19 23 33 11
23 12 33 19 10 8 ( The first line ) are the lottery results.
n ( in this specific case, 5 ) informs how many lines will follow below.
Each line has 6 numbers. The number order doesn't matter.
The rules are: numbers range from 1 to 60 ( including 1 and 60 ) and they never repeat themselves in the same line.
The variable "quadra" stores how many lines have got 4 numbers right.
The variable "quina" stores how many lines have got 5 numbers right.
The variable "sena" stores how many lines have got 6 numbers right.
So, a computer program is running some tests over my code below and it's claiming that it goes wrong for most of them, but I can't see what's the problem here. Does anybody have a clue? Is this code wrong, or is there something wrong with the software that's testing this code?
#include <stdio.h>
int main(){
int mega[6];
int v[50500][6];
int n,swap;
int i,j,k; //counters
int quadra,quina,sena;
quadra = 0;
quina = 0;
sena = 0;
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
scanf("%i",&n);
for(i=0;i<n;++i){
for(j=0;j<6;++j){
scanf("%i",&v[i][j]);
}
}
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=0;k<6;++k){
if(v[i][j] == mega[k]){
v[i][j] = 61;
}
}
}
}
//reverse bubble sort
for(i=0;i<n;++i){
for(j=0;j<6;++j){
for(k=j+1;k<6;++k){
if(v[i][j] < v[i][k]){
swap = v[i][k];
v[i][k] = v[i][j];
v[i][j] = swap;
}
}
}
}
for(i=0;i<n;++i){
for(j=0;v[i][j] == 61 && j<6;++j);
if(j == 4) ++quadra;
else if(j == 5) ++quina;
else if(j == 6) ++sena;
}
return 0;
}
Your code is true, I understood and tried the flow of it. Looks fine but if you dont need to sort everyline (and use j as a counter in this loop for(j=0;v[i][j] == 61 && j<6;++j); ), you can use simpler ifstatements to compare real lottery results with the ones that entered. What I mean is that your algorithm is a little complex. Try a simple one and see how it works.
Yes, there are a couple of noteworthy issues with your code:
Compile time indicates possibility of uninitialized variable:
But, run-time results in fatal run-time at unknown source location. Stack overflow. It is likely due to this line:
int v[50500][6];
Increase your stack size. It needs to be about 2.5Mbytes for v alone.
Also, this line may not be what you intended:
for(i=0;i<6;++i) scanf("%i",&mega[i]); //first line, lottery results
^
If you meant to loop around the remainder of the code, remove the ; after the for() statement, and use curly braces:
for(i=0;i<6;++i) scanf("%i",&mega[i]) //first line, lottery results
{
scanf("%i",&n);
....

I am trying to set a value to an array, but I can't seem to figure out why what I did on line 31 is wrong

I have a data file in the format <0:00> - <19321> , <1:00> - <19324>, up to <24:00> - <19648>, so for every hour there is the total power used so far(the total is incremented), I am supposed to calculate the power used, find the average, and the highest usage of power and its index(time), (I don't need help with finding the max power used at its time index). I traced the problem down to line 31, but I don't understand why what I did was wrong. Can someone explain to me why the code in line 31 isn't saving the value of power used into the array? And how I can fix it? Thanks in advance!
float compute_usage(int num, int vals[], int use[], int *hi_idx)
15 {
16 int i;// i is a general counter for all for loops
17 int r1, r2, u, v, pow_dif, temp;//for loop 1
18 int tot;//for loop 2
19 int max_use, init, fina, diff;//for loop 3 //don't have to worry about this for loop, I am good here
20 float avg;//average power used
21
22 for(r1=r2=i=u=v=0;i<num;i++)//for loop 1
23 {
24 r1= vals[v++];//I set values of every hour as reading 1 & 2(later)
25 #ifdef DEBUG
26 printf("pre-debug: use is %d\n", use[u]);
27 #endif
28 if(r1!=0 && r2!=0)
29 {
30 pow_dif = (r1 - r2);//I take the to readings, and calculate the difference, that difference is the power used in the interval between a time period
31 use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
32 }
33 r2=r1;//the first reading becomes the second after the if statement, this way I always have 2 readings to calculate the power used int the interval
34 #ifdef DEBUG
35 printf("for1-debug3: pow_dif is %d\n", pow_dif);
36 printf("for1-debug4: (%d,%d) \n", u, use[u]);
37 #endif
38
39 }
40 for(tot=i=u=0;i<num;i++)//for loop 2
41 {tot = tot + use[u++];}
42
43 avg = tot/(num-1);
44 #ifdef DEBUG
45 printf("for2-debug1: the tot is %d\n", tot);
46 printf("for2-debug2: avg power usage is %f\n", avg);
47 #endif
Just to understand, how did you figure out that the code in line 31 is problematic? Is it the printf statement in line 36?
When you do this:
use[u++] = pow_dif; //I'm suppose to save the power used in the interval in an array here
printf("for1-debug4: (%d,%d) \n", u, use[u]);
The "u" variable in printf statement is incremented in the previous operation (u++), so you are looking past the element you changed.
use[u++] = pow_dif; //I.e. u=0 here, but u=1 after this is executed.
printf("...\n", u=1, use[1]);
What is the "i" for in this loop? Why don't you try "u++" in the for statement instead of "i++" and remove the "u++" in the use assignment expression?

C bitmap: rotation and zoom

I'm recently checking out C for a friend having problems with it for school. As I only have learned java and C#, though it would be easy. But currently stuck on this.
I have a project reading a small bmp (512x512) image. I've managed to change some colors on it and have it rotated (both horizontal as vertical). Though I'm stuck with the -90° rotation.
1. ROTATION (512x512)
Currently I have this code (both getPixel and setPixel are my own functions):
typedef struct _bitmap {
char file_path[PATH_MAX+1];
char magic_number[3];
unsigned int size;
unsigned char application[5];
unsigned int start_offset;
unsigned int bitmapHeaderSize;
unsigned int width;
unsigned int height;
unsigned short int depth;
unsigned char* header;
PIXEL* raster;
} BITMAP;
void rotate(BITMAP* bmp) {
int i;
int j;
PIXEL* originalPixel;
BITMAP* originalBmp;
deepCopyBitmap(bmp, originalBmp);
for(j=1; j <= bmp->height; j++) {
for(i=1; i <= bmp->width; i++) {
originalPixel=getPixel(originalBmp->raster, bmp->width, bmp->height, j, i);
setPixel(bmp->raster, bmp->width, bmp->height, (bmp->width + 1 - i), j, originalPixel);
}
}
}
void deepCopyBitmap(BITMAP* bmp, BITMAP* copy) {
*copy = *bmp;
if (copy->raster) {
copy->raster = malloc(copy->height * sizeof(*copy->raster));
for (int i = 0; i < copy->height; i++) {
copy->raster[i] = malloc(copy->width * sizeof(*copy->raster[i]));
memcpy(copy->raster[i], bmp->raster[i], copy->width * sizeof(*copy->raster[i]));
}
}
}
indirection requires pointer operand ('PIXEL' (aka 'struct _pixel') invalid)
copy->raster[i] = malloc(copy->width * sizeof(*copy->raster[i]));
^~~~~~~~~~~~~~~~
indirection requires pointer operand ('PIXEL' (aka 'struct _pixel') invalid)
memcpy(copy->raster[i], bmp->raster[i], copy->width * sizeof(*copy->raster[i]));
^~~~~~~~~~~~~~~~
expanded from macro 'memcpy' __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest))
This correctly rotates the first diagonal part of the image, but the second part is totally wrong (having two times a part of the first diagonal).
I think the problem is, swapping pixels around and halfway I'm starting to swap already swapped pixels. So I tried to duplicate my bmp, to a original bitmap (originalBmp) and one rotated (rotatedBmp). Though I think it just copies the reference. Anyone has an idea how I create a duplicate bmp?
As example (sorry for the flue img): I want the vertical lines (left), to turn -90deg, so it becomes horizontal lines (right). Though the left diagonal part is correct. But the right part of the diagonal is incorrect copying a piece of the left diagonal. I think because it swaps pixels that are already swapped in the bmp file.
2. ROTATION (512x1024)
What happens if the height or width is the double of the other? Anyone knows how to start on this?
3. ZOOM (200%)
Anyone know how to do this? Get the center pixels of the bitmap, and make them twice at the start of the image, or is there a better/cleaner solution?
1 2 3 4 5 6 7 8 3 3 4 4 5 5 6 6
2 2 3 4 5 6 7 8 3 3 4 4 5 5 6 6
3 3 3 4 5 6 7 8 4 4 4 4 5 5 6 6
4 4 4 4 5 6 7 8 4 4 4 4 5 5 6 6
5 5 5 5 5 6 7 8 5 5 5 5 5 5 6 6
6 6 6 6 6 6 7 8 5 5 5 5 5 5 6 6
7 7 7 7 7 7 7 8 6 6 6 6 6 6 6 6
8 8 8 8 8 8 8 8 6 6 6 6 6 6 6 6
From your code it seems clear that both originalBmpand bmp are pointers to some BMP-type. So when you do originalBmp=bmp;, you just get two pointers pointing to the same BMP, i.e. they operate on the same data.
I assume you have something like
struct BMP
{
// ....
};
If that is the case you can make a copy like this:
struct BMP originalBmp = *bmp;
When using originalBmp you must use the . notation, e.g. originalBmp.raster
EDIT An alternative approach
Instead of making a copy of the original bmp you could do the rotation directly on the original. Each rotation will involve 4 locations. You can copy the 4 locations into temp variables first and then write them to their final location.
For a simple matrix it could be something like this:
#include <stdio.h>
#define WIDTH 4
// display function
void d(int t[WIDTH][WIDTH])
{
int i, j;
for (i=0; i<WIDTH;i++)
{
for (j=0; j<WIDTH; j++)
{
printf("%d ", t[i][j]);
}
printf("\n");
}
}
int main(void) {
int org[WIDTH][WIDTH];
int i, j;
// Just initialize the matrix
for (i=0; i<WIDTH;i++)
{
for (j=0; j<WIDTH; j++)
{
org[i][j] = 10 + i*5 + j;
}
}
printf("Original\n");
d(org);
// Rotate the matrix
for (j=0; j < (WIDTH/2); j++)
{
for (i=0; i < ((WIDTH+1)/2); i++)
{
int t1 = org[j][i];
int t2 = org[i][WIDTH-1-j];
int t3 = org[WIDTH-1-j][WIDTH-1-i];
int t4 = org[WIDTH-1-i][j];
org[j][i] = t2;
org[i][WIDTH-1-j] = t3;
org[WIDTH-1-j][WIDTH-1-i] = t4;
org[WIDTH-1-i][j] = t1;
}
}
printf("Rotated\n");
d(org);
return 0;
}
This will output:
Original
10 11 12 13
15 16 17 18
20 21 22 23
25 26 27 28
Rotated
13 18 23 28
12 17 22 27
11 16 21 26
10 15 20 25
Change to #define WIDTH 5 and it will output:
Original
10 11 12 13 14
15 16 17 18 19
20 21 22 23 24
25 26 27 28 29
30 31 32 33 34
Rotated
14 19 24 29 34
13 18 23 28 33
12 17 22 27 32
11 16 21 26 31
10 15 20 25 30

Incorrect output with counting and tallying bits in C

This is only my 2nd programming class. There are 30 rooms. We have to see what is in each room and tally it. I already used the for loop to go through the 30 rooms and I know I have tried to use a bit counter to see what is in each room. I am not getting the correct sample output after I redirect the sample output. When I printf("%d", itemCnt[loc]);, my output is 774778414trolls
When I printf("%d", itemCnt[0]);, my output is 0trolls. I'm just trying to get one output right so I can figure out how to get the rest of the 8 outputs. From the sample output, the first number is supposed to be 6, followed by 6, 1, 4, 4 ... and so on. Below are sample inputs/outputs and what I have so far in code.
Sample input:
1 20 ##
2 21 #A
3 22 ##
4 23 #1
5 22 ##
6 22 ##
7 22 ##
8 22 ##
9 23 #Z Here be trolls � not!
10 23 #+
12 23 ##
13 24 ##
11 22 ##
14 22 #2
15 21 #1
16 20 ##
17 19 ##
18 20 ##
19 19 ##
20 18 ##
21 17 #*
22 16 #*
23 15 #%
0 14 #7
0 gold_bar
1 silver_bar
2 diamond
3 copper_ring
4 jumpy_troll
5 air
6 angry_troll
7 plutonium_troll
Sample Output:
6 gold_bar
6 silver_bar
1 diamond
4 copper_ring
4 jumpy_troll
8 air
15 angry_troll
0 plutonium_troll
code
int main()
{
// contains x and y coordinate
int first, second;
char third[100];
char fourth[100];
char Map[30][30];
// map initialization
for(int x=0; x<30; x++){
for(int y=0; y<30; y++){
Map[x][y] = '.';
}
}
while(scanf("%d %d %s",&first, &second, third) != -1) {
// Condition 1: a zero coordinate
if (first==0 || second==0) exit(0);
// Condition 2: coordinate out of range
if (first<0 || first>30 || second<0 || second>30){
printf("Error: out of range 0-30!\n");
exit(1);
}
Map[second-1][first-1] = third[1];
fgets(fourth, 100, stdin);
// bit counter
int itemCnt[8] = {0}; // array to hold count of items, index is item type
unsigned char test; // holds contents of room.
int loc;
for(loc = 0; loc < 8; loc++) // loop over every bit and see if it is set
{
unsigned char bitPos = 1 << loc; // generate a bit-mask
if((test & bitPos) == bitPos)
++itemCnt[loc];
}
// print the map
for(int h=0; h<30; h++){
for(int v=0; v<30; v++){
printf("%c", Map[h][v]);
}
printf("\n");
}
// print values
printf("%d", itemCnt[0]);
}
return 0;
}
test is not initialized. It looks like you intended to assign 'third[1]' to test.
Also, 774778414 = 0x2E2E2E2E in hex, and 0x2E is the numeric value of ASCII '.', your initial value for map locations. (Tip: when you see wild decimals like that, try Google. I entered, "774778414 in hex" without the quotes.)
I would also suggest breaking down the code into two functions: the first reads from stdin to populate Map (like you do), and the second reads from stdin to populate 8 C strings to describe your objects. It's important to note, the first loop should not go until end of input, because your posted input continues with descriptions, not strictly 3 fields like the beginning.

Resources