title: Calculate Digit Sum of a String
slug: calculate-digit-sum-of-a-string
difficulty: easy
leetcode_id: 2243
leetcode_url: https://leetcode.com/problems/calculate-digit-sum-of-a-string/
categories:
  - strings
patterns:
  - sliding-window

description: |
  You are given a string `s` consisting of digits and an integer `k`.

  A **round** can be completed if the length of `s` is greater than `k`. In one round, do the following:

  1. **Divide** `s` into **consecutive groups** of size `k` such that the first `k` characters are in the first group, the next `k` characters are in the second group, and so on. **Note** that the size of the last group can be smaller than `k`.

  2. **Replace** each group of `s` with a string representing the sum of all its digits. For example, `"346"` is replaced with `"13"` because `3 + 4 + 6 = 13`.

  3. **Merge** consecutive groups together to form a new string. If the length of the string is greater than `k`, repeat from step 1.

  Return `s` *after all rounds have been completed*.

constraints: |
  - `1 <= s.length <= 100`
  - `2 <= k <= 100`
  - `s` consists of digits only.

examples:
  - input: 's = "11111222223", k = 3'
    output: '"135"'
    explanation: "In the first round, we divide s into groups: \"111\", \"112\", \"222\", and \"23\". The digit sums are 3, 4, 6, and 5, giving \"3465\". In the second round, we divide into \"346\" and \"5\", with sums 13 and 5, giving \"135\". Since len(\"135\") <= 3, we return \"135\"."
  - input: 's = "00000000", k = 3'
    output: '"000"'
    explanation: "We divide s into \"000\", \"000\", and \"00\". Each group sums to 0, so we get \"000\". Since len(\"000\") equals k, we return \"000\"."

explanation:
  intuition: |
    Imagine you have a very long receipt with a sequence of digits, and you want to compress it into a shorter summary. The rule is simple: split the digits into chunks of size `k`, add up the digits in each chunk, and write down those sums. If the result is still too long, repeat the process.

    Think of it like repeatedly "squashing" the string. Each round takes groups of digits and compresses them into their digit sums. The string gets shorter with each round (in most cases), and eventually it becomes short enough — length `k` or less — to be the final answer.

    The key insight is that this is a **simulation problem**: there's no clever shortcut. You simply follow the rules step by step until the termination condition is met. The constraint `s.length <= 100` is small enough that even a straightforward implementation runs quickly.

  approach: |
    We solve this using a **Simulation Approach**:

    **Step 1: Set up the loop condition**

    - Continue processing while `len(s) > k`
    - Once the string is short enough, we're done

    &nbsp;

    **Step 2: Divide the string into groups**

    - Iterate through `s` in steps of `k`
    - Extract each chunk using slicing: `s[i:i+k]`
    - The last chunk may have fewer than `k` characters (that's allowed)

    &nbsp;

    **Step 3: Calculate the digit sum for each group**

    - For each chunk, sum the integer values of its characters
    - Convert each digit character to an integer with `int(char)`
    - Convert the sum back to a string

    &nbsp;

    **Step 4: Merge and repeat**

    - Concatenate all the digit sum strings to form the new `s`
    - Go back to step 1 and check if another round is needed

    &nbsp;

    **Step 5: Return the result**

    - When `len(s) <= k`, return `s` as the answer

  common_pitfalls:
    - title: Off-by-One Errors in Chunking
      description: |
        When dividing the string into groups, it's easy to make mistakes with indices. Using `range(0, len(s), k)` with slicing `s[i:i+k]` handles this cleanly — Python's slicing automatically handles the case where `i+k` exceeds the string length.

        A common mistake is trying to manually check if you're at the last group and handling it specially. This adds unnecessary complexity and risk.
      wrong_approach: "Manual index tracking with special case for last group"
      correct_approach: "Use range with step k and let Python slicing handle boundaries"

    - title: Forgetting to Convert Types
      description: |
        The string contains digit *characters* (`'1'`, `'2'`, etc.), not integers. You must convert each character to an integer before summing, then convert the sum back to a string.

        Forgetting `int()` will cause string concatenation instead of addition: `'1' + '2' + '3'` becomes `'123'`, not `6`.
      wrong_approach: "sum(chunk) without converting to integers"
      correct_approach: "sum(int(c) for c in chunk) then str() the result"

    - title: Infinite Loop Risk
      description: |
        If you accidentally don't update `s` with the new compressed string, or have a bug in your loop condition, you could loop forever.

        Always ensure `s` is reassigned to the new string at the end of each round, and verify your while condition uses the updated length.

  key_takeaways:
    - "**Simulation pattern**: Some problems have no clever trick — just follow the rules carefully until termination"
    - "**Python slicing**: `s[i:i+k]` safely handles boundary cases where `i+k` exceeds string length"
    - "**Type awareness**: Remember to convert between strings and integers when working with digit strings"
    - "**Small constraints**: With `n <= 100`, even O(n²) approaches are acceptable, so focus on correctness over micro-optimisation"

  time_complexity: "O(n) in practice. Each round reduces the string length significantly (by roughly a factor of k), so the total work across all rounds is linear in the original length."
  space_complexity: "O(n). We create new strings during each round, with the total space bounded by the input size."

solutions:
  - approach_name: Simulation
    is_optimal: true
    code: |
      def digit_sum(s: str, k: int) -> str:
          # Keep compressing until string is short enough
          while len(s) > k:
              new_s = ""
              # Process the string in chunks of size k
              for i in range(0, len(s), k):
                  # Extract the current group (last group may be smaller)
                  chunk = s[i:i + k]
                  # Sum the digits and convert back to string
                  chunk_sum = sum(int(c) for c in chunk)
                  new_s += str(chunk_sum)
              # Update s for the next round
              s = new_s
          return s
    explanation: |
      **Time Complexity:** O(n) — Each character is processed once per round, and the string shrinks significantly each round.

      **Space Complexity:** O(n) — We build new strings during processing.

      We simulate the process exactly as described: divide into groups of `k`, sum each group's digits, merge, and repeat until the length is at most `k`. Python's slicing makes the chunking straightforward.

  - approach_name: Simulation with List Join
    is_optimal: true
    code: |
      def digit_sum(s: str, k: int) -> str:
          while len(s) > k:
              # Build list of digit sums for each chunk
              parts = []
              for i in range(0, len(s), k):
                  chunk = s[i:i + k]
                  # Sum digits in this chunk
                  total = sum(int(c) for c in chunk)
                  parts.append(str(total))
              # Join all parts to form new string
              s = "".join(parts)
          return s
    explanation: |
      **Time Complexity:** O(n) — Same as the basic simulation.

      **Space Complexity:** O(n) — We store parts in a list before joining.

      This variant collects all chunk sums in a list and uses `"".join()` at the end of each round. In Python, this is often more efficient for building strings since it avoids creating intermediate string objects during concatenation.
