summing the first and last elements of list - python

I'd like to sum the first element and last elements of a list, and then exclude those two numbers and repeat that process again until there is only one element in the list. Like this:
[5,4,3,2,1,6]
[11,5,5]
[16,5]
[21]
I used some methods but didn't work.
I am just a computer science student starting to python so help me out please guys.
Thank you.

Main logic of this answer is revolve around len of last list print. Lets break it in few points :
LOGIC :
1. Basically we need sum of first-ith and last-ith value for that we used this code:
l_u[-1][i] + l_u[-1][-i - 1]
2. Above point is only valid when lenght of last append list is even for odd-length we have to append this only at even poistion :
l_u[-1][i]
3. Among above two statement which is going to true this is done by this condition:
len(l_u[-1])%2 != 0 and i%2 != 0
CODE :
l = [5, 4, 3, 2, 1, 6]
l_u = [l]
condn = True
j = 0
while condn:
l_u.append([
l_u[-1][i] if len(l_u[-1]) % 2 != 0 and i % 2 != 0 else l_u[-1][i] +
l_u[-1][-i - 1] for i in range(
len(l_u[-1]) // 2 if len(l_u[-1]) % 2 == 0 else len(l_u[-1]) // 2 +
1)
])
if len(l_u[-1]) <= 1:
break
print(l_u)
OUTPUT :
[[5, 4, 3, 2, 1, 6], [11, 5, 5], [16, 5], [21]]

Related

Creating code to make sum of array elements with variable

I want to create a code that has the variable how many elements you take from an list and sum those. For example, if I type in 3, it takes the first 3 elements of an array and addes them together.
Preferably in some for loop but who knows what kind of creative solutions I get :)
x = [1, 3, 4, 2, 6, 9, 4]
Amount = 3
Sum = 0
Sum += x[Amount-3] + x[Amount-2] + x[Amount-1]
Desired result: 8
Amount_2 = 4
Sum = 0
Sum += x[Amount-4] + x[Amount-3] + x[Amount-2] + x[Amount-1]
Desired result: 11
Hope this explains it well.
x = [2, 6, 7, 7, 12] # your list here
amount = int(input("Enter amount: "))
print(f'desired result: {sum(x[:amount])}')

Is there a better solution in Python for this problem? Thanks

Given an array of scores sorted in increasing order, return true if the array contains 3 adjacent scores that differ from each other by at most 2, such as with {3, 4, 5} or {3, 5, 5}.
Examples
scoresClump([3, 4, 5]) → true
scoresClump([3, 4, 6]) → false
scoresClump([1, 3, 5, 5]) → true
A solution below here seems to work but Translating it into Python looks tricky.
function scoresClump(scores) {
for (let i = 0; i < scores.length - 1; i++) {
if (scores[i + 2] - scores[i] <= 2) {
return true;
}
}
return false;
}
I have tried this in Python and it keeps going out of range or giving the wrong output.
arr=[1,3, 5, 5]
i=0
while i<(len(arr)-1):
if (arr[i+2]-arr[i])<=2 and (arr[i+1]-arr[i])<=2:
print("True")
i=i+1
else:
print("False")
break
You're iterating until i < len(arr)-1, but you're reaching for arr[i+2], which is out of range.
In Python you usually do not need to use an index variable. As you've seen they're a source of errors, and Python offers cleaner syntax without using them. For instance:
# unpythonic
for i in range(len(scores)):
print(scores[i])
# pythonic
for score in scores:
print(score)
zip combines two (or more) things you can iterate over.
scores[2:] means "the scores list, but discarding the first two values".
scores = [1, 2, 3, 4, 5, 6]
for a, b in zip(scores, scores[2:]):
print(a, b)
# 1 3
# 2 4
# 3 6
# zip then ends because it reached the end of scores[2:]
So, you can use zip and list slicing to compare the list with itself without index variables:
def scores_clump(scores):
for a, b in zip(scores, scores[2:]):
if b - a <= 2:
return True
return False
scores_clump([1, 3, 4, 5])
# 4 - 1 is not <= 2
# 5 - 3 is <= 2, return True
scores_clump([1, 3, 6, 7, 9])
# 6 - 1 is not <= 2
# 7 - 3 is not <= 2
# 9 - 6 is not <= 2
# reached end of loop with no match, return False
scores_clump([3, 3, 7, 7, 9])
# 7 - 3 is not <= 2
# 7 - 3 is not <= 2
# 9 - 7 is <= 2, return True
Taking a leaf from Max's answer, you can reduce it further using any:
def scores_clump(scores):
return any(b - a <= 2 for a, b in zip(scores, scores[2:]))
You can use this following function -
def scoresClump(nums):
for x in range(2, len(nums)):
if nums[x] - nums[x-2] <= 2:
return True
return False
if you want a one-liner using any() -
def scoresClump(nums):
return any(nums[x] - nums[x-2] <= 2 for x in range(2, len(nums)))
>>> scoresClump([3, 4, 5])
True
>>> scoresClump([3, 4, 6])
False
>>> scoresClump([3, 4, 5, 5])
True
>>> scoresClump([3, 4])
False
>>> scoresClump([3])
False
>>> scoresClump([3, 3, 7, 7, 9])
True
Your if statement will reach arr[:-1] and then try and check two elements ahead of that, which don't exist, therefore going out of range. Rather than a while loop I would try something like this:
for x in range(0, len(arr)-2)
This is basically a "sliding window" problem where window size=3 and we keep iterating over the array until we find a window where difference between adjacent elements is less than or equal to 2.
Here we can simply check if difference between last and first element of the window is <=2 or not because we are given a sorted array.
def scoresClump(array):
for i in range(2,len(array)):
if array[i]-array[i-2]<=2:
return True
return False
print(scoresClump([1, 3, 5, 5]))

