Skip to content

Instantly share code, notes, and snippets.

@decagondev
Created August 19, 2025 21:57
Show Gist options
  • Select an option

  • Save decagondev/ab903121ed6d1736c71103fec98a116c to your computer and use it in GitHub Desktop.

Select an option

Save decagondev/ab903121ed6d1736c71103fec98a116c to your computer and use it in GitHub Desktop.

Step-by-Step Execution of Iterative joinAll for [ ["x", "y"], ["z"] ]

This document walks through the execution of the non-recursive iterative joinAll function for the input [ ["x", "y"], ["z"] ], which generates all possible permutations of strings from the input lists, joined by underscores. The function produces ["x_z", "y_z"]. Each step of the iterative process is detailed below, with a Mermaid diagram visualizing the state of the algorithm, including the result and new_result lists. The diagrams are compatible with GitHub’s Mermaid renderer.

Iterative joinAll Implementation

The iterative solution builds combinations by maintaining a list of partial combinations (result) and updating it for each sublist.

def joinAll(lls):
    result = [""]
    for sublist in lls:
        new_result = []
        for s in sublist:
            for r in result:
                if r == "":
                    new_result.append(s)
                else:
                    new_result.append(r + "_" + s)
        result = new_result
    return result

Input

lls = [ ["x", "y"], ["z"] ]
# Expected Output: ["x_z", "y_z"]

Execution Steps

Step 1: Initialization

  • Description: Initialize result = [""] to start building combinations. This mimics the recursive base case, providing a starting point for combining strings.
  • State:
    • result = [""]
    • new_result = [] (not yet used)
    • Current sublist: None
  • Action: Set up the initial result list before processing the first sublist.

Mermaid Diagram: Initialization

graph TD
    A("Start joinAll") --> B("Initialize result = ['']")
    B --> C("result = ['']")
    C --> D("Proceed to first sublist")
Loading

Step 2: Process First Sublist ["x", "y"] - Start

  • Description: Begin processing the first sublist ["x", "y"]. Create new_result = [] to store new combinations. Start looping over the strings in the sublist (s = "x" first).
  • State:
    • result = [""]
    • new_result = []
    • Current sublist: ["x", "y"]
    • Current string: s = "x"
  • Action: For s = "x" and r = "" in result, since r is empty, append s to new_result.

Mermaid Diagram: Processing s = "x" in First Sublist

graph TD
    A("Start processing sublist ['x', 'y']") --> B("new_result = []")
    B --> C("s = 'x', r = ''")
    C --> D{Is r empty?}
    D -->|Yes| E("Append 'x' to new_result")
    E --> F("new_result = ['x']")
Loading

Step 3: Process First Sublist ["x", "y"] - Continue

  • Description: Continue processing the first sublist, now with s = "y". Combine s = "y" with r = "" in result, appending y to new_result since r is empty.
  • State:
    • result = [""]
    • new_result = ["x"]
    • Current sublist: ["x", "y"]
    • Current string: s = "y"
  • Action: Append y to new_result, resulting in new_result = ["x", "y"].

Mermaid Diagram: Processing s = "y" in First Sublist

graph TD
    A("Continue sublist ['x', 'y']") --> B("new_result = ['x']")
    B --> C("s = 'y', r = ''")
    C --> D{Is r empty?}
    D -->|Yes| E("Append 'y' to new_result")
    E --> F("new_result = ['x', 'y']")
Loading

Step 4: Update Result After First Sublist

  • Description: After processing all strings in ["x", "y"], update result = new_result. Move to the next sublist.
  • State:
    • result = ["x", "y"]
    • new_result = [] (reset for next sublist)
    • Current sublist: None (moving to ["z"])
  • Action: Set result = ["x", "y"] and prepare to process the second sublist.

Mermaid Diagram: Update Result

graph TD
    A("Finish sublist ['x', 'y']") --> B("new_result = ['x', 'y']")
    B --> C("Set result = new_result")
    C --> D("result = ['x', 'y']")
    D --> E("Proceed to sublist ['z']")
Loading

Step 5: Process Second Sublist ["z"] - Start

  • Description: Begin processing the second sublist ["z"]. Create new_result = []. For s = "z", combine with each r in result = ["x", "y"]. Since r is not empty, append r + "_" + s.
  • State:
    • result = ["x", "y"]
    • new_result = []
    • Current sublist: ["z"]
    • Current string: s = "z", r = "x"
  • Action: Append "x_z" to new_result.

Mermaid Diagram: Processing s = "z", r = "x" in Second Sublist

graph TD
    A("Start sublist ['z']") --> B("new_result = []")
    B --> C("s = 'z', r = 'x'")
    C --> D{Is r empty?}
    D -->|No| E("Append 'x_z' to new_result")
    E --> F("new_result = ['x_z']")
Loading

Step 6: Process Second Sublist ["z"] - Continue

  • Description: Continue processing s = "z" with the next r = "y" in result. Append "y_z" to new_result.
  • State:
    • result = ["x", "y"]
    • new_result = ["x_z"]
    • Current sublist: ["z"]
    • Current string: s = "z", r = "y"
  • Action: Append "y_z" to new_result, resulting in new_result = ["x_z", "y_z"].

Mermaid Diagram: Processing s = "z", r = "y" in Second Sublist

graph TD
    A("Continue sublist ['z']") --> B("new_result = ['x_z']")
    B --> C("s = 'z', r = 'y'")
    C --> D{Is r empty?}
    D -->|No| E("Append 'y_z' to new_result")
    E --> F("new_result = ['x_z', 'y_z']")
Loading

Step 7: Final Update and Return

  • Description: After processing the second sublist, update result = new_result. Since there are no more sublists, return result.
  • State:
    • result = ["x_z", "y_z"]
    • new_result = []
    • Current sublist: None
  • Action: Return ["x_z", "y_z"] as the final output.

Mermaid Diagram: Final Update and Return

graph TD
    A("Finish sublist ['z']") --> B("new_result = ['x_z', 'y_z']")
    B --> C("Set result = new_result")
    C --> D("result = ['x_z', 'y_z']")
    D --> E("Return result")
Loading

Key Takeaways

  • The iterative joinAll function builds combinations by updating a result list with new combinations for each sublist.
  • Starting with [""] allows the algorithm to handle the first sublist correctly, mimicking the recursive base case.
  • The underscore is added only when combining with non-empty strings, ensuring correct formatting.
  • Each Mermaid diagram visualizes the state of result and new_result at each step, showing how combinations evolve.
  • The process for [ ["x", "y"], ["z"] ] produces ["x_z", "y_z"] in seven steps: initialization, processing each string in each sublist, updating result, and returning the final output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment