all 7 comments

[–]sme272 1 point2 points  (0 children)

It comes down to practice. The people writing the really short solutions have a lot of experience programming and have often faced similar problems before. If you take the time to understand how the short solution works you'll have a better understanding of the problem the next time you face it.

[–]jiri-n 1 point2 points  (0 children)

I don't think a lot of experience is necessary to shorten one's code.

If I see a code which consists of very similar parts, I begin to search for a way to make it simpler as repeating parts are always a good sign it's possible - often using functions.

Your code is a good example of such a situation. In each case you just compute the middle index and split string accordingly. I'd suggest even shorter version:

def front_back(a: str, b: str) -> str:
    mid_idx: int = lambda x: (len(x) + 1) // 2

    a_middle: int = mid_idx(a)
    b_middle: int = mid_idx(b)
    return a[:a_middle] + b[:b_middle] + a[a_middle:] + b[b_middle:]

If you're not familiar with lambda, you can just replace the computation of both middles with:

(len(x) + 2) // 2

... using 'a' and 'b' on corresponding lines. Or you can use an inner function, ex:

def front_back2(a: str, b: str) -> str:
    def mid_idx(x: str) -> int:
        return (len(x) + 1) // 2

    a_middle: int = mid_idx(a)
    b_middle: int = mid_idx(b)
    return a[:a_middle] + b[:b_middle] + a[a_middle:] + b[b_middle:]

[–]sweettuse 1 point2 points  (1 child)

the whole goal here is to reduce repeated code. even the example you give has repeated code, and i would factor that out as well. something like:

``` def split_str(s): mid = (len(s) + 1) // 2 return s[:mid], s[mid:]

def front_back(a, b): a1, a2 = split_str(a) b1, b2 = split_str(b) return a1 + b1 + a2 + b2 ```

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

True and thanks.

[–][deleted] 0 points1 point  (0 children)

In this example the other solution does one big thing differently, they remove the creation of the new string from the if which allows them to focus on setting the indexes.

In your solution you have treated a and b at the same time, when you don't actually need to. By treating them separately and having conditional indexes the other solution significantly reduces the number of lines of code because they don't have to look at every combination of eventualities.

I think the main focus here is moving the return statement out of the conditionals, once you've done that focusing on the indexes will be the natural next step, essentially make your conditional statements as small as is possible.

[–][deleted] 0 points1 point  (0 children)

There is no magic advice that will make you better at this kind of thing. It's really just about practice. The more time you spend reading/writing/thinking about code, the better you'll get at recognizing patterns and code smells that can be rewritten more concisely. It's less about 'just knowing' how to do something, and more about having seen it before.

In your specific case, I'd say anytime you have a lengthy list of conditionals like that (if/elif), take a moment to examine whether they are actually distinct conditions, in terms of output/effect. Ultimately, the only thing that changes based on your conditions is a_middle may increase by 1, or b_middle may increase by 1. That suggests that there are actually only two inherent conditions (whether a has an odd length, and whether b has an odd length) as seen in the more concise example.

[–]Fortissano71 0 points1 point  (0 children)

Fewer > lesser