Am trying to solve a Codechef problem (Turbo Sort). The problem is
Given the list of numbers, you are to sort them in non decreasing
order.
Input
t – the number of numbers in list, then t lines follow [t <= 10^6].
Each line contains one integer: N [0 <= N <= 10^6]
Output
Output given numbers in non decreasing order.
Example
Input:
5 5 3 6 7 1
Output:
1 3 5 6 7
My Solution is :
l = []
t = input()
MAX = 10**6
while t <= MAX and t != 0:
n = input()
l.append(n)
t = t - 1
st = sorted(l)
for x in st:
print x
The challenge is this program should run in 5 sec. When i submit the file, codechef says it is exceeding the time and needs optimization.
Can some one help, how to optimize it ?
My accepted solutions:
import sys
from itertools import imap
T = int(raw_input())
lines = sys.stdin.readlines()
lis = imap(str, sorted(imap(int, lines)))
print "\n".join(lis)
A readable version(accepted solution) :
import sys
T = raw_input()
lines = sys.stdin.readlines() #fetch all lines from the STDIN
lines.sort(key=int) #sort the list in-place(faster than sorted)
print "\n".join(lines) #use `str.join` instead of a for-loop
Things like readlines should be supported. I've just made an attempt and got this as an accepted solution:
import sys
print '\n'.join(map(str, sorted(map(int, sys.stdin.read().split()[1:]))))
Not pretty but functional. Took me a bit before I figured out you had to skip the first number, debugging is a bit annoying with this system ;)
Related
I have just started learning how to code 'competitively' in competitions and came across this problem:
A 'perfect' melody is one that has the same 3 numbers repeating over, for example:
123123123
And so a 'non-perfect' one would be for example: 123122121
Now the question asks how many numbers need to be changed in an imperfect melody to make it 'perfect'. Below is an example: (in the first row of the input file , the first one is the amount of notes and the second one is the max value each note can take and then the rest of the numbers are the notes in order)
Example:
Example
I have produced a solution that doesn't solve most of the test cases and I don't see why. My code is below:
#!/usr/bin/env python
import sys
sys.setrecursionlimit(1000000000)
# N is the number of notes.
N = None
# K is the largest number which could be a note.
K = None
# S contains the sequence of notes forming the song.
S = [None for x in range(100005)]
answer = None
# Open the input and output files.
input_file = open("melodyin.txt", "r")
output_file = open("melodyout.txt", "w")
# Read the value of N and K.
input_line = input_file.readline().strip()
N, K = map(int, input_line.split())
# Read each note in the song.
for i in range(0, N):
S[i] = int(input_file.readline().strip())
notes_list = []
for i in range(0, N):
notes_list.append(S[i])
count = 0
sep = []
for i in range(N//3):
sep.append([notes_list[count], notes_list[count+1], notes_list[count+2]])
count += 3
errors = 0
for i in range(len(sep)-1):
if sep[0][0] != sep[i+1][0]:
errors += 1
if sep[0][1] != sep[i+1][1]:
errors += 1
if sep[0][2] != sep[i+1][2]:
errors += 1
else:
pass
# Write the answer to the output file.
output_file.write("%d\n" % (errors))
# Finally, close the input/output files.
input_file.close()
output_file.close()
additionally these are the constraints:
• 3≤N≤99999.
• N is a multiple of three. • 1≤K≤100000.
• 1≤Si ≤K,for all i
Now I'm using while loops to try and do this because I'm not too good at using for loops. As the title reads, I'm trying to print out a table which has the line number next to the length of each line.
Error: When I hit run all I get is the above print out (line and number of words with dashes below). I do not get a series of printouts of y and z
Note: I'm probably making this way harder than it needs to be
Code:
list1 = ['Lets go outside','pizza time','show me the money']
list2 = []
print('line number of words')
print('---- ---------------')
x = 0
len_l1 = len(list1)
while len_l1 > 0:
split_lis1 = list1[0+x].split(' ')
list2.append(split_lis1)
len_l1 -= 1
x += 1
while len_l1 > 0:
q = 1
y = len(list1) - len(list1) + q(x)
z = len(list2[0+x])
print(y, z)
len_l1 -= 1
x += 1
what I want the print out to look like:
line number of words
---- ---------------
0 3
1 2
2 4
Thanks.
Yes, you might have overcomplicated the solution as there are out of the box Python methods that help you easily solve problems like this. For iteration with indexes, use enumerate, in the example below we set the index to start at 1. We can also use some simple string formatting defined in fmt to ensure consistent spacings.
li = ['Lets go outside','pizza time','show me the money']
print('line number of words')
print('---- ---------------')
fmt = ('{} {}')
for idx, sentence in enumerate(li,1):
no_of_words = len(sentence.split())
print(fmt.format(idx, no_of_words))
Then simple use split to split the whitespaces and get the total number of words and let enumerate manage the whole thing for you.
>>
line number of words
---- ---------------
1 3
2 2
3 4
list1 = ['Lets go outside','pizza time','show me the money']
print('line number of words')
print('---- ---------------')
for i in range(0, len(list1)):
length = len(list1[i].split(" "))
print(i + 1, " ", length)
Check out python docs for range and for details.
I am trying to write my own code for generating permutation of items represented by numbers. Say 4 items can be represented by 0,1,2,3
I've seen the code from itertools product. That code is pretty neat. My way of coding this is using binary or ternary,... My code below only works for bits of less than 10. Part of this code split the str using list(s). Number 120 in base 11 is 1010, splitting '1010' yields, 1,0,1,0. For it to work correctly, I need to to split to 10, 10. Is there a way around this and still work with the rest of the code?
Alternatively, what is a recursive version for this? Thanks
aSet = 11
subSet = 2
s = ''
l = []
number = aSet**subSet
#finding all permutation, repeats allowed
for num in range(number):
s = ''
while num//aSet != 0:
s = str(num%aSet) + s
num = num//aSet
else:
s = str(num%aSet) + s
s = s.zfill(subSet)
l.append(list(s))
Indeed, the problem with using a string, is that list(s) will chop it into individual characters. You should not create a string at all, but use a list for s from the start:
aSet = 11
subSet = 2
l = []
number = aSet**subSet
#finding all permutation, repeats allowed
for num in range(number):
s = []
for _ in range(subSet):
s.insert(0, num%aSet)
num = num//aSet
l.append(s)
Solving the Smoothing the Weather problem on Codeabbey. It prints the correct output for the first 32 values after which it doesn't read the inputted values correctly. Inputted test values are well over 150.
Here is my code:
from __future__ import division
num=int(raw_input());
inp=((raw_input()).split(" "));
lists=[];
for i in inp:
if inp.index(i)==0 or inp.index(i)==len(inp)-1:
lists.append(inp[inp.index(i)])
else:
a,b,c=0.0,0.0,0.0;
a=float(inp[(inp.index(i))+1])
b=float(inp[inp.index(i)])
c=float(inp[(inp.index(i))-1])
x=(a+b+c)/3
x = ("%.9f" % x).rstrip('0')
lists.append(x)
for i in lists:
print i,
The index in the following code will always return the first occurrence of i in inp. So, if there are duplicate values in inp, then the whole logic fails.
if inp.index(i)==0 or inp.index(i)==len(inp)-1:
lists.append(inp[inp.index(i)])
The correct approach would be to enumerate and us correct indices:
from __future__ import division
num = int(raw_input())
inp = ((raw_input()).split(" "))
lists = []
for i, item in enumerate(inp): # This will loop through inp, while filling the next item in item and keep on incrementing i each time starting with 0
if i == 0 or i == len(inp)-1:
lists.append(inp[i])
else:
a = float(inp[i+1])
b = float(inp[i])
c = float(inp[i-1])
x = (a+b+c) / 3.0
x = ("%.9f" % x).rstrip('0')
lists.append(x)
for i in lists:
print i,
Hope that helps.
Please help for task with the list in Python my logic is bad works:( .
This is full text of task: Write a program that takes a list of
numbers on one line and displays the values in a single row, are
repeated in it more than once.
To solve the problem can be useful sort method list.
The procedure for withdrawal of repetitive elements may be arbitrary.
My beginning code is :
st = (int(i) for i in input().split())
ls = []
for k in st:
if k == k + 1 and k > 1:
Task is : if we have replay value in list we must print it. We only can use sort() method and without any modules importing.
Results Examples:
Sample Input 1:
4 8 0 3 4 2 0 3
Sample Output 1:
0 3 4
Sample Input 2:
10
Sample Output 2:
Sample Input 3:
1 1 2 2 3 3
Sample Output 3:
1 2 3
This code isn't run( sort() function doesn't want sort my_list. But I must input values like my_list = (int(k) for k in input().split())
st = list(int(k) for k in input())
st.sort()
for i in range(0,len(st)-1):
if st[i] == st[i+1]:
print(str(st[i]), end=" ")
my_list = (int(k) for k in input().split())
After running this line, my_list is a generator, something that will create a sequence - but hasn't yet done so. You can't sort a generator. You either need to use []:
my_list = [int(k) for k in input().split()]
my_list.sort()
which makes my_list into a list from the start, instead of a generator, or:
my_list = list(int(k) for k in input().split()))
my_list.sort()
gather up the results from the generator using list() and then store it in my_list.
Edit: for single digits all together, e.g. 48304, try [int(k) for k in input()]. You can't usefully do this with split().
Edit: for printing the results too many times: make the top of the loop look backwards a number, like this, so if it gets to the second or third number of a repeating number, it skips over and continues on around the loop and doesn't print anything.
for i in range(0,len(st)-1):
if st[i] == st[i-1]:
continue
if st[i] == st[i+1]:
print...
st = (int(i) for i in input().split())
used = []
ls = []
for k in st:
if k in used: # If the number has shown up before:
if k not in used: ls.append(k) # Add the number to the repeats list if it isn't already there
else:
used.append(k) # Add the number to our used list
print ' '.join(ls)
In summary, this method uses two lists at once. One keeps track of numbers that have already shown up, and one keeps track of second-timers. At the end the program prints out the second-timers.
I'd probably make a set to keep track of what you've seen, and start appending to a list to keep track of the repeats.
lst = [num for num in input("prompt ").split()]
s = set()
repeats = []
for num in lst:
if num in s and num not in repeats:
repeats.append(num)
s.add(num)
print ' '.join(map(str,repeats))
Note that if you don't need to maintain order in your output, this is faster:
lst = [num for num in input("prompt ").split()]
s = set()
repeats = set()
for num in lst:
if num in s:
repeats.add(num)
s.add(num)
print ' '.join(map(str, repeats))
Although if you can use imports, there's a couple cool ways to do it.
# Canonically...
from collections import Counter
' '.join([num for num,count in Counter(input().split()).items() if count>1])
# or...
from itertools import groupby
' '.join([num for num,group in groupby(sorted(input().split())) if len(list(group))>1])
# or even...
from itertools import tee
lst = sorted(input('prompt ').split())
cur, nxt = tee(lst)
next(nxt) # consumes the first element, putting it one ahead.
' '.join({cur for (cur,nxt) in zip(cur,nxt) if cur==nxt})
this gives the answers you're looking for, not sure if it's exactly the intended algorithm:
st = (int(i) for i in input().split())
st = [i for i in st]
st.sort()
previous = None
for current in st:
if ((previous is None and current <= 1)
or (previous is not None and current == previous + 1)):
print(current, end=' ')
previous = current
>>> "4 8 0 3 4 2 0 3"
0 3 4
>>> "10"
>>> "1 1 2 2 3 3"
1 2 3
updated to:
start with st = (int(i) for i in input().split())
use only sort method, no other functions or methods... except print (Python3 syntax)
does that fit the rules?