Search for the numbers of the last two consecutive negative elements in an array. The length of the array is entered from the keyboard. Float type.
my code is:
import math
import numpy
import random
#i = (random.uniform(-1000, 1000))
o = []
a = []
n = int(input())
n += 1
l = 0
sh = 1
m2 = n
m = n-1
m=int(m)
for i in range(n):
x = (random.uniform(-1000, 1000))
a.append(x)
for i in range(m):
otric = a.pop(m)
otric = int(otric)
a.insert(otric,int(m+1))
if otric < 0:
o.append(otric)
m -= 1
if len(o) > 2: break
print(a)
print(o)
and this doesn't work, idk how to fix it.. please help
Use zip to get all consecutive negative numbers and return the last element of the resulting list:
a = [random.uniform(-1000, 1000) for _ in range(n)]
>>> [(x,y) for x,y in zip(a, a[1:]) if x<0 and y<0][-1]
(-696.9270891497699, -612.4999984966855)
Iterate the list in reverse and when a value is negative also grab the next one and see if it is the pair we're looking for:
lst = [1, -7, -8, 1, 1, -1, 1, -2, -3, 1, -4, 1, -5, 1, 1]
it = reversed(lst)
for a in it:
if a < 0:
b = next(it, 0)
if b < 0:
print(b, a)
break
Related
I need to print all the numbers in the list that do not have same digits ex: 22,33.
x,y=list(map(int,input().split()))
l=[]
m=[]
for i in range(x,y+1):
l.append(i)
for j in range(0,len(l)):
unit = l[j] % 10
while (l[j] != 0):
curr = l[j] %10
l[j]=l[j]//10
if(curr != unit):
m.append(l[j])
print(m)
Sample input: 10,20
Sample output: 10,12,13,14,15,16,17,18,19,20 (11 is removed)
my output: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
According to your sample of input and output, you want to remove the numbers which have the same digits.
So here is the solution:
x, y = list(map(int,input().split()))
ans = []
for i in range(x, y + 1):
list_num = list(str(i))
if list_num.count(str(i % 10)) != len(str(i)):
ans.append(i)
print(*ans)
range() returns an iterator. You dont care about previous or future numbers, so you dont need to store any lists other than your outputs
Focus on isolating your logic. What does it mean for a number to have all the same digit? For instance, if you uniquely count all digits to be 1, then you have the same digit. Make it a function
from collections import defaultdict
def all_same(x):
vals = defaultdict(int)
while x != 0:
x, tens = divmod(x, 10)
vals[tens] += 1
return len(vals) == 1
x, y = list(map(int,input().split()))
print(','.join( str(v) for v in range(x, y + 1) if not all_same(v) ))
x, y = list(map(int, input().split()))
result = []
for i in range(x, y+1):
counts = [0] * 10
n = i
while n > 0:
n, remainder = divmod(n, 10)
counts[remainder] += 1
if max(counts) == 1:
result.append(i)
If you are allowed to convert your number to string you can do
result = [n for n in range(x, y + 1) if len(str(n)) == len(set(str(n)))]
Wrote a simple code for left array rotation, getting the same array without any Rotation done to it as the wrong output.
def leftRotate(arr, d, n):
while (d-1) > 0:
leftRotatebyOne(arr, n)
def leftRotatebyOne(arr, n):
temp = arr[0]
for i in range(n-1):
arr[i] = arr[i + 1]
arr[n - 1] = temp
def PrintArray(arr, size):
for i in range(size):
print("%d" % arr[i], end=" ")
arr = []
l = int(input("Enter the number of elements: "))
for i in range(0, l):
ele = int(input())
arr.append(ele)
d = int(input("Enter the number of rotations: "))
n = len(arr)
leftRotate(arr, d, n)
PrintArray(arr, n)
and here's an example of the output i've got,
Enter the number of elements: 3
1
2
3
Enter the number of rotations: 1
1 2 3
I expected an output of 2 3 1 after one rotation.
I would suggest using array slicing, then adding the slices together, to perform rotation.
def left_rotate(data, num):
return data[num:] + data[:num]
def right_rotate(data, num):
return data[-num:] + data[:-num]
For example
>>> a = [1,2,3,4,5,6,7]
>>> left_rotate(a, 2)
[3, 4, 5, 6, 7, 1, 2]
>>> right_rotate(a, 2)
[6, 7, 1, 2, 3, 4, 5]
Also note that collections.deque has this behavior available already
>>> from collections import deque
>>> d = deque([1,2,3,4,5,6,7])
>>> d.rotate(2)
>>> d
deque([6, 7, 1, 2, 3, 4, 5])
>>> d.rotate(-2)
>>> d
deque([1, 2, 3, 4, 5, 6, 7])
In the function leftRotate,
there is an error in while loop.
Replace
while (d-1) > 0:
leftRotatebyOne(arr, n)
with
while d > 0:
leftRotatebyOne(arr, n)
d -= 1
When d == 1, while (d-1) > 0: will not be executed any time. Also, you never decrement d. The easiest way to solve is by using a for _ in range(d) loop:
def leftRotate(arr, d, n):
for _ in range(d):
leftRotatebyOne(arr, n)
NOTE: Python has way better ways to do rotations than this. This code seems to be C more than Python. Passing the array length makes no sense in Python for example. And the rotation can be done all in one assignation.
def leftRotate(arr, d):
d %= len(arr)
for _ in range(d):
arr[-1], arr[:-1] = arr[0], arr[1:]
Cory Kramer's answer is even more pythonic. But it has a bug and a difference with your question's methods. The bug is that it doesn't work when the number of rotations requested are higher than the length of the list. The difference is that they are returning a new list instead of modifying it. These two issues could be addresed like this:
def left_rotate(data, num):
num %= len(data)
data[:] = data[num:] + data[:num]
def right_rotate(data, num):
num %= len(data)
data[:] = data[-num:] + data[:-num]
Let's say I have a array like l = [1, 3, 4, 5, 6, 8]
where the nth element represents the distance between the nth and n+1th object.
I want to find the distance between any two objects, and I used this code for this:
def dis(l_list, index1, index2, mylist):
m = mylist.index(index1)
n = mylist.index(index2)
i=0
j=0
if n > m:
while n >= m:
i = i + mylist[m]
m = m + 1
elif n < m:
while n <= m:
i = i + mylist[n]
n = n + 1
else:
return(0)
j = mylist[n] % l_mylist
print(abs(i - j))
l_mylist = input()
l_mylist = int(l_mylist)
mylist = []
mylist = list(map(int, input().split()))
i,j = input().split()
i, j=int(i), int(j)
dis(l_mylist, i, j, mylist)
but I am still getting the wrong output. Can anyone please point out where I am wrong?
If you want to sum around a potentially circular list. You can use a collections.deque() to rotate the list, e.g.:
from collections import deque
def dist(l, i1, i2):
d = deque(l)
d.rotate(-i1)
return sum(list(d)[:i2-i1]))
In []:
l = [1,2,3,4,5,6,7,8]
dist(l, 3-1, 6-1) # 3, 4, 5
Out[]:
12
In []:
dist(l, 6-1, 3-1) # 6, 7, 8, 1, 2
Out[]:
24
def distance(first_index, second_index, my_list):
temp_list = my_list + my_list
if (first_index > second_index):
first_index += len(my_list)
requested_sum = sum(my_list[second_index-1:first_index-1])
else:
requested_sum = sum(my_list[first_index-1:second_index-1])
return requested_sum
If I understood you correctly, then this should do the trick.
There are much more compact and efficient ways to do this, but this is the simplest and easiest to understand in my opinion.
Now the contest is over, so I want to ask my algorithmic fails on my code.
This is the problem. If anyone interested, you can see it at here
def solve():
S = int(input())
D, A, B, M, N = [], [], [], [], []
for i in range(S):
d, a, b = [int(c) for c in input().split(" ")]
D.append(d); A.append(a); B.append(b)
M.append(d+a); N.append(d-b)
straightMstart, straightNstart = [0]*(S), [0]*(S)
crossedMstart, crossedNstart = [0]*(S), [0]*(S) # cross over
for i in range(1, S):
if M[i] == M[i-1]:
straightMstart[i] = straightMstart[i-1]
crossedNstart[i] = crossedNstart[i-1]
else:
straightMstart[i] = i
if N[i] == N[i-1]:
straightNstart[i] = straightNstart[i-1]
crossedMstart[i] = crossedMstart[i-1]
else:
straightNstart[i] = i
if M[i] != M[i-1]:
crossedNstart[i] = straightNstart[i-1]
if N[i] != N[i-1]:
crossedMstart[i] = straightMstart[i-1]
maxlen = 1
maxlensubsets = 1
for i in range(1, S):
thislen = i - min(crossedMstart[i], crossedNstart[i]) + 1
if maxlen < thislen:
maxlen = thislen
maxlensubsets = 1
elif maxlen == thislen:
maxlensubsets += 1
# print(crossedNstart)
# print(crossedMstart)
return "%d %d" % (maxlen, maxlensubsets)
testcase = int(input())
for tc in range(1, testcase+1):
print("Case %d: %s" % (tc, solve()))
I used crossed max length to find the maximum size of set.(for M and Ns)
I will give you the following example to make easier to understand my logic:
# Let's suppose that the M and N is:
M (=D[i]+A[i]) = [ 9, 9, 18, 22, 22]
N (=D[i]-B[i]) = [-10, -5, 7, -1, -1]
# Straight Start means starting index for same value.
# M=9 starts from index 0, M=18 starts from index 2, M=22 starts from index 3
straightMstart = [0, 0, 2, 3, 3]
# Same logic applied to straightNstart
straightNstart = [0, 1, 2, 3, 3]
# Crossed Start means cross-starting index of opponent array.
# For crossedMstart, you start from N[i] and climb N then cross to climb M
# The reason why I swapped order of cNs and cMs is that both arrays are based on opponent arrays
crossedNstart = [0, 0, 1, 2, 2]
crossedMstart = [0, 0, 0, 2, 2]
I'm really confusing, I don't really understand what is the point of my fault. Please help me to correct my logic.
Your algorithm has multiple ways it could fail. The simplest of them is entering a string in any of the inputs. Then I do see a problem with straightNstart[i] which is always zero for the current iteration if N[i] or M[i] match N[i-1] or M[i-1]. This sets the crossedMstart[i] and crossedNstart[i] values to 0. Another problem is when S <= 1 which ignores both loops.
The first problem is easy to solve which potentially covers the problems for d, a, b, testcase where d, a, b, testcase should raise only a TypeError:
S = input("[description]")
if S.isdigit():
S = int(S)
if S <= 1:
raise ValueError("Value must be greater then 1")
else:
raise TypeError("Value must be numeric")
For the other problem it could be possible to iterate twice so that the straightNstart[i], straightMstart[i] assignments have any effect on the outcome ( at least not when M[i] or N[i] are not equal to M[i-1] or N[i-1] ).
I found that my algorithm does not handling multiple crossover.
Let A be a non-empty set of integers. Write a function find that outputs a non-empty subset of A that has the maximum product. For example, find([-1, -2, -3, 0, 2]) = 12 = (-2)*(-3)*2
Here's what I think: divide the list into a list of positive integers and a list of negative integers:
If we have an even number of negative integers, multiply everything in both list and we have the answer.
If we have an odd number of negative integers, find the largest and remove it from the list. Then multiply everything in both lists.
If the list has only one element, return this element.
Here's my code in Python:
def find(xs):
neg_int = []
pos_int = []
if len(xs) == 1:
return str(xs[0])
for i in xs:
if i < 0:
neg_int.append(i)
elif i > 0:
pos_int.append(i)
if len(neg_int) == 1 and len(pos_int) == 0 and 0 in xs:
return str(0)
if len(neg_int) == len(pos_int) == 0:
return str(0)
max = 1
if len(pos_int) > 0:
for x in pos_int:
max=x*max
if len(neg_int) % 2 == 1:
max_neg = neg_int[0]
for j in neg_int:
if j > max_neg:
max_neg = j
neg_int.remove(max_neg)
for k in neg_int:
max = k*max
return str(max)
Am I missing anything? P.S. This is a problem from Google's foobar challenge, I am apparently missing one case but I don't know which.
Now here's actual problem:
from functools import reduce
from operator import mul
def find(array):
negative = []
positive = []
zero = None
removed = None
def string_product(iterable):
return str(reduce(mul, iterable, 1))
for number in array:
if number < 0:
negative.append(number)
elif number > 0:
positive.append(number)
else:
zero = str(number)
if negative:
if len(negative) % 2 == 0:
return string_product(negative + positive)
removed = max(negative)
negative.remove(removed)
if negative:
return string_product(negative + positive)
if positive:
return string_product(positive)
return zero or str(removed)
You can simplify this problem with reduce (in functools in Py3)
import functools as ft
from operator import mul
def find(ns):
if len(ns) == 1 or len(ns) == 2 and 0 in ns:
return str(max(ns))
pos = filter(lambda x: x > 0, ns)
negs = sorted(filter(lambda x: x < 0, ns))
return str(ft.reduce(mul, negs[:-1 if len(negs)%2 else None], 1) * ft.reduce(mul, pos, 1))
>>> find([-1, -2, -3, 0, 2])
'12'
>>> find([-3, 0])
'0'
>>> find([-1])
'-1'
>>> find([])
'1'
Here's a solution in one loop:
def max_product(A):
"""Calculate maximal product of elements of A"""
product = 1
greatest_negative = float("-inf") # greatest negative multiplicand so far
for x in A:
product = max(product, product*x, key=abs)
if x <= -1:
greatest_negative = max(x, greatest_negative)
return max(product, product // greatest_negative)
assert max_product([2,3]) == 6
assert max_product([-2,-3]) == 6
assert max_product([-1, -2, -3, 0, 2]) == 12
assert max_product([]) == 1
assert max_product([-5]) == 1
Extra credit: what if the integer constraint were relaxed? What extra information do you need to collect during the loop?
Here is another solution that doesn't require libraries :
def find(l):
if len(l) <= 2 and 0 in l: # This is the missing case, try [-3,0], it should return 0
return max(l)
l = [e for e in l if e != 0] # remove 0s
r = 1
for e in l: # multiply all
r *= e
if r < 0: # if the result is negative, remove biggest negative number and retry
l.remove(max([e for e in l if e < 0]))
r = find(l)
return r
print(find([-1, -2, -3, 0, 2])) # 12
print(find([-3, 0])) # 0
EDIT :
I think I've found the missing case which is when there are only two elements in the list, and the highest is 0.