Project Euler Problem 245 - python

I'm onto problem 245 now but have hit some problems. I've done some work on it already but don't feel I've made any real steps towards solving it. Here's what I've got so far:
We need to find n=ab with a and b positive integers. We can also assume gcd(a, b) = 1 without loss of generality and thus phi(n) = phi(ab) = phi(a)phi(b).
We are trying to solve:
Hence:
At this point I figured it would be a good idea to actually see how these numbers were distributed. I hacked together a brute-force program that I used to find all (composite) solutions up to 104:
15, 85, 255, 259, 391, 589, 1111, 3193, 4171, 4369, 12361, 17473, 21845, 25429, 28243, 47989, 52537, 65535, 65641, 68377, 83767, 91759
Importantly it looks like there won't be too many less than the 1011 limit the problem asks. The most interesting/ useful bit I discovered was that k was quite small even for the large values of n. In fact the largest k was only 138. (Additionally, it seems k is always even.)
Considering this, I would guess it is possible to consider every value of k and find what value(s) n can be with that value of k.
Returning to the original equation, note that it can be rewritten as:
Since we know k:
And that's about as far as I have got; I'm still pursuing some of my routes but I wonder if I'm missing the point! With a brute force approach I have found the sum up to 108 which is 5699973227 (only 237 solutions for n).
I'm pretty much out of ideas; can anyone give away some hints?
Update: A lot of work has been done by many people and together we've been able to prove several things. Here's a list:
n is always odd and k is always even. k <= 105.5. n must be squarefree.
I have found every solution for when n=pq (2 prime factors) with p>q. I used the fact that for 2 primes q = k+factor(k^2-k+1) and p = k+[k^2-k+1]/factor(k^2-k+1). We also know for 2 primes k < q < 2k.
For n with 2 of more prime factors, all of n's primes are greater than k.

Project Euler isn't fond of discussing problems on public forums like StackOverflow. All tasks are made to be done solo, if you encounter problems you may ask help for a specific mathematical or programming concept, but you can't just decide to ask how to solve the problem at hand - takes away the point of project Euler.
Point is to learn and come up with solutions yourself, and learn new concepts.

Let me continue what jug started, but try a somewhat different approach. The goal again is to just find the numbers that have two distinct factors n=pq. As you already pointed out we are looking for the numbers such that n-phi(n) divides n-1. I.e., if n=pq then that means we are looking for p,q such that
p+q-1 divides pq-1
Assume we fix p and are looking for all primes q satisfying the equation above. The equation above doesn't look very easy to solve, hence the next step is to eliminate q as much as possible. In particular, we use that if a divides b then a also divides b + ka for any integer k. Hence
p+q-1 divides pq - 1 - p(p+q-1)
and simplifying this leads to the condition
p+q-1 divides p^2 - p + 1.
We may assume that p is the smaller prime factor of n. Then p is smaller than the square root of 1011. Hence it is possible to find all numbers with two factors by iterating through all primes p below the square root of 1011, then find the divisors of p^2-p+1, solve for q and check if q is prime and pq is a solution of the problem.
This of course, still leaves the integers with more than two prime factors. A somewhat similar approach works here too, but is more involved and needs further optimizations.
One question I can't answer is why is this problem formulated so complicated. Couldn't the authors just have asked for the sum of composite integers where n-phi(n) divides n-1. So maybe I'm missing a big hint there.
Now, that the solutions with two prime factors are known, I'll try to find a potential algorithm for finding solutions with more than 2 prime factors. The goal is to find an algorithm that given a composite integer m finds all primes q such that mq is a solution. I.e., q must be such that
mq - phi(mq) divides mq - 1.
Let
F = mq - phi(mq).
Then of course
F = (m-phi(m)) q + phi(m).
As in the case of two prime factors it is possible to find a condition for F, by eliminating q from the left hand side of the equation above. Since F divides mq-1 it also divides
(m-phi(m))(mq - 1)
and hence also
m F - (m-phi(m))(mq - 1) = m phi(m) + m - phi(m).
Thus by finding all the divisors F of m phi(m) + m - phi(m) and by checking if
(F - phi(m))/ (m - phi(m)) is prime it is possible to find all solutions mq for a given m.
Since only the divisors F that satisfy
F == phi(m) (mod m - phi(m))
can lead to new solutions, this fact can somtimes be used to optimze the factorization of
m phi(m) + m - phi(m).

