Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns Module 1 – How to approach a coding round

Getting unstuck: heuristics and using hints

Six heuristics to try when no approach comes to mind in a coding round, how to think aloud so that a hint helps, and how to turn a hint into code.

  • Intermediate
  • 40 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot

What you will learn

  • Apply six problem-solving heuristics when no approach to a coding problem comes to mind
  • Explain your current idea aloud so that an interviewer can aim a hint at the gap
  • Translate a hint into a concrete next step while keeping a working brute force

Before you start

On this page

Most coding rounds have a moment when the problem is clear, a brute force is on the screen and no better idea comes. What you do next is a skill you can practise. This lesson gives you six questions to ask a problem when no approach comes to mind and follows them through one problem as a conversation. Then it covers the other half of getting unstuck: thinking aloud so that a hint can help, and turning a hint into code without throwing away what already works.

Six heuristics for when nothing comes to mind

A heuristic is a question that often produces an idea, with no promise that it will. Each of these takes a few minutes with a pen and paper, so you can try several before you need a hint. Start with the first two: they cost the least, and what they show you makes the others easier.

  1. Solve a smaller case by hand. What would you do with three items, or with one? This often shows the work that your brute force repeats, and the edge cases.
  2. Draw the data. What does the input look like as a table, a timeline, a grid or a graph? Running totals, overlaps and neighbours show up, and sometimes a graph hiding in a list.
  3. Work backwards from the answer. If you already had the answer, what would be true of it? This often gives a target value to look for, or the last step of a recursion.
  4. Fix one variable, optimise the other. If this index or value were fixed, what would be the best choice for the rest? A nested loop often becomes one loop and a lookup.
  5. Look for something monotonic. What only grows, or only shrinks, as you move through the input? That allows an early stop, two pointers or a binary search.
  6. Relax a constraint, then add it back. Which rule makes the problem hard, and could you solve it without that rule? The simpler problem often has a solution that you can repair.

Asking yourself questions, rather than following recipes, is the approach of George Pólya’s How to Solve It, a classic book on solving problems. It was written about mathematics, and working backwards from the goal is one of its techniques. The habits carry over to algorithms, where the variable you fix, the quantity that only grows or the rule you drop often names the data structure that the fast solution needs.

A loop: try a heuristic on a small case out loud; with a plan, code it beside the brute force; without one, try another or take a hint.No approachcomes to mindTry the cheapestheuristic you havenot tried yet, on asmall case, out loudA plan?Code it besidethe brute forceand compareTake a hint andrestate it as anoperationyesnostill no aftera few tries

What to do when no approach comes to mind

Text description of the diagram

The diagram is a loop, read from top to bottom.

  1. It starts when no approach comes to mind.
  2. Try the cheapest heuristic you have not tried yet on a small case, and say what you are doing.
  3. Ask whether that gave you a plan. If yes, code the plan beside the brute force and compare the two.
  4. If not, go back to step 2 with the next heuristic.
  5. If there is still no plan after a few tries, take a hint, restate it as an operation on the data, and go back to step 2 to try it on the small case.

Two habits make the list work. Try each heuristic on a concrete input small enough to finish by hand, because that is where patterns show. And say which one you are trying, which is what the second half of this lesson is about.

A worked example: side A and side B

The problem

A playlist is going onto a tape with two sides, in order. Find a cut that gives side A (the first songs) and side B (the rest) the same total time, with at least one song on each side. Return how many songs go on side A, or -1 if no cut works. Song lengths are whole minutes, each at least 1, and there can be up to 100,000 songs.

Here is one way the conversation can go when the fast idea does not come at once. Where a step uses one of the six heuristics, a note in italics names it.

  1. You: “Let me check the rules: one cut, the songs keep their order, each side gets at least one song, and every length is at least one minute?”

    Interviewer: “Yes. And there can be up to 100,000 songs.”

  2. You: “The brute force tries every cut and adds up both sides. That’s about n additions for each of n cuts, so about ten billion for 100,000 songs: far too slow. I’ll write it anyway, because it’s correct and I can test a faster version against it.”

  3. You: “I don’t see the faster version yet, so let me do a small case by hand: songs of 3, 1, 2, 4 and 2 minutes, every cut, as a table.”

    Heuristics: solve a smaller case by hand, and draw the data.

