i get runtime error when doing kattis oddmanout challenge - python

Hi im new to Kattis ive done this assignment "oddmanout" and it works when i compile it locally but i get runtime error doing it via Kattis. Im not sure why?
from collections import Counter
cases = int(input())
i = 0
case = 0
while cases > i:
list = []
i = 1 + i
case = case + 1
guests = int(input())
f = 0
while f < guests:
f = f + 1
invitation_number = int(input())
list.append(invitation_number)
d = Counter(list)
res = [k for k, v in d.items() if v == 1]
resnew = str(res)[1:-1]
print(f'Case#{case}: {resnew}')

Looking at the input data on Kattis : invitation_number = int(input()) reads not just the first integer, but the whole line of invitation numbers at once in the third line of the input. A ValueError is the result.
With invitation_numbers = list(map(int, input().split())) or alternatively invitation_numbers = [int(x) for x in input().split()] you will get your desired format directly.
You may have to rework your approach afterwards, since you have to get rid of the 2nd while loop. Additionally you don't have to use a counter, running through a sorted list and pairwise comparing the entries, may give you the solution aswell.
Additionally try to avoid naming your variables like the datatypes (list = list()).

Related

How can I optimize the following Python code, to prevent time exeption?

Everybody. I wrote the following code. Please help me, to optimize this, when I submit in some test cases compiler writing time-limit-exceeded 2.069s / 13.33Mb.
import math
N = int(input())
arr = [None]*N; new_list = []
stepen = 0; res = .0;
arr = input().split(" ")
arr = [float(h) for h in arr]
Q = int(input())
for j in range(Q):
x, y = input().split()
new_list.extend([int(x), int(y)])
for i, j in zip(new_list[0::2], new_list[1::2]):
stepen = (j - i)+ 1
res = math.prod(arr[i:j+1])
print(pow(res, 1./stepen))
The slowest thing in your algorithm is the math.prod(arr[i:j+1]). If all the x and y inputs denote the entire range, you will surely TLE, as the calls to prod must loop over the entire range.
In order to avoid this, you must do a prefix product on your array. The idea is this: Keep a second array pref, with the property that pref[i] = arr[i] * pref[i-1]. As a result, pref[i] will be the product of everything at the ith position and before in arr.
Then to find the product between positions i and j, you want pref[j] / pref[i-1]. See if you can figure out why this gives the correct answer.

Creating an empty list, adding points to it in a function, but error when trying to call it back

I am trying to use a list that I created in a previous function. The list is a set of times (each second is a point) and I need to add points every 1/20th of a second. The list of times was created in a previous function, but when I try to call back the list to np.linspace it, I get a typeerror code saying the global name list1 was not defined.
I've already tried renaming the list to something different like time = [], but this does not help. I've also defined the empty list in the function and outside of the function.
def time_finder():
v = 0
u = 0
list1 = []
while v < 286:
v = v + 1
u = u + 1
z = mce_data[0]
y = [a for b in z for a in b]
x = (y)[u]
w = np.array(x)[0]
x.tolist()
list1.append(w)
return (list1)
#print(list1)
time_finder()
#adds 1/20th second marks
def twentieth_second():
u = 0
while u < 286:
v = 1
timea = list1[u]
timeb = list1[v]
np.linspace(timea, timeb, parts+19)
u = u + 1
v = v + 1
print list1
twentieth_second()
The error that I get is NameError: global name 'list1' is not defined. This error changes depending on the troubleshooting that I do. Sometimes I get a call back error and other times I get an index is out of range error. I'm expecting to get a new list printed with the 1/20 second intervals included.
you need to assign the results of the first function to a variable:
list1 = time_finder()
It may even help to move that line into twentieth_second
Also your return in the time_finder is wrong. Remove the () around list1
#return (list1)
return list1

How can I write a method or a for loop for very similar code pieces