Multiply primes. What I did, is first check every 2-prime product; store the ones that are successes. Then using the stored products, check those with more primes (every 3-prime product shown in your brute force has a 2-prime subset that works). Use these stored products, and try again with 4 primes, 5 primes etc.
The only downside is that you need a good sieve or list of primes.
Here is a list of the ones for N<=(10^7):
2 primes
15,85,259,391,589,1111,3193,4171,4369,12361,17473,25429,28243,47989,52537,65641,
68377,83767,91759,100777,120019,144097,186367,268321,286357,291919,316171,327937
,346063,353029,360301,404797,406867,524851,531721,558013,563767,633727,705667,73
8607,910489,970141,1013539,1080769,1093987,1184233,1185421,1223869,1233823,12618
07,1264693,1455889,1487371,1529641,1574383,1612381,1617379,1657531,1793689,20163
79,2095087,2130871,2214031,2299459,2500681,2553709,2609689,2617963,2763697,30475
21,3146677,3397651,3514603,3539017,3820909,3961219,4078927,4186993,4197901,44997
07,4552411,4935883,4975687,5103841,5299351,5729257,5829877,5864581,6017299,62364
01,6802531,6856609,8759011,9059233,9203377,9301603,9305311,9526747,9536899,95832
79,9782347,9900217
3 primes
255,21845,335923,3817309
4 primes
65535
5 primes
83623935

In order not to give too much away, I'd suggest two things:
Analyze the sequence of numbers you've produced though brute-force: they all share a common characteristic. If you find what it is, you may then have a shot at brute forcing your way to a solution.
Find a more sophisticated factoring algorithm. Or even better: rather than finding the factors from the numbers, build the numbers from the factors...
EDIT: The patterns you wll find will only add to your understading, and hopefully show you how you could have achieved the same amount of knowledge by an adequate manipulation of the analytical expression. Without knowing that pattern, I'm afraid that there is no path to a solution. Plus, this is probably among the hardest Project Euler problems, so you need not worry about finding the solution without a lot of sweat and toil...

no direct help for this problem, but maybe interesting for future math projects: instead of using WolframAlpha to analyze the sequence, I'd recommend "The On-Line Encyclopedia of Integer Sequences" on research.att.com.
Have fun solving all Euler problems!

I haven't found a full solution, but I would like to share my thoughts. Perhaps someone could help.
I believe that one should try to reduce the problem to
(source: texify.com)
complexity.The following facts can be used to make the search more effective:
Any solution must be an odd number
Any solution must be a multiple of distinct primes (no square number factors are allowed)
Others have pointed out about these and it is easy to prove them using only the basic properties of the totient function.
I'll start by analyzing all prime and composite numbers up to sqrt(10^11). This is not a big task and the time required should be well below the 1 minute requirement. All solutions above the square root are of the form:
a*b, where at least one of a,b < sqrt(10^11)
While iterating the range 0..sqrt(10^11), I will search for multiples of the number in iteration that are solutions. I will only cover the case of multiplying a number below the square root with a single prime. The solution set I will get this way will be a superset of the two-prime factors solution set. It will still not be the complete solution set, as solutions of the form p1p2p3, where p1p2,p2p3,p1p3>sqrt(10^11) will not be found.
Let b be the number below the square root and a the prime to multiply it.
(source: texify.com)
We have:
(source: texify.com)
Based on the facts that
phi(a) = a - 1 and phi(a)*phi(b) = phi(a*b) if a, b coprime
we have
(source: texify.com)
The 'modulo' part on the right can be written as:
(source: texify.com)
Let me temporarily accept that
(source: texify.com)
Then I could solve the above equation for a (m=1), verify that the result is prime and then I will have the only solution that is a multiple of b. If the m is not within the limits to be the actual modulo, then I need to either solve the equation for different values of k:
(source: texify.com)
(k values must be somehow limited) or prove that in that case the will be a higher b < sqrt(10^11) to cover for this.
There is a special case for b prime or b composite and mb = 0. In that case:
(source: texify.com)
This can be calculated. For b a prime number:
(source: texify.com)
I need to find a prime a that satisfies the equation:
(source: texify.com)
For example, let b=3, phi(b)=2.
I need to solve:
k[3a-2(a-1)] - 6 = 1 => k(a + 2) = 5
For k=1, a=7, a prime (solution)
For all other values of k, the above equation can't be satisfied.

Related

Algorithm-finding-dedicated-sum-from-the-population-of-variables