A small case by hand, as a table Python · by_hand.py
"""Every cut of a five-song playlist, with the totals of both sides."""

lengths = [3, 1, 2, 4, 2]  # song lengths in minutes
total = sum(lengths)
print(f"playlist {lengths}, total {total} minutes")
print("songs on side A   side A   side B")
for k in range(1, len(lengths)):  # side A gets the first k songs
    side_a, side_b = sum(lengths[:k]), sum(lengths[k:])
    note = "   equal" if side_a == side_b else ""
    print(f"{k:>15}   {side_a:>6}   {side_b:>6}{note}")

Output

playlist [3, 1, 2, 4, 2], total 12 minutes
songs on side A   side A   side B
              1        3        9
              2        4        8
              3        6        6   equal
              4       10        2

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 by_hand.py

  1. You: “Side B is always 12 minus side A. So once the cut is fixed, I only need side A, and side B follows from the total.”

    Heuristic: fix one variable (the cut) and get the other from what you already know.

  2. Interviewer: “If a cut works, what do you know about side A?”

  3. You: “The two sides are equal, so side A is exactly half the total: 6 here. And an odd total can’t be halved, so then the answer is -1 straight away.”

    Heuristic: work backwards from the answer.

  4. You: “Moving the cut one song to the right adds exactly that song to side A. So a running total gives me side A for every cut in one pass: O(n) time and O(1) extra memory.”

  5. You: “And because every length is positive, the running total only grows. Once it passes half, no later cut can work, so I can stop there.”

    Heuristic: look for something monotonic.

Here are both versions in code. split_fast is the plan of steps 4 to 8: the check for an odd total, a running total and the early stop.

The brute force and the fast version Python · side_split/split.py
"""Cut a playlist into two sides that play for the same time."""


def split_brute(lengths):
    """Try every cut, adding up both sides from scratch: about n * n additions."""
    for k in range(1, len(lengths)):  # k songs on side A
        if sum(lengths[:k]) == sum(lengths[k:]):
            return k
    return -1


def split_fast(lengths):
    """Side A must be half the total, and each cut adds one song to it: O(n)."""
    total = sum(lengths)
    if total % 2 == 1:  # an odd total cannot be cut into equal halves
        return -1
    half = total // 2
    side_a = 0
    for k in range(1, len(lengths)):  # k songs on side A, at least one on B
        side_a += lengths[k - 1]
        if side_a == half:
            return k
        if side_a > half:  # lengths are positive: side A only grows
            return -1
    return -1


if __name__ == "__main__":
    playlists = [[3, 1, 2, 4, 2], [5, 5], [1, 2, 4], [2, 3], [7]]
    print([split_fast(p) for p in playlists])

Output

[3, 1, -1, -1, -1]

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 split.py

The demo covers the edge cases too: [5, 5] has a cut after one song, [1, 2, 4] and [2, 3] have odd totals, and [7] has nowhere to cut. If you prefer a library call to the loop, itertools.accumulate gives the same running totals.

Notice what made the single hint in step 5 work. Because steps 2 to 4 were said aloud, the interviewer knew that a correct brute force existed and that you had already seen side B as the total minus side A. The question could aim at the next idea that was missing.

Keep the brute force and test against it

The brute force does exactly what the problem says, so it is easy to trust, and the fast version has to give the same answers. A stress test runs both on many small random inputs, where the brute force is quick, and stops at the first disagreement:

A stress test against the brute force Python · side_split/stress.py
"""Compare split_fast with split_brute on 1,000 small random playlists."""
import random

from split import split_brute, split_fast

