Project Euler – Problem 71 Solution

Problem

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.

Solution

This problem is fairly easy, given that the answer we’re looking for much be very close to 3 / 7 (0.4285714286) I simply iterate through the denominators, d, and find the closest numerator, n, which will produce a value less than 3 / 7. Then filter the set so we end up with only the n, d pairs that have a GCD of 1 and pick the numerator from the n, d pair whose n / d fraction is the biggest.

Project Euler – Problem 59 Solution

Problem

Each character on a computer is assigned a unique code and the preferred standard is ASCII (American Standard Code for Information Interchange). For example, uppercase A = 65, asterisk (*) = 42, and lowercase k = 107.

A modern encryption method is to take a text file, convert the bytes to ASCII, then XOR each byte with a given value, taken from a secret key. The advantage with the XOR function is that using the same encryption key on the cipher text, restores the plain text; for example, 65 XOR 42 = 107, then 107 XOR 42 = 65.

For unbreakable encryption, the key is the same length as the plain text message, and the key is made up of random bytes. The user would keep the encrypted message and the encryption key in different locations, and without both “halves”, it is impossible to decrypt the message.

Unfortunately, this method is impractical for most users, so the modified method is to use a password as a key. If the password is shorter than the message, which is likely, the key is repeated cyclically throughout the message. The balance for this method is using a sufficiently long password key for security, but short enough to be memorable.

Your task has been made easy, as the encryption key consists of three lower case characters. Using cipher1.txt (right click and ‘Save Link/Target As…’), a file containing the encrypted ASCII codes, and the knowledge that the plain text must contain common English words, decrypt the message and find the sum of the ASCII values in the original text.

Solution

Project Euler – Problem 79 Solution

Problem

A common security method used for online banking is to ask the user for three random characters from a passcode. For example, if the passcode was 531278, they may ask for the 2nd, 3rd, and 5th characters; the expected reply would be: 317.

The text file, keylog.txt, contains fifty successful login attempts.

Given that the three characters are always asked for in order, analyse the file so as to determine the shortest possible secret passcode of unknown length.

Solution

This problem is actually solved much easier by hand with pen and paper, but regardless here’s a F# solution to the problem.

Project Euler – Problem 145 Solution

Problem

Some positive integers n have the property that the sum [ n + reverse(n) ] consists entirely of odd (decimal) digits. For instance, 36 + 63 = 99 and 409 + 904 = 1313. We will call such numbersreversible; so 36, 63, 409, and 904 are reversible. Leading zeroes are not allowed in either n or reverse(n).

There are 120 reversible numbers below one-thousand.

How many reversible numbers are there below one-billion (109)?

Solution

The solution I have posted here solves the problem but it takes a good 15 mins or so to run so doesn’t meet the 1 minute rule.. unfortunately brute force is the only way I know how to solve this problem :-(

Project Euler – Problem 74 Solution

Problem

The number 145 is well known for the property that the sum of the factorial of its digits is equal to 145:

1! + 4! + 5! = 1 + 24 + 120 = 145

Perhaps less well known is 169, in that it produces the longest chain of numbers that link back to 169; it turns out that there are only three such loops that exist:

169 ? 363601 ? 1454 ? 169

871 ? 45361 ? 871

872 ? 45362 ? 872

It is not difficult to prove that EVERY starting number will eventually get stuck in a loop. For example,

69 ? 363600 ? 1454 ? 169 ? 363601 (? 1454)

78 ? 45360 ? 871 ? 45361 (? 871)

540 ? 145 (? 145)

Starting with 69 produces a chain of five non-repeating terms, but the longest non-repeating chain with a starting number below one million is sixty terms.

How many chains, with a starting number below one million, contain exactly sixty non-repeating terms?

Solution

The solution I have here caches the previous results to avoid duplicated work, this complicates the code slightly but it should still be fairly easy to follow. The key thing here is the recursive function processChainRec which recursively generate the next number in the chain until it hits one of two conditions:

  1. you hit a number already in the chain (hence the end of the non-repeating chain)
  2. you hit a number whose non-repeating chain length has been cached

In the first case, suppose you have [69, 363600, 1454, 169, 363601] in the list already, and then the next number is 1454, which is in the list with index 2. At this point, you can work out the non-repeating chain length for 69, 363600 and 1454:

69 : list.length – index = 5 – 0 = 5

363600 : list.length – index = 5 – 1 = 4

1454 : list.length – index = 5 – 2 = 3

Hit three eggs with one stone? Awesome Smile

For the second case, suppose you had already come across 1454 before and have already calculated its non-repeating chain length, now you have [69, 363600] in the list and 1454 pop outs of the hat. So a quick look up in the cached data tells you that 1454 has a non-repeating chain of 3 terms, so to apply that knowledge to 69 and 363600:

69 : list.length – index + 3 = 2 – 0 + 3 = 5

363600 : list.length – index + 3 = 2 – 1 + 3 = 4

Voila!