I need a way of finding an exact value made of the sum of variables chosen from the population. The algorithm can find just the first solution or all. So we can have 10, 20, or 30 different numbers and we will sum some of them to get a desirable number. As an example we have a population of the below numbers: -2,-1,1,2,3,5,8,10 and we try to get 6 - this can be made of 8 and -2, 1 + 5 etc. I need at least 2 decimal places to consider as well for accuracy and ideally, the sum of variables will be exact to the asking value.
Thanks for any advice and help on this:)
I build a model Using the simplex method in Excel but I need the solution in Python.
This is the subset sum problem, which is an NP Complete problem.
There is a known pseudo-polynomial solution for it, if the numbers are integers. In your case, you need to consider numbers only to 2nd decimal point, so you could convert the problem into integers by multiplying by 1001, and then run the pseudo-polynomial algorithm.
It will works quite nicely and efficiently - if the range of numbers you have is quite small (Complexity is O(n*W), where W is the sum of numbers in absolute value).
Appendix:
Pseudo polynomial time solution is Dynamic Programming adaptation of the following recursive formula:
k is the desired number
n is the total number of elements in list.
// stop clause: Found a sum
D(k, i) = true | for all 0 <= i < n
// Stop clause: failing attempt, cannot find sum in this branch.
D(x, n) = false | x != k
// Recursive step, either take the current element or skip it.
D(x, i) = D(x + arr[i], i+1) OR D(x, i+1)
Start from D(0,0)
If this is not the case, and the range of numbers is quite high, you might have to go with brute force solution, of checking all possible subsets. This solution is of course exponential, and processing it is in O(2^n) .
(1) Consider rounding if needed, but that's a simple preprocessing that doesn't affect the answer.

8 Queens on a chessboard | PYTHON | Memory Error

I came across this question where 8 queens should be placed on a chessboard such that none can kill each other.This is how I tried to solve it:
import itertools
def allAlive(position):
qPosition=[]
for i in range(8):
qPosition.append(position[2*i:(2*i)+2])
hDel=list(qPosition) #Horizontal
for i in range(8):
a=hDel[0]
del hDel[0]
l=len(hDel)
for j in range(l):
if a[:1]==hDel[j][:1]:
return False
vDel=list(qPosition) #Vertical
for i in range(8):
a=vDel[0]
l=len(vDel)
for j in range(l):
if a[1:2]==vDel[j][1:2]:
return False
cDel=list(qPosition) #Cross
for i in range(8):
a=cDel[0]
l=len(cDel)
for j in range(l):
if abs(ord(a[:1])-ord(cDel[j][:1]))==1 and abs(int(a[1:2])-int(cDel[j][1:2]))==1:
return False
return True
chessPositions=['A1','A2','A3','A4','A5','A6','A7','A8','B1','B2','B3','B4','B5','B6','B7','B8','C1','C2','C3','C4','C5','C6','C7','C8','D1','D2','D3','D4','D5','D6','D7','D8','E1','E2','E3','E4','E5','E6','E7','E8','F1','F2','F3','F4','F5','F6','F7','F8','G1','G2','G3','G4','G5','G6','G7','G8','H1','H2','H3','H4','H5','H6','H7','H8']
qPositions=[''.join(p) for p in itertools.combinations(chessPositions,8)]
for i in qPositions:
if allAlive(i)==True:
print(i)
Traceback (most recent call last):
qPositions=[''.join(p) for p in itertools.combinations(chessPositions,8)]
MemoryError
I'm still a newbie.How can I overcome this error?Or is there any better way to solve this problem?
What you are trying to do is impossible ;)!
qPositions=[''.join(p) for p in itertools.combinations(chessPositions,8)]
means that you will get a list with length 64 choose 8 = 4426165368, since len(chessPositions) = 64, which you cannot store in memory. Why not? Combining what I stated in the comments and #augray in his answer, the result of above operation would be a list which would take
(64 choose 8) * 2 * 8 bytes ~ 66GB
of RAM, since it will have 64 choose 8 elements, each element will have 8 substrings like 'A1' and each substring like this consists of 2 character. One character takes 1 byte.
You have to find another way. I am not answering to that because that is your job. The n-queens problem falls into dynamic programming. I suggest you to google 'n queens problem python' and search for an answer. Then try to understand the code and dynamic programming.
I did searching for you, take a look at this video. As suggested by #Jean François-Fabre, backtracking. Your job is now to watch the video once, twice,... as long as you don't understand the solution to problem. Then open up your favourite editor (mine is Vi :D) and code it down!
This is one case where it's important to understand the "science" (or more accurately, math) part of computer science as much as it is important to understand the nuts and bolts of programming.
From the documentation for itertools.combinations, we see that the number of items returned is n! / r! / (n-r)! where n is the length of the input collection (in your case the number of chess positions, 64) and r is the length of the subsequences you want returned (in your case 8). As #campovski has pointed out, this results in 4,426,165,368. Each returned subsequence will consist of 8*2 characters, each of which is a byte (not to mention the overhead of the other data structures to hold these and calculate the answer). Each character is 1 byte, so in total, just counting the memory consumption of the resulting subsequences gives 4,426,165,368*2*8=70818645888. dividing this by 1024^3 gives the number of Gigs of memory held by these subsequences, about 66GB.
I'm assuming you don't have that much memory :-) . Calculating the answer to this question will require a well thought out algorithm, not just "brute force". I recommend doing some research on the problem- Wikipedia looks like a good place to start.
As the other answers stated you cant get every combination to fit in memory, and you shouldn't use brute force because the speed will be slow. However, if you want to use brute force, you could constrain the problem, and eliminate common rows and columns and check the diagonal
from itertools import permutations
#All possible letters
letters = ['a','b','c','d','e','f','g','h']
#All possible numbers
numbers = [str(i) for i in range(1,len(letters)+1)]
#All possible permutations given rows != to eachother and columns != to eachother
r = [zip(letters, p) for p in permutations(numbers,8)]
#Formatted for your function
points = [''.join([''.join(z) for z in b]) for b in r]
Also as a note, this line of code attempts to first find all of the combinations, then feed your function, which is a waste of memory.
qPositions=[''.join(p) for p in itertools.combinations(chessPositions,8)]
If you decided you do want to use a brute force method, it is possible. Just modify the code for itertools combinations. Remove the yield and return and just feed your check function one at a time.