rng = random.Random(2)  # a fixed seed: the same playlists on every run
with_a_cut = 0
for case in range(1000):
    lengths = [rng.randint(1, 6) for _ in range(rng.randint(1, 8))]
    expected, got = split_brute(lengths), split_fast(lengths)
    if got != expected:
        print(f"case {case}: {lengths}: brute force {expected}, split_fast {got}")
        raise SystemExit(1)
    if expected != -1:
        with_a_cut += 1
print(f"1000 playlists, {with_a_cut} of them with a cut: no mismatches")

Output

1000 playlists, 140 of them with a cut: no mismatches

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 stress.py

The fixed seed makes every run test the same 1,000 playlists. The count in the output matters as well: 140 of them have a cut that works, so the test compared real answers and not only -1.

Version note

A seed gives the same random numbers every time on one version of Python. Across versions, the documentation of the random module promises the same sequence only for random() itself, and most of its other functions may change; randint(), used here, is one of them. So when a stress test fails, print the failing input itself, as this one does, and keep it as a test case: the seed may not reproduce it on another version.

A common mistake: halving with //

This fast version looks right and gives the answer 3 for the playlist of the conversation. It halves the total with // and leaves out the check for an odd total. The same stress test finds the problem in the fifth playlist it tries:

The stress test catches a missing check Python · side_split/stress_floor.py
"""The same stress test on a plausible bug: // and no check for an odd total."""
import random

from split import split_brute


def split_floor(lengths):
    """split_fast without its check for an odd total."""
    half = sum(lengths) // 2  # 7 // 2 is 3: an odd total is rounded down
    side_a = 0
    for k in range(1, len(lengths)):
        side_a += lengths[k - 1]
        if side_a == half:
            return k
        if side_a > half:
            return -1
    return -1


rng = random.Random(2)
for case in range(1000):
    lengths = [rng.randint(1, 6) for _ in range(rng.randint(1, 8))]
    expected, got = split_brute(lengths), split_floor(lengths)
    if got != expected:
        print(f"case {case}: {lengths}: brute force {expected}, split_floor {got}")
        a, b = sum(lengths[:got]), sum(lengths[got:])
        print(f"with {got} songs on side A, side A plays {a} and side B {b}")
        raise SystemExit(1)
print("1000 playlists: no mismatches")

Output (exit status 1)

case 4: [5, 4, 5, 3, 1, 1]: brute force -1, split_floor 2
with 2 songs on side A, side A plays 9 and side B 10

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 stress_floor.py

The total is 19, and 19 // 2 is 9, so the function reports the cut where side A reaches 9 minutes and leaves 10 on side B. A rounded-down half is not a half. The fix is the line that split_fast has and this version lacks: return -1 when the total is odd.

Keeping the brute force matters most when time is short. On some online-assessment platforms each hidden test case is worth its own points, and your score is the sum over the cases that pass: HackerRank’s documentation of its coding questions describes exactly this. A correct slow solution then scores on every case it finishes in time, while a fast one that is half written scores nothing. So submit the version that works first, then improve it in a new function beside it.

Not affiliated

Based on public information about HackerRank. MySmartCoPilot is not affiliated with HackerRank, and HackerRank’s real scoring rules may differ from what this lesson describes.

Think aloud so that a hint can help

An interviewer can only redirect what they can hear. While you think in silence, they cannot tell whether you are one step from the answer or heading into a dead end, so a hint comes late or aims at the wrong gap. Whenever your plan changes, say three things in a sentence or two: what you are trying, why it might work, and what would show you whether it does.

Instead of Try saying
Several minutes of silence “I’m checking whether sorting helps. It would change the order of the songs, which the problem keeps, so probably not.”
“I’m stuck.” “My brute force adds up side A again for every cut. I’m looking for a way to reuse the sum from the cut before.”
“That won’t work.” “A hash map doesn’t help yet, because I don’t know what to look up. If I knew the target for side A, it would.”
A silent guess “Can I check one thing: can the playlist be empty, and what should I return then?”

