gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 19th, 2017 at 9:02:56 AM permalink
With all the math puzzles posted, I thought it may be fun to do a few math related programming challenges. I'm not taking credit for creating any of these, I'll be pulling from from various sources. You are free to post your solution in any language you wish, but I'll ask to avoid pseudo-code so that the solution can be verified.

For most of these challenges, there will be more than one way to achieve the correct result. However, the "winner" of each challenge will be whoever is first to post the most efficient solution possible, which anyone is free to debate.

Challenge #1:
A palindromic number reads the same both ways. 

The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

Find the largest palindrome made from the product of two 3-digit numbers.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 19th, 2017 at 10:49:25 AM permalink
I think this is the most efficient one I found - it's hard to tell as they all run so fast:



int A = 999;
int ASquared = 998001; // 999 x 999
int B;
BestResult = 0;
while (ASquared > BestResult && A >= 100)
{
B = 0;
AB = ASquared;
while (A + B < 1000 && AB > BestResult)
{
if (AB >= 100000 && AB / 100000 == AB % 10 && (AB % 100000) / 10000 == (AB % 100) / 10 && (AB % 10000) / 1000 == (AB % 1000) / 100)
{
BestResult = AB;
S.AppendLine((A + B).ToString() + " x " + (A - B).ToString() + " = " + BestResult.ToString());
}
else if (AB < 100000 && AB / 10000 == AB % 10 && (AB % 10000) / 1000 == (AB % 100) / 10)
{
BestResult = AB;
S.AppendLine((A + B).ToString() + " x " + (A - B).ToString() + " = " + BestResult.ToString());
}
B++;
AB -= (B + B - 1);
}
A--;
ASquared -= (A + A + 1);
}


I get 993 x 913 = 906609

The way it works is:
First, check 999 x 999
Next, check 998 x 998, then 999 x 997
Next, check 997 x 997, then 998 x 996, then 999 x 995
Keep checking N squared, then (N + 1)(N - 1), then (N + 2)(N - 2), and so on
Since N squared is the largest product in each "group", stop checking when N squared is less than the highest number already found.
To make it more efficient, multiplications are replaced by additions.

gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 19th, 2017 at 11:15:33 AM permalink
Quote: ThatDonGuy

I think this is the most efficient one I found - it's hard to tell as they all run so fast:



int A = 999;
int ASquared = 998001; // 999 x 999
int B;
BestResult = 0;
while (ASquared > BestResult && A >= 100)
{
B = 0;
AB = ASquared;
while (A + B < 1000 && AB > BestResult)
{
if (AB >= 100000 && AB / 100000 == AB % 10 && (AB % 100000) / 10000 == (AB % 100) / 10 && (AB % 10000) / 1000 == (AB % 1000) / 100)
{
BestResult = AB;
S.AppendLine((A + B).ToString() + " x " + (A - B).ToString() + " = " + BestResult.ToString());
}
else if (AB < 100000 && AB / 10000 == AB % 10 && (AB % 10000) / 1000 == (AB % 100) / 10)
{
BestResult = AB;
S.AppendLine((A + B).ToString() + " x " + (A - B).ToString() + " = " + BestResult.ToString());
}
B++;
AB -= (B + B - 1);
}
A--;
ASquared -= (A + A + 1);
}


I get 993 x 913 = 906609

The way it works is:
First, check 999 x 999
Next, check 998 x 998, then 999 x 997
Next, check 997 x 997, then 998 x 996, then 999 x 995
Keep checking N squared, then (N + 1)(N - 1), then (N + 2)(N - 2), and so on
Since N squared is the largest product in each "group", stop checking when N squared is less than the highest number already found.
To make it more efficient, multiplications are replaced by additions.


Efficiency is determined by the least amount of decisions the program makes, not runtime.

You got the correct answer, however, and I didn't trace your code in depth, but I believe you can further optimize your solution with some math.

Since 11 is prime, at least one of the values A or B must have a factor of 11.


I'm 100% positive that I am not the best at programming or math on the forum, so everyone is welcome to correct/debate anything I say.

I know that's C#, but name the language you used along with your solution.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 19th, 2017 at 11:28:00 AM permalink
Quote: gamerfreak


You got the correct answer, however, and I didn't trace your code in depth, but I believe you can further optimize your solution with some math.

Since 11 is prime, at least one of the values A or B must have a factor of 11.


That assumes the answer has 6 digits. 12321 = 111 x 111, but 111 is not a multiple of 11.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 19th, 2017 at 12:32:04 PM permalink
Quote: ThatDonGuy

That assumes the answer has 6 digits. 12321 = 111 x 111, but 111 is not a multiple of 11.


Full disclosure, this isn’t my explanation. It’s from the site where I grabbed the problem. I didn’t get this at first either. My initial solution was more brute force like.


Consider the digits of P – let them be x, y and z. P must be at least 6 digits long since the palindrome 111111 = 143×777 – the product of two 3-digit integers.

Since P is palindromic:
P=100000x+10000y+1000z+100z+10yx P=100001x+10010y+1100z
P=11(9091x+910y+100z)

Since 11 is prime, at least one of the integers a or b must have a factor of 11. So if a is not divisible by 11 then we know b must be.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 24th, 2017 at 12:20:43 PM permalink
Here is my C# implementation for what I think is the best way to solve the Palindrome Problem in Challenge #1:



static double LargestPalindrome ()
{
double largestPalindrome = 0;
double b;
double c;

for (double a = 999; a >= 100; a--)
{
if (a % 11 == 0)
{
b = 999;
c = 1;
}
else
{
b = 990;
c = 11;
}

while(b >= a)
{
if (a * b <= largestPalindrome)
break;

if (IsPalindrome(a * b))
largestPalindrome = a * b;

b = b-c;
}
}
return largestPalindrome;
}

