The short version: algorithms tell you how to think about a problem, and AI makes each step faster. Decide which problem type you are facing first, hand the most time-consuming step to AI, then check the result yourself.
Why problem-solving patterns carry over to life
After a full round of LeetCode, what stuck with me was not any particular solution. It was a handful of reflexes I use when reading a problem:
- What are the constraints: time, money, energy, things that are off the table.
- What am I maximizing or minimizing: efficiency, cost, regret, risk.
- What can I give up: perfection, getting it right the first time, other people's expectations.
Interview problems spell these three things out for you. Everyday decisions have the same three things; nobody writes them down. So this post is not about turning your life into code. It uses problem types as a shortcut for recognizing a situation. Once you see which kind of problem something resembles, you roughly know how to approach it and which traps to avoid.
AI has a simple role here: it lowers the cost of each step. Looking things up, listing options, doing the arithmetic, tidying records and writing first drafts are all things AI does quickly. But deciding which problem type this is, when to stop, and which result is acceptable is still up to you.
How to read this post
To keep things concrete, every example follows the same fictional person: Ming, an office worker in Taipei in his late twenties. He runs into the kind of things most people deal with day to day. Sometimes he asks his friend Hua for help, and some situations involve his family. The situations are made up, and the numbers are set for illustration.
The twenty algorithms fall into five groups, and every section follows the same structure:
- Signal in a problem: the words in a coding problem that point to it
- In daily life: a few common situations
- How to apply it: steps you can follow
- Example: a concrete situation Ming runs into, with numbers
- Diagram: a picture of how the algorithm works step by step on that example, with a caption underneath that tells you how to read it
- Where AI helps: which step AI is good for, followed by a "Ming could ask:" prompt you can copy and adapt to your own situation
- Common misuses: when it goes wrong
Each of the twenty algorithms solves one shape of problem, but a real goal usually has several shapes at once. So the section just before Further reading, titled "Putting it together, an algorithm that grows a strategy from your goal", combines them into one algorithm: you give it your goal and your current situation, and it picks which algorithms to use and in what order to connect them, growing a better strategy. That section also comes with a detailed explanation and diagrams.
There is no need to read it all at once. Look at the overview below, pick a situation you ran into recently, and jump to that section. If you want to see how everything fits together first, jump straight to the "Putting it together" section just before Further reading.
The big picture
Reading records without being fooled by noise
Picking from many options
What first and how to schedule
Big things into small, scattered things together
Habits, space and retries
Group one, reading data
The most common everyday mistake is drawing conclusions from a single day or a single data point. This group is about how to read your records.
Sliding window and two pointers, look at recent days instead of today
Signal in a problem: "consecutive", "the last k", "within a range", "two sorted lists", as in LC 643 for the average of a fixed-length window and LC 986 for interval intersections.
In daily life
- Practice time, sleep, spending and mood jump around every day. Look only at today, and skipping practice yesterday feels like everything is ruined, while one smooth session feels like the problem is solved.
- You want to find a time to meet someone, and each of you has a list of free slots. You need the overlap.
How to apply it
- Pick a window length: 7 days for things that change quickly, 14 to 30 days for habits.
- Each day, add the newest day and drop the oldest, and look only at the average or completion rate inside the window. You do not need to add up the whole window again: new total = yesterday's total − the day dropped + the day added.
- Compare windows with windows, such as this week against last week, never single days with single days.
- For two pointers, sort both lists by time and point one pointer at the start of each. Check whether the two current slots overlap, then advance whichever slot ends first. This is LC 986, Interval List Intersections.
Example: Ming is learning the guitar, and his goal is "an average of at least 20 minutes of practice a day over the last 7 days". Over 10 days he practises 20, 25, 0, 20, 30, 15, 30, 10, 0 and 5 minutes. On day 3 he works late and skips practice, and looking only at that day, the 0 makes it easy to feel that everything is wasted. But on day 7 the last 7 days add up to 140 minutes, an average of 20.0, exactly on target. After that, each day takes one subtraction and one addition. On day 8 he drops day 1's 20 and adds day 8's 10, so the total becomes 130 and the average about 18.6. On day 9 he drops day 2's 25 and adds 0: total 105, average 15.0. On day 10 he drops day 3's 0 and adds 5: total 110, average about 15.7. Day 3's zero is carried by the other six days, so the average is still 20.0; one low day on day 8 only nudges it down to 18.6; three low days in a row from day 8 pull the averages on days 9 and 10 to about 15, which clearly shows. The average on day 10 is slightly higher than on day 9 only because the day that left the window happened to be day 3's 0. It does not mean he is back on track. What he should look at is what changed in his life from day 8 on.
| Day 1 | Day 2 | Day 3 | Day 4 | Day 5 | Day 6 | Day 7 | Day 8 | Day 9 | Day 10 | |
|---|---|---|---|---|---|---|---|---|---|---|
| Day 7 | in | in | in | in | in | in | new | |||
| Day 8 | drop | in | in | in | in | in | in | new | ||
| Day 9 | drop | in | in | in | in | in | in | new | ||
| Day 10 | drop | in | in | in | in | in | in | new |
Arranging a meeting is a two-pointer job. Ming and Hua want to meet for an hour on Saturday to decide whether to sign up for a guitar class together. Ming is free 9:00–11:00, 13:00–15:00 and 16:00–18:00; Hua is free 10:00–12:00 and 14:00–17:00. Both lists are already sorted by time. Comparison 1 puts 9:00–11:00 against 10:00–12:00 and finds an overlap at 10:00–11:00; Ming's slot ends first, so Ming's pointer moves to the next slot. Comparison 2 puts 13:00–15:00 against 10:00–12:00: no overlap, and Hua's slot ends first, so Hua's pointer moves on. Comparison 3 puts 13:00–15:00 against 14:00–17:00 and finds 14:00–15:00; Ming's slot ends first, so Ming's pointer moves on. Comparison 4 puts 16:00–18:00 against 14:00–17:00 and finds 16:00–17:00; Hua's slot ends first, and Hua's list is used up, so they stop. Four comparisons find all three overlaps. With m slots in one list and n in the other, you never need more than m + n − 1 comparisons: for 30 and 40 slots that is at most 69, instead of checking all 1,200 pairs.
Ming 9:00–11:00, Hua 10:00–12:00
Ming 13:00–15:00, Hua 10:00–12:00
Ming 13:00–15:00, Hua 14:00–17:00
Ming 16:00–18:00, Hua 14:00–17:00
Stop after 4 comparisons, 3 overlaps found
Where AI helps: the arithmetic and spotting outliers. Scheduling works the same way: paste both lists of free slots and ask for every overlapping slot.
Ming could ask:
Below are the minutes I practised the guitar on each of the last 21 days, one line per day, with a note for each day (such as working late, dinner out, a cold). Compute the 7-day moving average for each day, list the 3 days whose minutes differ most from the average of the previous 7 days, and match them against the notes to suggest possible causes. Do not give generic practice advice.
Common misuses: a window that is too short, so you are still pushed around by noise, or one that is too long, so a real decline takes weeks to show. For two pointers, both lists must be sorted by time first; moving the pointers through unsorted lists misses overlaps.
Further reading: Two pointers and sliding windows
Prefix sums, always know the running total
Signal in a problem: "range sum", "from the start until now", "subarray sum equals k", as in LC 303 and LC 560.
In daily life
- How much of this month's budget is left, and will you overspend at the current pace?
- You want to read 24 books this year: how many have you read so far, and are you ahead or behind?
- The total over any stretch of time: how much you spent, or how many hours you practised an instrument, from last Wednesday to this Tuesday.
How to apply it
- When you record each day, also record a running total: today's total equals yesterday's total plus today's number.
- For the total over a range, subtract the running total on the day before the range from the running total on its last day, instead of adding up every day.
- Put the running total next to an "ideal pace" line, and you can see whether you are ahead or behind. Ideal pace = total budget ÷ number of days × days elapsed.
- To see how much you can still spend each day: (total budget − today's running total) ÷ days left.
Example: Ming's living budget for September is 15,000, and September has 30 days, so the ideal pace is 500 a day. Each time he logs his spending he also writes down the running total: 3,200 on day 6, 5,300 on day 9, 7,000 on day 12, 10,500 on day 17 and 11,400 on day 18. The ideal pace for day 18 is 9,000, so he has already spent 2,400 more than that. The 3,600 left has to last 12 days, which allows only 300 a day. At his current pace of about 633 a day (11,400 ÷ 18), he would reach 19,000 by the end of the month, 4,000 over budget. To find out how much he spent from day 10 to day 17, he subtracts the running total on day 9 from the one on day 17: 10,500 − 5,300 = 5,200, or 650 a day, 150 above the ideal pace. One subtraction gives the answer, with no need to add up eight days of spending one by one. A single day works the same way: day 18 alone cost 11,400 − 10,500 = 900, the day he had dinner with friends.
Where AI helps: turning a raw log into running totals and showing the gap to the ideal pace.
Ming could ask:
Below is my spending for each day from 1 to 18 September, one line per day with date, amount and category. My budget for the month is 15,000. Add a running total column, then estimate how much I will have spent by the end of the month at my current average pace. If that exceeds 15,000, list my three largest categories and the daily amount I need to stay under for the remaining 12 days. Also use differences of the running total to work out how much I spent on days 1 to 7, 8 to 14 and 15 to 18.
Common misuses: a few missed days keep the running total too low from then on. Fill missed days with a marked estimate instead of leaving them blank and treating them as zero. Another common slip is being off by one day: for days 10 to 17, subtract the running total of day 9, not day 10, or day 10's spending goes missing.
Further reading: LC 560 in Hashing and strings uses prefix sums
Monotonic stack, drop options that are beaten on every count
Signal in a problem: "next greater element", "how many days until it gets warmer", as in LC 739 and LC 496. The core idea: as you move forward, keep only the candidates that could still be the answer. Anything a newer option beats on every count never needs considering again.
In daily life
- Viewing flats, choosing a phone, looking for a job: options arrive one by one and you have to remember the earlier ones.
- Comparing prices: the same item shows up at different prices in different shops and at different times.
How to apply it
- Decide on the two or three criteria that matter most, and make sure they can be compared as numbers, such as rent and commute time for a flat.
- Each time a new option appears, compare it with the candidates on your list. If the new one is no worse than an old one on every criterion and better on at least one, remove the old one.
- The other way round: if a candidate already on the list is no worse than the new option on every criterion, the new one does not go on the list.
- Your list only ever holds options that have not been beaten on every count, and in the end you only weigh those few against one another.
Strictly speaking, the monotonic stack in LC 739 always pushes the new element and only pops beaten ones from the top; step 3, not adding a newcomer that is already beaten, extends the same idea to two criteria, which is called keeping only the non-dominated options.
Example: Ming is looking for a flat in Taipei and compares only two things: monthly rent and one-way commute time. Flat A costs 18,000 with a 40-minute commute, and goes on the candidate list first. Flat B costs 16,000 with 35 minutes, better on both counts, so A goes. Flat C costs 14,000 with 55 minutes: cheaper than B but further away, so each wins on something, and both stay. Flat D costs 15,000 with 30 minutes, better than B on both counts, so B goes; D and C each win on something, so both stay. Flat E costs 14,000 with 45 minutes: the same rent as C and a commute 10 minutes shorter, so C goes; E and D each win on something, so both stay. Flat F costs 17,000 with 50 minutes; D and E both beat it on both counts, so F never goes on the list. After six viewings only D and E remain, and Ming has a single question to answer: is paying 1,000 more a month worth a commute 15 minutes shorter each way? With 22 working days a month and two trips a day, that saves 15 × 2 × 22 = 660 minutes, or 11 hours, which works out to about 91 for each hour of commuting saved. Even after ten viewings, usually only two or three flats remain on the list.
Where AI helps: picking out the options that are not beaten from a long list.
Ming could ask:
Below are the 10 flats I have viewed over the past three weeks, each with monthly rent, one-way commute in minutes and floor area (lower rent and commute are better, larger floor area is better). If one flat is no worse than another on all three criteria and better on at least one, it "beats" the other. List the flats that no other flat beats, and explain the trade-off each one makes; for each flat that drops out, say which flat beats it.
Common misuses: too many criteria. With many criteria almost every option wins on something, and nothing gets eliminated. Keep only the two or three that actually change your decision. The opposite mistake is dropping options that merely trade off: as long as the old option is still better on one count, for example cheaper, it stays, or you throw away a real contender too early.
Group two, making choices
This group is about picking one option or a set of options, and about how much effort the picking deserves.
Hash table, turn common decisions into lookups
Signal in a problem: the same query keeps coming back, so you trade space for time, as in LC 1, Two Sum.
In daily life: every day you decide what to eat for breakfast, what to wear, what to buy at the supermarket, where to go at the weekend, whether to accept a certain kind of invitation. Each decision is small, but together they drain your energy.
How to apply it
- List the small decisions you made three or more times in a week.
- Write a default answer for each and keep it somewhere you see every day.
- When the question comes up, look it up instead of thinking it through again. You can change a default any time; you just do not start from zero.
- When a situation is not in the table, think it through once, then add the answer so you can look it up next time.
- Review once a month and update defaults that no longer fit.
Example: Ming kept notes for a week and found six kinds of small decision that each came up three or more times, 25 times in total: weekday breakfast 5 times, lunch 5 times, what to wear tomorrow 5 times, last-minute requests from colleagues 4 times, what to do at the weekend 3 times, and whether to buy something online 3 times. He wrote a default answer for each and kept them in the first note on his phone. The next week the same questions came up 25 times again; 21 times he simply followed the table. The other 4 were situations the table did not cover, such as not wanting to go out for breakfast on a rainy day. He thought each one through once and added the answer to the table.
Oats with yoghurt, a ham and egg sandwich, sweet potato with soy milk: one each Monday to Wednesday, then start again on Thursday.
A bento shop, a noodle shop and a buffet, in a fixed order.
Take one a day; no standing in front of the wardrobe in the morning.
Decide whether to say yes once you know the deadline and the hours.
Add to the list whenever something comes to mind; on Friday evening just pick one.
Put it in the cart; buy it only if you still want it three days later.
First time this came up: decide, write the answer into the table, and look it up next time.
Where AI helps: building AI a hash table of you.
Ming could ask:
Here are my preferences; please follow them in all your answers: I do not eat seafood, my budget is under NT$120 per meal, I only have 15 minutes to prepare on weekday mornings, my flat only has a rice cooker and a microwave, and I like simple, unfussy food. Based on these, give me five weekday breakfast combinations, each with ingredients and preparation time. I will pick two of them to add to the three I currently rotate.
Save these preferences and attach them every time you ask. AI then stops asking the same questions and suggests fewer things that obviously do not fit.
Common misuses: defaults turning into shackles. Defaults exist to save effort, not to stop you choosing. When your life changes, change the defaults too. Another misuse is writing too many at once: you cannot remember them, and looking one up becomes slower than just thinking. Start with the five or six that come up most often.
Further reading: Hashing and strings
Binary search, find the amount that is just enough
Signal in a problem: the answer lies within a range and the problem is monotonic, meaning more is always better or always worse. LC 875, Koko eating bananas, asks for exactly that: the slowest speed that still finishes in time.
In daily life: what time to go to bed to feel rested, how many cups of coffee is right, how long to practise an instrument or study each day without giving up the next day, how much to budget for something, what temperature to set the air conditioning to.
How to apply it
- Set reasonable lower and upper bounds.
- Check that the problem is monotonic: within this range, is more always better, or always worse?
- Start in the middle and try each value for several days, reading the result with a sliding window.
- Too much, search the lower half; not enough, search the upper half, until the range is small enough that the difference no longer matters.
Example: Ming has started learning the guitar and wants to find the longest daily practice time he can actually keep up. His standard is practising on at least 5 days a week, and the range is 10 to 90 minutes. The longer each session, the harder it is to do it every day, so the problem is monotonic. In week 1 he tries the middle value, 50 minutes, and only practises on 3 days: too much, so the answer lies between 10 and 50. In week 2 he tries 30 minutes and practises on 6 days: he can keep that up, so the answer lies between 30 and 50. In week 3 he tries 40 minutes and practises on 4 days: too much again, leaving 30 to 40. In week 4 he tries 35 minutes and practises on 5 days, just meeting the standard, leaving 35 to 40. A difference of 5 minutes no longer matters, so for now he practises 35 minutes a day. Four weeks to find it. Starting at 10 minutes and adding 5 each week, he would only learn the answer when 40 failed, which takes 7 weeks.
Where AI helps: designing the experiment and pointing out variables you are not controlling.
Ming could ask:
I want to find the longest daily guitar practice I can keep up, somewhere between 10 and 90 minutes, where keeping it up means practising on at least 5 days a week. Design a binary-search experiment for me: how many days to try each value, what to record each day, how to decide whether to go up or down, and how narrow the range should get before I stop. Also list factors that could distort the results, such as overtime, long weekends or a cold.
Common misuses: forcing it onto a problem that is not monotonic. More sleep is not always better; past a certain point you feel groggier, so compare values within a small range instead. Another misuse is trying each value for just one day, so noise sends you into the wrong half.
Further reading: Binary search
Greedy, take the best option at each step
Signal in a problem: "the most activities you can attend", "the fewest steps", "can you reach the end", as in LC 435 and LC 55. Greedy means taking whatever is best right now at each step, without looking back. It is only correct when locally best choices lead to the best overall result.
In daily life
- Several activities on a Saturday overlap and you want to attend as many as possible.
- Many tasks have deadlines and you want to minimize lateness.
- Paying with the largest note first when counting out change.
How to apply it
- To attend the most activities, sort by end time and keep picking the one that ends earliest without clashing with what you have already chosen. Ending early leaves more time for the rest.
- To keep the latest task as little overdue as possible, sort by deadline and do the one due soonest first. Scheduling theory calls this earliest deadline first.
- Before you use it, ask whether the options are worth roughly the same. If their value varies a lot, greedy can go wrong, and you need the knapsack approach in the next section.
Example: Ming has five activities he would like to go to this Saturday: yoga 9:00 to 10:00, a market 9:30 to 12:00, a book club 10:30 to 12:00, a lunch gathering 12:00 to 13:30, an exhibition 13:00 to 15:00. Sorted by end time and picked from the earliest: yoga ends at 10:00, so take it; the market starts at 9:30 and overlaps yoga, so skip it; the book club starts at 10:30, no clash, take it; the lunch starts at 12:00, right as the book club ends, take it; the exhibition starts at 13:00 while the lunch runs until 13:30, so skip it. Three activities is the maximum. If he starts with the most tempting one, the market, it takes 9:30 to 12:00 and clashes with both yoga and the book club, leaving him with only the market and the lunch.
| 9:00 | 9:30 | 10:00 | 10:30 | 11:00 | 11:30 | 12:00 | 12:30 | 13:00 | 13:30 | 14:00 | 14:30 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Yoga | pick | pick | ||||||||||
| Market | skip | skip | skip | skip | skip | |||||||
| Book club | pick | pick | pick | |||||||||
| Lunch | pick | pick | pick | |||||||||
| Exhibition | skip | skip | skip | skip |
Where AI helps: sorting and checking for clashes.
Ming could ask:
Below are the five activities I would like to go to this Saturday, with their times. Sort them by end time and use the "always take the earliest-ending one that does not clash" method to work out the most I can attend, and list which activity each excluded one clashes with. Also, if I definitely want to go to the exhibition, fix it first and then rearrange the rest of the day.
The same approach works for tasks: give AI each task's deadline and time estimate, ask it to sort by deadline, work out when each will be finished, and flag which will be late and by how many days; if there is a way to make fewer of them late, ask it to explain that separately.
Common misuses: using greedy when values differ a lot. Picking the earliest-ending activities maximizes how many you attend, not how worthwhile they are. If one activity really matters to you, schedule it first, then use greedy on the remaining time. If what Ming most wants is the exhibition, he fixes it at 13:00 to 15:00 first and then uses greedy on the time before 13:00: yoga and the book club. Still three activities; the lunch has simply been swapped for the exhibition.
Knapsack, fit the most value into limited time and money
Signal in a problem: "limited capacity", "each item has a weight and a value", "take it or leave it", as in LC 416 and LC 322. This is the classic dynamic programming problem.
In daily life: only 5 hours this weekend, only NT$3,000 for fun this month, a suitcase that holds 7 kilograms, room to learn only one or two new skills this quarter.
How to apply it
- List every option with two numbers: what it costs (time, money, weight) and what it is worth to you, on a 1 to 10 scale.
- Remove the obviously poor deals first: expensive and low value.
- With few options, list every combination and pick the one with the highest total value that fits.
- With many options, let AI or a spreadsheet do the calculation while you supply the scores.
Example: Ming has 5 free hours this Sunday. He also thought about going shopping, but it takes 3 hours for only 2 points, expensive and unimportant, so he cuts it in the first step. The remaining options are: guitar practice 2 hours, 6 points; reading a novel 3 hours, 7 points; tidying his room 1 hour, 3 points; dinner with Hua 3 hours, 8 points; a film 2 hours, 4 points. Picking greedily by points per hour: guitar and tidying both score 3 points an hour, the highest, so they go in first and use 3 hours. Next is dinner with Hua (about 2.7 points an hour), but that would make 6 hours, so it does not fit; the novel (about 2.3 points an hour) does not fit either; finally the film fits, for exactly 5 hours and 13 points. But list every combination that fits, 15 in all, and the best is dinner with Hua plus guitar: also 5 hours, but 14 points. This is exactly where greedy fails and knapsack is needed.
Where AI helps: working through the combinations while you supply the scores.
Ming could ask:
I have 5 free hours this Sunday. Below are the things I would like to do, each with the time it takes and how much it matters to me (1 to 10): guitar practice 2 hours, 6 points; reading a novel 3 hours, 7 points; tidying my room 1 hour, 3 points; dinner with Hua 3 hours, 8 points; a film 2 hours, 4 points. Find the combination with the highest total score that fits in 5 hours, and list the second and third best combinations so I can compare.
Common misuses: careless scores. The algorithm only works with the scores you give it; inaccurate scores give an inaccurate best answer. When scoring, ask yourself which choice you would regret least a month from now. Another misuse is looking at only one capacity: a weekend is often limited by money and energy as well as time, and when there are two limits, write both down before you calculate.
Further reading: Dynamic programming core
Optimal stopping, decide once you have seen enough
Signal in a problem: not a typical coding problem but a classic of probability, often called the secretary problem: options appear one at a time, you cannot go back to one you passed, so when should you stop and choose?
In daily life: house hunting, looking for a parking space, interviewing candidates, deciding within a window of time whether to take an opportunity. Look at too few and you may miss something better; look at too many and the best one may already be gone.
How to apply it
- Estimate roughly how many options you will see, or how long you will spend looking.
- For about the first 37%, only look and do not choose. Use them to set your standard.
- After that point, choose the first option that beats everything you have seen so far.
- Decide your fallback in advance: if nothing better turns up after that point, what will you do when time runs out, for example take the last one you see, or keep looking for longer.
The 37% comes from the mathematically optimal strategy. When you cannot go back and you only care about picking the single best option, this strategy finds the best one about 37% of the time, which is the best anyone can do under those conditions.
Example: Ming plans to spend a month looking for a flat to rent in Taipei and expects to view about 20. 37% of 20 is about 7, so for the first 7 he only looks and scores each one on the same sheet (out of 100): 62, 70, 55, 78, 66, 73, 60. The highest is flat 4 at 78, and that becomes his bar. From the 8th onwards he takes the first one that scores above 78: flat 8 scores 71 and flat 9 scores 75, neither clears it; flat 10 scores 82, so he signs, and does not need to view the other 10. A score of 82 is not necessarily the highest of all 20, but when you cannot go back, this rule gives the best chance of ending up with the best one.
Where AI helps: estimating the total and building a scoring standard.
Ming could ask:
I plan to look for a flat to rent in Taipei over one month and expect to view about 20. Design a scoring sheet (no more than 5 items, 100 points in total) so I can set a standard with the first 7, and tell me how to judge "better than all the earlier ones" from the 8th onwards. If nothing better turns up by the end, also suggest how I should wrap things up.
Common misuses: applying 37% rigidly. In real life you can often go back (the earlier flat may still be available), or "good enough" is fine and you do not need the very best. In both cases you should decide earlier rather than sticking to 37%.
Explore and exploit, how much new to try
Signal in a problem: a classic of machine learning and recommender systems, often called the multi-armed bandit: how should you split your tries between options you know are good and untried options that might be better?
In daily life: your usual restaurant versus a new one, a familiar way of working versus a new tool, the playlist you always play versus artists you have never heard, old friends versus new acquaintances.
How to apply it
- Consider how much longer you will be in this situation. With plenty of time left, explore more; near the end, exploit the good options you know. In your first month in a new city, try new restaurants; in your last month there, go to your favourites.
- Give exploration a fixed share, such as one try in five being something new. The similar method in machine learning is called epsilon-greedy: at each choice, with a fixed probability ε, try something new at random, which works out to that share on average.
- Record the result of every exploration, so the next decision is better informed.
Example: Ming has just moved from Taichung to Taipei for work and eats dinner out five times a week. In week 1 he knows no places at all, so Monday to Thursday he tries a new one each day, and on Friday he goes back to his favourite of those four. In week 2 he tries 3 new places; in weeks 3 and 4, 2 each; from week 5 he settles on one new place in five, close to epsilon-greedy with ε = 20%; tapering exploration over weeks 1 to 4 is like letting ε shrink over time. Over the first 8 weeks that is 40 dinners: 15 at new places and 25 back at places he already knows are good. Even if only 4 of the 15 are worth returning to, his list of known good options has grown from none to 4, and his dinners keep getting more reliable.
| Mon | Tue | Wed | Thu | Fri | |
|---|---|---|---|---|---|
| Week 1 | new | new | new | new | known |
| Week 2 | new | known | new | known | new |
| Week 3 | new | known | known | new | known |
| Week 4 | known | new | known | known | new |
| Week 5 | known | known | new | known | known |
| Week 6 | known | known | known | known | new |
| Week 7 | known | new | known | known | known |
| Week 8 | known | known | known | new | known |
Where AI helps: listing candidates to explore and organizing your records.
Ming could ask:
I moved to Taipei two months ago. Below are the 15 places I have eaten at, with ratings from 1 to 5. Based on what my highly rated places have in common, suggest 5 types of places I have not tried that I might like, and recommend a ratio of new places to familiar ones for the next month.
Common misuses: exploring without exploiting, constantly switching tools and methods without ever getting good at one, or exploiting without exploring, doing the same things year after year and missing better choices. Another is never adjusting the ratio: someone who has just moved and someone who has lived somewhere for years should not explore the same amount.
Further reading: how recommender systems handle exploration in Recommender system funnel
Group three, ordering work
This group is about what to do first and how to arrange your time.
Heap and Top-K, keep only a few things in flight
Signal in a problem: keep pulling the K most important items out of a large set while new items keep arriving, as in LC 215 and LC 347.
In daily life
- There are always more to-dos than time. Laying everything out and sorting it is tiring and unnecessary. What you need is to know, at any moment, the few things that matter most right now.
- New things arrive all day: a task from your manager, a message from a friend, a chore that suddenly comes to mind. Re-sorting the whole list every time something arrives costs a lot of time on sorting alone.
How to apply it
- Set a capacity K. K should be small enough to remember without looking at the list, for example only 3 priorities a day.
- Give each item a score, and write the criteria down first, for example extra points for a deadline and extra points for anything that blocks other people.
- When something new comes in, compare it only with the weakest of those K items. It comes in only if it matters more, and the item it replaces goes back to the backlog. On a tie, keep what you have and save the cost of switching. This is how a heap works: the weakest item always sits on top, so one comparison with it tells you whether the new item gets in.
- Do not sort anything else. Leave it where it is.
- At the end of each day, remove what is done and refill to K with the highest-scoring items from the backlog. Refilling is the only time you need to look through the backlog.
Example: Ming pushes at most 3 things forward each day. On Tuesday morning he has 8 things on his plate, each scored from 1 to 10: pay the electricity bill (due today) 9, the first draft of a report due Friday 8, review Hua's CV (Hua applies next week) 6, book a dentist appointment 5, practice guitar for 30 minutes 4, finish a borrowed book 3, look into Japanese classes 3, sort out the wardrobe 2. He takes the top 3, scoring 9, 8 and 6, and leaves the other 5 in the backlog. The weakest of the three, Hua's CV at 6, sets today's bar.
At 10:30 his manager asks for a client data summary by 3 p.m., and Ming scores it 7. He compares 7 only with the bar of 6: it is higher, so the client data comes in, Hua's CV goes back to the backlog, and the bar rises to 7. At 14:00 he remembers he needs snacks for Saturday's board-game night and scores it 3. That is below 7, so it goes straight to the backlog and the top 3 do not change at all. Two new things came in during the day, he made two comparisons, and he never re-sorted the whole list.
At the end of the day the electricity bill and the client data are done; the report draft is unfinished and stays. The backlog now holds 7 items, and he fills the two free slots with the two highest: Hua's CV at 6 and the dentist at 5. Wednesday's top 3 are the report draft, Hua's CV and the dentist.
Where AI helps: suggesting a top few from a messy list, provided you state the criteria first.
Ming could ask:
Below are all my current tasks, each with its deadline and whether it blocks anyone. Rank them by these three criteria: first, anything with a deadline; second, anything that blocks other people; third, anything that does the most for the two things I care about most this month (doing the report well and practicing guitar twice a week). List the top 3 with reasons and do not sort the rest. When I add something new later, just tell me whether it matters more than number 3.
Common misuses: setting K too high. With K at 10 there are no priorities. Another misuse is not stating the ranking criteria, so AI ranks by its own guesses. A third is scoring once and never looking again: if one of the top 3 gets stuck, for example while waiting for someone's reply, move it back to the backlog and give its slot to something you can move forward now.
Further reading: Heaps, Top-K and intervals
Interval merging, combine scattered time into blocks
Signal in a problem: a set of intervals with start and end times, where you merge overlaps or find the minimum number of meeting rooms, as in LC 56 and LC 253.
In daily life
- Meetings, messages and small chores cut the day into fragments, and fragments are useless for focused work.
- Several family members need the car at the weekend. The minimum number of cars you need is the meeting room problem.
How to apply it
- The night before, write down tomorrow's fixed commitments and sort them by start time. Meals and commuting count too, and write down how long things actually take, not how long they are scheduled for.
- Sweep from morning to evening: if the next commitment starts no later than the current block ends, they overlap or touch, so merge them and keep the later end time; otherwise start a new block, and the time in between is a free slot.
- Put the work that needs the most focus into the longest free slot.
- Batch small tasks such as replying to messages, paying bills and making appointments into one or two fixed slots.
Example: Ming works 9:00 to 18:00 tomorrow and has 7 fixed commitments: a stand-up 9:00 to 9:45 (scheduled to end at 9:30, but it has been running to 9:45 lately, so he writes down the real end), a one-on-one 9:30 to 10:00, a review with the designer 10:30 to 11:00, a project discussion 11:00 to 12:00, lunch 12:00 to 13:00, a team meeting 14:00 to 14:30 and the weekly update meeting 17:00 to 17:30.
Sweeping by start time: the stand-up and the one-on-one overlap and merge into 9:00 to 10:00; the design review, the project discussion and lunch run back to back and merge into 10:30 to 13:00; the team meeting and the weekly update stand alone. Seven commitments become 4 blocks with 270 busy minutes. The free slots are 10:00 to 10:30 (30 minutes), 13:00 to 14:00 (60 minutes), 14:30 to 17:00 (150 minutes) and 17:30 to 18:00 (30 minutes), also 270 minutes in total, and the two sides add up to exactly 9 hours.
At first Ming left lunch out, so 12:00 to 14:00 looked like a full 2 hours; with lunch added and merged, only the hour from 13:00 to 14:00 is left. The longest free slot is 14:30 to 17:00: the 2 hours of focused work go from 14:30 to 16:30, leaving 30 minutes of buffer. The two 30-minute gaps starting at 10:00 and 17:30 go to messages, and 13:00 to 14:00 goes to bills and appointments that need a phone call.
Where AI helps: finding slots that could be merged or moved.
Ming could ask:
Below is my calendar for tomorrow. The stand-up usually runs to 9:45, so please treat it as ending then. Merge overlapping or touching events, list every free slot and its length, and suggest which slot best suits 2 hours of focused work and which small gaps could be used for messages. If moving one meeting would create a longer free block, point that out too.
Common misuses: filling every gap. Leave some buffer so one overrun does not bring down the whole day. Another misuse is going by scheduled times only: meetings often run over, so free time calculated from the schedule looks larger than it really is. Whether to move someone else's meeting involves other people, so that call is yours.
Further reading: the interval problems in Heaps, Top-K and intervals
Topological sort, map dependencies before you start
Signal in a problem: tasks depend on one another, B can only start after A, and you need to know whether everything can be finished and in what order, as in LC 207, Course Schedule, and LC 210.
In daily life
- Moving house, travelling abroad, renovating, changing jobs, organizing an event: one task holds up the next.
- These usually stall not because there is too much to do but because the order is wrong: you do something that depends on a decision not yet made, and then have to redo it or pay extra.
How to apply it
- Write each task on its own card.
- On each card, note which tasks must be finished before it can start. The number of tasks it waits on is its in-degree.
- Do the tasks that are not waiting on anything, the ones with an in-degree of zero, first. When one is done, cross it off every other card's waiting list; when a card's waiting list is empty, its in-degree is zero and it is up next.
- When several tasks have an in-degree of zero at the same time, they can run in parallel. Start first on the one that waits longest on someone else, such as a landlord's reply or an official review.
- If A is waiting on B while B is waiting on A, you have a cycle. Find the one task that can break it.
Example: Ming is moving from Banqiao to Zhongshan District at the end of next month. He writes 8 cards and notes what each one waits on:
- Fix the moving date: waits on "confirm the move-out date with the landlord" and "sign the new lease".
- Book a moving company: waits on "fix the moving date" and "clear out unwanted things", because the quote depends on how much stuff there is.
- Set up internet at the new flat: waits on "sign the new lease" (he needs the address) and "fix the moving date" (to book the installation).
- Pack: waits on "book a moving company", since the company delivers the boxes.
- Moving day: waits on "pack".
- Confirm the move-out date with the landlord, sign the new lease, clear out unwanted things: these wait on nothing, so their in-degree is zero.
So in the first round he does the three tasks with an in-degree of zero at the same time. Once they are done, the waiting list for fixing the moving date is empty and it moves into round two; round three is booking the moving company and setting up the internet; round four is packing; round five is moving day.
At first he was stuck in a cycle: the moving company wanted to know how much stuff he had before giving a quote, while he wanted the quote before deciding how much to throw out. He broke it by doing one round of clearing out first and then asking for an estimate, which is why "clear out unwanted things" comes before "book a moving company". Paying the moving company's deposit before confirming the move-out date with the landlord is getting the order wrong: if the date changes, he may not get the deposit back.
In-degree zero, waits on nothing
Waits on the move-out date and the new lease, both crossed off in round 1
Each waits on two: one crossed off in round 1, the other when the moving date is fixed in round 2
Waits on the movers' boxes
Last step
Where AI helps: listing the usual steps and dependencies, which you then trim to your situation.
Ming could ask:
At the end of next month I am moving from Banqiao to Zhongshan District in Taipei. I live alone and my things fit in one small van. List what I need to prepare, mark which items each one must wait for, and put them in a workable order, with things that can be done at the same time in the same round. Flag the items I need to confirm with the landlord, the moving company or government offices for the latest rules, such as how the deposit is returned and what an address change involves.
Common misuses: trusting AI's list completely. AI's steps can be outdated or incomplete, and rules such as leases, deposits and household registration, or visas and taxes when moving abroad, must be confirmed at the original source: the contract itself, the landlord or the government website. Another misuse is forcing tasks that could run in parallel into a single line, for example waiting until the lease is signed before clearing anything out, which stretches the whole process for nothing.
Further reading: Graphs
Shortest path, the fewest steps or the lowest cost
Signal in a problem: "fewest steps", "shortest time", "lowest cost". Use BFS when every step costs the same, as in LC 127, and Dijkstra when steps cost different amounts, as in LC 743.
In daily life
- How few people you need to ask to find whoever is responsible for something.
- Which intermediate steps lead from your current job to a different role.
- Several commuting routes, each with a different cost in time and money.
How to apply it
- Define the "nodes" and a "step": a node is a state, such as the skills you have or where you are, and a step is an action that moves you to the next state.
- Decide what to minimize: steps, time or money. Use one measure at a time; if you care about two, convert them into one unit first, for example by putting a price on your time.
- Search outwards from the start, one layer at a time: where can you get in one step, then in two? The first route to reach the goal has the fewest steps. A state you have already reached does not need to be visited again.
- If steps differ a lot in time or money, counting steps is misleading. Switch to Dijkstra: always expand from the state with the lowest cost so far. Do not stop the first time the goal shows up as a neighbor, because a cheaper route may still come around another way. Wait until the goal itself is the state with the lowest cost so far and its turn comes to be picked; only then is that route's total cost certain to be the lowest.
Example: Ming has worked in customer support at an e-commerce company for three years and wants to become a UX designer. The start is "support agent who knows what users often complain about". Searching outwards one layer at a time:
- One step away: take an introductory UX course (about 2 months), send the product team a monthly summary of the top 10 support complaints, or prepare applications for a design master's (about 6 months).
- Two steps away: use what the course taught to redesign the company's returns flow as a first portfolio case (about 3 months); sit in on user interviews with the product team; or quit to study for the master's (about 24 months).
- Three steps away: apply for an internal transfer to UX designer with the portfolio (about 1 month), which reaches the goal. In the same ring, the interview route has got as far as "write up the interview findings as a redesign proposal" and the master's route as far as "look for an internship"; neither has arrived. The goal has appeared, so the search stops.
The first route to reach the goal is "course → portfolio → internal transfer": 3 steps, about 2 + 3 + 1 = 6 months. At step three the master's route is still looking for an internship (about 3 months), and after that it needs one more step to land a full-time job (about 3 months): 4 steps, about 6 + 24 + 3 + 3 = 36 months, with no income in the middle. A route that starts where you are and produces something real at every step is usually shorter than one that leaves your starting point and begins again. Of the two routes Ming can put times on, the one with the fewest steps is also the quickest, 6 months against 36. The interview route has no estimates yet; to compare total time, he would first have to add months to each of its steps. The fewest steps and the shortest time are not always the same route, for example a route with only two steps where one step means waiting a year; then compare the total months instead, as in step 4.
Where AI helps: listing possible intermediate states and steps, while you judge what each step really costs.
Ming could ask:
I have worked in customer support at an e-commerce company for three years and want to become a UX designer within a year. The company has a product design team. Lay out possible routes as a series of steps, with the time, cost and risk of each step, and mark the route with the fewest steps and the route with the lowest risk. Point out any route that requires me to quit.
Common misuses: negative costs. Dijkstra requires that no step has a negative cost. If a step in real life actually gives you time back, redefine your costs, or the calculation will be wrong. Another misuse is counting steps without looking at their size: "do a master's" and "take a course" are both one step, but one takes about 24 months and the other about 2, so compare total cost instead, as in step 4.
Further reading: Graphs
Group four, breaking down and combining
This group is about splitting big things into small ones and merging scattered things together.
Tree decomposition, break big goals down to something doable today
Signal in a problem: a big problem is made of subproblems, which split further. DFS digs all the way down; BFS expands one level at a time, as in LC 104 and LC 102.
In daily life: "learn a new language", "build a website of your own" and "get the home in order" are too big to fit into today. Keep breaking them down until each one becomes something you can tick off today.
How to apply it
- Start with BFS: break each big goal down by one level only and check that every direction makes sense, so you do not dig deep into one goal while the others never move.
- When you are ready to work on a goal, switch to DFS and keep breaking it down to the leaves.
- A leaf should be something you can finish in one sitting, roughly an hour or less. If a piece still cannot be finished in one sitting, break it down one more level.
- Each day, pick a few leaves into today. How many fit depends on how much time today has.
Example: Ming has three big goals this year: "learn enough Japanese to order food in Japan on his own", "build a small personal website" and "organise the flat".
He starts with BFS and breaks each goal down by one level only, 3 pieces each, 9 pieces in total. Looking at the three goals side by side, he notices that the Japanese branch originally said "sign up for the JLPT". But what he wants is to order food, not a certificate, so he swaps it for "10 ordering dialogues". A wrong direction like this is easy to spot only when every goal has first been broken down one level and laid out next to the others.
This month he most wants to get the website moving, so he runs DFS on that branch only. He digs into "make the first page" first. It takes about 2 hours, too long for one sitting, so he breaks it into three leaves: pick a free template, 40 minutes; write the about-me text, 50 minutes; swap in his own photos and colours, 30 minutes. The three add up to 120 minutes and each is under an hour, so he stops there. Swapping in photos and colours has to wait until the template is chosen, so picking the template goes first.
Tonight he has only 1 hour. After "pick a template" there are 20 minutes left, and the shortest remaining leaf needs 30, so today gets just this one. The other two big goals stay at the first level until the website reaches a natural pause.
First level, 3 pieces; the JLPT was swapped out
The branch to run DFS on next
First level, 3 pieces
Too big to fit into today
Dig into the first page: about 2 hours, too long for one sitting
120 minutes in all, each under 1 hour, stop
1 hour tonight: one leaf leaves 20 min, too little for the next
Where AI helps: producing a first breakdown for you to trim and adjust. Tell it your current level, how much time you have each day and the approaches you do not want, so the pieces actually fit into your days.
Ming could ask:
This year I want to build a small personal website with an about-me section and 3 small projects I have made. I know a bit of HTML and have about 1 hour on weekday evenings. Break it into 10 to 15 concrete pieces, none taking more than an hour, and mark which ones have to happen in order. Leave out anything that requires paying someone to do it.
Common misuses: breaking things down too far. Splitting "pick a template" into "search for templates", "compare three" and "download" only adds overhead. The test for a leaf is whether you can finish it in one sitting, not how small it is. Another misuse is doing only DFS: digging one goal all the way down at the start while the other goals do not even have a first level, and only finding out later that the direction was wrong.
Further reading: Binary trees and BSTs
Backtracking and pruning, find workable combinations among many
Signal in a problem: build a valid combination out of many options. Make a choice, go deeper, and step back when it fails. Pruning means abandoning impossible branches early, as in LC 39 and LC 51.
In daily life: planning a trip itinerary, a week of meals, a book club rota, or a dinner time the whole family can make. The number of combinations explodes quickly.
How to apply it
- Write down every hard constraint first, such as the budget ceiling, who is unavailable on which day, how long travel takes and which days places are closed.
- Make choices one at a time, checking each against the constraints. If one is broken, step back and try a different choice.
- Prune: the sooner you can tell a path is impossible, the sooner you drop it. Schedule the most constrained parts first, such as a sight that can only be visited on one day. Check first the constraints that remove a large block at once, such as the budget: once a restaurant is over budget, none of its dates need checking.
- Choose among the remaining workable plans by preference. Preferences are soft constraints; save them for the end and do not use them for pruning.
Example: Ming is organising a family dinner for five: Ming, his dad, his mum, his younger sister and his grandmother. There are 4 candidate times: Friday dinner, Saturday lunch, Saturday dinner and Sunday lunch. There are 3 candidate restaurants: a hot pot place at about 650 per person, closed on Sundays; a Taiwanese restaurant with a set menu for five at 3,800, which is 760 per person, closed on Saturdays; and an Italian restaurant with a set menu at 1,100 per person. The budget is under 800 per person.
4 times by 3 restaurants makes 12 combinations. Ming prunes in this order:
- Budget first: the Italian place is 1,100 per person, over 800, so its whole column of 4 goes at once, leaving 8.
- Then people: his dad works late on Friday evening, so the Friday dinner row goes. Only hot pot and Taiwanese are left to remove in that row, 2 combinations, leaving 6.
- Closing days last: the Taiwanese restaurant is closed on Saturdays, which removes Saturday lunch and Saturday dinner, 2 combinations; the hot pot place is closed on Sundays, which removes Sunday lunch, 1 combination. That leaves 3.
The workable ones are hot pot on Saturday lunch, hot pot on Saturday dinner and Taiwanese on Sunday lunch. Then preferences: his grandmother prefers lunch, and of the three restaurants only the Taiwanese one has a private room where everyone can talk at ease, so Ming picks the Taiwanese restaurant on Sunday lunch.
Checking every cell against all three constraints would take 36 checks. Pruning whole columns and rows first means checking 3 restaurant prices, who is free at 4 times and the closing days of the 6 remaining cells, 13 checks in total.
| Time / place | Hot pot | Taiwanese | Italian |
|---|---|---|---|
| Fri dinner | Someone busy | Someone busy | Over budget |
| Sat lunch | Works | Closed | Over budget |
| Sat dinner | Works | Closed | Over budget |
| Sun lunch | Closed | Works | Over budget |
Where AI helps: this is one of the places where AI shines. Hand AI every constraint as a list and ask it to list all the combinations and mark which constraint each removed one breaks; you only have to check that it removed the right ones. Trip itineraries work the same way: write the maximum number of sights a day, which afternoon you are busy, which sight needs a morning visit and the daily budget as constraints.
Ming could ask:
I am organising a family dinner for five. Candidate times: Friday dinner, Saturday lunch, Saturday dinner, Sunday lunch. Restaurants: a hot pot place at about 650 per person, closed on Sundays; a Taiwanese restaurant with a set menu for five at 3,800, closed on Saturdays; an Italian restaurant with a set menu at 1,100 per person. Hard constraints: under 800 per person; my dad works late on Friday evening. Preferences: my grandmother prefers lunch, and a private room would be nice. List all 12 combinations, mark which constraint each removed combination breaks, then recommend one of the workable combinations and explain why.
Common misuses: not checking AI's plans. AI sometimes produces plans that look reasonable but break a constraint, such as listing the Taiwanese restaurant on a Saturday as workable, so check each one against every constraint. Another misuse is treating preferences as hard constraints. If Ming made "must have a private room" a hard constraint too, only the Taiwanese restaurant on Sunday lunch would be left; if it were fully booked that day, nothing would be left and he would have to start over. Prune with hard constraints first and save preferences for the final pick.
Further reading: Backtracking
Union-Find, merge things that are really the same thing
Signal in a problem: "how many groups", "which items are connected", "merge duplicates", as in LC 547 and LC 684.
In daily life
- Several items on your to-do list are really different wordings of the same task.
- Notes, bookmarks and photos are scattered everywhere and you want to sort them into a few topics.
- Several people each wrote down which pieces of work belong to the same project, and you want to know how many projects there are in total.
How to apply it
- Look at two items at a time and ask: are these the same thing, and can they be handled together? If they are, link them.
- Once linked, an item belongs to the same group as everything its partners are linked to, with no need to compare them one by one.
- When you are done, each group is one real task or one topic. Every link that joins two items from different groups reduces the count by one.
Example: Ming's to-do list has 12 items. He looks at two at a time and draws a link whenever they are the same thing:
- "Reply to the landlord" and "ask the landlord to fix the tap": one message covers both, link.
- "Reply to the landlord" and "check the renewal date": the landlord's message is asking whether he will renew, link.
- "Check the renewal date" and "find the lease": he has to look at the lease to know the date, link.
- "Book a table" links with "ask the family when they are free" and with "check three restaurants' prices"; these three are the family dinner from the previous section.
- "Compare phone plans" links with "ask which carrier Hua uses" and with "back up the old phone"; all are part of getting a new phone.
That is 7 links in total, and each one joins two groups that were separate before. With 12 to-dos and one fewer per link, 12 − 7 = 5, so he ends with 5 things: talking to the landlord about renewal and repairs, the family dinner, the new phone, and "pay the utility bills" and "return the library books", which have no partners.
Notice that "ask the landlord to fix the tap" and "find the lease" were never compared directly, but both sit on the same chain, so they land in the same group. Once the four landlord items are one task, Ming finds the lease first, then sends one message that covers both the renewal and the tap. One contact with the landlord is enough instead of several rounds back and forth.
If Ming also linked "ask the landlord to fix the tap" with "check the renewal date", the count would not drop, because they are already in the same group. That extra link is exactly the edge LC 684 asks you to find.
4 items → one contact with the landlord
3 items → sorted in one evening
3 items → handled in one go at the weekend
No partner, done as it is
No partner, done as it is
Where AI helps: AI is good at judging whether two items are the same thing. Compared pairwise, 12 items make 66 pairs and 40 items make 780, so once the list gets long, AI is a good fit for the first pass, and you check whether its merges are right.
Ming could ask:
Below are my 12 to-dos. Find the items that are really the same task or can be handled together, group them, give each group a new name and explain in one sentence why each pair is linked. Do not delete anything; only group. Any item with no partner forms a group of its own.
Common misuses: groups that are too broad. Putting all of "work" or "household stuff" in one group does not help. The point of grouping is to let you finish one thing in one go. The test is whether items can be handled in one go, not whether they are related: "pay the utility bills" and the landlord group both concern the flat, but paying takes a minute on his phone and does not wait on the landlord, so Ming leaves it in a group of its own.
Further reading: Graphs
Dynamic programming, remember the solutions you already have
Signal in a problem: the same subproblems keep recurring, so you store their answers and reuse them. Today's state depends only on yesterday's state and today's choice, as in LC 70 and LC 198.
In daily life
- Planning the week's meals from scratch every week, writing a fresh packing list for every trip, starting every report on a blank page. All of these recompute subproblems you have already solved.
- A habit streak is the simplest state transition there is: today's streak depends only on yesterday's streak and whether you did it today. Ming practises Japanese, and yesterday his streak was 6 days. If he practises today it becomes 7; if not, it resets to zero. He only needs to remember yesterday's number, not dig through the whole log.
How to apply it
- After finishing something you will do again, spend five minutes saving it as a template or checklist.
- Next time, start by editing the template instead of starting from nothing.
- After each use, add whatever you thought of this time, and the template keeps improving. Written as a state transition: the template for time n = the template for time n − 1 + whatever you thought of this time.
Example: the first time Ming goes on a work trip, to Taichung, he writes a packing list from scratch. It takes 35 minutes of thinking and comes to 18 items, and when he arrives he finds he forgot his charging cable. Back home, he saves the list as a template and adds the charging cable, making 19 items.
- 2nd trip: ticking through the template takes 8 minutes, plus 2 minutes to add "business cards", 10 minutes in all; the template grows to 20 items.
- 3rd trip: ticking takes 4 minutes, plus 2 minutes to add "folding umbrella", 6 minutes in all; the template grows to 21 items.
- 4th trip: ticking takes 3 minutes, nothing new to add, and the template stays at 21 items.
- 5th trip: again ticking only, 3 minutes, with nothing new to add.
The 5th trip takes only 3 minutes, less than a tenth of the first. What he saves is not typing time but thinking time: the subproblem of what to bring was solved and stored on the earlier trips. Meeting notes, reports and travel plans work the same way.
Where AI helps: having AI turn the process into a template as it goes. After finishing something that will recur, ask AI to turn this time's list or steps into a reusable format; next time, hand it the template together with what is different this time. Quarterly reviews and meeting notes work this way too.
Ming could ask:
Here is the packing list I threw together for my first work trip: 18 items, and when I arrived I found I had forgotten my charging cable. Turn it into a reusable work-trip packing template: add the charging cable, sort it into four categories (documents, clothes, electronics, work items) and mark the items needed only for overnight trips. Next time I will hand you the template directly and tell you how many days the trip is.
Common misuses: so many templates you cannot find them. Keep templates in one place with consistent names, for example all starting with "Template". Another misuse is saving a template and never updating it. If you do not add back what you thought of after each use, the template slowly drifts away from reality, and in time you are back to starting from scratch.
Further reading: Dynamic programming core
Group five, running for the long term
This group is about what happens over the long run: habits, space and retries.
Linked list, attach new habits to old ones
Signal in a problem: nodes follow one another, and inserting a node only changes the pointer on the node before it; reversing a list, LC 206, is just changing those pointers one by one. Fast and slow pointers detect whether the list loops back on itself, as in LC 141. LC 142 goes one step further and finds the node where the cycle begins.
In daily life
The hardest part of a new habit is deciding when to do it. Attaching it to an action that is already stable is like inserting a node into a list: you only change the "next step" of the action before it, and nothing else moves.
- You want to learn something new, such as Japanese or the guitar, but never find a fixed time for it.
- Your morning routine runs smoothly until you squeeze in one new thing, and then the whole chain falls apart.
- Every so often you end up in the same state again, staying up late or putting off the same kind of task.
How to apply it
- List the actions you do every day without fail: getting up, brushing your teeth, pouring coffee, arriving at work, finishing lunch, showering.
- Attach the new habit to one of them, in the form "after X, I will...".
- Attach only one new habit to a node at a time, and add the next once it is stable.
- Decide in advance what "stable" means, for example 12 days out of two weeks, and only add the next habit once you reach it.
- If you keep coming back to the same state, treat it as a cycle and find the node where you enter it.
Example: Ming wants to start learning Japanese, but keeps saying he will "study when I have time", and a month goes by without a single word learned. He first lists what he does every morning without fail: getting up, brushing his teeth, pouring coffee, taking the MRT, arriving at work. He does these five almost every day, so they are stable nodes.
- Weeks 1 and 2: he inserts just one new node, "after pouring my coffee, I learn 5 Japanese words". He manages it on 12 of the 14 days, 60 words in total.
- His standard for stable is "at least 12 days out of two weeks". He just reaches it, and only then adds the next one.
- Week 3: he inserts a second node, "after I board the MRT, I listen to one 10-minute Japanese podcast episode". The ride takes 25 minutes, so he still has 15 minutes to spare.
Only two pointers on existing nodes changed: the next step after pouring coffee went from taking the MRT to learning words, and the next step after boarding the MRT went from arriving at work to the podcast. The new nodes simply point to where the chain used to go: learning words leads to the MRT, and the podcast leads to arriving at work. Getting up, brushing his teeth and arriving at work did not move.
next step was the MRT, now learning words
inserted in week 1, done 12 of 14 days
next step was work, from week 3 the podcast
inserted in week 3, 10 minutes an episode
the last node in the chain
Fast and slow pointers translate to spotting cycles. In a list, the fast pointer moves two steps at a time and the slow one moves one, and if there is a cycle the fast one eventually catches up with the slow one from behind; LC 142 then finds the entrance to the cycle. In daily life you do not need to run two pointers. What matters is two things: first admit "this is a cycle", then find the entrance. If you notice that every so often you end up in the same state again, staying up late or putting off the same kind of task, the entrance is usually a particular trigger.
At the end of week 3, Ming gave two months of records to AI to sort through, and found that 7 of his 9 late nights had the same node right before them: scrolling his phone in bed. In the three weeks since he started learning words, he missed only 2 days, the 2 in weeks 1 and 2, and both came after late nights. Finding that entrance works better than blaming himself: what needs to change is the step that leads into the entrance, such as charging his phone in the living room when he gets home, so that getting into bed no longer leads to scrolling.
asleep before 11, not in the cycle
7 of 9 late nights start here
asleep after 1 a.m.
leaves after coffee, skips the words
back in bed with the phone
Where AI helps: choosing an anchor that is stable enough, and finding recurring patterns and triggers in your records.
Ming could ask:
Below are my daily records for the last two months (bedtime and a note for each day; for the last three weeks, also whether I learned my Japanese words that morning). Find the recurring pattern behind my late nights: which days of the week they usually fall on, what the day before or the day itself had in common, and, in the three weeks where I tracked word learning, whether it breaks more often the morning after a late night. Only list patterns you can see in the data; do not speculate about psychological causes.
Common misuses: attaching to an unstable action. If going to a Saturday Japanese class is not a habit yet, do not attach a new habit to it. Another is inserting several new nodes at once: add word learning, a podcast and a journal to the same morning, and when one breaks the others often break with it, and you cannot tell which one caused the problem.
Further reading: Linked lists
LRU cache, when space runs out remove what you used least recently
Signal in a problem: a cache with limited capacity that, when full, evicts the item used least recently, as in LC 146. The standard implementation is a hash map plus a doubly linked list: move an item to the front when it is used and remove from the back when full, both in O(1).
In daily life
There is never enough space, and the question is what to get rid of.
- A packed wardrobe, and at each change of season you do not know what to put away or give away.
- A bookshelf with no room for the books you just bought.
- Your phone's home screen, kitchen cupboards and the files on your desktop, piling up.
How to apply it
- Every time you use something, put it back at the "front", such as hanging a worn shirt at the right-hand end of the wardrobe.
- After a while, whatever is at the left-hand end is what you have not used for the longest time.
- When space runs out, start with whatever has gone unused longest.
- Before letting anything go, take out the exceptions: seasonal items, emergency items and things with sentimental value.
Example: Ming's wardrobe has a single rail that holds exactly 60 hangers, and it is full. On 1 April he hangs every hanger facing the same way; from then on, whenever he puts back something he has worn, he hangs it at the right-hand end, and if the hanger still faces the original way he turns it around; a hanger already turned stays as it is. On 1 July and 1 September he clips a peg onto the rail at the right-hand end as a divider. The hanger direction tells him whether something was worn in the last six months, and the position tells him how long ago. On 1 October, exactly six months later:
- 38 hangers are turned around: 20 items to the right of the 1 September peg, worn in the last month; 12 between the two pegs, worn one to three months ago; and 6 to the left of the 1 July peg, worn three to six months ago.
- 22 hangers are not turned around: not worn in six months.
- Of those 22, he first takes out the exceptions: 3 winter coats (nobody wears them from April to October) and 1 suit for formal occasions. The other 18 are candidates for removal.
- He needs to free 12 spaces for the jumpers and heavy jackets that come out of storage boxes when the season changes. From the 18 candidates he picks the 12 that no longer fit or are worn out, and donates or recycles them; the other 6 he is still unsure about, so they stay at the left-hand end of the rail.
Afterwards there are 48 items on the rail and 12 free spaces. The next time space runs out, the first batch is those 6, followed by the 6 worn three to six months ago.
A bookshelf works the same way: put each book you have opened back at the left-hand end, and after a while the books at the right-hand end are the ones you have not opened for the longest time.
Where AI helps: deciding the threshold for "unused" and the exceptions.
Ming could ask:
I tracked my wardrobe for six months by turning hangers around: of my 60 items, 22 have not been worn in six months, including 3 winter coats and 1 suit for formal occasions. I want to free up 12 hangers. Give me a set of rules: how long without wearing something before I consider letting it go, in what order to deal with the remaining 18 candidates (for example, does not fit, worn out, too many of the same kind), and which kinds of clothes should be exceptions.
Common misuses: no exceptions. Some things are used once a year but matter a lot, such as a winter coat or a first-aid kit. The eviction rule must exclude seasonal and emergency items first. An observation period that is too short also misleads: Ming only watched from April to October, which cannot show whether his winter clothes get worn, so the winter coats have to be protected by the exception list. And LRU only looks at when something was last used, not how often: a shirt that happened to be worn to a party last week jumps to the top layer, but that does not mean he wears it often. To know how often something is used you have to count uses separately, which is the idea behind LFU (least frequently used), as in LC 460.
Further reading: LC 146 in Linked lists is the LRU cache
Exponential backoff, after each failure wait longer before retrying
Signal in a problem: a common system design technique: when a request fails, wait and try again; if it fails again, wait longer, for example 1, 2, 4 then 8 seconds, so retries do not overwhelm the system.
In daily life
- How long to wait before following up on an email that got no reply.
- Getting back into practice after being ill or away on a work trip, or restarting a habit after a break.
- Being stuck on the same problem and wondering whether to set it aside.
How to apply it
- After the first failure, wait briefly and try again.
- After another failure, double the wait.
- Set a limit, and when you reach it, change approach or let go.
- Write the limit down before you start, such as "three times at most", and when you reach it, stop as the rule says instead of renegotiating on the spot.
Example: on 1 October Ming applied for a job and emailed the recruiter, and has had no reply. He sets the rule in advance: double the wait each time, and follow up three times at most.
- Follow-up 1: wait 3 days, on 4 October.
- Follow-up 2: wait another 6 days, on 10 October.
- Follow-up 3: wait another 12 days, on 22 October. This is the last one.
- After that he treats it as a no, stops following up, and puts his time into other openings.
From 1 October to 22 October is 21 days, and he sends only 3 follow-ups; chasing every day would mean 21 emails in 21 days. That is more courteous than chasing every day, and it stops the matter from nagging at him.
A broken habit borrows the other half of backoff: lower the intensity first and build back up, rather than doubling a wait. Ming used to practise the guitar for 20 minutes a day, and a week-long work trip broke the habit. On his first day back he does not practise for 40 minutes to make up for it. He starts with 10 minutes; after 3 days in a row, he goes up to 15; after another 3 days, he is back to his usual 20. Do not demand double the next day to make up for it. Restart at a smaller amount than before and build back up.
Where AI helps: drafting each follow-up and tracking the dates. You can also ask it to work out the dates for you so you do not get them wrong.
Ming could ask:
On 1 October I applied for a job at a company and emailed the recruiter, and have had no reply. Set out an exponential backoff schedule for following up (wait 3, 6 and 12 days, three follow-ups at most), list the date of each one, and write three follow-up emails whose tone gradually winds down, each under 80 words. The third should make clear that this is my last message.
Common misuses: no limit, so you chase forever, or punishing yourself harder after a failure, such as doing double the next day after missing one day of a habit. Backoff means longer intervals and lower intensity, not heavier penalties. Starting too long is also wrong: wait a month before the first follow-up and the other person may have forgotten all about it. Start short, then double.
Further reading: Rate limiter and URL shortener
System design building blocks work too
Beyond algorithm problems, a few basic system design building blocks are just as useful day to day:
- Rate limiter: rate-limit notifications and messages, for example by handling messages only in two fixed slots a day and letting them pile up in between for one batch.
- Cache: keep frequently used things where they are easiest to reach, such as a ready-packed bag and important documents in a fixed place.
- Queue: anything that pops up goes into an inbox first and gets handled at a fixed time, instead of each item interrupting what you are doing.
- Optimistic locking: when a family shares a list, everyone edits freely and conflicts are checked on save. That is easier than agreeing in advance who may edit.
- Idempotency: doing the same thing twice gives the same result. Before paying a bill, check whether it has already been paid, so you never pay twice.
Example: Ming and his family share a weekend shopping list, and Ming and his mother both open version 7. On his phone, Ming changes "milk, 1 bottle" to 2 bottles. At the same time, on her tablet, his mother deletes the milk and adds a box of eggs. She saves first, so the list becomes version 8. When Ming submits, the list app sees that he edited version 7 and refuses to let him overwrite it. That is the optimistic lock. It then compares what each side changed; merging is an extra step on top of the optimistic lock. Only his mother touched the eggs, so they stay. Both of them changed the milk, so Ming is asked to look at the latest version first and then decide whether to add the milk back, instead of simply overwriting his mother's edit.
The list has 1 bottle of milk
Ming changes milk to 2 bottles; his mother deletes milk and adds eggs
Versions match, so it saves as version 8
He edited version 7, but the list is now version 8, so he cannot overwrite it
An extra step: only his mother changed the eggs, so they stay; both changed the milk, so Ming looks and decides
Further reading: System design fundamentals, Rate limiter and URL shortener
Where AI belongs
Every section above came with a prompt Ming could use, and they all follow the same process:
What kind of problem this is
Budget, time, what you will not accept
Arithmetic, options, drafts
Cases where you know the answer
Pay, send, commit
- You choose the pattern, AI runs the steps. Work out what kind of problem it is first, then ask AI to do the most time-consuming step. Asking "what should I do?" usually gets generic advice.
- Give AI the problem's constraints. In algorithm problems the constraints determine the solution. The same goes for AI: state your budget, your time and what you will not accept, and the answer fits your situation much better.
- Validate with test cases. You run tests on your solutions; before adopting AI's output, check it against one or two cases where you already know the answer. If they do not match, do not take the result wholesale. For example, if Ming asks AI to total three months of expenses by category, he can check rent first: it is a fixed NT$18,000 a month, so three months should come to exactly NT$54,000. If it does not, the categorizing or the totals are wrong.
- Keep irreversible decisions for yourself. Paying, sending emails, deleting things and making commitments to other people are steps I always take myself. It is the same principle as the agent safety boundaries I wrote about in Day 8.
- Be careful with what you paste into AI. Before pasting health records, finances or other people's personal details into a cloud AI, ask whether it is necessary and whether you can strip out anything that identifies someone first. This is also the topic of Private AI Cluster Log Day 1.
When not to use any of this
- When the decision is cheap: lunch is not worth a binary search. Use the default from your hash table.
- When there is too little data: with three days of records, a sliding window shows nothing. Collect more first.
- When the subject is people: relationships, being there for someone and caring for family are not optimization problems. Algorithms can help you schedule time, but they should not be used to calculate whether something is worth it.
- When planning becomes procrastination: breaking things down, ranking and building spreadsheets feel productive. If you spend more time planning than doing, stop and start doing.
- When you are using algorithms to avoid feelings: after a breakup, a job loss or a family member falling ill, deal with the emotions and talk to someone first. The algorithms can wait.
A one-week practice plan
Twenty is too many to learn at once. Pick the seven you will use most, one a day:
| Day | Algorithm | What to do today |
|---|---|---|
| Day 1 | Hash table | List three small decisions you make every week and write a default answer for each |
| Day 2 | Heap and Top-K | In the morning, pick only the 3 most important things for today and park the rest |
| Day 3 | Interval merging | The night before, lay out tomorrow and put its most important task in the longest free slot |
| Day 4 | Topological sort | Take one stuck project, map its dependencies and start with a task that waits on nothing |
| Day 5 | Tree decomposition | Take one big goal, have AI break it into 10 pieces, then trim them and add them to your to-dos |
| Day 6 | Dynamic programming | Save one thing you did this week and will do again as a template |
| Day 7 | Sliding window | Give the last two to three weeks of records to AI, compute a 7-day moving average for each day, and see which way it trends, which day deviates most, and why |
After a week, look back: which one saved the most effort? That is the one that suits you best and is worth turning into a reflex first.
Takeaways
When something comes up, ask yourself in turn:
- Does it have dependencies? Map them first (topological sort)
- Several routes from where you are to a goal? Write down what each step costs, then find the route with the lowest total cost (shortest path)
- Is it too big to do today? Break it down to the leaves (tree decomposition)
- Are several of these really the same thing? Merge them first (Union-Find)
- Am I looking for a workable combination among many options? Write the constraints down and prune (backtracking)
- Want to fit as many things as possible into limited time, each worth about the same? Sort by end time and keep taking the earliest-ending one that does not clash; if you want the worst delay to be as small as possible, sort by deadline instead (greedy)
- Limited time or money, with options of different value? Work out combinations, not just efficiency (knapsack)
- Options appearing one by one, gone once passed? Look at some first to set a standard, then decide (optimal stopping)
- Should I try something new? Depends on how much longer I will be here (explore and exploit)
- Am I looking for the amount that is just enough? Check it is monotonic, then halve each time (binary search)
- Do I care about the trend? Use a fixed-length window, not single days (sliding window)
- Do I need to know the running total? Keep a cumulative column (prefix sums)
- Many options, each winning on something? Drop the ones beaten on every count first (monotonic stack)
- Too much to get through? Keep only the top K (heap and Top-K)
- Is my time too fragmented? Merge the fragments into blocks (interval merging)
- Have I done something similar before? Look for a template or default answer first (dynamic programming, hash table)
- Want to add a new habit? Attach it to a stable action (linked list)
- Out of space? Remove whatever has gone unused longest (LRU cache)
- Keep failing? Lengthen the interval, lower the intensity, set a limit (exponential backoff)
At every step, ask two more questions: would handing this step to AI make it faster, and how will I check the result?
This checklist is also the input to the combined algorithm in the next section: answer these questions first, and you will know which building blocks your goal needs.
Putting it together, an algorithm that grows a strategy from your goal
Each of the twenty sections above solves one shape of problem. But the things you actually want to get done rarely have just one shape. Take "change jobs within six months": it is too big to finish today, so it needs tree decomposition; its steps have an order, so it needs topological sort; time is limited and you must choose what to learn first, which is a knapsack problem; it runs for weeks and you have to find time every week, so it needs heap and Top-K and interval merging; applications get rejected and you wait for replies, so it needs exponential backoff. Pick one algorithm and you solve one piece; the other pieces are still guesswork.
Using all of them at once is no answer either. In the wrong order, algorithms work against each other: for example, you use knapsack to pick the highest-scoring combination, then find that one item's prerequisite was never picked. So this section builds an "algorithm for choosing algorithms". It looks at your goal and decides which ones this goal needs, in what order to connect them, and which one to follow when they disagree. After each round it also saves what it learned, so the next round starts from a better place.
What it is
Name: the strategy router, a router that grows with use; "the router" for short.
One-sentence definition: you give it a goal and your current situation in plain words. It first decides how carefully to work, based on what a mistake would cost and whether you can take it back; then it checks memory for a template from something you have done before; then, with ten yes-no questions, it picks the few algorithms out of twenty that this goal needs, puts them in order and fills in their parameters. While you carry out the plan it checks the last 4 weeks every week and writes what worked and what did not back to memory, so the next goal starts from a better place.
A few key points:
- The router does not use all twenty every time. When a question gets a no, its algorithms stay out. What to have for lunch stops at the first question; changing jobs is worth all ten.
- The ten yes-no questions are a condensed version of the checklist in "Takeaways" above.
- Eight algorithms appear twice. The first time they are building blocks in the plan, such as using exponential backoff to time follow-up emails; the second time they are parts of the router itself:
- Hash table and dynamic programming: remember past goals and strategies;
- Explore and exploit: pick the methods that work out of several;
- Exponential backoff: cool down methods that failed;
- Binary search: tune parameters such as weekly hours;
- Prefix sums: correct capacity from the actual running total;
- Union-Find and LRU cache: merge similar templates and drop stale ones.
- That is why it "grows". It is a process that gets better the more you use it, not a formula that guarantees the optimum.
How costly a mistake is and whether you can undo it decide how carefully to work
If you have done something similar, start from that template
Answer ten yes-no questions; only a yes calls its algorithms; settle conflicts by priority
Order the steps, fill in parameters, push only the top K at once
Was the plan done, did the result move; look at the last 4 weeks, not one week
Count a success for what worked, cool down what failed, try the middle value, save a template
What optimal really means here
"Optimal" always means optimal for the scores and limits you wrote down, not optimal for your life. The methods inside the router fall into three kinds, by how strong their guarantee is.
Exact optimum. When the four conditions below all hold, knapsack, backtracking and pruning, and shortest path give the exact answer:
- There are few enough options to list them all. By hand that is about 5, or 2⁵ = 32 combinations; with a spreadsheet or a small program written by AI it is about 20, or 2²⁰ = 1,048,576 combinations, which a computer gets through in a moment.
- You trust the scores and costs.
- The hard limits can be written down.
- Nothing changes while you compute.
Binary search also finds an exact threshold when the relationship is monotonic and each trial gives a reliable result.
The best rule under assumptions. Optimal stopping assumes that "options arrive one at a time, cannot be recalled once passed, and only the very best one counts". Under those assumptions the 37% rule gives the highest chance of picking the best option, but that chance is still only about 37%. A good rule does not guarantee a good outcome.
Good enough is rational. When there are too many options, the scores are fuzzy, you only learn the result by trying, or the stakes are low, use greedy, heap and Top-K, a good-enough bar, and explore and exploit. This is not laziness: computing further would cost more effort than it gains. Epsilon-greedy is not the theoretically best way to explore, but it is simple and good enough. Greedy is also optimal only for a few problems, such as LC 435, picking activities by end time; in daily life it is usually just good enough.
So the router as a whole does not guarantee a global optimum, because goals and people change. What it does guarantee is these four things:
- exact methods are used only where they really apply;
- a problem with execution becomes visible within one window;
- a problem with results becomes visible in the first window after that method has been tried 10 times;
- a method already known to fail is not made the main method by accident; it is only retried, to a limited extent, in exploration slots under the backoff rule.
Few enough options to list them all, scores you trust, limits written down, nothing changes while you compute
Options arrive one at a time, cannot be recalled, and only the very best counts; the 37% rule gives the best chance of the top option, and that chance is still only about 37%
Too many options, fuzzy scores, results you only learn by trying, or low stakes; set a bar and stop when you reach it
Input, a goal card
The router's input is a goal card. Six lines are enough:
- What you want: what should become true, in one plain sentence, ideally saying what counts as done.
- Limits: weekly time, money and energy, and things you will not do.
- Deadline: the latest week by which you need a result.
- Three things you care about: in order; they become the weights for scoring.
- Can it be undone: mark, step by step, which steps are reversible and which are not.
- What you have tried before: both what worked and what failed. This line is filled into the routing table in advance: methods still cooling down or retired are ruled out; methods that failed before but whose cooldown is over may only use exploration slots, never as the main method.
Step one, set the effort
First answer two questions, each scored 1 to 3:
- Stakes: if this goes wrong, how long until you recover? Within a week is 1, within a month is 2, longer is 3.
- Undo: can you take it back once it is done? Yes is 1, partly is 2, no is 3.
Multiply the two scores to get the effort for this goal:
| Can undo 1 | Partly 2 | Cannot undo 3 | |
|---|---|---|---|
| Low stakes 1 | light 1 | light 2 | medium 3 |
| Medium stakes 2 | light 2 | medium 4 | heavy 6 |
| High stakes 3 | medium 3 | heavy 6 | heavy 9 |
A product of 1 or 2 is light, 3 or 4 is medium, 6 or 9 is heavy. Each tier works differently:
- Light, or lookup mode: ask only the first question, "have I done something similar?". If there is a template or a default answer, follow it; if not, use greedy and take the best option in front of you. Decide within 5 minutes and fix it next time if it was wrong.
- Medium, or heuristic mode: run through the ten questions quickly, relying mainly on pruning, greedy and Top-K to get something good enough; when the options are few enough to list them all, you can still ask AI to write a small program that computes the exact answer. Every goal at medium or above gets window checks. Planning is capped at 1 hour.
- Heavy: go through the ten questions carefully. Where all four conditions hold, compute the exact answer; where options arrive in sequence and cannot be undone, write down a good-enough bar and a fallback in advance; before every irreversible step, sleep on it for a night. Planning is capped at half a day, split into two sittings.
Two more rules:
- Planning time must not exceed doing time. This echoes "When not to use any of this": once planning itself becomes procrastination, stop and start doing.
- Within one goal, look at each step separately. The less reversible a step, the more you should think before doing it; reversible steps you simply do, then check.
These time caps are rules of thumb, not derived numbers; adjust them to your own situation.
Step two, check memory
This step uses a hash table and dynamic programming.
- Memory key: the goal type, for example "learn a skill while working" or "job search". The ten questions have not been answered yet at this point, so the key is the goal type alone. Once a template is found, compare the tier and ten answers stored in it with this goal card and mark what differs.
- What is stored: each template holds the tier at the time, the ten answers, the strategy, parameters, how it was checked, the result, and when it was last used. This is dynamic programming's memo table: a solved subproblem is stored, and next time you start by editing it.
- Found one: start from the template and change only what is different this time.
- Found none: the strategy starts empty, but scattered records still help, for example a method that failed before.
- Light tier: if there is a template, just follow it; if not, use greedy and take the best option in front of you. The process ends here.
Step three, route with ten yes-no questions
Answer each question yes or no. A yes calls the matching algorithms and fills in their parameters; a row with a no stays out this time. Each algorithm is applied the way its section above describes. The answer to Q1 is simply the result of the memory check in step two.
| Q | Question | A yes calls | How to set the parameters |
|---|---|---|---|
| Q1 | Have I done something similar before? | Hash table (default answers), dynamic programming (templates) | Which version of the template |
| Q2 | Is it too big to finish today? | Tree decomposition | Each leaf can be done within an hour |
| Q3 | Does it have an order, or several routes to the same place? | Topological sort; add shortest path when there are several routes | The cost of each leg, in days, weeks or money |
| Q4 | Are several of these really the same thing? | Union-Find | The merge test: can they be handled in one go |
| Q5 | Are there hard limits I can write down? | Backtracking and pruning | The list of limits |
| Q6 | Must I choose within limited time, money or space? | First drop options beaten on every count with a monotonic stack, then knapsack or greedy; add an LRU cache when the limit is space | Capacity; at most 3 dimensions to compare |
| Q7 | Do options appear one by one, gone once passed? | Optimal stopping | Look at the first 37% of the total. Shorten it when you can go back or when good enough is fine. With only 1 to 3 options, switch to calibration plus a good-enough bar |
| Q8 | Do I only learn the result by trying, and can I try repeatedly? | Explore and exploit; when looking for an amount that is just enough and the relationship is monotonic, use binary search instead | Exploration share, see step four; or the search bounds |
| Q9 | Will it run for weeks, needing time every week? | Heap and Top-K, interval merging, linked list; add two pointers when coordinating time with someone else | K, the length of time blocks, the anchor action |
| Q10 | Can it fail, be rejected, or depend on someone replying? | Exponential backoff | Starting interval, multiplier, maximum attempts |
| Not asked | Always done at medium effort or above | Sliding window, prefix sums | Window length 4 weeks by default; threshold 70% of plan; cumulative plan line |
All twenty algorithms are in the table. The two techniques from "Sliding window and two pointers" are placed separately: two pointers under Q9, the sliding window in the last row. The last row is not a question: any goal at medium effort or above must be checked, so the sliding window and prefix sums are always in.
| Question | Memory | Structure | Choose | Run | Check and learn |
|---|---|---|---|---|---|
| Q1 Done before | Hash tableDynamic programming | ||||
| Q2 Too big today | Tree decomposition | ||||
| Q3 Order or routes | Topological sortShortest path | ||||
| Q4 Really the same | Union-Find | ||||
| Q5 Hard limits | Backtracking and pruning | ||||
| Q6 Limited, must pick | Monotonic stackKnapsackGreedy | LRU cache | |||
| Q7 Gone if missed | Optimal stopping | ||||
| Q8 Must try to know | Explore and exploitBinary search | ||||
| Q9 Runs for weeks | Heap and Top-KInterval mergingLinked listTwo pointers | ||||
| Q10 May fail or wait | Exponential backoff | ||||
| Always check | Sliding windowPrefix sums | ||||
| Router uses itself | Hash tableDynamic programmingExplore and exploitExponential backoffBinary searchPrefix sumsUnion-FindLRU cache |
Who wins in a conflict
The algorithms you call sometimes give different answers. Then follow these six layers in order; a higher layer always beats a lower one:
- Hard limits and irreversibility: prune with the written limits first; a person always takes the irreversible step.
- Dependency order: options whose prerequisites are not done are not compared.
- Real feedback: real numbers from the last 4 weeks beat the original estimates, scores and templates.
- Exact when computable: with few options, trusted scores and a tier above light, the exact answer beats the approximation.
- Time windows: if it is gone once missed, use optimal stopping or a good-enough bar; only use exploration when you can try again.
- Defaults and templates: only a first guess.
Common conflicts are settled like this:
- Knapsack vs greedy: with few options, trusted scores and a medium or heavy tier, use knapsack. Otherwise shrink the options with a monotonic stack first, then use greedy.
- Optimal stopping vs explore and exploit: one-off choices you cannot go back to use optimal stopping; choices you can repeat use explore and exploit.
- Binary search vs exploration: looking for an "amount" with a monotonic relationship, use binary search; looking for "which one", explore.
- Union-Find vs topological sort: when two things are merged into one, neither may skip what it was waiting for. Dependencies are layer 2 and beat merging.
- Knapsack vs dependencies: every prerequisite of a combination knapsack picks must be in it, or layer 2 prunes it.
- Template vs feedback: if the template says 10 hours a week and you actually manage 6, follow the actual number. Layer 3 beats layer 6.
- Exponential backoff vs deadline: the backoff intervals added together must not run past the decision deadline.
- Top-K vs too many leaves: put the leaves in a waiting list first and push only K at a time.
Step four, assemble and run
- Put all the steps in order with topological sort.
- Fill in the parameters: leaf size, K, capacity, thresholds, exploration share, window length, backoff intervals. The exploration share is 20% by default, the "one in five" from the explore and exploit section; in the last quarter of a phase it drops to 10%; irreversible steps get 0%, because they are not for experimenting.
- Make two final checks: total hours do not exceed the hours available, and every hard limit is written into the plan.
- Each week push only the top K; the rest stays in the waiting list.
- At paying, signing, sending, accepting an offer or resigning, the process stops and hands over to a person.
Step five, check two signals
Once a week, look at two signals over the last 4 weeks:
- Execution signal: what was done ÷ what was planned, for example hours or applications sent.
- Result signal: actual result ÷ planned result, for example interviews.
Both use a sliding window over the last 4 weeks, never a single week; prefix sums put the actual running total next to the plan line, so you can see whether you are ahead or behind.
Looking at the two signals separately tells you which step to go back to:
| Result moved | Result did not move | |
|---|---|---|
| Plan was done | Carry on and count a success | The method is wrong: back off this method, go back to step three and switch to the one with the next best evidence |
| Plan was not done | Right direction, wrong cost estimate: re-estimate from real numbers, go back to step four and reschedule; the schedule that could not be kept also records a failure | Fix execution first, go back to step four and reschedule; the schedule that could not be kept also records a failure. When the plan was not followed, the result signal tells you nothing |
A few more rules:
- The goal or a limit changed: go back to step one and set the effort again.
- Threshold: falling below 70% of plan triggers a change. After reassembling, the window starts again from zero.
- Sample size: execution data arrives every week, so it can be read quickly; result data is scarce, so wait until the same method has been tried at least 10 times before judging it. Drawing conclusions from too few tries is the same mistake as "When there is too little data" in "When not to use any of this".
- Overshooting: if the result is above 130% for two windows in a row, give the extra time back to other things; if execution reaches 100% but the amount you want is not reached yet, use binary search to try higher. Both can be true at once: when the result has been above 130% for two windows in a row, give the extra time back first and stop trying higher; the amount you want also becomes the current amount.
- 70%, 130% and 10 tries are all defaults you can adjust.
Step six, learn and get better with use
After each round of checks, the router does six things. The algorithms used here are the same ones used in plans, only this time the router uses them on itself:
- Template memory, with a hash table and dynamic programming: save this goal's ten answers, parameters, checks and result as a template.
- Routing statistics, with explore and exploit: keep two numbers for every method, how many times it was tried and how many times it worked. The method with the best evidence is the main one, and 20% of the slots go to trying others. Numbers from small samples mislead, hence the rule "judge only after at least 10 tries".
- Cooling down failed methods, with exponential backoff:
- 1st failure: cool down 2 weeks, then come back only in the exploration slot;
- 2nd failure: cool down 4 weeks;
- 3rd failure: never use it again for this kind of goal, and record that in memory.
- Tuning parameters, with binary search: for an amount such as weekly hours, new target = (highest amount known to be achievable + lowest amount known to fail) ÷ 2; stop when the gap is 1 unit or less. This assumes monotonicity: the higher the target, the harder it is to hit.
- Correcting costs, with prefix sums: compute capacity from the actual running total of hours, not the planned figure.
- Pruning memory, with Union-Find and an LRU cache: merge similar templates into one; when there are more than 20, delete the one unused for the longest, so a stale template is not applied to a new situation.
What AI does and what stays human
This follows on from "Where AI belongs" above: AI runs the steps, and a person sets the problem, checks the result and takes the last step. Across the router's six steps, the split looks like this:
| Stage | AI does | A person does |
|---|---|---|
| Set the effort | Lists which steps are irreversible and finds hidden irreversible ones | Decides the stakes and the tier, and how much time to spend |
| Check memory | Finds the closest match among the templates you paste in | Confirms that it really is similar |
| Route | Answers the ten questions from the goal card first and flags the uncertain ones | Corrects the answers and writes down the hard limits and scores |
| Assemble and run | Writes a small program to enumerate combinations, solves the knapsack, draws the dependency graph, schedules, drafts messages and follow-ups | Picks one of the top few; clicks pay, send, sign and accept, and hands in the resignation |
| Check | Computes window averages and running totals, and looks for causes in the daily notes | Judges whether the number still stands for the goal |
| Learn | Updates the routing table and templates | Approves the changes, decides what counts as success, decides whether to extend the deadline |
A person always keeps five things:
- What matters, that is, the scores;
- The hard limits;
- The irreversible last step;
- The decision to stop or give up;
- Anything that involves other people.
The whole thing in pseudocode
Here are the six steps as pseudocode. You can read it without knowing how to code: one action per line, "←" means "set to", and text after "//" is a comment.
Strategy router (goal card)
// Step one: set the effort
stakes ← ask "If this goes wrong, how long until I recover?" // within a week = 1, a month = 2, longer = 3
undo ← ask "Can I take it back once it is done?" // yes = 1, partly = 2, no = 3
effort ← stakes × undo // 1–2 light, 3–4 medium, 6–9 heavy
planning cap ← light 5 minutes, medium 1 hour, heavy half a day in two sittings
// Step two: check memory
key ← goal type // the ten questions are not answered yet
template ← the most recently used template in memory with the same key
if there is a template: strategy ← template; compare its stored tier and ten answers with the goal card and mark what differs
else: strategy ← empty
if effort is light: follow the template or default answer if there is one, otherwise take the best option in front of you (greedy); done
// Step three: route
Q1 ← the result of the memory check in step two
for each question Q1 to Q10:
if the answer is yes: add that question's algorithms from the routing table
add sliding window and prefix sums // every goal at medium or above is checked
remove methods that are cooling down or retired
methods that failed before and finished cooling down: exploration slots only, never the main method
if two candidates conflict: keep the one in the higher priority layer
for each choice to make:
if all four exact conditions hold: compute the exact answer // knapsack, backtracking, shortest path
else if options arrive one by one and cannot be recalled: write a good-enough bar and a fallback
else: use greedy or Top-K, good enough first
// Step four: assemble and run
order the steps by topological sort
fill in parameters: leaf size, K, capacity, threshold, exploration share, window length, backoff intervals
exploration share ← 20% if reversible; 10% in the last quarter of the phase; 0% if irreversible
push only the top K each week
at paying, signing, sending, accepting or resigning: stop and hand it to a person
// Step five: check, once a week, over the last 4 weeks
execution signal ← what was done ÷ what was planned
result signal ← actual result ÷ planned result
if the goal or a constraint changed:
go back to step one
else if execution signal < 70%:
re-estimate cost and capacity from real numbers
if the parameter is an amount such as hours: new target ← bisect(highest achieved, lowest failed)
if the problem is a particular schedule: backoff(that schedule)
go back to step four and reschedule only the failing piece
else if result signal < 70% and this method has been tried at least 10 times:
backoff(this method)
go back to step three and switch to the method with the next best evidence
else if result signal > 130% for two windows in a row:
give the extra time back to other things
desired amount ← current amount; stop trying higher
else if execution signal ≥ 100% and the desired amount is not reached:
new target ← bisect(highest achieved, lowest failed) // stop when the gap is 1 unit or less
// methods tried fewer than 10 times are not judged yet; keep collecting data
// after reassembling, the window starts again from zero
// Step six: learn
for each method used: tries plus 1; if it worked, successes plus 1
memory.save(key, tier, ten answers, strategy, parameters, checks, result)
merge similar templates into one
if memory holds more than 20 templates: delete the least recently used one
return to step five until the goal is met or the deadline arrives; a person decides whether to extend it
bisect(low, high):
return (low + high) ÷ 2
backoff(method):
method.failures plus 1
1 failure: cool down 2 weeks, then use only the exploration slot
2 failures: cool down 4 weeks
3 failures: never use it again for this kind of goal, and record that in memory
Worked example, Ming moves into a front-end job in six months
In the shortest path section, Ming compared routes from customer support to UX designer. Later, in the weeks he spent building his small personal website, he found that the part he enjoyed most was the coding, and he changed his goal to front-end web development. When the goal changes, the strategy has to be grown again. Below is the router's full run from week 0 to week 26. Only week numbers are used, and the numbers are set for illustration.
Goal card
| Field | What Ming wrote |
|---|---|
| What he wants | Within 26 weeks, move from his current customer support job to a junior front-end web job; the finish line is accepting an offer |
| Limits | No quitting during preparation; at most 10 hours a week |
| Deadline | Week 26 |
| Three things he cares about | 1 the work is building web pages; 2 a one-way commute under 40 minutes; 3 someone to mentor him. As a score: 40 + 30 + 30 = 100 points |
| Can it be undone | Learning, applying and interviewing are reversible; accepting an offer and resigning are not |
| What he has tried before | Last year he tried getting up at 6 am to code and stopped after two weeks; in a past job search he used the follow-up rule "wait 3, 6, then 12 days, at most three follow-ups", the method from the exponential backoff section |
Set the effort
- Stakes 3: a mistake would take more than six months to recover from.
- Undo 2: applying and interviewing are reversible, accepting an offer and resigning are not, so it is partly reversible.
- 3 × 2 = 6, heavy: go through all ten questions carefully, spend half a day planning in two sittings, and sleep on it for a night before accepting an offer.
Within the goal, each step is looked at separately: choosing what to learn has few options and scores he can give himself, so it can be solved exactly; choosing a job is gone once missed, so it uses a rule plus a bar; small things like which piece to do first on a given evening simply use a default answer from the hash table.
Check memory
There is no template for "change careers while working", so the strategy starts empty. But memory holds two scattered records: the follow-up rule can be used as is, and "getting up at 6 am" failed once last year; its cooldown ended long ago, so under the rules it may only use exploration slots, never as the main method, and this time Ming does not give it one.
The ten answers
| Q | Ming's answer | Calls | Parameters |
|---|---|---|---|
| Q1 | Half yes | Hash table | Follow-up rule 3, 6, 12 days; "getting up at 6 am" failed once, exploration slots only, not the main method |
| Q2 | Yes | Tree decomposition | Three branches: skills, portfolio, job search; every leaf within an hour |
| Q3 | Yes | Topological sort, shortest path | The order produced: HTML and CSS → JavaScript → portfolio site → Git and deployment → CV → applications → interviews → offer. Three routes compared by weeks until he can apply: self-study 12 weeks (basics 7, portfolio 4, buffer 1); an online course 10 + portfolio 4 = 14 weeks; an evening course 26 weeks. He picks self-study. An internal transfer is not possible, because the company's engineering department has no junior front-end opening this year |
| Q4 | Yes | Union-Find | The portfolio site, the projects section of his CV and the stories he will tell in interviews are merged into one thing; the small personal website from the tree decomposition section is merged in too, as the portfolio site |
| Q5 | Yes | Backtracking and pruning | No quitting; ≤10 hours a week; the job must be front-end; commute ≤40 minutes |
| Q6 | Yes, the limit is time | Knapsack; add a monotonic stack for the job search | Capacity 12 weeks × 10 hours = 120 hours; no space limit, so no LRU |
| Q7 | Yes, jobs and offers | Optimal stopping, changed to calibration plus a good-enough bar | He expects only 1 to 3 offers; the first 3 interviews are used only to calibrate the score |
| Q8 | Yes, application channels | Explore and exploit | 1 of every 5 applications a week tries another channel, 20%; at the start there is no amount to find, so binary search stays out for now |
| Q9 | Yes | Heap and Top-K, interval merging, linked list, two pointers | K = 3; time blocks of 1.5 hours on four weekday evenings + 4 hours on Saturday = 10 hours; anchor "get home → open the laptop"; during the job search, two pointers to line up free time with Hua for mock interviews |
| Q10 | Yes | Exponential backoff | Follow up after 3, 6, 12 days, at most three times |
| Not asked | — | Sliding window, prefix sums | Window 4 weeks; threshold 70% × 10 = 7 hours a week; cumulative plan line adds 10 hours a week |
Four algorithms did not come in this time: dynamic programming, because there is no template to adapt; greedy, because there are few enough learning options to compute the exact answer, and the job search uses Top-K; the LRU cache, because there is no space limit; and binary search, because at the start there is no amount to find. As you will see, the router uses three of them on itself: binary search to tune the weekly hours, dynamic programming to save this run as a template, and the LRU cache to drop stale templates when there are too many.
Knapsack, the exact answer
Ming lists 7 things he wants to learn, estimates the hours for each and gives each a score. The dependencies are: JavaScript needs HTML and CSS first; both portfolio sites need HTML and CSS and JavaScript first; React needs JavaScript first; Git and deployment, and algorithm practice, need nothing first.
| Option | Hours | Ming's score |
|---|---|---|
| HTML and CSS | 30 | 9 |
| JavaScript | 40 | 10 |
| First portfolio site | 30 | 9 |
| Second portfolio site | 35 | 8 |
| Intro to React | 25 | 6 |
| Algorithm practice | 30 | 4 |
| Git and deployment | 10 | 7 |
- With 7 options, each either in or out, there are 2⁷ = 128 combinations. Ming asks AI to write a small program (or a spreadsheet formula) that works out all 128, then checks a few himself.
- Best answer: HTML and CSS + JavaScript + first site + Git and deployment, 110 hours and 35 points in total, and it is the only best answer.
- Five items can never fit: the five smallest add up to 10 + 25 + 30 + 30 + 30 = 125, more than 120.
- Two combinations tie for second at 34 points, both 115 hours: HTML and CSS + JavaScript + second site + Git; and JavaScript + first site + second site + Git. The second has no HTML and CSS, so layer 2, dependency order, prunes it.
- The plan uses 110 of the 120 hours; the remaining 10 hours are buffer.
This is the best answer for the scores Ming gave himself. Change the scores and the answer changes too.
| 1–2 | 3–4 | 5–6 | 7–8 | 9–10 | 11–12 | 13–14 | 15–16 | 17–18 | 19–20 | 21–22 | 23–24 | 25–26 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| HTML and CSS | heavy | medium | |||||||||||
| JavaScript | medium | heavy | medium | ||||||||||
| Portfolio site | medium | heavy | |||||||||||
| Git and deploy | medium | ||||||||||||
| CV and buffer | medium | ||||||||||||
| Apply and interview | heavy | heavy | heavy | heavy | heavy | heavy | |||||||
| Follow up | light | light | light | light | light | light | |||||||
| Buffer | light |
First feedback: the execution signal
Week 4 is the first time there are 4 full weeks of data. Hours actually done in the first 4 weeks:
| Week | Weekdays | Saturday | Total |
|---|---|---|---|
| 1 | Mon 1.5, Tue 1.5, Wed 1.5, Thu 0.5 = 5 | 4 | 9 |
| 2 | Mon 1.5, Tue 0.5 = 2 | 4 | 6 |
| 3 | Mon 1.5 | 3.5 | 5 |
| 4 | 0 | 4 | 4 |
- 24 hours in 4 weeks, an average of 6.0 hours a week, 60% of plan and below the 7-hour threshold.
- Prefix sums: the actual running total is 24 hours against a plan line of 40, 16 hours behind.
- Broken down: weekdays reached only 8.5 of a planned 24 hours, about 35%; Saturdays reached 15.5 of a planned 16 hours, about 97%.
Only the weekday piece is failing. This is "the plan was not done", not "it was done but did not work", so the router goes back to step four and reschedules only the weekday piece. Checking against the daily notes, AI finds that on the missed evenings Ming usually got into bed as soon as he got home and started scrolling his phone, and did not feel like moving after that. It is the same entry point as the late-night cycle in the linked list section: scrolling his phone in bed.
Rescheduling the weekday piece
- "Four weekday evenings" records 1 failure and starts cooling down.
- "6 am" failed once last year, so it may only use exploration slots and cannot become the new main schedule.
- Saturday's 97% suggests that fixed, solid blocks hold up better. The router switches to interval merging plus linked list and moves the anchor from "get home" to "walk out of the office": 1 hour each on Tuesday and Thursday right after work in a café next to the office, 4 hours on Saturday, 2 hours on Sunday.
- The new weekly target comes from binary search: using four-week averages, between the achievable 6 hours and the failed 10 hours, the middle is 8 hours, and 1 + 1 + 4 + 2 is exactly 8.
- New threshold: 70% × 8 = 5.6 hours.
Capacity has to be re-estimated too
This is layer 3, real feedback, beating the original estimate.
- AI works out: at 8 hours a week, 110 − 24 = 86 hours remain, and 86 ÷ 8 = 10.75, so 11 more weeks, which stretches the learning phase to week 15.
- AI lists two options:
- Extend: the 110 learning hours were due to finish in week 11 and will now finish in week 15; the CV buffer from week 12 moves to after learning, to week 16, and applications move from week 13 to week 17.
- Do not extend, and still start applying in week 13: capacity for weeks 1 to 12 becomes 24 + 8 × 8 = 88 hours, and the knapsack is solved again. With dependencies, the best is HTML and CSS + JavaScript + Git, 80 hours and 26 points, leaving 8 hours for the CV, but the portfolio site is squeezed out.
- Ming picks option 1. The portfolio site is his ticket into the job search, and the scores he gave at the start did not reflect that. This is exactly where a person has to judge: the algorithm calculates from the scores, and a person has to add what the scores missed.
Weeks 5 to 8
- 8, 7, 8 and 9 hours a week, 32 hours in total, an average of 8.0. He missed Thursday in week 6 and did 1 extra hour on Sunday in week 8.
- Execution signal 100%. The running total is 24 + 32 = 56 hours, exactly on the new plan line: 24 + 4 × 8 = 56.
- He reached 100% but not yet the 10 hours he originally wanted, so binary search tries higher: (8 + 10) ÷ 2 = 9. Sunday goes from 2 to 3 hours, and the new threshold is 70% × 9 = 6.3 hours.
- 110 − 56 = 54 hours remain, and 54 ÷ 9 = 6 weeks, so the learning phase shrinks back to end in week 14, and writing the CV and starting to apply both move up to week 15.
Weeks 9 to 14
- 9, 9, 8, 10, 9 and 9 hours a week, 54 hours in total; by week 14 the running total is exactly 110 hours.
- The week 12 check covers weeks 9 to 12: 9 + 9 + 8 + 10 = 36, an average of 9, execution 100%. Achievable 9 and failed 10 are only 1 hour apart, so the search stops.
- The 10 hours in week 12 were a single week; a four-week average of 10 hours has never been reached, so the upper bound is still 10. But 10 hours failed under the old schedule, and the new schedule has not tried it; the search stops at 9 for now, and if Ming wants to try 10 later, he can test it for one window in an exploration slot. 9 hours a week is the current answer.
- Learning finishes in week 14. Ming writes his CV with the 9 hours of week 15 and sends only 1 application that week; the other 4 are made up in weeks 16 to 18, so window 1 still has 20 applications.
| W1 | W2 | W3 | W4 | W5 | W6 | W7 | W8 | |
|---|---|---|---|---|---|---|---|---|
| Mon eve | done | done | done | missed | ||||
| Tue eve | done | part | missed | missed | done | done | done | done |
| Wed eve | done | missed | missed | missed | ||||
| Thu eve | part | missed | missed | missed | done | missed | done | done |
| Sat | done | done | part | done | done | done | done | done |
| Sun | done | done | done | done |
Second feedback: the result signal, job search in weeks 15 to 26
Every week:
- Prune with the hard limits: jobs that are not front-end, or with a one-way commute over 40 minutes, are dropped straight away;
- Use a monotonic stack to drop jobs beaten on all three dimensions;
- Apply to the top 5 by score, that is, Top-K.
Channels and thresholds:
- Main channel: job boards, 4 applications a week.
- Exploration: emailing the team directly with the portfolio attached, 1 a week, 20%.
- Result threshold: 20 applications every 4 weeks should bring 2 interviews, that is, 10%. Ming guessed this number; there was no template to go on.
- Before each interview, Ming uses two pointers to line up his free time with Hua's and books a mock interview; when an application or an interview gets no reply, he follows up after 3, 6 and 12 days, as the follow-up rule says.
| Window | Applications | Interviews | Achieved |
|---|---|---|---|
| 1, weeks 15–18 | Job boards 16, direct email 4 = 20 | 0 + 1 = 1 | 1 ÷ 2 = 50% |
| 2, weeks 19–22 | Direct email 16, Hua's referral 2, job boards 2 = 20 | 3 + 1 + 0 = 4 | 4 ÷ 2 = 200% |
Window 1
- Execution signal: 20 planned, 20 sent, 100%.
- Result signal: 1 interview against 2 planned, 50%, below 70%.
- The plan was done and the result did not move, so the method is wrong: back to step three.
- Job boards have been tried 16 times, more than 10, so they can be judged: 1 failure recorded, cooled down for 2 weeks, and back only in the exploration slot.
- Direct email has been tried only 4 times, with 1 interview. The sample is still small, but it has the best evidence, so it becomes the main channel at 4 a week.
Window 2
- After reassembling, the window starts again from week 19. The exploration slot goes to a new channel, Hua's referral, in weeks 19 and 20, and to the job boards, now out of cooldown, in weeks 21 and 22.
- Result signal 200%. Only one window is above 130%, so nothing changes yet.
- Running totals: direct email 20 sent, 4 interviews, 20%; Hua's referral 2 sent, 1 interview, too small a sample, so it stays in the exploration slot; job boards 18 sent, 0 interviews. If the next window is 0 again, that is the 2nd failure and a 4-week cooldown.
How to choose an offer
- No 37% rule. There are three reasons: he expects only 1 to 3 offers; sometimes you can ask a company to wait a few days, so a missed offer is not always gone; and good enough is fine, it does not have to be the best. This is exactly the case the "Common misuses" of the optimal stopping section warned about.
- After each interview, Ming scores that job against the three things on his goal card, out of 100. The first 3 are used only to calibrate: 61 points in week 18, 74 in week 20, 68 in week 21.
- The bar: every hard limit passes, and the score is ≥ 74, the highest of the first 3.
- The fallback: if there is still no offer above the bar by the end of week 24, the bar drops to 70.
- In week 22 there are two more interviews, scoring 71 and 80. Interviewing further is reversible, so there is no need to rush to drop the 71-point company; the bar applies only at the moment of accepting an offer.
- In week 24 the 80-point company makes an offer: 80 ≥ 74, and every hard limit passes. All the router says is "this meets the rule you wrote down".
- Ming sleeps on it for a night and then decides for himself to accept, 2 weeks before the deadline. Giving notice follows the notice period in his contract and is handled separately, outside this goal.
Saving to memory
- The "learn a skill while working" template: solid blocks of time are more reliable than scattered weekday evenings; start from an amount you can manage and use binary search to try higher; compute capacity from actual hours.
- The "job search" template: channel order is direct email with portfolio > Hua's referral > job boards; window 4 weeks, result threshold 10%; follow up after 3, 6, 12 days.
In the first 4 weeks weekdays reached 8.5 of a planned 24 hours, about 35%; 1 failure recorded, and after a 2-week cooldown it can only be an exploration option
1 failure last year and its cooldown ended long ago, so under the rules it can only be an exploration option; no exploration slot was spent on it this time
Binary search: 6 was achieved and 10 failed, so try the middle, 8; once 8 worked, try 9, between 8 and 10
The 110 hours finished in week 14 instead of week 11; writing the CV moved to week 15, the same week applications started
16 sent, 0 interviews; cooled down 2 weeks, then only 1 a week
20 sent in total, 4 interviews, 20%
The skill template keeps the time slots and the starting-hours rule; the job-search template keeps channel order, check thresholds and the follow-up rule
How the next goal grows faster
- Ming wants to learn enough Japanese to order food and ask for directions before a trip to Japan with Hua in six months, and plans to sign up for a term of Japanese classes.
- Set the effort: stakes 2 × undo 2 (one term's fee is paid up front) = 4, medium.
- Q1 hits "learn a skill while working". The template was saved at the heavy tier and this goal is medium, so that is marked as a difference; the time-slot rule carries over as is: 1 hour each on Tuesday and Thursday + 2 hours on Saturday = 4 hours.
- "Four weekday evenings" already has 1 failure recorded, so it may only use exploration slots and is not scheduled as the main option. Planning takes only 20 minutes this time; the medium cap is 1 hour.
None of this guarantees Ming an offer. What it guarantees is that every four weeks he knows whether he is following the plan; whether he is heading the right way, he learns once each method has been tried 10 times, instead of finding out in month six.
Where AI helps: answering the ten questions from the goal card first, solving the knapsack and the capacity sums, computing the two signals every week, and updating the routing table; scores, hard limits and the irreversible step stay with a person.
Ming could ask:
Below are my goal card, my answers to the ten yes-no questions, and my routing table (how many times each method has been tried, how many times it worked, and until which week it is cooling down). First decide, step by step, whether to use lookup, heuristics or an exact answer, then assemble a strategy: which algorithms, in what order, what value for each parameter, and which two numbers I should record every week, with their thresholds. Flag any question you are unsure about. Mark irreversible steps such as paying, signing, accepting an offer or resigning, and leave them for me to decide; do not decide them for me.
Limits of this algorithm
- The output is only as good as the scores and limits you put in. Wrong scores give a wrong optimum, just as the score Ming first gave the portfolio site did not reflect that it was his ticket into the job search.
- The ten questions are a rule of thumb; a new kind of problem may need another question.
- 70%, 130%, at least 10 tries, 20 templates, and cooldowns of 2 and 4 weeks are all defaults you can adjust, not laws.
- With too small a sample, such as only a week or two of data, or a method tried fewer than 10 times, do not rush to judge. It is the same principle as "When there is too little data" in "When not to use any of this".
- Once a number becomes a target, it can be gamed. Check regularly that the weekly hours still stand for real progress, and not for sitting in a café scrolling on your phone.
- Relationships, being there for someone and caring for family are not what it is for. When maintaining the spreadsheet takes longer than the work itself, fall back to lookup mode. Both points echo "When not to use any of this".
- Before pasting records into a cloud AI, strip out details that could identify anyone, such as company names and interviewers' names.
Further reading
Many of the ideas here are explored more fully in Brian Christian and Tom Griffiths' Algorithms to Live By, especially optimal stopping, explore and exploit, caching and scheduling. I recommend it if you want to go deeper. Where this post differs is that it starts from the problem types you meet when grinding LeetCode and puts AI into every step.
Grinding problems trains you to see a problem's shape within 45 minutes. Life has no time limit, but the same eye can make everyday decisions take a little less effort and leave more energy for the things that matter.