Thinking aloud does not mean talking without a break. It is fine to say “give me a minute to work this example” and write in silence, then say what the example showed. When you want a hint, ask a specific question: “Is a running total the right direction, or is there a better first step?” is easier to answer well than “Can you help me?”.

In an online assessment nobody hears you, but the habit still helps. A one-line comment with the idea you are trying keeps you from circling back to it, and the six heuristics are your hints. If none of them gives you a plan, move on to another question and come back to this one later.

Turn a hint into the next step

Hints usually arrive as questions, and a question is hard to code. Before you touch the code, restate the hint as an operation on the data, then try that operation on your small example.

The hint Restated as an operation Check before you rely on it
“What if the array were sorted?” Sort a copy, then compare neighbours or move two pointers inwards Do you need the original positions? Then sort (value, index) pairs
“If a cut works, what do you know about side A?” Compute the total once and look for a side A of half of it An odd total has no answer
“What changes from one step to the next?” Keep a running value and update it by one item per step What is the value before the first step?
“Can you avoid the inner loop?” Replace it with a lookup in a set or dict of what you have seen What exactly is the key you look up?
“What does your brute force compute twice?” Store it the first time: a prefix sum, a table or a cache How much memory will it take?

A lookup in a Python set or dict takes constant time on average (the documentation’s table of time complexity gives O(1) for x in s), which is why replacing an inner loop with one can turn O(n²) into O(n).

Then change the plan, not the whole program. A hint that sounds like a new direction usually replaces one loop. Write the new idea as a new function next to the brute force, run both on the small example, then run the stress test. If the idea fails, you still have working code, and the interviewer has seen you test before you trust.

A hint ladder for the playlist problem

When you practise alone, a hint ladder plays the interviewer’s part: hints written in order, from the lightest nudge to an almost complete plan, and opened one at a time only when you are stuck. Here is one for the playlist problem, with what each rung changes in the plan.

Hint Restated as an operation What changes
Rung 1: if a cut works, what do you know about side A? Compute the total; side A must be half of it, and an odd total means -1 Each cut needs side A only
Rung 2: what changes from one cut to the next? Add one song to a running total at each cut One pass instead of a sum for every cut
Rung 3: the lengths are positive, so what does that say about side A? Stop once side A is past half An early stop, and at most one cut can work
Rung 4: keep a running total and return the cut where it equals half. Nothing left to restate The finished plan

How much work does each rung save? This program counts the additions made by the plan after each rung, on two playlists of 1,000 songs: one with an even total and no cut that works, and one with an odd total.

Additions made after each hint Python · side_split/hint_ladder.py
"""Count the additions each plan of the hint ladder makes on 1,000 songs."""

additions = 0


def add(a, b):
    """a + b, counted."""
    global additions
    additions += 1
    return a + b


def total_of(songs):
    total = 0
    for length in songs:
        total = add(total, length)
    return total


def plan0(lengths):
    """No hint yet: try every cut, adding up both sides from scratch."""
    for k in range(1, len(lengths)):
        if total_of(lengths[:k]) == total_of(lengths[k:]):
            return k
    return -1


def plan1(lengths):
    """Hint 1: side A must be half the total, so an odd total has no cut."""
    total = total_of(lengths)
    if total % 2 == 1:
        return -1
    for k in range(1, len(lengths)):
        if total_of(lengths[:k]) == total // 2:
            return k
    return -1


def plan2(lengths):
    """Hint 2: each cut adds one song to side A, so keep a running total."""
    total = total_of(lengths)
    if total % 2 == 1:
        return -1
    side_a = 0
    for k in range(1, len(lengths)):
        side_a = add(side_a, lengths[k - 1])
        if side_a == total // 2:
            return k
    return -1


def plan3(lengths):
    """Hint 3: the lengths are positive, so stop once side A is past half."""
    total = total_of(lengths)
    if total % 2 == 1:
        return -1
    side_a = 0
    for k in range(1, len(lengths)):
        side_a = add(side_a, lengths[k - 1])
        if side_a == total // 2:
            return k
        if side_a > total // 2:
            return -1
    return -1


