Find The Parity Outlier Python - python

def find_outlier(lstOfints):
for integer in lstOfints:
#print(integer)
if integer % 2 ==1:
integer
elif integer % 2 == 0:
integer
return integer
I keep getting the incorrect answer and I don't know what's going on.
This is the problem:
You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N.

This seems to work for me:
def find_outlier(lstOfints):
if lstOfints[0] % 2 == 1 and lstOfints[1] % 2 == 1:
for integer in lstOfints[2::]:
if integer % 2 == 0:
return integer
elif lstOfints[0] % 2 == 0 and lstOfints[1] % 2 == 0:
for integer in lstOfints[2::]:
if integer % 2 == 1:
return integer
else:
if lstOfints[0] % 2 == lstOfints[2] % 2:
return lstOfints[1]
else:
return lstOfints[0]
Firstly, I am seeing if this list is either all odds, or all evens, bar the outlier. Then if it is even, it goes through the list looking for an odd number, the same for if the list is all odd. However, if the outlier is in the first two numbers, then it checks to see whether the outlier is the first number or the second number by comparing the modulos to the modulo of the third number in the list.

A pythonic answer might be something like that:
def find_outlier(lst):
mods = [n % 2 for n in lst]
return lst[mods.index(0)] if sum(mods[:3]) > 1 else lst[mods.index(1)]
print(find_outlier([5, 31, 57, 45, 9, 17, 8, 37, 123, 67])) # --> 8
print(find_outlier([4, 30, 56, 44, 8, 16, 7, 36, 122, 66])) # --> 7
Explanation: first create the list of all n % 2 for all n in the provided list. Then you simply have to check the sum of the first 3 elements of this new list to know whether the outlier is odd or even. Then find index of the outlier remainder (either 0 or 1) and return the corresponding integer from the first list...

There are many things to change in your code, so I will try to change it at steps to get it working at the end.
Run the function from the question
Well, I tested your code here and I see why it is confusing. I have this script:
def find_outlier(lstOfints):
for integer in lstOfints:
#print(integer)
if integer % 2 ==1:
integer
elif integer % 2 == 0:
integer
return integer
print(find_outlier([1,3,4,5]))
print(find_outlier([1,2,3,4]))
...and if I run it, we get this:
$ python disparity.py
5
4
It is just printing the last number! Why so?
Why is it always printing the last number from the list?
Well, because you just return at the end of the function. You expect the function to return from inside the if statement, but you did not used the return command. It is easy to solve:
def find_outlier(lstOfints):
for integer in lstOfints:
if integer % 2 ==1:
return integer
elif integer % 2 == 0:
return integer
return integer
print(find_outlier([1,3,4,5]))
print(find_outlier([0,2,3,4]))
So now we run it and get
$ python disparity.py
1
0
Now it is just returning the first element!
Why is it now always printing the first number from the list?
It prints the first element because your if statements are complementary. Given any element, regardless of its parity, it modulo 2 will be either 0 or 1. If it is zero, the first if returns; if it is 1, the second returns! Since it is true to all elements, it is true to the first one, so the function ends at the very first iteration.
This is not the algorithm you want. What you want is to first know which parity is the outlier, and then look for the outlier number.
How to discover which parity is an outlier if I don't know which number is the outlier?
Since the list has at least three elements, that is easy: we consider two scenarios.
The first scenario is, the outlier is one of the first three elements. In this case, we will have one outlier parity and two "normal" parities.
The second scenario is, the outlier is not one of the first three elements. In this case, we will have three equal parities, and the outlier will be the opposite one.
So, if we count the number of even numbers and odd numbers in the first three values, we know that the parity with less numbers is the outlier one.
If there are more even numbers than odd numbers (either two even and one odd, or three even and no odd), then we know the outlier is odd.
If there are more odd numbers than even numbers, we know the outlier is even.
Now, how to do it in code?
To do that, I will write pieces of code below that, at then end, put together, will give us the answer. First I create two variables to count the even and odd numbers (with 0 at first).
even_numbers = 0
odd_numbers = 0
Then, I see if the first element is even. If so, I increment the counter of even numbers:
if listOfints[0] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
Then I do the same thing with the second and third elements:
if listOfints[1] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if listOfints[2] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
If we have more even numbers than odd numbers, we know the outlier parity is odd (that is, the rest of the division of the outlier to 2 is 1); if we have more odd numbers than even numbers, the outlier parity will be even (that is, the rest will be zero)
if even_numbers > odd_numbers:
outlier_parity = 1
else:
outlier_parity = 0
So, now I know if the outlier number is even or odd, I agree. But I want to know what is the number!
Now that we do know the parity of the outlier, we just need to look for it:
for integer in lstOfints:
if integer % 2 == outlier_parity:
return integer
Bundling all together, this is our new function:
def find_outlier(lstOfints):
even_numbers = 0
odd_numbers = 0
if lstOfints[0] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if lstOfints[1] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if lstOfints[2] % 2 == 0:
even_numbers = even_numbers + 1
else:
odd_numbers = odd_numbers + 1
if even_numbers > odd_numbers:
outlier_parity = 1
else:
outlier_parity = 0
for integer in lstOfints:
if integer % 2 == outlier_parity:
return integer
print(find_outlier([1,3,4,5]))
print(find_outlier([0,2,3,4]))
Does it work? Let's test:
$ python disparity.py
4
3
Oh, it worked! Not bad, right? :)
Some considerations
This code here isn't the most elegant, but my purpose here is mostly that you understand what is going on. It could be done with a waaaaaay shorter, more readable function, but since you are still looking for basic concepts, I did a more detailed, explainable function, which is kind of cumbersome as a consequence.

