tags:

views:

157

answers:

2

So here’s the challenge. Given 2 integers named a and b:

// Find the 2 largest numbers, smaller than a and b, that are divisible by each other.

// input: a:102,b:53 // output: (102,51)

// input: a:7,b:4 // output: (6,3)

// input: a:3,b:2 // output: (2,2)

The catch is, I don’t want to brute force it. I think it comes out to O(n²).

Here’s the signature for the method:

static Tuple<int, int> Analyze(int a, int b)
{
    if (a % b == 0)
        return new Tuple<int, int>(a, b);
    else
        // Here’s where the algorithm kicks in
}

Here’s a sample implementation:

static Tuple<int, int> Analyze(int left, int right)
{
    if (left % right == 0)
        return new Tuple<int, int>(left, right);
    else
    {
        for (int i = left; i >= right; i--)
        {
            for (int j = right; j >= 0; j--)
                if (i % j == 0)
                    return new Tuple<int, int>(i, j);
                else
                    i--;
        }
    }

    return null;
}

Here’s the test client:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(Analyze(102, 53));
        Console.WriteLine(Analyze(6, 4));
        Console.WriteLine(Analyze(3, 2));
    }
}

There are obviously problems with my implementation, but it’s not bad for starters. For instance when I use 106 and 54 for my arguments, had I not decremented the outter loop variable (i-- in the else block), I’d have found a match with 106 and 53. Instead I find a match a 104 and 52, which isn’t quite right but is relatively close to the desired result. However, my sample implementation is much faster than a brute forced approach because I’d never loop anymore than b times, making it O(b). Thoughts, inputs?

+1  A: 

Have you looked at the Wolfram article on Greatest Common Divisor and with a little google-ing I found for you a nice java code that implements a good GCD algorithm that you can modify for your purposes here

Kjartan Þór Kjartansson
I don't see how GCD helps, but maybe you have an algorithm in mind.
GregS
For starters one might start by calculating the GCD for the input numbers if the GCD is 1 then lower the larger number by 1, and calculating the GCD for again, if the GCD is 1 then lower the larger number by 1 again.
Kjartan Þór Kjartansson
@Kjartan: What exactly would you do different *with* the gcd information than *without* it? The only case the gcd may matter is the trivial case when the gcd is b (that is, b divides a and there's nothing to do).
ShreevatsaR
Now after sleeping on the matter I can see that I was thinking in a wrong direction, so as a note to self I should not be doling out advice when I really should be sleeping :P
Kjartan Þór Kjartansson
@Kjartan. Thanks for the input.
Antwan W. A-Dubb
+1  A: 

I think this would work, and be pretty straightforward, if I'm not confused, it should find the largest sum(a,b):

static Tuple Analyze(int a, int b)
{
    if (a % b == 0)
        return new Tuple(a, b);
    else {
        // The algorithm starts here.
        // This is fairly easy to implement with tail recursion, but not optimal:
        // There are two cases to worry about:
        //   1) 'b' will never divide into 'a' evenly, but 'b-1' might.
        //   2) 'a' doesn't divide evenly by 'b', but 'a-1' might.
        if (a < b*2) return Analyze(a, b-1);
        else return Analyze(a-1, b);
    }
}

Finding the largest lexicographically is trivial. Just loop from b downto 1.

You'll be able to do better if you jump by more than one, obviously. Here's an example in python (assuming a>b, if it's not, swap them):

>>> def analyze(a, b):
...   if 0 == a%b: return (a,b)          # If b is a factor, return them.
...   if a < b*2: return analyze(a,a/2)  # If b can't factor, adjust 'b' to next.
...   return analyze(a-(a%b),b)          # Otherwise, adjust 'a' to next.
... 
>>> map(lambda p: analyze(*p), [(102, 53), (6, 4), (3,2)])
[(102, 51), (6, 3), (3, 1)]
Stephen
No this isn't for a school project. It's for an extension method that I'm writing that will be quite handy. I'll post the implementation soon.
Antwan W. A-Dubb
I'll post the brute force implementation then everyone should know what is meant by "largest".
Antwan W. A-Dubb
How do I color code the source code? It's easier to read that way.
Antwan W. A-Dubb
I think modulus will solve my problem. Maybe I've made this a lot more complicated than it should be. I'll post the extension method that I'm writing and show you why I've gone this far in the first place.
Antwan W. A-Dubb
@Antwan : The source code colors automatically when you use the 1010 button, or indent the text 4 spaces, or highlight and hit [ctrl+k]. Don't use pre tags, it loses angle brackets.
Stephen
Cool. Thanks for the tip.
Antwan W. A-Dubb
@Stephen Very cool Stephen. I'd like to post my extension method that caused this whole mess in the first place, but it's saying it too long. I guess since I'm posting it as a comment instead of code. How do I switch the mode?
Antwan W. A-Dubb
@Antwan : You'll have to edit your question, and add the code there.
Stephen