So I'm trying to find a way to find the difference between 3 ints;
a, b, c
so I need to find the difference between a - b and the difference between b - c
and then print true if the difference is the same, else printing false.
I've been attempting to use the abs() function but can't seem to get the result I need. any help would be appreciated.
Here is the problem statement:
Given three ints, a b c, one of them is small, one is medium and
one is large. Print True if the three values are evenly spaced,
so the difference between small and medium is the same as the
difference between medium and large.
this is what i have so far;
a = int(input())
b = int(input())
c = int(input())
if abs(a-b) == abs(b-c) :
print("True")
else :
print("False")
#
Test Input Expected Actual
1 4 6 2 True False
2 6 2 4 True False
3 10 9 11 True False
Based on the problem description, it sounds like you need to sort the numbers first:
numbers = sorted(int(input()) for _ in range(3))
print(numbers[1] - numbers[0] == numbers[2] - numbers[1])
You have 3 possible "middle" numbers, therefore you need to perform 3 comparisons.
x = abs(a - b)
y = abs(a - c)
z = abs(b - c)
if (x == y) or (x == z) or (y == z):
...
Related
Let a,b,c be the first digits of a number (e.g. 523 has a=5, b=2, c=3). I am trying to check if abc == sqrt(a^b^c) for many values of a,b,c. (Note: abc = 523 stands for the number itself.)
I have tried this with Python, but for a>7 it already took a significant amount of time to check just one digit combination. I have tried rewriting the equality as multiple logs, like log_c[log_b[log_a[ (abc)^2 ]]] == 1, however, I encountered Math Domain Errors.
Is there a fast / better way to check this equality (preferably in Python)?
Note: Three digits are an example for StackOverflow. The goal is to test much higher powers with seven to ten digits (or more).
Here is the very basic piece of code I have used so far:
for a in range(1,10):
for b in range(1,10):
for c in range(1,10):
N = a*10**2 + b*10 + c
X = a**(b**c)
if N == X:
print a,b,c
The problem is that you are uselessly calculating very large integers, which can take much time as Python has unlimited size for them.
You should limit the values of c you test.
If your largest possible number is 1000, you want a**b**c < 1000**2, so b**c < log(1000**2, a) = 2*log(1000, a)), so c < log(2*log(1000, a), b)
Note that you should exclude a = 1, as any power of it is 1, and b = 1, as b^c would then be 1, and the whole expression is just a.
To test if the square root of a^b^c is abc, it's better to test if a^b^c is equal to the square of abc, in order to avoid using floats.
So, the code, that (as expected) doesn't find any solution under 1000, but runs very fast:
from math import log
for a in range(2,10):
for b in range(2,10):
for c in range(1,int(log(2*log(1000, a), b))):
N2 = (a*100 + b*10 + c)**2
X = a**(b**c)
if N2 == X:
print(a,b,c)
You are looking for numbers whose square root is equal to a three-digit integer. That means your X has to have at most 6 digits, or more precisely log10(X) < 6. Once your a gets larger, the potential solutions you're generating are much larger than that, so we can eliminate large swathes of them without needing to check them (or needing to calculate a ** b ** c, which can get very large: 9 ** 9 ** 9 has 369_693_100 DIGITS!).
log10(X) < 6 gives us log10(a ** b ** c) < 6 which is the same as b ** c * log10(a) < 6. Bringing it to the other side: log10(a) < 6 / b ** c, and then a < 10 ** (6 / b ** c). That means I know I don't need to check for any a that exceeds that. Correcting for an off-by-one error gives the solution:
for b in range(1, 10):
for c in range(1, 10):
t = b ** c
for a in range(1, 1 + min(9, int(10 ** (6 / t)))):
N = a * 100 + b * 10 + c
X = a ** t
if N * N == X:
print(a, b, c)
Running this shows that there aren't any valid solutions to your equation, sadly!
a**(b**c) will grow quite fast and most of the time it will far exceed three digit number. Most of the calculations you are doing will be useless. To optimize your solution do the following:
Iterate over all 3 digit numbers
For each of these numbers square it and is a power of the first digit of the number
For those that are, check if this power is in turn a power of the second digit
And last check if this power is the third digit
We're given N (3 <= N <= 50000) cards with unique numbers from 1 to N.
We lost some 3 cards and our goal is to find them.
Input: first line contains number of cards N.
Second line contains 3 numbers: sum of all left cards we have, sum of their squares and sum of their cubes.
Output: numbers of 3 lost cards in any order.
Here what I tried: I found the same 3 sums for lost cards and then check of possible numbers until three of them satisfy our sums.
Is there a faster solution? I have to pass 2sec time limit in Python with max N = 50000.
N = int(input())
lst = list(range(1, N+1))
s_rest, s2_rest, s3_rest = list(map(int, input().split()))
s = sum(lst)
s2 = sum([x**2 for x in lst])
s3 = sum([x**3 for x in lst])
# sums of 3 lost numbers
s_lost = s - s_rest
s2_lost = s2 - s2_rest
s3_lost = s3 - s3_rest
def find_numbers():
"""Find first appropriate option"""
for num1 in range(s_lost):
for num2 in range(s_lost):
for num3 in range(s_lost):
if (num1 + num2 + num3 == s_lost) and (num1**2 + num2**2 + num3**2 == s2_lost)\
and (num1**3 + num2**3 + num3**3 == s3_lost):
return (num1, num2, num3)
answer = find_numbers()
print(answer[0], answer[1], answer[2])
Examples
Input:
4
1 1 1
Output:
2 3 4
Input:
5
6 26 126
Output:
2 3 4
If your unknown numbers are x,y,z, then you have a system of three equations
x + y + z = a //your s_lost
x^2 + y^2 + z^2 = b //your s2_lost
x^3 + y^3 + z^3 = c //your s3_lost
While direct solution of this system seems too complex, we can fix one unknown and solve simpler system. For example, check all possible values for z and solve system for x and y
for z in range(s_lost):
....
Now let's look to new system:
x + y = a - z = aa
x^2 + y^2 = b - z^2 = bb
substitute
x = aa - y
(aa - y)^2 + y^2 = bb
2 * y^2 - 2 * y * aa - bb + aa^2 = 0
solve this quadratic equation for y
D = 4 * aa^2 - 8 * (aa^2 - bb) = 8 * bb -4 * aa^2
y(1,2) = (2*aa +- Sqrt(D)) / 4
So for every z value find:
- whether solution gives integer values of y
- then get x
- and then check if cube sum equation is true.
Using this approach you'll get solution with linear complexity O(N) against your cubic complexity O(N^3).
P.S. If rather simple mathematical solution for equation system does exist, it has complexity O(1))
This can be simplified by mathematical approach. You are given 3 equations and have 3 unknowns.
sum(1+2+..+N) - x1 - x2 - x3 = a
sum(1^2+2^2+..+N^2) - x1^2 - x2^2 - x3^3 = b
sum(1^3+2^3+..+N^3) - x1^3 - x2^3 - x3^3 = c
Obviously sum(1..N) is 1/2 *N(N+1), while sum(1^2+2^2+3^2+..+N^2) is 1/6 *N*(N+1)*(2N+1) and sum(1^3+2^3+..+N^3) can be written as 1/4 *N^2 *(N+1)^2. Here are wolframalpha outputs: ∑k, ∑k^2, ∑k^3
At this point only thing left is solving given system of equations (3 with 3 unknowns is totally solvable) and implementing this. You only need to find one solution which makes it even easier. Running time is O(1).
Surely there exists a faster approach!
For N=50,000 your brute-force function would have to make up to
N * N * N = 125,000,000,000,000
iterations, so this is not an option.
Additionally, you should check for num1 == num2 etc. to avoid duplicated numbers (the problem does not state it explicitly, but I understand 'We lost some 3 cards' means you need to find three different numbers satisfying the conditions given).
You can sort the list, and find the pairs such that a[i+1] =/= a[i]+1. For every such pair numbers [a[i]+1;a[i+1]) are missing. This would give you O(n log n) running time.
I can give you an idea,
let sum1 = 1+2+3...n
let sum2 = 1^2+2^2+3^2...n
and p, q, r is three numbers given by input consecutively.
We need to search a, b, c. Iterate for c = 1 to N.
For each iteration,
let x = sum1 - (p+c)
let y = sum2 - (q+c*c)
so a+b = x and a^2+b^2 = y.
Since a^2+b^2 = (a+b)^2 - 2ab, you can find 2ab from equation a^2+b^2 = y.
a+b is known and ab is known, by a little math calculation, you can find if there exist a solution for a and b (it forms quadratic equation). If exist, print the solution and break the iteration.
It's an O(N) solution.
This question already has answers here:
What is the purpose of the return statement? How is it different from printing?
(15 answers)
Closed 4 months ago.
Write a simple procedure, myLog(x, b), that computes the logarithm of a number x relative to a base b.n other words, myLog should return the largest power of b such that b to that power is still less than or equal to x.
x and b are both positive integers; b is an integer greater than or equal to 2. Your function should return an integer answer.
Do not use Python's log functions; instead, please use an iterative or recursive solution to this problem that uses simple arithmatic operators and conditional testing.
What is wrong in the below code? As they have not mentioned what to return when the condition fails, so had kept false
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
print str(count)
break
elif (ans > x):
print str(count-1)
break
count += 1
else:
return False
Since you haven't explained what problem you're trying to solve, all I can do is guess. But…
Your function never returns a number. If it succeeds, it prints out a number, then falls off the end of the function and returns None. If it fails, it returns False. And there's no other return anywhere in the code.
That's easy to fix: just return the value instead of print-ing it:
def myLog(x, b):
count = 1
while x > 0 and b >= 2:
ans = b ** count
if (ans == x):
return count
elif (ans > x):
return count-1
count += 1
else:
return False
You can improve performance by doing ans *= b each time through the loop instead of ans = b ** count. If the numbers are huge, dividing x by b might be better—division is usually slower than multiplication, but getting out of the huge-number domain early might help more than avoiding division.
It's also got some style problems, like the unnecessary parentheses some (but not all) of your conditions.
And finally, you may want to consider writing a "test driver". For example:
repcount = 100
errcount = 0
for _ in range(repcount):
x = generate_nice_random_x()
b = generate_random_base()
log1, log2 = myLog(x, b), int(math.log(x, b))
if log1 != log2:
print('log({}, {}): {} != {}'.format(x, b, log1, log2))
errcount += 1
print('{}/{} errors'.format(errcount, repcount))
Start with a small repcount to make sure you don't spam the screen; when you're happier with it, use a much larger one. Meanwhile, I'll leave it to you to figure out a good domain to choose from for testing log functions.
This is a question on an exam, that is currently ongoing.MITx: 6.00.1x Introduction to Computer Science and Programming
A Python HOMEWORK Assignment asks me to write a function “that takes as input a positive whole number, and prints out a multiplication, table showing all the whole number multiplications up to and including the input number.”(Also using the while loop)
# This is an example of the output of the function
print_multiplication_table(3)
>>> 1 * 1 = 1
>>> 1 * 2 = 2
>>> 1 * 3 = 3
>>> 2 * 1 = 2
>>> 2 * 2 = 4
>>> 2 * 3 = 6
>>> 3 * 1 = 3
>>> 3 * 2 = 6
>>> 3 * 3 = 9
I know how to start, but don’t know what to do next. I just need some help with the algorithm. Please DO NOT WRITE THE CORRECT CODE, because I want to learn. Instead tell me the logic and reasoning.
Here is my reasoning:
The function should multiply all real numbers to the given value(n) times 1 less than n or (n-1)
The function should multiply all real numbers to n(including n) times two less than n or (n-2)
The function should multiply all real numbers to n(including n) times three less than n or (n-3) and so on... until we reach n
When the function reaches n, the function should also multiply all real numbers to n(including n) times n
The function should then stop or in the while loop "break"
Then the function has to print the results
So this is what I have so far:
def print_multiplication_table(n): # n for a number
if n >=0:
while somehting:
# The code rest of the code that I need help on
else:
return "The input is not a positive whole number.Try anohter input!"
Edit: Here's what I have after all the wonderful answers from everyone
"""
i * j = answer
i is counting from 1 to n
for each i, j is counting from 1 to n
"""
def print_multiplication_table(n): # n for a number
if n >=0:
i = 0
j = 0
while i <n:
i = i + 1
while j <i:
j = j + 1
answer = i * j
print i, " * ",j,"=",answer
else:
return "The input is not a positive whole number.Try another input!"
It's still not completely done!
For example:
print_multiplication_table(2)
# The output
>>>1 * 1 = 1
>>>2 * 2 = 4
And NOT
>>> 1 * 1 = 1
>>> 1 * 2 = 2
>>> 2 * 1 = 2
>>> 2 * 2 = 4
What am I doing wrong?
I'm a little mad about the while loop requirement, because for loops are better suited for this in Python. But learning is learning!
Let's think. Why do a While True? That will never terminate without a break statement, which I think is kind of lame. How about another condition?
What about variables? I think you might need two. One for each number you want to multiply. And make sure you add to them in the while loop.
I'm happy to add to this answer if you need more help.
Your logic is pretty good. But here's a summary of mine:
stop the loop when the product of the 2 numbers is n * n.
In the mean time, print each number and their product. If the first number isn't n, increment it. Once that's n, start incrementing the second one. (This could be done with if statements, but nested loops would be better.) If they're both n, the while block will break because the condition will be met.
As per your comment, here's a little piece of hint-y psuedocode:
while something:
while something else:
do something fun
j += 1
i += 1
where should original assignment of i and j go? What is something, something else, and something fun?
This problem is better implemented using nested loops since you have two counters. First figure out the limits (start, end values) for the two counters. Initialize your counters to lower limits at the beginning of the function, and test the upper limits in the while loops.
The first step towards being able to produce a certain output is to recognize the pattern in that output.
1 * 1 = 1
1 * 2 = 2
1 * 3 = 3
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
3 * 1 = 3
3 * 2 = 6
3 * 3 = 9
The number on the right of = should be trivial to determine, since we can calculate it by multiplying the other two numbers on each row; obtaining those is the core of the assignment. Think of the two operands of * as two counters, let's call them i and j. We can see that i is counting from 1 to 3, but for each i, j is counting from 1 to 3 (resulting in a total of 9 rows; more generally there will be n2 rows). Therefore, you might try using nested loops, one to loop i (from 1 to n) and another to loop j (from 1 to n) for each i. On each iteration of the nested loop, you can print the string containing i, j and i*j in the desired format.
I have started looking at the project Euler site as a way to learn Haskell, and improve my Python and Ruby. I think the Haskell and Python versions are ok, but I'm sure there must be a cleaner way for Ruby.
This is not about how can I make one language look like another one.
This is Problem 1:
Q: Add all the natural numbers below one thousand that are multiples of 3 or 5.
Haskell:
sum [ x | x <- [1..999], mod x 3 == 0 || mod x 5 == 0 ]
Python:
sum ( [ x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 ] )
Ruby:
(1..999) . map {|x| x if x % 3 == 0 || x % 5 == 0 } . compact . inject(:+)
They all give the same answer.
OK, so Python can become:
sum ( x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 )
it is now a generator (a good thing as we are not storing the list)
but even more fun is:
sum( set(range(0,1000,3)) | set(range(0,1000,5)) )
For some reason I was looking at this again and tried a summation approach which should be constant time. In Python 3:
def step_sum(mn,mx,step):
amax = mx - (mx - mn) % step
return (mn + amax) * ((1 + ((amax - mn) / step)) / 2)
step_sum(3,999,3) + step_sum(5,999,5) - step_sum(15,999,15)
Ruby can become:
(1..999) . select {|x| x % 3 == 0 || x % 5 == 0} . inject(:+)
or
(1..999) . select {|x| x % 3 == 0 or x % 5 == 0} . reduce(:+)
I am presuming as unlike map, select doesn't produce 'nul' and therefore there is no need to call compact. nice.
Haskell can also be:
let ƒ n = sum [0,n..999] in ƒ 3 + ƒ 5 - ƒ 15
or to be clearer:
let ƒ n = sum [ 0 , n .. 999 ] in ƒ 3 + ƒ 5 - ƒ (lcm 3 5)
as a function that lets us provide the two numbers ourselves:
ƒ :: (Integral a) => a -> a -> a
ƒ x y = let ƒ n = sum [0,n..999] in ƒ x + ƒ y - ƒ (lcm x y)
For Haskell I like
let s n = sum [0,n..999] in s 3 + s 5 - s 15
or
sum $ filter ((>1).(gcd 15)) [0..999]
For fun the Rube-Goldberg version:
import Data.Bits
sum $ zipWith (*) [1..999] $ zipWith (.|.) (cycle [0,0,1]) (cycle [0,0,0,0,1])
Okay, explanation time.
The first version defines a little function s that sums up all multiples of n up to 999. If we sum all multiples of 3 and all multiples of 5, we included all multiples of 15 twice (once in every list), hence we need to subtract them one time.
The second version uses the fact that 3 and 5 are primes. If a number contains one or both of the factors 3 and 5, the gcd of this number and 15 will be 3, 5 or 15, so in every case the gcd will be bigger than one. For other numbers without a common factor with 15 the gcd becomes 1. This is a nice trick to test both conditions in one step. But be careful, it won't work for arbitrary numbers, e.g. when we had 4 and 9, the test gdc x 36 > 1 won't work, as gcd 6 36 == 6, but neither mod 6 4 == 0 nor mod 6 9 == 0.
The third version is quite funny. cycle repeats a list over and over. cycle [0,0,1] codes the "divisibility pattern" for 3, and cycle [0,0,0,0,1] does the same for 5. Then we "or" both lists together using zipWith, which gives us [0,0,1,0,1,1,0,0,1,1,0,1...]. Now we use zipWith again to multiply this with the actual numbers, resulting in [0,0,3,0,5,6,0,0,9,10,0,12...]. Then we just add it up.
Knowing different ways to do the same thing might be wasteful for other languages, but for Haskell it is essential. You need to spot patterns, pick up tricks and idioms, and play around a lot in order to gain the mental flexibility to use this language effectively. Challenges like the project Euler problems are a good opportunity to do so.
Try this for Ruby:
(1..999).select {|x| x % 3 == 0 or x % 5 == 0}.reduce(:+)
Or a little different approach:
(1..999).reduce(0) {|m, x| (x % 3 == 0 or x % 5 == 0) ? m+x : m }
Not a list comprehension, I know, but to solve that I would use:
3*((999/3)**2+999/3)/2+5*((999/5)**2+999/5)/2-15*((999/15)**2+999/15)/2
Faster then any list comprehension one might come up with, and works in any language ;)
Only posting to show another way of looking at the same problem using http://en.wikipedia.org/wiki/Summation.
I think the following is a better Ruby one:
(1..999).select{|x| x % 3 == 0 || x % 5 == 0}.reduce(:+)
Try something like this:
(1...1000).inject(0) do |sum, i|
if (i % 3 == 0) or (i % 5 == 0)
sum + i
else
sum
end