my solution is:
def find_outlier(integers):
odd = []
even = []
for i in integers:
if i% 2 != 0:
odd.append(i)
elif i% 2 == 0:
even.append(i)
if len(odd) < len(even):
return odd[0]
else:
return even[0]

Related

Create 3 digit numbers that are even and count them

I need to make a program in Python that do this:
Write a program that, for a given sequence of digits, prints the number of different three-digit even numbers that can be formed from the given digits. When forming each three-digit even number, each element of the sequence of digits can be used at most once.
The first line of the standard input contains the number of digits N, such that 3≤N≤50000. In the second row is N digits separated by one space.
Print only one number to the standard output, the requested number of three-digit numbers.
n=int(input())
num=[]
for i in range (n):
num.append ()
Input
4
2 4 2 2
Output
4
Explanation
From the digits 2, 4, 2, 2, 4 different three-digit even numbers can be formed, namely 222, 224, 242, 422.
This is a general solution that checks all permutations of these digits and print even numbers out of them:
from itertools import permutations
k = 3
c = 0
n = int(input())
num = input().strip().split(" ")
perms = set(permutations(num, k))
for perm in perms:
t = int("".join(perm))
if t % 2 == 0 and len(str(t)) == k:
print(t)
c += 1
print(c)
This is another solution if you don't want to use this generalized approach and just want to solve it for 3 digits:
c = 0
n = int(input())
num = [int(x) for x in input().strip().split(" ")]
r = set()
for i in range(n):
for j in range(n):
for k in range(n):
if i == j or i == k or j == k:
continue
t = num[i] * 100 + num[j] * 10 + num[k]
if t % 2 == 0 and len(str(t)) == 3:
r.add(t)
print(r)
print(len(r))
First You should declare which user input u expect and how to handle false input.
Then the inputString is split into a list of Strings aka inputList. Now You can loop through each of those inputItem and check if they fit your expectations (is int and smaller then 10 ). Since You still deal with String Items You can try to cast ( convert them) into Int. That can fail and a unhandled failure could cripple Your script so it has to happen in an try- catch-block. If the casting works You wanna make sure to check your matchList if You allready added a simular number before You add the new Number to Your matchList.You do so again by looping through each item. If there is mo such number yet there is a last check for if the number is uneven or 0. In that case there is one possible combination less for each number that is 0 or uneven so they are counted in the variable minusOneCombi. That will be substrated from the maximum amount of combinations which is the amount of numbers in you matchList multiplied with itself (pow(2)). Be very careful with the Indentations. In Python they are determining the ends of if blocks and loops.
InputString=(input("Enter your number stream eg 1 0 0 5 ( non numeric signs and numbers greater 9 will be ignored): "))
inputList= inputString.split(‘ ’)
matchList=[]
minusOneCombi= 0
for inputItem in inputList:
try:
anInt= int(inputItem)
except ValueError:
# Handle the exception
print(“item is not an integer and therefore ignored”)
NotYetinMatchList= True
for MatchItem in MatchList:
If matchItem == inputItem:
notYetinMatchList= False
Break
If notYetinMatchList:
matchList.append(anInt)
if ((anInt % 2) != 0) OR (anInt ==0):
minusOneCombi++
NumofMatches=matchList.count()
NumOfMatchesPow= pow(NumofMatches,2)
Result=NumOfMatchesPow -minusOneCombi
Print(Result)