static bool IsPalindrome(double n)
{
string a = n.ToString();
string b = new string(a.ToCharArray().Reverse().ToArray());

if (a == b)
return true;
else
return false;
}



Challenge #2
The four adjacent digits in the below 1000-digit number that 
have the greatest product are 9 × 9 × 8 × 9 = 5832.

73167176531330624919225119674426574742355349194934
96983520312774506326239578318016984801869478851843
85861560789112949495459501737958331952853208805511
12540698747158523863050715693290963295227443043557
66896648950445244523161731856403098711121722383113
62229893423380308135336276614282806444486645238749
30358907296290491560440772390713810515859307960866
70172427121883998797908792274921901699720888093776
65727333001053367881220235421809751254540594752243
52584907711670556013604839586446706324415722155397
53697817977846174064955149290862569321978468622482
83972241375657056057490261407972968652414535100474
82166370484403199890008895243450658541227588666881
16427171479924442928230863465674813919123162824586
17866458359124566529476545682848912883142607690042
24219022671055626321111109370544217506941658960408
07198403850962455444362981230987879927244284909188
84580156166097919133875499200524063689912560717606
05886116467109405077541002256983155200055935729725
71636269561882670428252483600823257530420752963450

Find the thirteen adjacent digits in the 1000-digit number that have the greatest product.

What is the value of this product?
Dalex64
Dalex64
  • Threads: 1
  • Posts: 1067
Joined: Feb 10, 2013
October 24th, 2017 at 1:49:45 PM permalink
brute force python, very little optimization



#!/usr/bin/env python3

bignum=(
"73167176531330624919225119674426574742355349194934"
"96983520312774506326239578318016984801869478851843"
"85861560789112949495459501737958331952853208805511"
"12540698747158523863050715693290963295227443043557"
"66896648950445244523161731856403098711121722383113"
"62229893423380308135336276614282806444486645238749"
"30358907296290491560440772390713810515859307960866"
"70172427121883998797908792274921901699720888093776"
"65727333001053367881220235421809751254540594752243"
"52584907711670556013604839586446706324415722155397"
"53697817977846174064955149290862569321978468622482"
"83972241375657056057490261407972968652414535100474"
"82166370484403199890008895243450658541227588666881"
"16427171479924442928230863465674813919123162824586"
"17866458359124566529476545682848912883142607690042"
"24219022671055626321111109370544217506941658960408"
"07198403850962455444362981230987879927244284909188"
"84580156166097919133875499200524063689912560717606"
"05886116467109405077541002256983155200055935729725"
"71636269561882670428252483600823257530420752963450"
)


def compute_product(digits):
result = 1
for d in digits:
result *= int(d)
return result


num_digits = len(bignum)
window_size = 13

pos = 0
biggest_sequence=""
biggest_product=0
while pos <= num_digits - window_size:
digits = bignum[pos:pos+13]
pos += 1
if "0" in digits:
continue
product = compute_product(digits)
if product > biggest_product:
biggest_product = product
biggest_sequence = digits

print(biggest_sequence, biggest_product)


5576689664895 23514624000

ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 24th, 2017 at 1:51:42 PM permalink

23,514,624,000, starting with digit 198 (5 5 7 6 6 8 9 6 6 4 8 9 5)

Here is the code:

String D = "73167176531330624919225119674426574742355349194934"
+ "96983520312774506326239578318016984801869478851843"
+ "85861560789112949495459501737958331952853208805511"
+ "12540698747158523863050715693290963295227443043557"
+ "66896648950445244523161731856403098711121722383113"
+ "62229893423380308135336276614282806444486645238749"
+ "30358907296290491560440772390713810515859307960866"
+ "70172427121883998797908792274921901699720888093776"
+ "65727333001053367881220235421809751254540594752243"
+ "52584907711670556013604839586446706324415722155397"
+ "53697817977846174064955149290862569321978468622482"
+ "83972241375657056057490261407972968652414535100474"
+ "82166370484403199890008895243450658541227588666881"
+ "16427171479924442928230863465674813919123162824586"
+ "17866458359124566529476545682848912883142607690042"
+ "24219022671055626321111109370544217506941658960408"
+ "07198403850962455444362981230987879927244284909188"
+ "84580156166097919133875499200524063689912560717606"
+ "05886116467109405077541002256983155200055935729725"
+ "71636269561882670428252483600823257530420752963450";

long Product = 1L;
int N = 0;
long BestProduct = 0L;
int BestLocation = 0;
int Digit;
int K;
while (N < 987)
{
// N points to either the first digit, or the first nonzero digit following a zero
// Search for the next group of 13 nonzero digits
K = 0;
while (N < 1000 && K < 13)
{
if (D[N] == '0')
{
K = 0;
}
else
{
K++;
}
N++;
}
// If K = 13, then N now points to the first digit following a group of 13
if (K == 13)
{
Product = 1L;
for (K = 1; K <= 13; K++)
{
Product *= (D[N - K] - '0');
}
if (Product > BestProduct)
{
BestProduct = Product;
BestLocation = N - 13;
}
// Search digits one at a time; if it is nonzero, multiply the current
// product by it, and divide by the digit 13 behind it
while (N < 1000 && D[N] != '0')
{
Product *= (D[N] - '0');
Product /= (D[N - 13] - '0');
if (Product > BestProduct)
{
BestProduct = Product;
BestLocation = N - 12;
}
N++;
}
}
}


gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 24th, 2017 at 1:59:47 PM permalink
Both are correct. I'm not sure about the most efficient way to do this yet. My solution was bruteforce like Dale's. It looks like Don did a little more by checking for numbers that do not contain 0's. I tried to pick only numbers that ended with 9 but that doesn't work.

