This post goes over how I updated my 2048 merge function code from spaghetti code to being somewhat more readable.
I incorporated a few techniques from pretty much all of your suggestions! I realized there were a lot of logical mistakes and redundancy in my code, like why append 0's over and over again when it's not necessary at all, because in the end I back-track, account for missing numbers, and then append 0(s) in their place.
Improvements in new code vs. old code:
- Use of list comprehensions
- Use of Python's built-in truthiness
- Minimal branches (fewer
if
(s),else
(s), etc.) - Infusing new and useful methods like
extend
into my code - Improving the code style by enhancing readability
- Removing redundandcy and flawed logic
def merge(nums):
'''
Takes a list as input
returns merged pairs with
non zero values shifted to the left.
fancy interactive doc test below, no output means no problems.
>>> merge([2, 0, 2, 4])
[4, 4, 0, 0]
>>> merge([0, 0, 2, 2])
[4, 0, 0, 0]
>>> merge([2, 2, 0, 0])
[4, 0, 0, 0]
>>> merge([2, 2, 2, 2, 2])
[4, 4, 2, 0, 0]
>>> merge([8, 16, 16, 8])
[8, 32, 8, 0]
'''
slide = [num for num in nums if num]
pairs = []
for idx, num in enumerate(slide):
if idx == len(slide)-1:
pairs.append(num)
break
elif num == slide[idx+1]:
pairs.append(num*2)
slide[idx+1] = None
else:
pairs.append(num) # Even if not pair you must append
slide = [pair for pair in pairs if pair]
slide.extend([0] * (len(nums) - len(slide)))
return slide
if __name__ == '__main__':
import doctest
doctest.testmod()
Sidenote: Pylint yells at me for using i
instead of idx
.