playlists = {
    # Total 1998, so half is 999. Side A runs 2, 4, ..., 1000 and then
    # 1001, 1003, ...: it never equals 999.
    "even, no cut": [2] * 500 + [1] + [2] * 498 + [1],
    "odd total": [2] * 999 + [1],
}
print("additions" + "".join(f"{name:>16}" for name in playlists))
for plan in (plan0, plan1, plan2, plan3):
    counts = []
    for lengths in playlists.values():
        additions = 0
        assert plan(lengths) == -1  # no plan finds a cut in either playlist
        counts.append(additions)
    print(f"{plan.__name__:<9}" + "".join(f"{count:>16,}" for count in counts))

Output

additions    even, no cut       odd total
plan0             999,000         999,000
plan1             500,500           1,000
plan2               1,999           1,000
plan3               1,500           1,000

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 hint_ladder.py

The second rung is the big one: it turns about n²/2 additions into about 2n. The first pays off at once when the total is odd, and the third saves another quarter here by stopping halfway. Counts like these come out the same on every computer, which timings do not.

Practise with the exercise

The exercise below is a harder relative of the playlist problem, and it comes with a hint. Work it the way this lesson suggests: set a time limit, write a brute force and pass the sample tests with it, try the heuristics on a small playlist, and open the hint only when the time is up. Before you code the hint, write it down as an operation.

Timer Set a time limit for each attempt, so that you open the hint when you planned to and not before. Python Online Compiler Time your solution to the exercise on a long random playlist, with nothing to install.

Key takeaways

  • When no approach comes to mind, ask the problem questions: a smaller case by hand, the data drawn as a table, the answer worked backwards, one variable fixed, something monotonic, a constraint relaxed. Try the cheap ones first, on an input small enough to finish.
  • Say what you are trying, why, and what would show that it works: an interviewer can only aim a hint at a gap they can hear.
  • Restate each hint as an operation on the data and try it on your small case before you code it.
  • Keep the brute force runnable. It earns the points of the test cases it passes, and it is the reference that your stress test compares the fast version with.
  • When a stress test fails, print the failing input and keep it as a test case.

Exercise

Exercise · Medium · Python

Drop one song so that both sides play equally long

A playlist is meant for a tape with two sides, but it is one song too long. Drop exactly one song; the songs that are left keep their order. Then cut them into side A (the first part) and side B (the rest) so that both sides play for the same total time. Each side needs at least one song.

Write drop_one(lengths). lengths holds the length of every song in whole seconds, each at least 1, and a playlist can have up to 100,000 songs. Return a pair (dropped, side_a): dropped is the position of the song you drop in lengths, counting from 0, and side_a is how many of the remaining songs go on side A. When several answers work, return any one of them; when none does, return None.

drop_one([4, 1, 2, 3])  # (2, 1): [4, 1, 3] becomes [4] and [1, 3]; (0, 2) is right too
drop_one([1, 2, 4])     # None

Use it to practise the routine of the lesson:

  1. Write a brute force first, one that tries every song to drop and every cut, and make the sample tests pass with it. Keep it in the file under another name.
  2. Try the heuristics on a small playlist. If no faster plan comes after a few minutes, open the hint and write it down, in a comment, as an operation on the list.
  3. Write the fast version beside the brute force, and compare the two on random short playlists before you trust it.

The sample tests use short playlists only. With 100,000 songs a brute force is far too slow, so aim for one or two passes over the list.

Starter code · drop.py

def drop_one(lengths):
    """Drop one song so that the rest cuts into two sides of equal total time.

    Return (dropped, side_a): the position of the dropped song in lengths,
    counting from 0, and how many of the remaining songs go on side A.
    Return None when no single drop makes such a cut possible.
    """
    # Your code here: a brute force first, then a faster version beside it.
    return None
The sample tests · test_drop.py
from drop import drop_one