I'm interested to see if anyone can come up with anything better.
Dalex64
Dalex64
  • Threads: 1
  • Posts: 1067
Joined: Feb 10, 2013
October 24th, 2017 at 3:02:56 PM permalink
I did check to see if there is a 0 within the 13 digits, but I never advance the pointer by more than 1 at a time.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 24th, 2017 at 4:54:05 PM permalink
The problem with brute force is, you have to do 13 multiplications in each step. Mine starts with 13, then does a multiplication and a division in each step - that is, until the 13th digit is a zero, at which point you know the next 13 products will all be zero, so you can skip ahead 13 digits.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 24th, 2017 at 5:14:18 PM permalink
Quote: ThatDonGuy

The problem with brute force is, you have to do 13 multiplications in each step. Mine starts with 13, then does a multiplication and a division in each step - that is, until the 13th digit is a zero, at which point you know the next 13 products will all be zero, so you can skip ahead 13 digits.


Yea, I realize brute force isn’t the best. Skipping once hitting a 0 is probably the most optimial, trying to wrack my brain for something better and not thinking of anything.
DRich
DRich
  • Threads: 86
  • Posts: 11724
Joined: Jul 6, 2012
October 24th, 2017 at 7:17:02 PM permalink
Quote: ThatDonGuy

The problem with brute force is, you have to do 13 multiplications in each step. Mine starts with 13, then does a multiplication and a division in each step - that is, until the 13th digit is a zero, at which point you know the next 13 products will all be zero, so you can skip ahead 13 digits.



If you are optimizing for speed it would probably be quicker to do addition and subtraction instead of the multiplication and division.
At my age, a "Life In Prison" sentence is not much of a deterrent.
someone
someone
  • Threads: 0
  • Posts: 36
Joined: Nov 9, 2014
October 25th, 2017 at 1:31:14 AM permalink
You can optimize a bit by not bothering to check if the next number is smaller than the number rolling off the back of the 13 digit number. ie when going from 9876543219876 to 8765432198765 you don't have to check. the problem is when you then have an increase you have to multiply the skipped digits again, but I;m sure something clever could be done to make it worth the optimization.
RS
RS
  • Threads: 62
  • Posts: 8626
Joined: Feb 11, 2014
October 25th, 2017 at 2:15:46 AM permalink
I'd think step one would be to split the 1000 digit number by 0's and make an array. Ignore arrays (or sets?) with fewer than 13 digits.

If there are 13 numbers in a set, multiply them all, and you're done for that set. If there are 14, then compare digit #1 with #14. If 1 is larger than 14, then your numbers are 1-13. If 14 is larger then 2-14.

If there are 15 numbers, then you know digits 3-13 must exist in the biggest number thingie. Multiply 1 and 2, 2 and 14, 14 and 15. Whichever product is highest, that set of 2 is going to be in the biggest 13.

If there are 16 digits, then all EXCEPT the first three and final three numbers are needed. Mutiply 1,2,3 and 2,3,14 and 3,14,15 and 14,15,16. Highest product will be the answer (for that set).

Of course this gets a bit cumbersome, perhaps, when you start to get many more digits. And once you get to like 25 or 26 digits, it doesn't work anymore. Although I suppose you could break it up into a few smaller arrays (so, three 17 digit arrays or so?).

If any set's first or last number is a 1, it can be ignored, assuming the +13'th number isn't also a 1. Maybe.

After all this nonsense, you're left with a bunch of sets of 13 which are possibilities to be the highest, but you've also removed a majority of the original 988 sets.

Of the remaining sets, you rearrange the numbers from lowest to highest. Get rid of all the 1s, since multiplying by 1 obviously does nothing, AFAIK. :)

Think I just pooped my pants but I'll edit this or make. New reply.
RS
RS
  • Threads: 62
  • Posts: 8626
Joined: Feb 11, 2014
October 25th, 2017 at 2:39:32 AM permalink
Okay that was a false alarm, all's good, thank you for your concerns.