One excess element in the array is always left

I'm working on a validator of credit cards. That sphere is new for me, so please, don't laugh:D
I'm trying to finish it without any libraries.
def creditCardValidation(creditcard):
creditcard = creditcard.replace( ' ', '' )
creditcard = [int(i) for i in creditcard]
evens = creditcard[::2]
odds = creditcard[1::2]
evens = [element * 2 for element in evens]
for j in evens:
if j >= 10:
j = [int(d) for d in str(j)]
for x in j:
evens.append(x)
for j in evens:
if j >= 10:
evens.remove(j)
return ((sum(evens) + sum(odds)) % 10 == 0)
creditCardValidation('1234 5678 9101 1213')
creditCardValidation('4561 2612 1234 5464')
creditCardValidation('4561 2612 1234 5467')
So the problem is in the array evens.
It returns
[2, 6, 14, 0, 2, 2, 1, 0, 1, 4, 1, 8]
[8, 4, 2, 2, 6, 12, 1, 2, 1, 0, 1, 2]
[8, 4, 2, 2, 6, 12, 1, 2, 1, 0, 1, 2]
It should return the same results except those which greater than 10. Everything works fine. Take a look at the first array, 18 deleted as well as 10, but 14 is not.
Removing while iterating over the array is not the best thing to do and will mostly result in skipping some elements in the array while iterating, so a safer way to do this
for j in evens:
if j >= 10:
evens.remove(j)
is to collect all the elements you want to remove in another list then subtract it from your original if you are using numpy arrrays or removing them one by one, as python lists has no subtraction operation defined to subtract one array from a another
to_remove = []
for j in evens:
if j >= 10:
to_remove.append(j)
for j in to_remove:
events.remove(j)
or you could whitelist instead of blacklisting
small_evens = []
for j in evens:
if j < 10:
small_evens.append(j)
# use small_evens and discard evens array
A couple of issues:
Python has zero indexed arrays, so evens[::2] is actually returning the first, third, etc. digit. Luhn's algo requires even digits (assuming 1 indexing) to be doubled.
You shouldn't modify a list you are iterating over.
You can simplify, removing a lot of the list creations:
def creditCardValidation(creditcard):
*creditcard, checkdigit = creditcard.replace(' ', '')
total = 0
for i, digit in enumerate(map(int, creditcard), 1):
if i % 2 == 0:
digit *= 2
total += digit // 10 # Will be zero for single digits
total += digit % 10
return 9*total % 10 == int(checkdigit)
In []:
creditCardValidation('1234 5678 9101 1213')
Out[]:
True
In []:
creditCardValidation('4561 2612 1234 5464')
Out[]:
False

Transforming an array of integers and computing the sum