I have a code sample below. Code works perfectly but my problem is, this code isn't clean and costing too much line, I believe this code can be reduced with a method or for-loop, but I couldn't figure out how can I achieve this. The code pieces are %90 same, only changes are happening in variable side. I only put 2 of the pieces but my code consists of 5 pieces just like this
#KFOLD-1
all_fold_X_1 = pd.DataFrame(columns=['Sentence_txt'])
index = 0
for k, i in enumerate(dfNew['Sentence_txt'].values):
if k in kFoldsTrain1:
all_fold_X_1 = all_fold_X_1.append({index:i}, ignore_index=True)
X_train1 = count_vect.fit_transform(all_fold_X_1[0].values)
Y_train1 = [i for k,i in enumerate(dfNew['Sentence_Polarity'].values) if k in kFoldsTrain1]
Y_train1 = np.asarray(Y_train1)
#KFOLD-2
all_fold_X_2 = pd.DataFrame(columns=['Sentence_txt'])
index = 0
for k, i in enumerate(dfNew['Sentence_txt'].values):
if k in kFoldsTrain2:
all_fold_X_2 = all_fold_X_2.append({index:i}, ignore_index=True)
X_train2 = count_vect.fit_transform(all_fold_X_2[0].values)
Y_train2 = [i for k,i in enumerate(dfNew['Sentence_Polarity'].values) if k in kFoldsTrain2]
Y_train2 = np.asarray(Y_train2)
A full example hasn't been provided, so I'm making some assumptions. Perhaps something along these lines:
def train(dataVar, dfNew):
ret = {}
index = 0
for k, i in enumerate(dfNew['Sentence_txt'].values):
if k in kFoldsTrain1:
dataVar = dataVar.append({index:i}, ignore_index=True)
ret['x'] = count_vect.fit_transform(dataVar[0].values)
ret['y'] = [i for k,i in enumerate(dfNew['Sentence_Polarity'].values) if k in kFoldsTrain1]
ret['y'] = np.asarray(Y_train1)
return ret
#KFOLD-1
kfold1 = train(pd.DataFrame(columns=['Sentence_txt']), dfNew)
#KFOLD-2
kfold2 = train(pd.DataFrame(columns=['Sentence_txt']), dfNew)
You perhaps get the idea. You may not need the second argument in the function dependent on if the variable 'dfNew' is global. I'm also far from a Python expert! ;)

python list variables dictionary