How to find even sum

I need to find the sum of all even numbers below the inserted number. For example if I insert 8 then the sum would be 2+4+6+8=20. If I insert 9 then it also needs to be 20. And it needs to be based on recursion.
This is what I have so far:
def even(a):
if a == 0:
else:
even(a - 1)
even(8)
I cannot figure out what to change under the "if" part for it to give the right outcome
If the function is called with an odd number, n, then you can immediately call again with the number below (an even).
Then if the function is called with an even number return that even number plus the result of summing all the even numbers below this number by calling again with n - 2.
Finally, your base case occurs when n = 0. In this case just return 0.
So we have
def even_sum(n):
if n % 2 == 1: # n is odd
return even_sum(n - 1)
if n == 0:
return 0
return n + even_sum(n - 2)
which works as expected
>>> even_sum(8)
20
>>> even_sum(9)
20
>>> even_sum(0)
0
To design a recursive algorithm, the first thing to wonder is "In what cases can my algorithm return an answer trivially?". In your case, the answer is "If it is called with 0, the algorithm answers 0". Hence, you can write:
def even(n):
if n == 0:
return 0
Now the next question is "Given a particular input, how can I reduce the size of this input, so that it will eventually reach the trivial condition?"
If you have an even number, you want to have this even number + the sum of even numbers below it, which is the result of even(n-2). If you have an odd number, you want to return the sum of even numbers below it. Hence the final version of your function is:
def even(n):
if n == 0 or n == 1:
return 0
if n % 2 == 0:
return n + even(n - 2)
return even(n - 1)
Both with o(n) time complexity
With For loop
num = int(input("Enter a number: ")) # given number to find sum
my_sum = 0
for n in range(num + 1):
if n % 2 == 0:
my_sum += n
print(my_sum)
With recursion
def my_sum(num):
if num == 0:
return 0
if num % 2 == 1:
return my_sum(num - 1)
return num + my_sum(num - 2)
always avoid O(n^2) and greater time complexity
For a recursive solution:
def evenSum(N): return 0 if N < 2 else N - N%2 + evenSum(N-2)
If you were always given an even number as input, you could simply recurse using N + f(N-2).
For example: 8 + ( 6 + (4 + ( 2 + 0 ) ) )
But the odd numbers will require that you strip the odd bit in the calculation (e.g. subtracting 1 at each recursion)
For example: 9-1 + ( 7-1 + ( 5-1 + ( 3-1 + 0 ) ) )
You can achieve this stripping of odd bits by subtracting the modulo 2 of the input value. This subtracts zero for even numbers and one for odd numbers.
adjusting your code
Your approach is recursing by 1, so it will go through both the even and odd numbers down to zero (at which point it must stop recursing and simply return zero).
Here's how you can adjust it:
Return a value of zero when you are given zero as input
Make sure to return the computed value that comes from the next level of recursion (you are missing return in front of your call to even(a-1)
Add the parameter value when it is even but don't add it when it is odd
...
def even(a):
if a == 0 : return 0 # base case, no further recusion
if a%2 == 1 : return even(a-1) # odd number: skip to even number
return a + even(a-1) # even number: add with recursion
# a+even(a-2) would be better
A trick to create a recursive function
An easy way to come up with the structure of a recursive function is to be very optimistic and imagine that you already have one that works. Then determine how you would use the result of that imaginary function to produce the next result. That will be the recursive part of the function.
Finally, find a case where you would know the answer without using the function. That will be your exit condition.
In this case (sum of even numbers), imagine you already have a function magic(x) that gives you the answer for x. How would you use it to find a solution for n given the result of magic(n-1) ?
If n is even, add it to magic(n-1). If n is odd, use magic(n-1) directly.
Now, to find a smaller n where we know the answer without using magic(). Well if n is less than 2 (or zero) we know that magic(n) will return zero so we can give that result without calling it.
So our recursion is "n+magic(n-1) if n is even, else magic(n-1)"
and our stop condition is "zero if n < 2"
Now substitute magic with the name of your function and the magic is done.
For an O(1) solution:
Given that the sum of numbers from 1 to N can be calculated with N*(N+1)//2, you can get half of the sum of even numbers if you use N//2 in the formula. Then multiply the result by 2 to obtain the sum of even numbers.
so (N//2)*(N//2+1) will give the answer directly in O(1) time:
N = 8
print((N//2)*(N//2+1))
# 20
# other examples:
for N in range(10):
print(N,N//2*(N//2+1))
# 0 0
# 1 0
# 2 2
# 3 2
# 4 6
# 5 6
# 6 12
# 7 12
# 8 20
# 9 20
Visually, you can see the progression like this:
1..n : 1 2 3 4 5 6 7 8
∑n : 1 3 6 10 15 21 28 36 n(n+1)/2
n/2 : 0 1 1 2 2 3 3 4
1..n/2 : 1 2 3 4
∑n/2 : 1 3 5 10 half of the result
2∑n/2 : 2 6 10 20 sum of even numbers
So we simply replace N with N//2 in the formula and multiply the result by 2:
N*(N+1)//2 --> replace N with N//2 --> N//2*(N//2+1)//2
N//2*(N//2+1)//2 --> multiply by 2 --> N//2*(N//2+1)
Another way to see it is using Gauss's visualisation of the sum of numbers but using even numbers:
ascending 2 4 6 8 ... N-6 N-4 N-2 N (where N is even)
descending N N-2 N-4 N-6 ... 8 6 4 2
--- --- --- --- --- --- --- ---
totals N+2 N+2 N+2 N+2 ... N+2 N+2 N+2 N+2 (N/2 times N+2)
Because we added the even numbers twice, once in ascending order and once in descending order, the sum of all the totals will be twice the sum of even numbers (we need to divide that sum by 2 to get what we are looking for).
sum of evens: N/2*(N+2)/2 --> N/2*(N/2+1)
The N/2(N/2+1) formulation allows us to supply the formula with an odd number and get the right result by using integer division which absorbs the 'odd bit': N//2(N//2+1)
Recursive O(1) solution
Instead of using the integer division to absorb the odd bit, you could use recursion with the polynomial form of N/2*(N+2)/2: N^2/4 + N/2
def sumEven(n):
if n%2 == 0 : return n**2/4 + n/2 # exit condition
return sumEven(n-1) # recursion
Technically this is recursive although in practice it will never go deeper than 1 level
Try out this.
>>> n = 5
>>> sum(range(0, n+1, 2))
with minimum complexity
# include <stdio.h>
void main()
{
int num, sum, i;
printf("Number: ");
scanf("%d", &num);
i = num;
if (num % 2 != 0)
num = num -1;
sum = (num * (num + 2)) / 4;
printf("The sum of even numbers upto %d is %d\n\n", i, sum);
}
It is a C program and could be used in any language with respective syntax.
And it needs to be based on recursion.
Though you want a recursion one, I still want to share this dp solution with detailed steps to solve this problem.
Dynamic Programming
dp[i] represents the even sum among [0, i] which I denote as nums.
Case1: When i is 0, there is one number 0 in nums. dp[0] is 0.
Case2: When i is 1, there are two numbers 0 and 1 in nums. dp[1] is still 0.
Case3: When i is 2, there are three numbers 0, 1 and 2 in nums. dp[2] is 2.
Case4: When i is greater than 2, there are two more cases
If i is odd, dp[i] = dp[i-1]. Since i is odd, it is the same with [0, i-1].
If i is even, dp[i] = dp[i-2] + i by adding the current even number to the even sum among [0, i-2] (i-1 is odd, so won't be added).
PS. dp[i] = dp[i-1] + i is also ok. The difference is how you initialize dp.
Since we want the even sum among [0, n], we return dp[n]. You can conclude this from the first three cases.
def even_sum(n):
dp = []
# Init
dp.append(0) # dp[0] = 0
dp.append(0) # dp[1] = 0
# DP
for i in range(2, n+1): # n+1 because range(i, j) results [i, j) and you take n into account
if i % 2 == 1: # n is odd
dp.append(dp[i-1]) # dp[i] = dp[i-1]
else: # n is even
dp.append(dp[i-2] + i) # dp[i] = dp[i-2] + i
return dp[-1]

Checking integers in python

I need to write a code that asks the user for a range of integers and then calculates which integers in that range have at least 3 factors (excluding 1 and the integer itself). I don't know how to take into consideration the fact that an integer can have multiple same factors, for example, in my code integer 8 returns a false value because the program divides it into two integers, 2 and 4. I want the return value to be true, because 8 can be divided into three factors of 2. How do i fix it?
def does_integer_have_3_or_more_factors(x):
num_of_factors = 0
for i in range(2, x):
if x % i == 0:
num_of_factors += 1
if num_of_factors >= 3 :
return True
else :
return False
def main():
integer1 = int(input("Give first positive integer.\n"))
integer2 = int(input("Give last integer.\n"))
print("These integers have at least 3 factors.")
for x in range(integer1, integer2 + 1):
if does_integer_have_3_or_more_factors(x) == True:
print(x)
main()
You need to use the factors you found, and apply them as often as necessary. Maybe you also want to keep track of the factors you found.
factors = []
...
for ... # see below
while x > 1 and not x%i:
factors.append(i)
x /= i
You can also stop checking for factors after sqrt(x) has been reached.
from math import sqrt
for i in range(2,int(sqrt(x))+1):
Finally, you're handling booleans in an overly complicated way. Just do
return len(factors) > 2 # "len(factors) > 2" will result in True or False directly
and check for
if does_integer_have_3_or_more_factors(x):
print(x)

Luhn checksum method; separating two digits and finding the sum of that list

I am currently trying to use the luhn method to determine whether a credit card is valid or not in python and here is what I have so far:
print('What is your Credit Card number? :) (please put a space between each number)')
a = [int(x) for x in input().split()]
lengthy = len(a)
print(lengthy)
a.reverse()
print(a)
listx2 = []
listx1 = []
for x in range(len(a)):
modulus = x % 2
print(x, a[x])
if modulus != 0:
listx2.append(a[x]*2)
else:
listx1.append(a[x])
print(listx2)
print(listx1)
I don't know how to do the next step which is getting the sum of all of the digits of the numbers multiplied by two.(listx2) I have looked at different programs with the luhn method but I just can't seem to pick that part out. Thanks!
This is my interpretation of the Luhn algo.
def luhn(sequence):
digits = [int(digit) for digit in str(sequence)] # converts a full string of nums to a list comp of individual numbers
odd = digits[-1::-2] # string stepping (-1) indicates last item in list (-2) means to travel back another 2
even = digits[-2::-2]
checksum = 0
checksum += sum(odd)
evenmod = []
for digit in even:
if digit * 2 > 9:
digit = digit * 2
digit = int(str(digit)[0]) + int(str(digit)[1])
else:digit = digit * 2
evenmod.append(digit)
checksum += sum(evenmod)
if checksum % 10 == 0:
return True
else:
return False
print luhn(378282246310005)
print luhn(111111111111111)
print luhn(4751290083628479)
print luhn(5573485043994670)
Separate the even and the odd indeces to separate lists, then use a for statement to loop through the list, multiplying the list entries by two.
Notice the if statement that catches the issue with (e.g) 8 * 2 = 16.
Use sum:
summed_x2 = sum(listx2)

given and integer, return the next integer that is a prime number and a palindrome . Python

Given any random integer, create a function to find the next number that is a prime number and also a palindrome.
My attempt
def golf(number):
x = number + 1
for i in range(2, x):
if x % i == 0 or str(x) != str(x)[::-1]:
golf(number + 1)
return x
E.g golf(13) = 101
I'm actually looking for an alternative option than the recursion method i used. How can this best be accomplished without using recursion?
Thanks
Here's a variation on byron he's answer which adds several optimizations:
We can eliminate all even x values (other than 2) before doing any elaborate tests, since we can trivially tell they are not prime.
A small improvement is to only call str(x) once, and reuse the value later.
We can take advantage of the fact that all even-length palindromes are multiples of 11, which means that (except for 11 itself) they're not prime. We can jump ahead to the next odd-length x value.
Since we've already eliminated even numbers, our prime test only needs to test odd divisors. Further we can stop our loop when we reach sqrt(x), rather than going all the way to x itself.
Finally, there's no need to use a Boolean flag variable to carry the primeness out of the loop. If we don't break, the else block attached to the loop will be run.
The code:
import math
def next_prime_palindrome(x):
while True:
x += 1
if x > 2 and x % 2 == 0: # even numbers greater than 2 are non-prime
continue
s = str(x) # compute str(x) just once
if x > 11 and len(s) % 2 == 0: # all even-length palindromes are multiples of 11
x = 10 ** len(s) # so jump to the next odd-length integer
continue
if s != s[::-1]: # palindrome test
continue
for i in xrange(3, round(math.sqrt(x))+1, 2): # loop over odd potential divisors
if x % i == 0: # prime test
break
else: # this else block runs only if no break happened in the loop, so x is prime
return x
Here are some tests runs, showing a few cases where the optimizations save significant time:
>>> next_prime_palindrome(1)
2
>>> next_prime_palindrome(3)
5
>>> next_prime_palindrome(9)
11
>>> next_prime_palindrome(11)
101
>>> next_prime_palindrome(99999)
1003001
>>> next_prime_palindrome(999999999)
10000500001
A further improvement might be to directly generate palindromes, rather than working with integers to start with, and doing a palindrome test to filter them. That would get quite a bit further from your original design, so I'll leave that for someone else.
Palindrome are a sparser set of numbers than primes, and you can generate palindromes directly.
Consider the sequence 98.102
These are palidrome numbers you can base on these
989, 9889, 999, 9999, 10001, 100001, 10101, 101101, 10201, 102201
ADDED
Not also that all of the palidromes with an odd number of digits will come before the palidromes with an even number of digits.
If you write this as a generator (ie using yield) get get a straightforward algorithm for generating palindromic numbers in order.
For 1..9 you generate either 9 or 18 palindromes depending upon whether you consider 1 digit numbers palindromic.
For 10..99 you generate 90 even digit and 90 odd digit palindromes.
For 100..999 you generate 900 even digit and 900 odd digit palindromes.
You have just generated all 1989 (or 1997 if including single digit numbers) of the palindromic numbers less than 1 million. There are 78,498 primes less than 1 million
Any algorithm that is based on generating primes then testing for a palindrome will be much slower that generating palindromes and then testing for primes
def golf(number):
primes = []
i = 2
while i <= number:
if isPrime(i, primes):
primes.append(i)
i += 1
answer = primes[-1] + 1
while True:
if isPrime(answer, primes):
primes.append(answer)
if str(answer) == str(answer)[::-1]:
return answer
answer += 1
def isPrime(n, primes):
for (p for p in primes if p<=n**0.5):
if n%p == 0:
return False
return True
Your solution can be slightly modified in order to create an iterative solution:
def golf(number):
x = number + 1
while True:
is_golf = True
for i in range(2, x):
if x % i == 0 or str(x) != str(x)[::-1]:
is_golf = False
break
if is_golf:
return x
x += 1
improved according to Blckknght's advice, thanks.
def golf(number):
x = number
while True:
x += 1
if str(x) != str(x)[::-1]:
continue
for i in xrange(2, x):
if x % i == 0 :
break
else:
return x

Categories

Resources