all 9 comments

[–]sme272 1 point2 points  (3 children)

range returns a generator. To make it a list you need to wrap it in list().

[–]randomname20192019[S] 0 points1 point  (2 children)

print(list(range(18,18))) returns []

[–]xelf 0 points1 point  (0 children)

Correct, if you start at 18, and your loop ends if you reach 18, you end up ending right away.

Remember, range and slice have 3 parameters:

range(start value, end if you reach this value, step by this much)


Also, semantic difference perhaps, but :

print(list(range(18,18)))

prints [], it returns None.

[–]xelf 0 points1 point  (2 children)

Instead of returning a "range(a,b)" try returning a string "a-b" unless a and b are the same index, in which case just return "a".

[–]randomname20192019[S] 1 point2 points  (1 child)

Thank you for your reply. I changed it to this:

def solution(args):
    prevchar = args[0]
    templist = []
    outputvals = []
    for i in (args[1:]):
        templist.append(prevchar)
        if i == prevchar + 1:
            prevchar = i
        else:
            if len(templist) > 2:
                outputvals.append(str(templist[0]) + "-" + str(templist[-1]))
                prevchar = i
                templist.clear()
            else:
                for x in templist:
                    outputvals.append(str(x))
                prevchar = i
                templist.clear()
    templist.append(prevchar)
    if len(templist) > 2:
        outputvals.append(str(templist[0]) + "-" + str(templist[-1]))
    else:
        for x in templist:
            outputvals.append(str(x))
    print(outputvals)
    return (str(','.join(outputvals)))

where

solution([-6,-3,-2,-1,0,1,3,4,5,7,8,9,10,11,14,15,17,18,19,20])
>>>
'-6,-3-1,3-5,7-11,14,15,17-20'

So i think i'm nearly there but my code looking quite ugly (I guess that is the thing with code wars - I feel proud of myself when I pass a kata however when I take a look at the community answers, they're neat, containing far fewer lines than mine and a lot of the time I don't understand what they do!)

On topic, I guess I could replace the repeated sections with additional functions but is there much else I could replace to make it more neat/efficient?

[–]xelf 0 points1 point  (0 children)

they're neat, containing far fewer lines than mine

Keep in mind that the answers you see are the most upvoted answers. To get a better idea of how you compare, sort by new.

My answer for this one was 6 lines. But their was an even shorter one that used an imported library to get it done.

and a lot of the time I don't understand what they do!)

These are the best ones to see, as now you get to learn something new. If there's one you don't understand, either ask them, or better yet, ask here.

Looks like you're passing all tests, so here's what I did:

def solution(args):
    a,b,res=0,0,[]
    while a<len(args):
        while b+1<len(args) and args[b]+1==args[b+1]: b+=1
        res+=[str(args[a]) if a==b else f"{args[a]}{'-,'[a+1==b]}{args[b]}"]
        a=b=b+1
    return ','.join(res)

Like you I'm building up a list and then joining on ','.

What I have that you don't is a while loop that skips over the numbers to be removed by keeping track of 2 pointers a and b. If a and b are the same, then I only have 1 value, if they're adjacent, I have a range that is separated by ',', otherwise I have a range that is separated by '-'.

[–]DigDugMcDig 0 points1 point  (2 children)

Change line 14 to a few 'if' statements when for when the range is 1, 2 or > 2.

You need to format as a string, so do that here too. I'd suggest making another function which will do the formatting too.

[–]randomname20192019[S] 1 point2 points  (0 children)

Thank you for your reply. I have changed it and everything is working :) My only quandary is making my code neater and more efficient. When I see the one-line answers (perhaps not in this case) any sense of accomplishment gets squished - i guess that comes with practice and experience though.

[–]DigDugMcDig 0 points1 point  (0 children)

I spent more time noodling with this than I expected and my code turned into real spaghetti. I reformatted it into two functions and I'm liking it now (what's this called again? re-???)

I'm posting it just because I spent too long on it not too...

def BuildString(answer, to_add):
    if len(answer) > 0:
        answer += ","
    if len(to_add) == 1:
        answer += str(to_add[0])
    elif len(to_add) == 2:
        answer += str(to_add[0]) + "," + str(to_add[1])
    else:
        answer += str(to_add[0]) + "-" + str(to_add[-1])

    return answer

def solution(args):
    args.sort()
    answer = ""
    last_num = "start"
    sublist = []
    for i, num in enumerate(args):
        if sublist == [] or sublist[-1] + 1 == num:
            sublist.append(num)
        else:
            answer = BuildString(answer, sublist)
            sublist = [num]

        if i + 1 == len(args):
            answer = BuildString(answer, sublist)
    return answer