Below I am trying to read a file and store every other second and third lines.
I have 4000 lines but there is a pattern of 4 lines which repeats 1000 times.
After I have read and split the lines into three variables x,y,z. But these are string variables. Next for-loop I am trying to convert the lists into numpy arrays. I use a dictionary for this. However, at the end of the code when I print the type of y is still a str variable. As I understand from what happens python did not store the numpy array p as y, although I loop over x,y,z
#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
fl = open('input.sis','r')
lines = []
x = []
y = []
z = []
for i in range(1000):
line = []
for j in range(4):
f= fl.readline()
line.append(f)
lines.append(line)
xyz = lines[i][2].split(' ')
x.append(xyz[0])
y.append(xyz[1])
z.append(xyz[2])
fl.close()
dic = {'x':x,'y':y,'z':z}
for k in dic:
p = dic[k]
p = np.asfarray(p)
print(type(p))
print(type(y[0]))
Any idea how to tell python to recognize that p = np.asfarray(p) is actually y = np.asfarray(y) and when I print the type of y at the end to be float instead of str? Your help will be highly appreciated!
A way to understand what happens is to replace = by is now a name for.
What you do in your loop is:
p is now a name for dic[k]
p is now a name for the output of np.asfarray(p)
and so on, in each loop. When you leave the for loop, p refers to the output of np.asfarray(dic('z')). And that's all that happened here.
If you want to update the values in your dict, you should do:
dic = {'x':x,'y':y,'z':z}
for k in dic:
dic[k] = np.asfarray(dic[k])
or, a bit nicer:
for key, value in dic.items():
dic[key] = np.asfarray(value)
Now, dic['y'] refers to the array returned bynp.asfarray`
But you haven't done anything to y, so it still refers to the same object as before. If you want to change that, you must write something like y = ....
You could for example do:
y = dic['y']
For a more thorough explanation, have a look at Facts and myths about Python names and values
for k in dic:
p = dic[k]
p = np.asfarray(p)
print(type(p))
Should be
for k in dic:
p = dic[k]
dic[k] = np.asfarray(p)
print(type(p))
When you set p = dic[k] you are calling dic[k] and retrieving a value, now, since dic[x] == x now p == x. Now when you are trying to assign that value to its corresponding key you want to call dic[k] = np.asfarry(p) this translates to dic['x'] = np.asfarry(x) and now it is assigned to the value for the corresponding key.
Here's a visual to break it down whats happening
dicta = {'a': 1 }
for k in dicta:
print(dicta[k])
p = dicta[k]
print(p)
dicta[k] = 3*p
print(dicta[a])
1
1
3
for i in range(1000):
line = []
for j in range(4):
f= fl.readline()
line.append(f)
lines.append(line)
xyz = lines[i][2].split(' ')
x.append(xyz[0])
y.append(xyz[1])
z.append(xyz[2])
fl.close()
dic = {'x':x,'y':y,'z':z}
for k in dic:
p = dic[k]
p = np.asfarray(p)
print(type(p))
print(type(y[0]))
The answer to the question I asked is to use globals(). Some people would discourage you using it but is the only solution I could find. Let me explain:
Right in the first for-loop y.append(xyz[1]) will return y as list of <str>, where the same holds for x and z.
Step 2. I create a dictionary of these variables x,y and z and their values.
Step 3. I want to loop over each variable in dic and change the type of x, y,z from str list to numpy arrays.
Therefore when I print the type of y[0] it is still str.
Now if the second loop is replaced by:
dic = {'x':x,'y':y,'z':z}
for k in sorted(dic):
globals()[k] = np.asfarray(dic[k])
print(type(y[0]))
I get for type(y[0]):
<type 'numpy.float64'>

Problems with the zip function: lists that seem not iterable

I'm having some troubles trying to use four lists with the zip function.
In particular, I'm getting the following error at line 36:
TypeError: zip argument #3 must support iteration
I've already read that it happens with not iterable objects, but I'm using it on two lists! And if I try use the zip only on the first 2 lists it works perfectly: I have problems only with the last two.
Someone has ideas on how to solve that? Many thanks!
import numpy
#setting initial values
R = 330
C = 0.1
f_T = 1/(2*numpy.pi*R*C)
w_T = 2*numpy.pi*f_T
n = 10
T = 1
w = (2*numpy.pi)/T
t = numpy.linspace(-2, 2, 100)
#making the lists c_k, w_k, a_k, phi_k
c_karray = []
w_karray = []
A_karray = []
phi_karray = []
#populating the lists
for k in range(1, n, 2):
c_k = 2/(k*numpy.pi)
w_k = k*w
A_k = 1/(numpy.sqrt(1+(w_k)**2))
phi_k = numpy.arctan(-w_k)
c_karray.append(c_k)
w_karray.append(w_k)
A_karray.append(A_k)
phi_karray.append(phi_k)
#making the function w(t)
w = []
#doing the sum for each t and populate w(t)
for i in t:
w_i = ([(A_k*c_k*numpy.sin(w_k*i+phi_k)) for c_k, w_k, A_k, phi_k in zip(c_karray, w_karray, A_k, phi_k)])
w.append(sum(w_i)
Probably you mistyped the last 2 elements in zip. They should be A_karray and phi_karray, because phi_k and A_k are single values.
My result for w is:
[-0.11741034896740517,
-0.099189027720991918,
-0.073206290274556718,
...
-0.089754003567358978,
-0.10828235682188027,
-0.1174103489674052]
HTH,
Germán.
I believe you want zip(c_karray, w_karray, A_karray, phi_karray). Additionally, you should produce this once, not each iteration of the for the loop.
Furthermore, you are not really making use of numpy. Try this instead of your loops.
d = numpy.arange(1, n, 2)
c_karray = 2/(d*numpy.pi)
w_karray = d*w
A_karray = 1/(numpy.sqrt(1+(w_karray)**2))
phi_karray = numpy.arctan(-w_karray)
w = (A_karray*c_karray*numpy.sin(w_karray*t[:,None]+phi_karray)).sum(axis=-1)

Categories

Resources