Suppose we need to transform an array of integers and then compute the sum.
The transformation is the following:
For each integer in the array, subtract the first subsequent integer that is equal or less than its value.
For example, the array:
[6, 1, 3, 4, 6, 2]
becomes
[5, 1, 1, 2, 4, 2]
because
6 > 1 so 6 - 1 = 5
nothing <= to 1 so 1 remains 1
3 > 2 so 3 - 2 = 1
4 > 2 so 4 - 2 = 2
6 > 2 so 6 - 2 = 4
nothing <= to 2 so 2 remains 2
so we sum [5, 1, 1, 2, 4, 2] = 15
I already have the answer below but apparently there is a more optimal method. My answer runs in quadratic time complexity (nested for loop) and I can't figure out how to optimize it.
prices = [6, 1, 3, 4, 6, 2]
results = []
counter = 0
num_prices = len(prices)
for each_item in prices:
flag = True
counter += 1
for each_num in range(counter, num_prices):
if each_item >= prices[each_num] and flag == True:
cost = each_item - prices[each_num]
results.append(cost)
flag = False
if flag == True:
results.append(each_item)
print(sum(results))
Can someone figure out how to answer this question faster than quadratic time complexity? I'm pretty sure this can be done only using 1 for loop but I don't know the data structure to use.
EDIT:
I might be mistaken... I just realized I could have added a break statement after flag = False and that would have saved me from a few unnecessary iterations. I took this question on a quiz and half the test cases said there was a more optimal method. They could have been referring to the break statement so maybe there isn't a faster method than using nested for loop
You can use a stack (implemented using a Python list). The algorithm is linear since each element is compared at most twice (one time with the next element, one time with the next number smaller or equals to it).
def adjusted_total(prices):
stack = []
total_substract = i = 0
n = len(prices)
while i < n:
if not stack or stack[-1] < prices[i]:
stack.append(prices[i])
i += 1
else:
stack.pop()
total_substract += prices[i]
return sum(prices) - total_substract
print(adjusted_total([6, 1, 3, 4, 6, 2]))
Output:
15
a simple way to do it with lists, albeit still quadratic..
p = [6, 1, 3, 4, 6, 2]
out= []
for i,val in zip(range(len(p)),p):
try:
out.append(val - p[[x <= val for x in p[i+1:]].index(True)+(i+1)])
except:
out.append(val)
sum(out) # equals 15
NUMPY APPROACH - honestly don't have alot of programming background so I'm not sure if its linear or not (depending on how the conditional masking works in the background) but still interesting
p = np.array([6, 1, 3, 4, 6, 2])
out = np.array([])
for i,val in zip(range(len(p)),p):
pp = p[i+1:]
try:
new = val - pp[pp<=val][0]
out = np.append(out,new)
except:
out = np.append(out,p[i])
out.sum() #equals 15

Adding to a specific variable in a list

I'm trying to add two lists. If the last variable is greater than 10, it needs to carry over to the previous variable in the list. For example :
1 / 2 / 3 (List 1)
7 / 8 / 9 (List 2)
Should equal
9 / 1 / 2 not 8/10/12
So far, I have
list1 = [1, 2, 3]
list2 = [7, 8, 9]
SumOfLists = [x+y for x,y in zip(list1, list2)]
That adds the lists together, but I'm not sure how to make the number carry over.
You can try this code.
list1 = [1, 2, 3]
list2 = [7, 8, 9]
def add_list(a,b):
carry = 0
res_list = []
for i,j in zip(a[::-1],b[::-1]): # Iterate through the lists in reverse
val = (i+j+carry)%10 # Store the sum in val
carry = (i+j+carry)//10 # Store the carry
res_list.append(val) # Append to the returning list
return res_list[::-1] # Return the list
print add_list(list1,list2)
Wil print
[9, 1, 2]
Algorithm
Loop through each of the values in reverse. Add each corresponding values. If the values are above 10 then find the exceeding value and put it to carry. Finally return the reverse of the list.
list1 = [1, 2, 3]
list2 = [7, 8, 9]
cur = 0 # num to carry over
result = []
for x,y in zip(reversed(list2),reversed(list1)):
if x + y + cur > 10: # if sum greater than 10, remember to add 1 on
t = x+y + cur # the next loop
d = str(t)[1] # get the rightmost digit
result.append(int(d))
cur = 1
else: # nothing to curry over, but still add cur,
# it may be 1
result.append(x+y+cur)
cur = 0
print(list(reversed(result)) )
[9, 1, 2]
just subtract 10 if it's more then 10 and add 1 to it's previous element. Do this proccess for all element in sum list
if SumOfLists[2] >= 10:
SumOfLists[2] -= 10
SumOfLists[1] += 1
And at last check
if SumOfLists[0] >= 10:
for i in range(len(SumOfLists)-1,0,-1):
SumOfLists[i] = SumOfLists[i-1]
SumOfLists[0] = 1

Categories

Resources