Code finding the first triangular number with more than 500 divisors will not finish running

Okay, so I'm working on Euler Problem 12 (find the first triangular number with a number of factors over 500) and my code (in Python 3) is as follows:
factors = 0
y=1
def factornum(n):
x = 1
f = []
while x <= n:
if n%x == 0:
f.append(x)
x+=1
return len(f)
def triangle(n):
t = sum(list(range(1,n)))
return t
while factors<=500:
factors = factornum(triangle(y))
y+=1
print(y-1)
Basically, a function goes through all the numbers below the input number n, checks if they divide into n evenly, and if so add them to a list, then return the length in that list. Another generates a triangular number by summing all the numbers in a list from 1 to the input number and returning the sum. Then a while loop continues to generate a triangular number using an iterating variable y as the input for the triangle function, and then runs the factornum function on that and puts the result in the factors variable. The loop continues to run and the y variable continues to increment until the number of factors is over 500. The result is then printed.
However, when I run it, nothing happens - no errors, no output, it just keeps running and running. Now, I know my code isn't the most efficient, but I left it running for quite a bit and it still didn't produce a result, so it seems more likely to me that there's an error somewhere. I've been over it and over it and cannot seem to find an error.
I'd merely request that a full solution or a drastically improved one isn't given outright but pointers towards my error(s) or spots for improvement, as the reason I'm doing the Euler problems is to improve my coding. Thanks!
You have very inefficient algorithm.
If you ask for pointers rather than full solution, main pointers are:
There is a more efficient way to calculate next triangular number. There is an explicit formula in the wiki. Also if you generate sequence of all numbers it is just more efficient to add next n to the previous number. (Sidenote list in sum(list(range(1,n))) makes no sense to me at all. If you want to use this approach anyway, sum(xrange(1,n) will probably be much more efficient as it doesn't require materialization of the range)
There are much more efficient ways to factorize numbers
There is a more efficient way to calculate number of factors. And it is actually called after Euler: see Euler's totient function
Generally Euler project problems (as in many other programming competitions) are not supposed to be solvable by sheer brute force. You should come up with some formula and/or more efficient algorithm first.
As far as I can tell your code will work, but it will take a very long time to calculate the number of factors. For 150 factors, it takes on the order of 20 seconds to run, and that time will grow dramatically as you look for higher and higher number of factors.
One way to reduce the processing time is to reduce the number of calculations that you're performing. If you analyze your code, you're calculating n%1 every single time, which is an unnecessary calculation because you know every single integer will be divisible by itself and one. Are there any other ways you can reduce the number of calculations? Perhaps by remembering that if a number is divisible by 20, it is also divisible by 2, 4, 5, and 10?
I can be more specific, but you wanted a pointer in the right direction.
From the looks of it the code works fine, it`s just not the best approach. A simple way of optimizing is doing until the half the number, for example. Also, try thinking about how you could do this using prime factors, it might be another solution. Best of luck!
First you have to def a factor function:
from functools import reduce
def factors(n):
step = 2 if n % 2 else 1
return set(reduce(list.__add__,
([i, n//i] for i in range(1, int(pow(n,0.5) + 1)) if n % i
== 0)))
This will create a set and put all of factors of number n into it.
Second, use while loop until you get 500 factors:
a = 1
x = 1
while len(factors(a)) < 501:
x += 1
a += x
This loop will stop at len(factors(a)) = 500.
Simple print(a) and you will get your answer.

How to quickly find sum of all pairs of elements in 2 different arrays

So recently I hit upon this programming problem which I couldn't seem to make the complexity less (my current code runs in O(n^2)).
Essentially, I have four different lists (I'm using python btw) of integers, both positive and negative, say lists A, B, C, D. Now, each of these lists has 1000 integers, and these integers range from -25000 to 25000 inclusive. Now, suppose from each of these lists we choose an integer, say a, b, c, d. I would like the quickest way to find these a, b, c, d such that a+b=-(c+d).
Currently, my method relies on iterating through every single possible combination of a, b, and c, d, before then trying to find if an element in the set (a+b) exists in the set -(c+d). This, of course, is impractical since it runs in O(n^2) time, even more so considering the large list sizes (1000).
Hence I was wondering if anyone could think of a more efficient way (preferably O(n log n) or smaller), coded in python if possible.
Apologies if it's rather confusing. If you have any questions please inform me, I'll try to provide more clarification.
EDIT:
This problem is part of a larger problem. The larger problem states that if we have 4 sequences of numbers with at most 1000 integers in each, say A, B, C, D, find an a, b, c, d such that a+b+c+d=0.
I asked the above question since a+b+c+d=0 implies that a+b=-(c+d), which I thought would lead to the fastest way to solve the problem. If anyone can think of an even faster way, please do share it with me.
Thanks in advance! :)
Your problem isn't that combining pairs of elements is O(n^2), but rather the fact that you're combining two such processes naively to end up with an O(n^4) algorithm. I'm going to assume you just need to find >= 1 ways to add up to 0 -- my method given below can easily be extended to find all ways, if it's required.
Given that you have a relatively narrow range of accepted values (-25k to +25k, let's call those MIN and MAX respectively), here's what you do:
Create 2 int arrays of size (MAX - MIN + 1), "indicesA" and "indicesB". That's not even 0.5 MB of memory all together, so nothing to worry about on a modern system.
Now loop on all elements of lists A and B, just like you were doing. Do something like this pseudo-code (not too familiar with python so I'm not sure if it's valid as-is):
for idxA, valA in enumerate(A):
for idxB, valB in enumerate(B):
indicesA[valA + valB - MIN] = idxA + 1
indicesB[valA + valB - MIN] = idxB + 1
Now just use this as an O(1) lookup-table when looping on B and C:
for valC in C:
for valD in D:
neededVal = -(valC + valD) - MIN
if indicesA[neededVal] > 0:
print('Found solution: {0} {1} {2} {3}'.format(A[indicesA[neededVal] - 1],
B[indicesB[neededVal] - 1], valC, valD))
Lookup-table initialization with 0s: O(MAX - MIN) (~50k, smaller than n^2 in this case)
Filling lookup-table by looping on A and B: O(n^2)
Looping on C and D and checking for any solutions: O(n^2)
Overall, O(n^2 + (MAX - MIN)) =~ O(n^2) with the values given. Probably can't do much better than that.
You have four arrays and you want to choose one number from each array, such that the sum of the four numbers is zero. The technical name for this problem is 4SUM×4.
This problem is at least as hard 3SUM×3, where three numbers summing to zero must be chosen from three arrays. An instance of 3SUM×3 can be converted to an instance of 4SUM×4 by simply adding an array of zeros. So any algorithm solving your problem can be used to solve 3SUM×3 in the same time complexity.
It doesn't appear to be known for certain that 3SUM×3 isn't easier than the more famous 3SUM problem, but it seems very likely to be equally difficult. A 3SUM×3 algorithm can be used to solve the 3SUM problem or determine with arbitrarily high probability that no solution exists. (The only issue with reducing 3SUM to 3SUM×3 is that 3SUM×3 allows solutions like 1, 1, -2 whereas 3SUM doesn't.) The theoretically-best known algorithms for 3SUM only beat O(n2) by factors of (log n) to some power.
Given all of that, it seems very unlikely that your problem can be solved in significantly less than O(n2) time, asymptotically.

What category of combinatorial problems appear on the logic games section of the LSAT?

EDIT: See Solving "Who owns the Zebra" programmatically? for a similar class of problem
There's a category of logic problem on the LSAT that goes like this:
Seven consecutive time slots for a broadcast, numbered in chronological order I through 7, will be filled by six song tapes-G, H, L, O, P, S-and exactly one news tape. Each tape is to be assigned to a different time slot, and no tape is longer than any other tape. The broadcast is subject to the following restrictions:
L must be played immediately before O.
The news tape must be played at some time after L.
There must be exactly two time slots between G and
P, regardless of whether G comes before P or whether G comes after P.
I'm interested in generating a list of permutations that satisfy the conditions as a way of studying for the test and as a programming challenge. However, I'm not sure what class of permutation problem this is. I've generalized the type problem as follows:
Given an n-length array A:
How many ways can a set of n unique items be arranged within A? Eg. How many ways are there to rearrange ABCDEFG?
If the length of the set of unique items is less than the length of A, how many ways can the set be arranged within A if items in the set may occur more than once? Eg. ABCDEF => AABCDEF; ABBCDEF, etc.
How many ways can a set of unique items be arranged within A if the items of the set are subject to "blocking conditions"?
My thought is to encode the restrictions and then use something like Python's itertools to generate the permutations. Thoughts and suggestions are welcome.
This is easy to solve (a few lines of code) as an integer program. Using a tool like the GNU Linear Programming Kit, you specify your constraints in a declarative manner and let the solver come up with the best solution. Here's an example of a GLPK program.
You could code this using a general-purpose programming language like Python, but this is the type of thing you'll see in the first few chapters of an integer programming textbook. The most efficient algorithms have already been worked out by others.
EDIT: to answer Merjit's question:
Define:
matrix Y where Y_(ij) = 1 if tape i
is played before tape j, and 0
otherwise.
vector C, where C_i
indicates the time slot when i is
played (e.g. 1,2,3,4,5,6,7)
Large
constant M (look up the term for
"big M" in an optimization textbook)
Minimize the sum of the vector C subject to the following constraints:
Y_(ij) != Y_(ji) // If i is before j, then j must not be before i
C_j < C_k + M*Y_(kj) // the time slot of j is greater than the time slot of k only if Y_(kj) = 1
C_O - C_L = 1 // L must be played immediately before O
C_N > C_L // news tape must be played at some time after L
|C_G - C_P| = 2 // You will need to manipulate this a bit to make it a linear constraint
That should get you most of the way there. You want to write up the above constraints in the MathProg language's syntax (as shown in the links), and make sure I haven't left out any constraints. Then run the GLPK solver on the constraints and see what it comes up with.
Okay, so the way I see it, there are two ways to approach this problem:
Go about writing a program that will approach this problem head first. This is going to be difficult.
But combinatorics teaches us that the easier way to do this is to count all permutations and subtract the ones that don't satisfy your constraints.
I would go with number 2.
You can find all permutations of a given string or list by using this algorithm. Using this algorithm, you can get a list of all permutations. You can now apply a number of filters on this list by checking for the various constraints of the problem.
def L_before_O(s):
return (s.index('L') - s.index('O') == 1)
def N_after_L(s):
return (s.index('L') < s.index('N'))
def G_and_P(s):
return (abs(s.index('G') - s.index('P')) == 2)
def all_perms(s): #this is from the link
if len(s) <=1:
yield s
else:
for perm in all_perms(s[1:]):
for i in range(len(perm)+1):
yield perm[:i] + s[0:1] + perm[i:]
def get_the_answer():
permutations = [i for i in all_perms('GHLOPSN')] #N is the news tape
a = [i for i in permutations if L_before_O(i)]
b = [i for i in a if N_after_L(i)]
c = [i for i in b if G_and_P(i)]
return c
I haven't tested this, but this is general idea of how I would go about coding such a question.
Hope this helps

Categories