Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

This is what I have to do https://www.codeeval.com/open_challenges/140/

I've been on this challenge for three days, please help. It it is 85-90 partially solved. But not 100% solved... why?

This is my code:

import sys
test_cases = open(sys.argv[1], 'r')
for test in test_cases:
    saver=[]
    text=""
    textList=[]
    positionList=[]
    num=0
    exists=int()
    counter=0
    for l in test.strip().split(";"):
        saver.append(l)
    for i in saver[0].split(" "):
        textList.append(i)
    for j in saver[1].split(" "):
        positionList.append(j)

    for i in range(0,len(positionList)):
        positionList[i]=int(positionList[i])

    accomodator=[None]*len(textList)

    for n in range(1,len(textList)):
        if n not in positionList:
            accomodator[n]=textList[len(textList)-1]
            exists=n       

    for item in positionList:
        accomodator[item-1]=textList[counter]
        counter+=1
        if counter>item:
            accomodator[exists-1]=textList[counter]

    for word in accomodator:
            text+=str(word) + " "
    print text
test_cases.close()
share|improve this question
    
Try replacing .split(';') with .rsplit(';',1). If I were designing the test, I'd have an input line with an extra ; in it. – Robᵩ Jul 31 '14 at 1:16
    
I did it and it still says it is partially solved... I dont understand – FutoRicky Jul 31 '14 at 1:18
up vote 2 down vote accepted

This code works for me:

import sys


def main(name_file):
    _file = open(name_file, 'r')
    text = ""
    while True:
        try:
            line = _file.next()
            disordered_line, numbers_string = line.split(';')
            numbers_list = map(int, numbers_string.strip().split(' '))
            missing_number = sum(xrange(sorted(numbers_list)[0],sorted(numbers_list)[-1]+1)) - sum(numbers_list)
            if missing_number == 0:
                missing_number = len(disordered_line)
            numbers_list.append(missing_number)
            disordered_list = disordered_line.split(' ')
            string_position = zip(disordered_list, numbers_list)
            ordered = sorted(string_position, key = lambda x: x[1])
            text +=  " ".join([x[0] for x in ordered])
            text += "\n"
        except StopIteration:
            break
    _file.close()
    print text.strip()

if __name__ == '__main__':
    main(sys.argv[1])

I'll try to explain my code step by step so maybe you can see the difference between your code and mine one:

while True 

A loop that breaks when there are no more lines.

try:

I put the code inside a try and catch the StopIteracion exception, because this is raised when there are no more items in a generator.

line = _file.next()

Use a generator, so that way you do not put all the lines in memory from once.

disordered_line, numbers_string = line.split(';')

Get the unordered phrase and the numbers of every string's position.

numbers_list = map(int, numbers_string.strip().split(' '))

Convert every number from string to int

missing_number = sum(xrange(sorted(numbers_list)[0],sorted(numbers_list)[-1]+1)) - sum(numbers_list)

Get the missing number from the serial of numbers, so that missing number is the position of the last string in the phrase.

if missing_number == 0:
    missing_number = len(unorder_line)

Check if the missing number is equal to 0 if so then the really missing number is equal to the number of the strings that make the phrase.

numbers_list.append(missing_number)

Append the missing number to the list of numbers.

disordered_list = disordered_line.split(' ')

Conver the disordered phrase into a list.

string_position = zip(disordered_list, numbers_list)

Combine every string with its respective position.

ordered = sorted(string_position, key = lambda x: x[1])

Order the combined list by the position of the string.

text +=  " ".join([x[0] for x in ordered])

Concatenate the ordered phrase, and the reamining code it's easy to understand.

UPDATE

By looking at your code here is my opinion tha might solve your problem.

split already returns a list so you do not have to loop over the splitted content to add that content to another list.

So these six lines:

for l in test.strip().split(";"):
    saver.append(l)
for i in saver[0].split(" "):
    textList.append(i)
for j in saver[1].split(" "):
    positionList.append(j)

can be converted into three:

splitted_test = test.strip().split(';')
textList = splitted_test[0].split(" ")
positionList = map(int, splitted_test[1].split(" "))

In this line positionList = map(int, splitted_test[0].split(" ")) You already convert numbers into int, so you save these two lines:

for i in range(0,len(positionList)):
    positionList[i]=int(positionList[i])

The next lines:

accomodator=[None]*len(textList)

for n in range(1,len(textList)):
    if n not in positionList:
         accomodator[n]=textList[len(textList)-1]
         exists=n       

can be converted into the next four:

missing_number = sum(xrange(sorted(positionList)[0],sorted(positionList)[-1]+1)) - sum(positionList)
if missing_number == 0:
    missing_number = len(textList)
    positionList.append(missing_number)

Basically what these lines do is calculate the missing number in the serie of numbers so the len of the serie is the same as textList.

The next lines:

for item in positionList:
    accomodator[item-1]=textList[counter]
    counter+=1
    if counter>item:
       accomodator[exists-1]=textList[counter]
for word in accomodator:
   text+=str(word) + " "

Can be replaced by these ones:

string_position = zip(textList, positionList) 
ordered = sorted(string_position, key = lambda x: x[1])
text +=  " ".join([x[0] for x in ordered])
text += "\n"

From this way you can save, lines and memory, also use xrange instead of range.

Maybe the factors that make your code pass partially could be:

  1. Number of lines of the script
  2. Number of time your script takes.
  3. Number of memory your script uses.

What you could do is:

  1. Use Generators. #You save memory
  2. Reduce for's, this way you save lines of code and time.
  3. If you think something could be made it easier, do it.
  4. Do not redo the wheel, if something has been already made it, use it.
share|improve this answer
1  
This doesn't directly answer why the code in OP's question doesn't work perfectly. Perhaps you want to highlight the differences and what's missing in OP's code. – justhalf Jul 31 '14 at 2:57
    
@justhalf What about now? – Victor Castillo Torres Jul 31 '14 at 3:36
    
Hmm, better, but you only explain your code, not his code. His question is about his code. Just think of this question like this: imagine OP reads your answer and says "But that's exactly what I'm trying to do with my code! Do you know where I go wrong?" How would you answer that? – justhalf Jul 31 '14 at 3:45
    
@justhalf I do not know where is his code wrong, because the webpage he gives to test the code, return that his code passed with 95% and does not tell you anymore, thats why I made my code and posted my answer. – Victor Castillo Torres Jul 31 '14 at 3:50
3  
This whole thread illuminates why codeeval makes a poor learning tool. – jgritty Sep 30 '14 at 18:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.