def sides(lengths, answer):
    """The totals of side A and side B after the drop and cut that answer names."""
    assert answer is not None, "drop_one returned None, but a song can be dropped here"
    assert isinstance(answer, tuple), "return a pair (dropped, side_a)"
    assert len(answer) == 2, "return a pair (dropped, side_a)"
    dropped, side_a = answer
    assert 0 <= dropped < len(lengths), f"there is no song at position {dropped}"
    rest = lengths[:dropped] + lengths[dropped + 1 :]
    assert 1 <= side_a <= len(rest) - 1, f"side A gets {side_a} of {len(rest)} songs: each side needs one"
    return sum(rest[:side_a]), sum(rest[side_a:])


def test_example():
    """balances [4, 1, 2, 3], the example of the prompt"""
    a, b = sides([4, 1, 2, 3], drop_one([4, 1, 2, 3]))
    assert a == b, "side A and side B play for different times"


def test_drop_before_the_cut():
    """drops the first song of [9, 2, 2], the only answer"""
    a, b = sides([9, 2, 2], drop_one([9, 2, 2]))
    assert a == b, "side A and side B play for different times"


def test_drop_after_the_cut():
    """drops the last song of [2, 2, 9], the only answer"""
    a, b = sides([2, 2, 9], drop_one([2, 2, 9]))
    assert a == b, "side A and side B play for different times"


def test_drop_in_the_middle():
    """drops the 7 from [3, 7, 1, 2]"""
    assert drop_one([3, 7, 1, 2]) == (1, 1)


def test_same_length_on_both_sides():
    """drops the second 2 of [2, 1, 2, 1]: without the first 2, no cut gives equal sides"""
    assert drop_one([2, 1, 2, 1]) == (2, 1)


def test_equal_songs():
    """balances three songs of the same length"""
    a, b = sides([3, 3, 3], drop_one([3, 3, 3]))
    assert a == b, "side A and side B play for different times"


def test_no_answer():
    """returns None when no single drop balances the sides"""
    assert drop_one([1, 2, 4]) is None
    assert drop_one([6, 1, 1, 4]) is None


def test_too_short():
    """returns None for one or two songs: what is left cannot be cut in two"""
    assert drop_one([5]) is None
    assert drop_one([5, 5]) is None


def test_longer_playlists():
    """finds the only answer of two 12-song playlists, once on each side"""
    first = [241, 183, 171, 151, 186, 242, 154, 155, 214, 293, 267, 248]
    second = [230, 174, 170, 233, 254, 194, 232, 239, 160, 229, 311, 323]
    assert drop_one(first) == (3, 6)
    assert drop_one(second) == (7, 6)
A hint

Cut the playlist first, before you drop anything, and compare the two sides. If side A plays 3 seconds longer than side B, which song could you drop to balance them, and on which side would it have to be? Work it out by hand for each of the three cuts of [4, 1, 2, 3].

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Check yourself

