title: Calculate Money in Leetcode Bank
slug: calculate-money-in-leetcode-bank
difficulty: easy
leetcode_id: 1716
leetcode_url: https://leetcode.com/problems/calculate-money-in-leetcode-bank/
categories:
  - math
patterns:
  - slug: prefix-sum
    is_optimal: true

function_signature: "def total_money(n: int) -> int:"

test_cases:
  visible:
    - input: { n: 4 }
      expected: 10
    - input: { n: 10 }
      expected: 37
    - input: { n: 20 }
      expected: 96
  hidden:
    - input: { n: 1 }
      expected: 1
    - input: { n: 7 }
      expected: 28
    - input: { n: 8 }
      expected: 30
    - input: { n: 14 }
      expected: 63
    - input: { n: 100 }
      expected: 678
    - input: { n: 1000 }
      expected: 7089

description: |
  Hercy wants to save money for his first car. He puts money in the Leetcode bank **every day**.

  He starts by putting in `$1` on Monday, the first day. Every day from Tuesday to Sunday, he will put in `$1` more than the day before. On every subsequent Monday, he will put in `$1` more than the **previous Monday**.

  Given `n`, return *the total amount of money he will have in the Leetcode bank at the end of the* `n`<sup>th</sup> *day*.

constraints: |
  - `1 <= n <= 1000`

examples:
  - input: "n = 4"
    output: "10"
    explanation: "After the 4th day, the total is 1 + 2 + 3 + 4 = 10."
  - input: "n = 10"
    output: "37"
    explanation: "After the 10th day, the total is (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4) = 37. Notice that on the 2nd Monday, Hercy only puts in $2."
  - input: "n = 20"
    output: "96"
    explanation: "After the 20th day, the total is (1 + 2 + 3 + 4 + 5 + 6 + 7) + (2 + 3 + 4 + 5 + 6 + 7 + 8) + (3 + 4 + 5 + 6 + 7 + 8) = 96."

explanation:
  intuition: |
    Think of this problem like filling a piggy bank with a predictable pattern. Each week forms a mini arithmetic sequence starting from a different base value.

    The **key insight** is recognising the repeating weekly structure. The first week contributes `1 + 2 + 3 + 4 + 5 + 6 + 7 = 28`. The second week contributes `2 + 3 + 4 + 5 + 6 + 7 + 8 = 35`. Each complete week adds `7` more than the previous week (because every day that week starts `$1` higher).

    So if you have `k` complete weeks, you're summing `28, 35, 42, ...` — an arithmetic sequence where each term increases by `7`. After the complete weeks, you may have some leftover days forming a partial week.

    The mental model: **split the problem into complete weeks plus remaining days**, then use arithmetic series formulas to compute each part efficiently.

  approach: |
    We solve this using a **Mathematical Formula Approach**:

    **Step 1: Calculate complete weeks and remaining days**

    - `complete_weeks`: Divide `n` by `7` to get the number of full weeks
    - `remaining_days`: Use `n % 7` to get the leftover days in the partial week

    &nbsp;

    **Step 2: Sum all complete weeks**

    - The 1<sup>st</sup> week sums to `1 + 2 + ... + 7 = 28`
    - The 2<sup>nd</sup> week sums to `2 + 3 + ... + 8 = 35`
    - The k<sup>th</sup> week sums to `28 + 7*(k-1)`
    - Total for `k` complete weeks: sum of arithmetic sequence with first term `28`, common difference `7`, and `k` terms
    - Formula: `k * 28 + 7 * (0 + 1 + 2 + ... + (k-1))` = `k * 28 + 7 * k * (k-1) / 2`

    &nbsp;

    **Step 3: Sum the remaining days**

    - The partial week starts on the `(complete_weeks + 1)`<sup>th</sup> Monday
    - First day of partial week = `complete_weeks + 1`
    - Sum `remaining_days` consecutive values starting from that base
    - Formula: `remaining_days * base + (0 + 1 + ... + (remaining_days - 1))`
    - Simplifies to: `remaining_days * base + remaining_days * (remaining_days - 1) / 2`

    &nbsp;

    **Step 4: Return total**

    - Add the complete weeks sum and remaining days sum

  common_pitfalls:
    - title: Simulating Day by Day
      description: |
        A naive approach simulates each day individually:

        ```python
        total = 0
        for day in range(1, n + 1):
            week = (day - 1) // 7
            day_of_week = (day - 1) % 7
            total += week + 1 + day_of_week
        ```

        While this works and passes given the small constraint (`n <= 1000`), it's O(n) when an O(1) mathematical solution exists. Understanding the formula approach builds skills for harder problems where simulation would be too slow.
      wrong_approach: "Loop through each day"
      correct_approach: "Use arithmetic series formulas"

    - title: Off-by-One Errors in Week Calculation
      description: |
        Be careful with zero-indexing vs one-indexing. Day 1 is Monday of week 1 (not week 0). Day 7 is still week 1, but day 8 is week 2.

        Using `(day - 1) // 7` gives week index starting from 0, while `(day - 1) % 7` gives day-of-week index (0 = Monday, 6 = Sunday).
      wrong_approach: "Confusing which day belongs to which week"
      correct_approach: "Use (day - 1) // 7 for zero-indexed week number"

    - title: Forgetting the Base Increment
      description: |
        Each week's starting value increases by 1. Week 1 starts at `$1`, week 2 starts at `$2`, etc. The partial week at the end must use `complete_weeks + 1` as its starting value, not `1`.

        For `n = 10`, the partial week (days 8-10) starts at `$2`, not `$1`.

  key_takeaways:
    - "**Arithmetic series formula**: Sum of `1 + 2 + ... + k` is `k * (k + 1) / 2` — memorise this for many math problems"
    - "**Pattern recognition**: Breaking a problem into repeating units (weeks) plus a remainder is a common technique"
    - "**O(1) vs O(n)**: Even when simulation passes, deriving a closed-form solution demonstrates deeper understanding"
    - "**Related problems**: This pattern appears in problems involving periodic contributions, interest calculations, and cyclic sequences"

  time_complexity: "O(1). We use constant-time arithmetic operations regardless of the input size."
  space_complexity: "O(1). We only store a few integer variables for calculations."