Actually I'm not really sure what I'd do next. And I guess part of my assumption (which probably isn't good) is that the computer would be getting bogged down by such big numbers and that was part of the "optimization" game (sorta like 9^(9^9) problem)......turns out 9^13 isn't all that big. =\
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 25th, 2017 at 4:35:25 AM permalink
I never did well in classes where we had to figure out the time-complexity of algorithms, but my general understanding is that time-complexity increases with the amount of decisions a algorithm has to make.

I'm thinking the simple 0 check is best way about this, so I'm going to post another challenge, but if anyone thinks of something better for any of these please post.

Challenge #3
A little more maths in this one, and I do not think it can be brute forced in any reasonable amount of time.
The sequence of triangle numbers is generated by adding the natural numbers. 
So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28.

The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...

Let us list the factors of the first seven triangle numbers:

1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five divisors.

What is the value of the first triangle number to have over five hundred divisors?
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 25th, 2017 at 6:18:49 AM permalink

T(12375) = 76,576,500 = 22 x 32 53 x 7 x 11 x 13 x 17 has 576 divisors
Each divisor is the product of {1, 2, 4} {1, 3, 9} {1, 5, 25, 125} {1, 7} {1, 11} {1, 13} {1. 17}

The number of factors a positive integer N has = (P(2) + 1) (P(3) + 1) (P(5) + 1) (P(7) + 1) P((11) + 1)...
where P(K) is the number of times the prime K appears in N's prime factorization
For example, 25,200 = 24 x 32 x 52 x 7, so P(2) = 4, P(3) = 2, P(5) = 2, P(7) = 1, and P(N) = 0 for all other primes


// This assumes int Primes[] is defined as a constant array of all primes < 10,000
int PrimesCount = Primes.Length;

int[] Factors = new int[PrimesCount];

int FactorCount = 0;
int TCount = 1;
int T = 1;
// int P;
while (FactorCount < 500)
{
for (N = 0; N < PrimesCount; N++)
{
Factors[N] = 1;
}
TCount++;
T += TCount;
N = T;
for (P = 0; Primes[P] * Primes[P] <= N; P++)
{
while (N % Primes[P] == 0)
{
Factors[P]++;
N /= Primes[P];
}
}
for (P = 0; P < PrimesCount && Primes[P] != N; P++) ;
if (P < PrimesCount)
{
Factors[P]++;
}
FactorCount = 1;
for (N = 0; N < PrimesCount; N++)
{
FactorCount *= Factors[N];
}
}

DRich
DRich
  • Threads: 86
  • Posts: 11724
Joined: Jul 6, 2012
October 25th, 2017 at 6:20:54 AM permalink
For challenge #2, since multiplication is commutative shouldn't the largest sum of the sequence of 13 numbers with no zeros also be the largest product? Is there any point in doing any multilpication?
At my age, a "Life In Prison" sentence is not much of a deterrent.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 25th, 2017 at 6:29:35 AM permalink
Quote: DRich

For challenge #2, since multiplication is commutative shouldn't the largest sum of the sequence of 13 numbers with no zeros also be the largest product? Is there any point in doing any multilpication?


9991111111111 has product 729 and sum 37
2222222222222 has product 8192 and sum 26
DRich
DRich
  • Threads: 86
  • Posts: 11724
Joined: Jul 6, 2012
Thanked by
RS
October 25th, 2017 at 6:38:26 AM permalink
Quote: ThatDonGuy

9991111111111 has product 729 and sum 37
2222222222222 has product 8192 and sum 26



Wow, you didn't have to disprove so quickly. Now I feel foolish.
At my age, a "Life In Prison" sentence is not much of a deterrent.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 25th, 2017 at 6:47:17 AM permalink
Quote: ThatDonGuy


T(12375) = 76,576,500 = 22 x 32 53 x 7 x 11 x 13 x 17 has 576 divisors
Each divisor is the product of {1, 2, 4} {1, 3, 9} {1, 5, 25, 125} {1, 7} {1, 11} {1, 13} {1. 17}

The number of factors a positive integer N has = (P(2) + 1) (P(3) + 1) (P(5) + 1) (P(7) + 1) P((11) + 1)...
where P(K) is the number of times the prime K appears in N's prime factorization
For example, 25,200 = 24 x 32 x 52 x 7, so P(2) = 4, P(3) = 2, P(5) = 2, P(7) = 1, and P(N) = 0 for all other primes


// This assumes int Primes[] is defined as a constant array of all primes < 10,000
int PrimesCount = Primes.Length;

int[] Factors = new int[PrimesCount];

int FactorCount = 0;
int TCount = 1;
int T = 1;
// int P;
while (FactorCount < 500)
{
for (N = 0; N < PrimesCount; N++)
{
Factors[N] = 1;
}
TCount++;
T += TCount;
N = T;
for (P = 0; Primes[P] * Primes[P] <= N; P++)
{
while (N % Primes[P] == 0)
{
Factors[P]++;
N /= Primes[P];
}
}
for (P = 0; P < PrimesCount && Primes[P] != N; P++) ;
if (P < PrimesCount)
{
Factors[P]++;
}
FactorCount = 1;
for (N = 0; N < PrimesCount; N++)
{
FactorCount *= Factors[N];
}
}


Correct, and a primes array is the best way to do it as well. I think it could only be improved slightly by figuring out how to start the calculation safely with primes > 3.

I need to make these harder!
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 25th, 2017 at 9:54:13 AM permalink
Challenge #4
Since many of these problems have a recurring theme of involving prime numbers, 
this challenge is to create the fastest primality test you can.

The function IsPrime(N) should take any integer N as a parameter, and return true/false.

Heuristic and Probabilistic tests are acceptable.
Romes
Romes
  • Threads: 29
  • Posts: 5602
Joined: Jul 22, 2014
October 25th, 2017 at 12:11:59 PM permalink
Quote: gamerfreak

Challenge #4

Since many of these problems have a recurring theme of involving prime numbers, 
this challenge is to create the fastest primality test you can.

The function IsPrime(N) should take any integer N as a parameter, and return true/false.

Heuristic and Probabilistic tests are acceptable.


So let's find out if this is cheating... Because here's my real world application of this. If I needed to find out if a number was a prime number for an application I'm working on, the first thing I would do is take to google and type "c# check for prime number" which led me to the following stack overflow page and answer:

https://stackoverflow.com/questions/15743192/check-if-number-is-prime-number


public static bool IsPrime(int number)
{
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;

var boundary = (int)Math.Floor(Math.Sqrt(number));

for (int i = 3; i <= boundary; i+=2)
{
if (number % i == 0) return false;
}

return true;
}


So all said and done this literally took me about 30 seconds. I believe that's the most efficient you could be.
Playing it correctly means you've already won.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 25th, 2017 at 12:39:44 PM permalink
Quote: Romes

Quote: gamerfreak

Challenge #4

Since many of these problems have a recurring theme of involving prime numbers, 
this challenge is to create the fastest primality test you can.

The function IsPrime(N) should take any integer N as a parameter, and return true/false.

Heuristic and Probabilistic tests are acceptable.


So let's find out if this is cheating... Because here's my real world application of this. If I needed to find out if a number was a prime number for an application I'm working on, the first thing I would do is take to google and type "c# check for prime number" which led me to the following stack overflow page and answer:

https://stackoverflow.com/questions/15743192/check-if-number-is-prime-number


public static bool IsPrime(int number)
{
if (number == 1) return false;
if (number == 2) return true;
if (number % 2 == 0) return false;

var boundary = (int)Math.Floor(Math.Sqrt(number));

for (int i = 3; i <= boundary; i+=2)
{
if (number % i == 0) return false;
}

return true;
}


So all said and done this literally took me about 30 seconds. I believe that's the most efficient you could be.


Yes looking up the answer is cheating



In all seriousness, I use answers posted on stack overflow constantly for work things. It's had to have saved me hundreds of hours.

Most of these challenges I'm posting are more so math problems that require programming due their scale. And a lot of them will involve prime numbers.

The solution you posted is a simple trial division, which is terribly slow when you get into large numbers. You can do much better with a sieve or heuristic/probabilistic test.
Romes
Romes
  • Threads: 29
  • Posts: 5602
Joined: Jul 22, 2014
October 25th, 2017 at 12:42:41 PM permalink
Yeah, but I didn't modify it at all and it took me 30 seconds to find lol... I like the challenges you post and I start thinking about "okay you'd just have to do this, then that, then this, etc..." but then I don't want to write out the code =P. You should allow pseudo-code, as it can clearly show the understanding of the concepts! Or are all of these questions just homework questions we're answering for someone?? =D
Playing it correctly means you've already won.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
Thanked by
Romes
October 25th, 2017 at 12:54:07 PM permalink
Quote: Romes

Yeah, but I didn't modify it at all and it took me 30 seconds to find lol... I like the challenges you post and I start thinking about "okay you'd just have to do this, then that, then this, etc..." but then I don't want to write out the code =P. You should allow pseudo-code, as it can clearly show the understanding of the concepts! Or are all of these questions just homework questions we're answering for someone?? =D


I was in-between on allowing pseudocode when I made the OP. Is doing actual code really that much harder? I just keep a "sandbox" C# visual studio project laying around and plug my code into a new function whenever I want to mess around with something. And the other benefit of that, if you are at work it will look like you're actually working.
Dalex64
Dalex64
  • Threads: 1
  • Posts: 1067
Joined: Feb 10, 2013
October 25th, 2017 at 1:23:43 PM permalink
90% of coding is actually problem solving, figuring out how to solve a problem, and the best way to solve a problem. 10% is writing the code to do it.

For example, look at the quick and dirty, naive, and inefficient code that I wrote. For that I probably put in maybe 10% of the effort into finding a good solution and 90% to write it up, in a very short amount of time. Given the sub-second execution time of the code I wrote for the problem I solved, I didn't feel like putting more effort into it.

ThatDonGuy's code would be faster and more efficient, especially once you scale up to less trivial problems, and shows more thought in the best way of how to solve the problem first.
Romes
Romes
  • Threads: 29
  • Posts: 5602
Joined: Jul 22, 2014
October 25th, 2017 at 1:42:47 PM permalink
Quote: Dalex64

90% of coding is actually problem solving, figuring out how to solve a problem, and the best way to solve a problem. 10% is writing the code to do it...

In the real world, this all day.

Another fun thing to reminisce over, since this is mainly a "programming" thread. I just had an error, a very simple one, in an application I'm working on. It made me laugh because I personally believe it's the most common error that finally compilers caught up to pointing out. Back in the day you would just get an error or even worse the program would WORK and you'd get the wrong output... the good 'ol double equals.

if (code == x) works for comparison... if(code = x) reassigns and evaluates as true (at least it used to, the compiler I'm working with now in the .NET framework just caught this and threw an error to me). I remember back in college this not being the case... the program would run fine, setting the value of code = x, then evaluating that as a true statement and running the if block. Man, finding that missing = was PAINFUL back then.
Playing it correctly means you've already won.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 25th, 2017 at 2:02:50 PM permalink
Quote: Romes

In the real world, this all day.

Another fun thing to reminisce over, since this is mainly a "programming" thread. I just had an error, a very simple one, in an application I'm working on. It made me laugh because I personally believe it's the most common error that finally compilers caught up to pointing out. Back in the day you would just get an error or even worse the program would WORK and you'd get the wrong output... the good 'ol double equals.

if (code == x) works for comparison... if(code = x) reassigns and evaluates as true (at least it used to, the compiler I'm working with now in the .NET framework just caught this and threw an error to me). I remember back in college this not being the case... the program would run fine, setting the value of code = x, then evaluating that as a true statement and running the if block. Man, finding that missing = was PAINFUL back then.


I never had much issue remembering to do the ==.

All of my University's general CS courses were C++ based, and my worst memories were implementing data structures where pointers and manual memory management were required. Even thinking about the words "Segmentation Fault" make me want to slam my keyboard against the wall. Dat garbage collection is why I like C# so much. Although I still think it was valuable to learn about how those things are dealt with in a lower level language.

I also loathe recursion. Fortunately I haven't run into many real-world scenarios where it was required. Iterative solutions are usually more efficient anyway.
DRich
DRich
  • Threads: 86
  • Posts: 11724
Joined: Jul 6, 2012
October 25th, 2017 at 2:07:30 PM permalink
Quote: Romes

In the real world, this all day.

Another fun thing to reminisce over, since this is mainly a "programming" thread. I just had an error, a very simple one, in an application I'm working on. It made me laugh because I personally believe it's the most common error that finally compilers caught up to pointing out. Back in the day you would just get an error or even worse the program would WORK and you'd get the wrong output... the good 'ol double equals.

if (code == x) works for comparison... if(code = x) reassigns and evaluates as true (at least it used to, the compiler I'm working with now in the .NET framework just caught this and threw an error to me). I remember back in college this not being the case... the program would run fine, setting the value of code = x, then evaluating that as a true statement and running the if block. Man, finding that missing = was PAINFUL back then.



Yes, the = sign has got everybody that programs in C.
At my age, a "Life In Prison" sentence is not much of a deterrent.
DRich
DRich
  • Threads: 86
  • Posts: 11724
Joined: Jul 6, 2012
October 25th, 2017 at 2:18:02 PM permalink
Quote: gamerfreak



I also loathe recursion. Fortunately I haven't run into many real-world scenarios where it was required. Iterative solutions are usually more efficient anyway.



I would guess that I have used recursion about five times in my 34 years of professional programming.
At my age, a "Life In Prison" sentence is not much of a deterrent.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 25th, 2017 at 2:35:18 PM permalink
Quote: gamerfreak

Challenge #4

Since many of these problems have a recurring theme of involving prime numbers, 
this challenge is to create the fastest primality test you can.

The function IsPrime(N) should take any integer N as a parameter, and return true/false.

Heuristic and Probabilistic tests are acceptable.


By "integer," is it limited to 64-bit or smaller integers, or are unlimited-sized integers (what .NET calls BigInteger) allowed?

In fact, I was just working on this sort of problem - I wanted to see if 1065536 + 1 was prime or not, using Miller-Rabin (a probabilistic method).

However, the first step involves calculating 2(565536) mod (1065536 + 1), which takes God's own number of forevers. The second step would be to take that number squared, mod (1065536 + 1), and then do that 65,534 more times.


Let P be an odd number to be checked (not much sense to check an even number; 2 is prime, and the others are not)

Let M be any integer >= 2

Express P as 2K * Q + 1, where K is a non-negative integer and Q is odd (it can be 1, if P is 1 + a power of 2)

S0 = MQ mod P
S1 = S02 mod P
S2 = S12 mod P
...
SK-1 = SK-22 mod P
If S0 = 1, or Sn = P - 1 for any n, then P "may be" prime
Otherwise, P is not prime

The theory is, if N different values of M show that P "may be" prime, the probability that P is not prime is 22N.

gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 25th, 2017 at 2:42:08 PM permalink
Quote: DRich

I would guess that I have used recursion about five times in my 34 years of professional programming.


I'm sure it comes up more in particular niches like 3D rendering. But anything that's done recursively can also be done iteratively, and the latter usually makes way more sense to me. There's a few classic problems they gave us in school, like n-queens or Towers of Hanoi where the recursive solutions were much simpler and more readable than their iterative counterparts.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 25th, 2017 at 2:43:40 PM permalink
Quote: ThatDonGuy

Quote: gamerfreak

Challenge #4

Since many of these problems have a recurring theme of involving prime numbers, 
this challenge is to create the fastest primality test you can.

The function IsPrime(N) should take any integer N as a parameter, and return true/false.

Heuristic and Probabilistic tests are acceptable.


By "integer," is it limited to 64-bit or smaller integers, or are unlimited-sized integers (what .NET calls BigInteger) allowed?

In fact, I was just working on this sort of problem - I wanted to see if 1065536 + 1 was prime or not, using Miller-Rabin (a probabilistic method).

However, the first step involves calculating 2(565536) mod (1065536 + 1), which takes God's own number of forevers. The second step would be to take that number squared, mod (1065536 + 1), and then do that 65,534 more times.


I meant integer just as any whole number. You can use any datatype you like.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 25th, 2017 at 2:54:51 PM permalink
Quote: gamerfreak

I meant integer just as any whole number. You can use any datatype you like.


As I said in an earlier post, even probabilistic methods can be quite time-consuming for relatively small numbers.

This is one reason why searches tend to be restricted to things like Mersenne primes, where the formula is much faster:

To determine if N = 2P - 1 is prime, where P is a prime:
S0 = 4
SK = (SK-12 - 2) mod N
N is prime if and only if SP-2 is zero.

For example, for 25 - 1 = 31:
S0 = 4
S1 = 14 mod 31 = 14
S2 = 194 mod 31 = 8
S3 = 62 mod 31 = 0
31 is prime

Although, again, it does take a while; on my old 3 GHz processor laptop, it would take 4 weeks of nonstop processing to check a number where P was around 40 million.
RS
RS
  • Threads: 62
  • Posts: 8626
Joined: Feb 11, 2014
October 25th, 2017 at 4:14:47 PM permalink
Quote: gamerfreak

I'm sure it comes up more in particular niches like 3D rendering. But anything that's done recursively can also be done iteratively, and the latter usually makes way more sense to me. There's a few classic problems they gave us in school, like n-queens or Towers of Hanoi where the recursive solutions were much simpler and more readable than their iterative counterparts.


I had an old computer and decided to see how far along it'd get if I let it run all year, recursively getting the next Fibonacci number, without cache(?). By coincidence, I had also run the nyan cat website for whatever reason. I closed the computer, but it under my bed, and let it run. I guess the cord got unplugged sometime and thus, the Fibonacci program failed (or else the number got too big).

So I open the computer on one of the last days of school, because I totally forgot about it. Turns out, the nyan cat website's timer goes off of your system clock, or something like that, so it said I had been watching the nyan cat for like 300,000+ seconds, even though the computer was off most/all of that time.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 27th, 2017 at 11:11:31 AM permalink
Quote: RS

Quote: gamerfreak

I'm sure it comes up more in particular niches like 3D rendering. But anything that's done recursively can also be done iteratively, and the latter usually makes way more sense to me. There's a few classic problems they gave us in school, like n-queens or Towers of Hanoi where the recursive solutions were much simpler and more readable than their iterative counterparts.


I had an old computer and decided to see how far along it'd get if I let it run all year, recursively getting the next Fibonacci number, without cache(?). By coincidence, I had also run the nyan cat website for whatever reason. I closed the computer, but it under my bed, and let it run. I guess the cord got unplugged sometime and thus, the Fibonacci program failed (or else the number got too big).

So I open the computer on one of the last days of school, because I totally forgot about it. Turns out, the nyan cat website's timer goes off of your system clock, or something like that, so it said I had been watching the nyan cat for like 300,000+ seconds, even though the computer was off most/all of that time.


Should have saved them to a file. It would have derped out pretty quickly if you were using standard datatypes. Unsigned 32-bit integers max out at 4294967295 which would only get you to the 47th Fibbonacci number. If it was using a big-int datatype it would have derped out when your computer ran out of memory.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 27th, 2017 at 11:19:55 AM permalink
Quote: ThatDonGuy

As I said in an earlier post, even probabilistic methods can be quite time-consuming for relatively small numbers.

This is one reason why searches tend to be restricted to things like Mersenne primes, where the formula is much faster:

To determine if N = 2P - 1 is prime, where P is a prime:
S0 = 4
SK = (SK-12 - 2) mod N
N is prime if and only if SP-2 is zero.

For example, for 25 - 1 = 31:
S0 = 4
S1 = 14 mod 31 = 14
S2 = 194 mod 31 = 8
S3 = 62 mod 31 = 0
31 is prime

Although, again, it does take a while; on my old 3 GHz processor laptop, it would take 4 weeks of nonstop processing to check a number where P was around 40 million.


It's not an easy problem for a computer to solve. I did a fermat probability test that would repeat N times, and at N=20 it seemed very reliable. It seemed slower than a division test though, so I need to work on it a bit and figure out why. I think it's because I was using .net BigInt library to raise the number to a power, which is probably super slow.

It looks like Wolfram Alpha uses the Rabin-Miller test: http://mathworld.wolfram.com/PrimalityTest.html

I'm not sure how they do it so fast on their engine. Maybe they have precalculated tables? There doesn't seem to be a limit to how many digits you can enter, though.
Romes
Romes
  • Threads: 29
  • Posts: 5602
Joined: Jul 22, 2014
October 27th, 2017 at 2:26:25 PM permalink
Quote: gamerfreak

...I also loathe recursion. Fortunately I haven't run into many real-world scenarios where it was required. Iterative solutions are usually more efficient anyway.

You probably wouldn't have liked my "scheme" class I took in college. It's a programming language built entirely on recursion...
Playing it correctly means you've already won.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 27th, 2017 at 6:55:51 PM permalink
Quote: gamerfreak

It looks like Wolfram Alpha uses the Rabin-Miller test: http://mathworld.wolfram.com/PrimalityTest.html

I'm not sure how they do it so fast on their engine. Maybe they have precalculated tables? There doesn't seem to be a limit to how many digits you can enter, though.


I am not sure, but I think it tries a "fast" method of some sort. I entered 9,223,372,036,854,775,783 (which is 263 - 25), and it answered that it was prime quickly. It could be brute force, as it does return factorizations of nonprimes, but there are over 50 million primes less than 1 billion, so it would have to divide by each one of those, and even then, it may not work if the number is more than 1018.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 31st, 2017 at 6:55:12 AM permalink
Prime challenge is still open (or any other if you can do better). It's a very difficult problem to solve once you get into big numbers.

A Pythagorean triplet is a set of three natural numbers where a < b < c, for which a^2 + b^2 = c^2

For example:
3^2 + 4^2 = 9 + 16 = 25 = 5^2.

There exists exactly one Pythagorean triplet for which a + b + c = 1000.

Find the product abc.
Last edited by: gamerfreak on Oct 31, 2017
RS
RS
  • Threads: 62
  • Posts: 8626
Joined: Feb 11, 2014
October 31st, 2017 at 8:00:52 AM permalink
Bruh, you should write x^2 instead of x2. Makes comprehending this much easier....assuming that's what you mean.

Is this the proper interpretation of the "For example:"

3^2 + 4^2 = 9 + 16 = 25 and that's equal to 5^2 ?

ie: a, b, c = 3, 4, 5 respectively?

Also, should use QUOTE or even SPOILER instead of CODE, because on some of the challenges you have to scroll right to read rest of description.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 31st, 2017 at 8:09:02 AM permalink
Quote: RS

Bruh, you should write x^2 instead of x2. Makes comprehending this much easier....assuming that's what you mean.

Is this the proper interpretation of the "For example:"

3^2 + 4^2 = 9 + 16 = 25 and that's equal to 5^2 ?

ie: a, b, c = 3, 4, 5 respectively?

Also, should use QUOTE or even SPOILER instead of CODE, because on some of the challenges you have to scroll right to read rest of description.


My bad, copy and paste got me on the squares, I edited.

And damn how small is your screen? I formatted so it even shows up on my phone without scrolling. BUT HAVE IT YOUR WAY, it's in a spoiler now.
RS
RS
  • Threads: 62
  • Posts: 8626
Joined: Feb 11, 2014
October 31st, 2017 at 8:16:14 AM permalink
I said SOME of the previous challenges, ie: challenge #1.

And putting it in CODE within a SPOILER doesn't halp. Obvii in this case it doesn't matter b/c he's not too long, width-wise. But the earlier ones would still be wonky.
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
October 31st, 2017 at 8:19:07 AM permalink
Quote: RS

I said SOME of the previous challenges, ie: challenge #1.

And putting it in CODE within a SPOILER doesn't halp. Obvii in this case it doesn't matter b/c he's not too long, width-wise. But the earlier ones would still be wonky.


It's all fixed and I'll do it that way from now on. Now go solve it.
CrystalMath
CrystalMath
  • Threads: 8
  • Posts: 1911
Joined: May 10, 2011
October 31st, 2017 at 9:58:39 AM permalink

a=200
b=375
c=425
a*b*c=31875000


public class FindPythagoreanTriplets {

public static void main(String[] args) {
new FindPythagoreanTriplets();
}

public FindPythagoreanTriplets() {
boolean solutionFound = false;
int a = 3;
int b = 0;
int c = 0;

while (1000 % (a + b + c) >0) {
a++;
if (a % 2 == 0) // even
{
b = a * a / 4 - 1;
c = b + 2;
} else {
b = (a * a - 1) / 2;
c = b + 1;
}
}
int mult = 1000 / (a + b + c);
a *= mult;
b *= mult;
c *= mult;
System.out.println(a + " " + b + " " + c + " " + a * b * c);
}
}

I heart Crystal Math.
ThatDonGuy
ThatDonGuy
  • Threads: 117
  • Posts: 6274
Joined: Jun 22, 2011
October 31st, 2017 at 10:01:13 AM permalink
Quote: gamerfreak

Prime challenge is still open (or any other if you can do better). It's a very difficult problem to solve once you get into big numbers.

A Pythagorean triplet is a set of three natural numbers where a < b < c, for which a^2 + b^2 = c^2

For example:
3^2 + 4^2 = 9 + 16 = 25 = 5^2.

There exists exactly one Pythagorean triplet for which a + b + c = 1000.

Find the product abc.



Sometimes, just some good old-fashioned math will do.

C = 1000 - (A + B)
A^2 + B^2 = C^2 = (1000 - (A + B))^2
A^2 + B^2 = 1,000,000 - 2000 A - 2000 B + A^2 + 2AB + B^2
0 = 1,000,000 - 2000 A - 2000 B + 2AB
1000 A + 1000 B = 500,000 + AB
This means AB is a multiple of 1000

1000 B - AB = 500,000 - 1000 A
B = (500,000 - 1000 A) / (1000 - A)
= 1000 (500 - A) / (1000 - A)
= 1000 ((1000 - A) - 500) / (1000 - A)
= 1000 - 500,000 / (1000 - A)
(1000 - A) must be a factor of 500,000
Also, 500,000 / (1000 - A) < 1000, as otherwise B <= 0
This means 500,000 < 1,000,000 - 1000 A
1000 A < 500,000
A < 500
1000 - A > 500

The only integers between 500 and 1000 that are factors of 500,000 = 2^5 x 5^6 are 625 and 800
1000 - A = 625 -> A = 375 -> B = 200, but A < B is given
1000 - A = 800 -> A = 200 -> B = 375 -> C = 425
200^2 + 375^2 = 40,000 + 140,625 = 180,625 = 425^2 = (1000 - (200 + 375))^2

gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
November 8th, 2017 at 8:48:15 AM permalink
Quote: CrystalMath


a=200
b=375
c=425
a*b*c=31875000


public class FindPythagoreanTriplets {

public static void main(String[] args) {
new FindPythagoreanTriplets();
}

public FindPythagoreanTriplets() {
boolean solutionFound = false;
int a = 3;
int b = 0;
int c = 0;

while (1000 % (a + b + c) >0) {
a++;
if (a % 2 == 0) // even
{
b = a * a / 4 - 1;
c = b + 2;
} else {
b = (a * a - 1) / 2;
c = b + 1;
}
}
int mult = 1000 / (a + b + c);
a *= mult;
b *= mult;
c *= mult;
System.out.println(a + " " + b + " " + c + " " + a * b * c);
}
}


Correct answer. However I believe there is a more efficient solution using Primitive Triplets and Parametrization.

Quote: ThatDonGuy

Quote: gamerfreak

Prime challenge is still open (or any other if you can do better). It's a very difficult problem to solve once you get into big numbers.

A Pythagorean triplet is a set of three natural numbers where a < b < c, for which a^2 + b^2 = c^2

For example:
3^2 + 4^2 = 9 + 16 = 25 = 5^2.

There exists exactly one Pythagorean triplet for which a + b + c = 1000.

Find the product abc.



Sometimes, just some good old-fashioned math will do.

C = 1000 - (A + B)
A^2 + B^2 = C^2 = (1000 - (A + B))^2
A^2 + B^2 = 1,000,000 - 2000 A - 2000 B + A^2 + 2AB + B^2
0 = 1,000,000 - 2000 A - 2000 B + 2AB
1000 A + 1000 B = 500,000 + AB
This means AB is a multiple of 1000

1000 B - AB = 500,000 - 1000 A
B = (500,000 - 1000 A) / (1000 - A)
= 1000 (500 - A) / (1000 - A)
= 1000 ((1000 - A) - 500) / (1000 - A)
= 1000 - 500,000 / (1000 - A)
(1000 - A) must be a factor of 500,000
Also, 500,000 / (1000 - A) < 1000, as otherwise B <= 0
This means 500,000 < 1,000,000 - 1000 A
1000 A < 500,000
A < 500
1000 - A > 500

The only integers between 500 and 1000 that are factors of 500,000 = 2^5 x 5^6 are 625 and 800
1000 - A = 625 -> A = 375 -> B = 200, but A < B is given
1000 - A = 800 -> A = 200 -> B = 375 -> C = 425
200^2 + 375^2 = 40,000 + 140,625 = 180,625 = 425^2 = (1000 - (200 + 375))^2


¯\_(ツ)_/¯

I can code but I'm terrible at math :(
gamerfreak
gamerfreak
  • Threads: 57
  • Posts: 3540
Joined: Dec 28, 2014
March 21st, 2018 at 10:25:55 AM permalink
Here is a fun one:


Consider the fraction, n/d, where n and d are positive integers. If n<d and HCF(n,d)=1, it is called a reduced proper fraction.

If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8, 2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

It can be seen that 2/5 is the fraction immediately to the left of 3/7.

By listing the set of reduced proper fractions for d ≤ 1,000,000 in ascending order of size, find the numerator of the fraction immediately to the left of 3/7.

  • Jump to: