Skip to main content
Add "Really Dry" block...
Source Link
user272752
user272752

Really DRY

The observant reader will notice two translation lookup instances into pair[] in that code snippet.

Instead of pushing "opens" onto the stack, this would be a time to push its required "close" mate. The popping operations are, already, tricky to think about:

        stack = [ '$' ] # Best guess in my ignorance of Python
        corrupted_ch = None
        for ch in line.strip():
            if ch in pairs: # Opening bracket
                stack.append( pairs[ch] ) # Push its mate
            else: # Closing bracket
                if stack.pop() != ch: # Mismatched! corrupted
                    corrupted_ch = ch
                    break # end of the road, corrupt or '$' depleted stack

        if corrupted_ch:
            total_score += points[corrupted_ch]
        else: # instead of 'continue'. Avoid explicit flow control if possible!
            score = 0
            while stack:
                top = stack.pop()
                if top != '$':
                    score = score * 5 + values[top]
            if score: # Only record non-zero results...
                scores.append(score)

(I believe guidelines probably discourage too much density (dangling comments on the same line as code statements. This is presented, as-is, to illustrate replacing two lookups with only one lookup.)

The calculation of "points" no longer needs to translate "opens" to "closes" when looking-up the value of each character.


Maybe?:
When calculating "points" perhaps more could be done simply using the index of each closing bracket character in a simpler string (".)]}>") to give 1, 2, 3, or 4.


Really DRY

The observant reader will notice two translation lookup instances into pair[] in that code snippet.

Instead of pushing "opens" onto the stack, this would be a time to push its required "close" mate. The popping operations are, already, tricky to think about:

        stack = [ '$' ] # Best guess in my ignorance of Python
        corrupted_ch = None
        for ch in line.strip():
            if ch in pairs: # Opening bracket
                stack.append( pairs[ch] ) # Push its mate
            else: # Closing bracket
                if stack.pop() != ch: # Mismatched! corrupted
                    corrupted_ch = ch
                    break # end of the road, corrupt or '$' depleted stack

        if corrupted_ch:
            total_score += points[corrupted_ch]
        else: # instead of 'continue'. Avoid explicit flow control if possible!
            score = 0
            while stack:
                top = stack.pop()
                if top != '$':
                    score = score * 5 + values[top]
            if score: # Only record non-zero results...
                scores.append(score)

(I believe guidelines probably discourage too much density (dangling comments on the same line as code statements. This is presented, as-is, to illustrate replacing two lookups with only one lookup.)

The calculation of "points" no longer needs to translate "opens" to "closes" when looking-up the value of each character.


Maybe?:
When calculating "points" perhaps more could be done simply using the index of each closing bracket character in a simpler string (".)]}>") to give 1, 2, 3, or 4.

deleted 38 characters in body
Source Link
user272752
user272752
        stack = []
        stack.append('$') # NEW!
        corrupted_char = None
        for char in line.strip():
            if char in pairs:
                # Opening bracket
                stack.append(char)
            else:
                # Closing bracket
                top = stack.pop()
                if pairs[top] != char:
                    # Mismatched closing bracket, corrupted
                    if top != '$':
                        corrupted_char = char
                    break # end of the road, corrupt or empty"empty" stack

        if corrupted_char:
            total_score += points[corrupted_char]
        else: # instead of 'continue'. Avoid explicit flow control if possible!
            score = 0
            while stack:
                top = stack.pop()
                if top != '$':
                    score = score * 5 + values[pairs[top]]
            if score: # Only record non-zero results...
                scores.append(score)
        stack = []
        stack.append('$') # NEW!
        corrupted_char = None
        for char in line.strip():
            if char in pairs:
                # Opening bracket
                stack.append(char)
            else:
                # Closing bracket
                top = stack.pop()
                if pairs[top] != char:
                    # Mismatched closing bracket, corrupted
                    if top != '$':
                        corrupted_char = char
                    break # end of the road, corrupt or empty stack

        if corrupted_char:
            total_score += points[corrupted_char]
        else: # instead of 'continue'. Avoid explicit flow control if possible!
            score = 0
            while stack:
                top = stack.pop()
                if top != '$':
                    score = score * 5 + values[pairs[top]]
            if score: # Only record non-zero results...
                scores.append(score)
        stack = []
        stack.append('$') # NEW!
        corrupted_char = None
        for char in line.strip():
            if char in pairs:
                # Opening bracket
                stack.append(char)
            else:
                # Closing bracket
                top = stack.pop()
                if pairs[top] != char:
                    # Mismatched closing bracket, corrupted
                    corrupted_char = char
                    break # end of the road, corrupt or "empty" stack

        if corrupted_char:
            total_score += points[corrupted_char]
        else: # instead of 'continue'. Avoid explicit flow control if possible!
            score = 0
            while stack:
                top = stack.pop()
                if top != '$':
                    score = score * 5 + values[pairs[top]]
            if score: # Only record non-zero results...
                scores.append(score)
Fix a few typos, and improve text...
Source Link
user272752
user272752

(Note Note: '$' must be added as a 5th record to pairs[] so that it can be found when needed.)

pairs: Final[dict[str, str]] = {
    '(': ')',
    '[': ']',
    '{': '}',
    '<': '>',
    '$': '$'
}

When the characters of line are exhausted, and presuming there is no 'corruption', the stack will not be empty. Fine! Go ahead! Drain what remains on the stack and tabulate some score. Just make sure that the 'value' of '$' is 0 in pairs[]. (May needNeed to account for '$' in this bizarre calculation because of the compounding x = x * 5 + y. Nuisance, really...) This eliminates the line if stack: toward the bottom of the loop.

        stack = []
        stack.append('$') # NEW!
        corrupted_char = None
        for char in line.strip():
            if char in pairs:
                # Opening bracket
                stack.append(char)
            else:
                # Closing bracket
                top = stack.pop()
                if pairs[top] != char:
                    # Mismatched closing bracket, corrupted
                    if top != '$':
                        corrupted_char = char
                    break # end of the road, corrupt or empty stack

        if corrupted_char:
            total_score += points[corrupted_char]
        else: # instead of 'continue'. Avoid explicit flow control if possible!
            score = 0
            while stack:
                chartop = stack.pop()
                if chartop != '$':
                    score = score * 5 + values[pairs[char]]values[pairs[top]]
            if score: # Only record non-zero results...
                scores.append(score)

(Note: '$' must be added as a 5th record to pairs[] so that it can be found when needed.)

When the characters of line are exhausted, and presuming there is no 'corruption', the stack will not be empty. Fine! Go ahead! Drain what remains on the stack and tabulate some score. Just make sure that the 'value' of '$' is 0 in pairs[]. (May need to account for '$' in this bizarre calculation because of the compounding x = x * 5 + y. Nuisance, really...) This eliminates the line if stack: toward the bottom of the loop.

        stack = []
        stack.append('$') # NEW!
        corrupted_char = None
        for char in line.strip():
            if char in pairs:
                # Opening bracket
                stack.append(char)
            else:
                # Closing bracket
                top = stack.pop()
                if pairs[top] != char:
                    # Mismatched closing bracket, corrupted
                    if top != '$':
                        corrupted_char = char
                    break # end of the road, corrupt or empty stack

        if corrupted_char:
            total_score += points[corrupted_char]
        else: # instead of 'continue'. Avoid explicit flow control!
            score = 0
            while stack:
                char = stack.pop()
                if char != '$':
                    score = score * 5 + values[pairs[char]]
            if score: # Only record non-zero results...
                scores.append(score)

Note: '$' must be added as a 5th record to pairs[] so that it can be found when needed.

pairs: Final[dict[str, str]] = {
    '(': ')',
    '[': ']',
    '{': '}',
    '<': '>',
    '$': '$'
}

When the characters of line are exhausted, and presuming there is no 'corruption', the stack will not be empty. Fine! Go ahead! Drain what remains on the stack and tabulate some score. (Need to account for '$' in this bizarre calculation because of the compounding x = x * 5 + y.) This eliminates the line if stack: toward the bottom of the loop.

        stack = []
        stack.append('$') # NEW!
        corrupted_char = None
        for char in line.strip():
            if char in pairs:
                # Opening bracket
                stack.append(char)
            else:
                # Closing bracket
                top = stack.pop()
                if pairs[top] != char:
                    # Mismatched closing bracket, corrupted
                    if top != '$':
                        corrupted_char = char
                    break # end of the road, corrupt or empty stack

        if corrupted_char:
            total_score += points[corrupted_char]
        else: # instead of 'continue'. Avoid explicit flow control if possible!
            score = 0
            while stack:
                top = stack.pop()
                if top != '$':
                    score = score * 5 + values[pairs[top]]
            if score: # Only record non-zero results...
                scores.append(score)
Develop full code fragment for examination and consideration...
Source Link
user272752
user272752
Loading
Add a code snippet that shows one suggested revision..
Source Link
user272752
user272752
Loading
added 124 characters in body
Source Link
user272752
user272752
Loading
Source Link
user272752
user272752
Loading