solutions:
  - approach_name: Mathematical Formula
    is_optimal: true
    code: |
      def total_money(n: int) -> int:
          # Calculate complete weeks and remaining days
          complete_weeks = n // 7
          remaining_days = n % 7

          # Sum of complete weeks using arithmetic series
          # Each week sums to 28 + 7*(week_index) for week_index 0, 1, 2, ...
          # Total = k*28 + 7*(0 + 1 + ... + (k-1)) = k*28 + 7*k*(k-1)/2
          weeks_sum = complete_weeks * 28 + 7 * complete_weeks * (complete_weeks - 1) // 2

          # Sum of remaining days in partial week
          # Base value for the partial week is (complete_weeks + 1)
          base = complete_weeks + 1
          # Sum of arithmetic sequence: base, base+1, ..., base+(remaining_days-1)
          partial_sum = remaining_days * base + remaining_days * (remaining_days - 1) // 2

          return weeks_sum + partial_sum
    explanation: |
      **Time Complexity:** O(1) — Only arithmetic operations, no loops.

      **Space Complexity:** O(1) — Only a few integer variables.

      We decompose the problem into complete weeks and a partial week, then apply arithmetic series formulas to compute each sum directly.

  - approach_name: Simulation
    is_optimal: false
    code: |
      def total_money(n: int) -> int:
          total = 0
          day = 1

          while day <= n:
              # Calculate which week we're in (0-indexed)
              week = (day - 1) // 7
              # Calculate day of the week (0 = Monday, 6 = Sunday)
              day_of_week = (day - 1) % 7

              # Amount deposited = base for this week + day offset
              # Week 0 starts at $1, week 1 at $2, etc.
              amount = (week + 1) + day_of_week
              total += amount
              day += 1

          return total
    explanation: |
      **Time Complexity:** O(n) — We iterate through each day from 1 to n.

      **Space Complexity:** O(1) — Only tracking a running total.

      This straightforward simulation calculates the deposit for each day based on which week it falls in. While correct, it's less elegant than the formula approach. Useful for verifying the mathematical solution.