7 questions about this lesson. Every answer and why it is right is on the page, behind “Show the answer”. Your score stays in this browser.

  1. Question 1 of 7 Stuck on the playlist problem, you write out every cut of [3, 1, 2, 4, 2] with the totals of both sides. Which heuristic is that?

    Choose one answer.

    Show the answer to question 1

    Answer: Solving a smaller case by hand, with the data drawn as a table

    Five songs are few enough to work through by hand, and the table is a drawing of the data. It is what shows that side B is always the total minus side A, the observation the faster plan starts from.

  2. Question 2 of 7 The interviewer asks: “What changes from one cut to the next?” Which next step restates that hint as an operation?

    Choose one answer.

    Show the answer to question 2

    Answer: Keep a running total of side A and add one song to it at each cut

    Moving the cut one song to the right adds exactly that song to side A, so a running total gives side A for every cut in one pass. Sorting would change the order of the songs, which the problem keeps.

  3. Question 3 of 7 split.py runs split_fast on the playlists [3, 1, 2, 4, 2], [5, 5], [1, 2, 4], [2, 3] and [7]. What does it print?

    What does this program print? Choose one answer.

    """Cut a playlist into two sides that play for the same time."""
    
    
    def split_brute(lengths):
        """Try every cut, adding up both sides from scratch: about n * n additions."""
        for k in range(1, len(lengths)):  # k songs on side A
            if sum(lengths[:k]) == sum(lengths[k:]):
                return k
        return -1
    
    
    def split_fast(lengths):
        """Side A must be half the total, and each cut adds one song to it: O(n)."""
        total = sum(lengths)
        if total % 2 == 1:  # an odd total cannot be cut into equal halves
            return -1
        half = total // 2
        side_a = 0
        for k in range(1, len(lengths)):  # k songs on side A, at least one on B
            side_a += lengths[k - 1]
            if side_a == half:
                return k
            if side_a > half:  # lengths are positive: side A only grows
                return -1
        return -1
    
    
    if __name__ == "__main__":
        playlists = [[3, 1, 2, 4, 2], [5, 5], [1, 2, 4], [2, 3], [7]]
        print([split_fast(p) for p in playlists])
    Show the answer to question 3

    Answer: it prints

    [3, 1, -1, -1, -1]

    Only [3, 1, 2, 4, 2] (three songs on side A, 6 minutes a side) and [5, 5] (one song a side) can be cut. [1, 2, 4] and [2, 3] have odd totals, and [7] has no cut that leaves a song on each side. A version that halves the total with // and has no check for an odd total returns 2 and 1 for the two odd playlists.

  4. Question 4 of 7 You are stuck on the playlist problem in a live round. Which of these are useful to say aloud?

    Choose every answer that is right.

    Show the answer to question 4

    Answer:

    • “My brute force adds up side A again for every cut; I'm looking for a way to reuse the last sum.”
    • “Can I check one thing: is every length at least one minute?”
    • “I'm checking whether sorting helps; the order of the songs matters here, so I doubt it.”

    Each useful sentence says what you are trying and why, or checks a fact that the algorithm depends on, so the interviewer can confirm it or redirect you with a hint. Silence gives them nothing to work with, and an apology tells them nothing about your thinking.

  5. Question 5 of 7 Put these hints for the playlist problem in the order a hint ladder gives them, from the lightest nudge to the near-solution.

    Give each item its position, from 1 (first).

    Show the answer to question 5

    Answer:

    1. If a cut works, what do you know about side A?
    2. What changes from one cut to the next?
    3. The lengths are positive: what does that say about side A as the cut moves?
    4. Keep a running total and return the cut where it equals half the total.

    Each rung gives away a little more: the first points at the target (half the total), the second at the work the brute force repeats, the third at the running total that only grows and allows an early stop, and the last is almost the solution itself.

  6. Question 6 of 7 An online assessment scores each hidden test case on its own. Ten minutes are left, and you have a correct brute force that passes the sample tests and a fast version that is half written. What should you do first?

    Choose one answer.

    Show the answer to question 6

    Answer: Submit the correct brute force, then go on with the fast version in a new function beside it

    Where every test case scores on its own, the correct slow version earns the points of every case it finishes in time, and an unfinished fast version earns none. Keep the brute force afterwards too: it is the reference you test the fast version against.

  7. Question 7 of 7 This version has no check for an odd total. For which playlist does it return a wrong answer?

    Read the code, then choose one answer.

    def split_floor(lengths):
        half = sum(lengths) // 2
        side_a = 0
        for k in range(1, len(lengths)):
            side_a += lengths[k - 1]
            if side_a == half:
                return k
            if side_a > half:
                return -1
        return -1
    Show the answer to question 7

    Answer: [1, 2]

    The total of [1, 2] is 3, so half is 3 // 2, which is 1. Side A reaches 1 after the first song and the function returns 1, although side B then plays for 2 minutes; the right answer is -1. [2, 2] and [1, 1, 2] have even totals and real cuts (1 and 2), and [3] has no cut to try.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.