Common Subexpression Elimination in Go
Common Subexpression Elimination (CSE) is a compiler optimization technique that identifies and removes redundant calculations within a program. This challenge asks you to implement a simplified version of CSE for a sequence of arithmetic expressions. By identifying and reusing common subexpressions, you can improve the efficiency of code execution.
Problem Description
You are tasked with writing a Go program that performs Common Subexpression Elimination on a list of arithmetic expressions. Each expression is represented as a string containing only integers, '+', '-', '*', and '/' operators, and spaces. Your program should analyze the expressions, identify common subexpressions (sequences of operations that result in the same value), and rewrite the expressions to reuse the calculated values instead of recomputing them. The output should be a list of strings representing the optimized expressions.
Key Requirements:
- Expression Parsing: The program must be able to parse the input expressions. While full parsing isn't required, the program needs to be able to identify and extract subexpressions.
- Subexpression Identification: The core of the challenge is to identify common subexpressions. For simplicity, consider subexpressions as contiguous sequences of operators and operands.
- Expression Rewriting: Once a common subexpression is identified, the program should replace the original subexpression with a placeholder variable (e.g., "X1", "X2", etc.).
- Value Storage: The program needs to store the calculated values of the subexpressions.
- Output Format: The output should be a list of strings, where each string represents an optimized expression.
Expected Behavior:
The program should take a list of expressions as input and return a list of optimized expressions. The optimized expressions should be functionally equivalent to the original expressions but with redundant calculations eliminated. The placeholder variables should be unique within the output.
Edge Cases to Consider:
- Empty input list.
- Expressions with only a single number.
- Expressions with division by zero (handle gracefully - either skip the expression or return an error).
- Expressions with invalid characters (assume input is well-formed for this challenge).
- Expressions with different operator precedence (assume left-to-right evaluation for simplicity).
Examples
Example 1:
Input: ["2 + 3 * 4", "2 + 3 * 4", "5 + 2 + 3 * 4"]
Output: ["2 + 3 * 4", "2 + 3 * 4", "5 + X1"]
Explanation: "2 + 3 * 4" is a common subexpression. It's assigned the placeholder "X1" in the third expression.
Example 2:
Input: ["10 - 5 + 2", "10 - 5 + 2", "10 - 5 + 2"]
Output: ["10 - 5 + 2", "10 - 5 + 2", "10 - 5 + 2"]
Explanation: While the expression is repeated, it's not a *subexpression* in the contiguous sense. No optimization is performed.
Example 3:
Input: ["2 * 3 + 4", "2 * 3 + 4", "2 * 3 + 4", "2 * 3 + 4"]
Output: ["2 * 3 + 4", "X1", "X1", "X1"]
Explanation: "2 * 3 + 4" is a common subexpression and is replaced with "X1" in the subsequent expressions.
Constraints
- The input list will contain at most 10 expressions.
- Each expression will be a string of length at most 50 characters.
- Expressions will contain only integers (non-negative), '+', '-', '*', and '/' operators, and spaces.
- The program should be reasonably efficient; avoid excessively complex data structures or algorithms. A simple, functional approach is preferred.
- Placeholder variables should be unique and start with "X" followed by a number (e.g., "X1", "X2", "X3").
Notes
- For simplicity, assume left-to-right evaluation of operators. Parentheses are not supported.
- You don't need to evaluate the expressions; only identify and replace common subexpressions.
- Focus on the core logic of identifying and replacing common subexpressions. Error handling and input validation can be simplified.
- Consider using a simple data structure (e.g., a map) to store the calculated values of subexpressions and their corresponding placeholder variables.
- The goal is to demonstrate the concept of CSE, not to create a production-ready CSE implementation.