Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 08-26-2005, 11:35 AM   #1 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
[puzzle] Improve my bad code.

Assume a mathematical vector (which is just a 1-D matrix) containing n numbers in Z .
For C++ this means that the range of the vector is: Numbers [0...n) .

The task is to find all possible odd and even product pairs (all permitations, not combinations).
Or more formally:

ep = | {(i,j) :: 0 <= i < n AND 0 <= j < n AND even(Numbers[ i ] * Numbers[ j ]) |
op = | {(i,j) :: 0 <= i < n AND 0 <= j < n AND odd(Numbers[ i ] * Numbers[ j ]) |


I'll give you the full working code below which does that precisely. However, with the type of mathematical problem as stated above my code is totally unacceptable! This direct method is called: canonical form.

Your task:
Improve my code so the run-time complexity decreases from a horrible N^2 to N.

Motivation:
Here lies the foundation of classical programming. These kind of problems are for any coder to solve if you take yourself serious.

Code:
#include <iostream>
#include <cstdlib>

void odd_even_pairs(const int* vec, std::size_t size, unsigned& ep, unsigned& op);
void odd_even_pairs_fast(const int* vec, std::size_t size, unsigned& ep, unsigned& op);
bool even(int num);

static const int Numbers[] = {12, 4, 6, 3, 7, 9, 10 , 44, 63, 63, 23, 34, 36, 
  346, 43, 61, 56, 264, 2463, 25, 2544, 14, 14, 11, 99, 345, -5, -34, -24};
  
int main()
{
  unsigned ep(0), op(0);
  std::size_t size(0);
  size = sizeof Numbers / sizeof *Numbers;
  
  odd_even_pairs_fast(Numbers, size, ep, op);
  std::cout<<"Even pairs: " << ep << std::endl;
  std::cout<<"Odd pairs: " << op <<std::endl;
  
  return 0;
}

//------------------------------------

bool even(int num)
{
  return ((num % 2) == 0);
}

//-------------------------------------

void odd_even_pairs(const int* vec, std::size_t size, unsigned& ep, unsigned& op)
{  
  for(std::size_t i = 0; i < size; ++i)
  {
    for(std::size_t j = 0; j < size; ++j)
    {
      if( even(vec[i] * vec[j]) )
      {
        ++ep;
      }
      else
      {
        ++op;
      }
    }
  }  
}

//-------------------------------------

void odd_even_pairs_fast(const int* vec, std::size_t size, unsigned& ep, unsigned& op)
{
  //TO DO BY STUDENT
}
__________________

Last edited by Valmont; 08-28-2005 at 01:30 AM.
Valmont is offline   Reply With Quote
Old 08-26-2005, 07:14 PM   #2 (permalink)
Feis
Registered User
 
Join Date: Apr 2005
Posts: 18
Feis is on a distinguished road
Ok, dont try to compile, as my compiler is messed up and this probly has a few errors

The basis of the program is this: YOU DONT HAVE TO KNOW WHETHER ITS EVEN!


Yes, I know that sounds weird, but look:

you take a number, lets say 5 for example. if you add the next number, 6, the sum is ALWAYS odd. this is true for all whole numbers. adding 2 to this next number keeps the number odd. so 5+8=13, 5+10=15, etc.

The same goes for even. still using 5, 5+7=12, always even. Adding 2 to the second number insures tha the sum is always even. so here it is, please excuse any coding errors, but I think that you'll get the gist of the concept.

Code:
#include<iostream>
int n = 999;       //whatever n is
using std::cout;

int Numbers[n] = (1,2,3)          //so on and so forth

int main()
{
    int even=0, odd=0;
    
    for(int i=0, i>n, i++;)
    {
            
               for(int k = i+2, k>n, k+=2;)
                 {
                         even++;
                 }
                 for(int l=i+1, l>n, l+=2;)
                 {
                         odd++;
                 }
}

cout << "The # of even pairs are:" << even;
cout << "The # of odd pairs are:" << odd;


return 0;
}
heres to hoping I didnt make a blatant error in my logic
Feis is offline   Reply With Quote
Old 08-26-2005, 08:49 PM   #3 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
You've got more wrong then only your logic.
__________________
Valmont is offline   Reply With Quote
Old 08-27-2005, 07:01 AM   #4 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
Valmont,
are you looking for pairs like 33 or 22 where both digits are the same?
Scott
smckittr is offline   Reply With Quote
Old 08-27-2005, 10:58 AM   #5 (permalink)
redhead
Newbie
 
redhead's Avatar
 
Join Date: Jun 2002
Location: Denmark
Posts: 1,705
redhead is on a distinguished road
odd and even pairs, like [2,6] ; [17,9]
__________________
Don't worry Ma'am, We're university students, We know what We're doing.
-----
If you pull the pin, Mr.Grenade would no longer be your friend.
-----
01000111 01101111 00100000 01000011 00100000 00100001
redhead is offline   Reply With Quote
Old 08-27-2005, 01:31 PM   #6 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Like redhead's example. Run and debug my code to seee what it does. Altough it should be pretty obvious what it does from here.
__________________
Valmont is offline   Reply With Quote
Old 08-27-2005, 04:58 PM   #7 (permalink)
redhead
Newbie
 
redhead's Avatar
 
Join Date: Jun 2002
Location: Denmark
Posts: 1,705
redhead is on a distinguished road
Quote:
Run and debug my code to seee what it does.
To make this clear, here is a small example:
Code:
const int numbers[] = {1, 2, 4, 3, 6, 5, 14};
There will be 6 odd pairs ({1,3};{3,1};{1,5}{5,1};{3,5};{5,3}) or 3! since theres 3 odd numbers in the vector.
(Oops was that too much of a hint...)
Anyway I think people get the idear, the task here is to make a way of looping through the array in O(N) time instead of the O(N^2) time which Valmonts solution does.
__________________
Don't worry Ma'am, We're university students, We know what We're doing.
-----
If you pull the pin, Mr.Grenade would no longer be your friend.
-----
01000111 01101111 00100000 01000011 00100000 00100001
redhead is offline   Reply With Quote
Old 08-27-2005, 04:59 PM   #8 (permalink)
teknomage1
Jack of all trades
 
teknomage1's Avatar
 
Join Date: Feb 2005
Location: Los Angeles
Posts: 598
teknomage1 is on a distinguished road
Send a message via AIM to teknomage1
I have a question, Val. In the current code, won't pairs that are both even or both odd get added to ep while pairs that that are one even and one odd be added to op? Is it supposed to be tallied this way?
__________________
Stop intellectual property from infringing on me
teknomage1 is offline   Reply With Quote
Old 08-27-2005, 07:18 PM   #9 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Quote:
I have a question, Val. In the current code, won't pairs that are both even or both odd get added to ep while pairs that that are one even and one odd be added to op? Is it supposed to be tallied this way?
YOU ARE RIGHT! I MADE A MISTAKE.
The program does what it should do but I explained it wrong!!!! OMG.

We want to know the amount of EVEN or ODD PRODUCT pairs.
So basically:
ep = even(Numbers[i] * Numbers[j])
op = odd(Numbers[i] * Numbers[j])


Thanks for pointing out this huge flaw in the postcondition. However the code remains correct. I have updated it in my original post.
Well done!
__________________
Valmont is offline   Reply With Quote
Old 08-27-2005, 10:05 PM   #10 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
You know what? Nevermind at all because this postcondition isn't correct either. I think we found a serious error somewhere. I need to figure out what is going on. It boils down to kicking the butt of a colleague...

edit
Ok I figured it out my self. See the first post in this thread. It's updated.
My colleage got this from a book:
MatheMagie (author Maarten Pennings)
But he never checked it. Nor did I. Both the algorithms in the book were wrong.

Anyway, continue solving this simple puzzle. Just reread the first post and the code.
__________________

Last edited by Valmont; 08-28-2005 at 01:28 AM.
Valmont is offline   Reply With Quote
Old 08-28-2005, 02:51 AM   #11 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
If I'm understanding the problem correctly we're looking for the number of pairs for which the product is even/odd. A number is even if it has 2 as one of it's factors and odd if it hasn't.

So:
even*even=even
even*odd=even
odd*odd=odd.

op then becomes ((num_o * num_o) - num_o).
The total number of pairs is ((size * size) - size), so ep becomes ((size * size) - size) - op.

Code:
void odd_even_pairs_fast(const int* vec, std::size_t size, unsigned& ep, unsigned& op)
{
	op = 0;		//Being able to call the function more than once, for whatever reason, is probably nice.
	std::size_t i;
	
	for (i = 0; i < size; ++i)
	{
		if (!even(vec[i])) ++op;
	}

	op = (op*op) - op;
	ep = ((size * size) - size) - op;
}
I should probably test the code before posting, but m3h
Locutus is offline   Reply With Quote
Old 08-28-2005, 03:48 AM   #12 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
- The total number of all possible pairs you guessed wrong.
- The algorithm for odd/even products is wrong too but that is closely related on your guesstimation on total possible pairs.
- Resetting variables in that function for re-use is inappropriate since that is not the responsibility of that function. Nor was that part of the task.
However, setting that variable to "0" for reasons of correctness would have been correct. I should have done that to make sure the precondition is right. In your (and mine) case you should have set "ep" to 0 as well for this very reason.

You forgot that both "i" and "j" INCLUDE index "0". So you need to start with Numbers[0]*Numbers[0]. If you did that right then your algorithm would have been correct.

Also this:
Code:
std::size_t i;
	
for (i = 0; i < size; ++i)
Keep "i" in the scope of the for-loop only. Now it's scope has been extended to the function for no valid reason.

All this the correct code:
Code:
void odd_even_pairs_fast(const int* vec, std::size_t size, unsigned& ep, unsigned& op)
{
  ep =0; op =0; //Guarantee correct precondition.
  for(std::size_t i = 0; i < size; ++i)
  {
    if( !even(vec[i]))
    {
      ++op;      
    }
  }
  op *= op;
  ep = (unsigned)(size * size) - op;
}
I think you did well.
__________________
Valmont is offline   Reply With Quote
Old 08-28-2005, 04:26 AM   #13 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
Quote:
Originally Posted by Valmont
- The total number of all possible pairs you guessed wrong.
- The algorithm for odd/even products is wrong too but that is closely related on your guesstimation on total possible pairs.
I assumed (wrongly?) you shouldn't count pairs of elements with themselves.

Quote:
Originally Posted by Valmont
- Resetting variables in that function for re-use is inappropriate since that is not the responsibility of that function. Nor was that part of the task.
However, setting that variable to "0" for reasons of correctness would have been correct. I should have done that to make sure the precondition is right. In your (and mine) case you should have set "ep" to 0 for this very reason.
It's not so much about re-use as it is about initialising variables before you modify/read from them. It all comes down to the same thing, really, but I guess I should have formulated it differently.
I didn't set ep to 0 because you never read from it.

Quote:
Originally Posted by Valmont
Also this:
Code:
std::size_t i;
	
for (i = 0; i < size; ++i)
Keep "i" in the scope of the for-loop only. Now it's scope has been extended to the function for no valid reason.
I actually knew that
I kinda got used to doing it this way for clarity / compiler portability, since certain dodgy compilers (like MSVC6) extend the scope of "i" to the entire function even if you do declare it within the for-loop.
Locutus is offline   Reply With Quote
Old 08-28-2005, 04:37 AM   #14 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Quote:
you shouldn't count pairs of elements with themselves.
The postcondition was set (in blue). We don't know what the reason is. So don't change it.

Quote:
I didn't set ep to 0 because you never read from it.
Agreed!

Quote:
since certain dodgy compilers (like MSVC6) extend the scope of "i" to the entire function even if you do declare it within the for-loop.
Good point but you can circumvent this problem whilst keeping the portability by explicity scoping:
Code:
void my_function()
{
   {//scope start
   for(int i = 0;; i++)
   {
   }
   }//scope end;
}
__________________
Valmont is offline   Reply With Quote
Old 08-28-2005, 04:55 AM   #15 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
Quote:
Originally Posted by Valmont
The postcondition was set (in blue). We don't know what the reason is. So don't change it.
True. Nevertheless, this line is slightly misleading
Quote:
Originally Posted by Valmont
The task is to find all possible odd and even product pairs (all permitations, not combinations).
Informal explanations are tricky. That's why I added the formal definition.

Last edited by Valmont; 08-28-2005 at 05:19 AM.
Locutus is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Hey guys! Code malfunction - need experts workover groundfrog Platform/API C++ 1 06-09-2005 07:46 AM
how the servlet will integrate the LDAP code j.gohel Java 19 04-16-2005 12:55 AM
Total beginner, need help with my code! Urgent timeframe cleverest Standard C, C++ 3 03-20-2005 05:44 PM
Cisco Code breaking sde Code Newbie News 0 05-21-2004 07:10 AM


All times are GMT -8. The time now is 03:16 PM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting