Anatidaephobia: Ducks, Ponds and Probability

We discussed another interesting question at work, this time over Slack. This one seemed more mathematical than programming-based, though.

Four small ducks are in a large circular pond. They can be at any point in the circle, with equal probability. What is the probability that a diameter can be drawn so that all four ducks are in the same semicircle in the pond?

Naturally, there is a straightforward generalisation:

N small ducks are in a large circular pond. They can be at any point in the circle, with equal probability. What is the probability that we can fence off some sector of the pond which subtends an angle P, so that all four ducks are enclosed in the fenced area?

If I had to do this as part of an engineering problem, my first reaction would be to implement a Monte Carlo simulation. This would quickly reveal an answer of \frac{1}{2} for the first part, but in the second part things might become less obvious.

Usually for this kind of problem I tend to start by varying some of the parameters and trying to solve a simpler version of the problem. With one duck, drawing a suitable diameter is trivial; with two, drawing a diameter through one of the ducks is sufficient (since the second duck is on one side or the other – ‘small’ here means that we don’t consider the case where a duck lies exactly on the diameter). Going up to three, things get a little complicated; depending on the position of the first two ducks, the third duck can either be placed anywhere (if the first two ducks are at the same location, for example) or perhaps might be quite restricted (if the ducks are on almost opposite sides of the pond).

I then looked at other possible ways of simplifying the problem. For example, we don’t really care about where the ducks are relative to the centre of the pond. The relative angles between the ducks and the centre of the pond suffice to identify whether drawing the diameter is possible, and how far they are from the centre of the pond on a given axis won’t affect this. We can thus consider the ducks as uniform randomly occupying points on a looping one-dimensional continuum, such as the interval [0, 1).

Returning to three ducks, we can try to formalise the intuition that the range of positions allowed for the third duck varies depending on the position of the first two ducks. Define the span of n ducks S_n to be the total space on the continuum that the ducks occupy. For base cases, we define S_1 = 0, and S_2 is just the smaller distance between the first and second duck, so it has to be uniformly distributed between 0 and 0.5.

If we fix the value of S_2 = x, we can attempt to find the range of allowable third-duck positionings such that S_3 \leq n. Without loss of generality, suppose the two ducks are sitting at points 0 and x. Then, the lowest possible point the third duck can sit at would be x - n, and the highest possible point n (assuming of course n \geq x; if this is not the case then there are clearly no possible positions). The range of this interval is n - (x - n) = 2n - x, and the probability that a duck lands in that range is 2n - x. This of course makes the assumption that 2n - x is less than 1; if it is more than 1, then the probability would be 1; however, in our specific case since x > 0 and n = \frac{1}{2} we don’t have to worry about this.

This then reduces to a problem about conditional probabilities. We want to weight each possible value of S_2 based on how likely it is; the relative likelihood of each value is given by the probability density function. For S_2, we have

\displaystyle f_{S_2}(x) = \left \{ \begin{array}{lr} 2 & 0 \leq x \leq 0.5 \\ 0 & \text{otherwise} \end{array} \right.

Then, weighting based on this density function, we have:

\displaystyle P(S_3 \leq n) = \int_{x} P(S_3 \leq n | S_2 = x) f_{S_2}(x) \text{d}x = \int_{0}^{n} (2n-x) f_{S_2}(x) \text{d}x

If n \leq 0.5 then that will be equal to

\displaystyle \int_{0}^{n} (2n-x) (2) \text{d}x = \left[ 4nx - x^2 \right]_{0}^{n} = 3n^2

Thus we can find a diameter for \dfrac{3}{4} = 0.75 of cases with three ducks. If n > 0.5, then we need to make several refinements – most obviously, the upper bound of the integral stops at 0.5, as there’s no span with two ducks larger than that. Furthermore, there may be values of x where 2n - x > 1 in which case we need to clamp it down to 1. For simplicity, we focus on the case where n \leq 0.5 which is sufficient for our purposes.

Moving on, to find P(S_4 \leq n), we can similarly formulate

\displaystyle P(S_4 \leq n) = \int_{x} P(S_4 \leq n | S_3 = x) f_{S_3}(x) \text{d}x

f_{S_3}(x) may not seem immediately obvious, but we can rely on the CDF of S_3 which was calculated earlier – the probability density function is simply its derivative. Thus f_{S_3}(x) = 6x, and the conditional probability can be handled with the same logic that we used to go from S_2 to S_3, bearing in mind that the middle duck(s) aren’t important. Hence

\displaystyle P(S_4 \leq n) = \int_{0}^{n} (2n-x) (6x) \text{d}x = 6 \int_{0}^{n} 2nx - x^2 \text{d}x = 6 \left[ nx^2 - \frac{x^3}{3} \right]_{0}^{n} = 4n^3

and we have the answer to the original question, by substituting n = \frac{1}{2} we obtain an answer of \frac{1}{2}.

Interestingly, the CDFs of the various S_k seems to take on the form kn^{k-1}. We can prove this result by induction on k. This clearly holds for k \leq 4, based on our work so far – though note that k \leq 2 is enough for our proof. So we now take some arbitrary integer k, and assume that P(S_k \leq n) = kn^{k-1}. We need to show that P(S_{k+1} \leq n) = (k+1)n^k. The way we can do this is very similar to what we did for the concrete steps.

\displaystyle P(S_{k+1} \leq n) = \int_{x} P(S_{k+1} \leq n | S_k = x) f_{S_k}(x) \text{d}x

Since we’re assuming that P(S_k \leq n) = kn^{k-1}, f_{S_k}(x) = k(k-1)x^{k-2}. We can simplify out the conditional probability term, based on a similar argument on the conditional probability as before. Thus

\displaystyle P(S_{k+1} \leq n) = \int_{0}^{n} (2n-x) k(k-1)x^{k-2} \text{d}x = k(k-1) \int_{0}^{n} (2n-x) x^{k-2} \text{d}x

What follows is a bit of careful rewriting:

\displaystyle P(S_{k+1} \leq n) = k(k-1) \int_{0}^{n} 2n x^{k-2}- x^{k-1} \text{d}x = k(k-1) \left[ \frac{2n x^{k-1}}{k-1} - \frac{x^k}{k} \right]_{0}^{n}

And we can simplify this to:

\displaystyle P(S_{k+1} \leq n) = \left[ 2nk x^{k-1} - (k-1)x^k \right]_{0}^{n} = 2kn^k - (k-1)n^k = (k+1)n^k

which was what we expected. This also allows us to draw more specific conclusions – for example, in general for n = \frac{1}{2} the probability is just simply \frac{k}{2^{k-1}} for k ducks.

Learning German 3: Prüfungen

Image by rawpixel from Pixabay

Ich kann nicht so einfach meine Deutsch bewerten. Eine Methode ist Prüfungen machen. Ich will Goethe-Institut Deutsch Zertifikat Prüfung machen, deshalb ihre Prüfungen wären gut. Allerdings gibt es nur ein wenige Modellprüfungen online.

I can’t easily evaluate my progress in German. One method (of evaluating progress) is to do exams. I want to take the Goethe Institute German exam. Thus their past papers would be good practice. However, there are only a few practice papers available online.


A part of life growing up in Singapore for me was, unfortunately, to find ways to maximise performance on exams, especially given limited understanding of the underlying subject matter. Some of these techniques might be classified as “common sense”, such as knowing the format of exams, what one was being assessed on, and making sure to spend enough time on each question or part, as marks within each question tend to get progressively harder to score. There were others that tended to be a little more subject-specific; for example, final answers in mathematics exams tended to be reasonably simple forms.

The Common European Framework for Reference of Languages (CEFR) outlines six levels of language proficiency – these are, in order from lowest to highest, A1, A2, B1, B2, C1 and C2. Typically, each language level is associated with a set of competencies that speakers at that level would generally be able to perform; these have been outlined in a table published by the European Council.

Looking at that table, I’d rate my English skills at probably C2 across the board, though I’d be a little hesitant to claim that for spoken interaction. For Chinese, I’m probably a rough B2 for listening/reading, and somewhere between B1 and B2 for speaking/writing. On the other hand, for German I’m probably somewhere between A1 and A2 for listening and reading, and closer to (or possibly even below) A1 for speaking and writing.

Another way to assess one’s skills is to look at language certification examinations. These are often used as part of work permit requirements. For example, the UK Tier 2 (General) visa typically requires applicants to pass an approved English language test at a B1 level. Chinese work visas operate on a point-based system, and additional points are successively offered with each level of the HSK completed. It seems one doesn’t even need to speak any German to get a German work visa; however, reaching a B1 level allows for quicker permanent residency.

I haven’t actually formally taken any of these exams, though I have looked at the test material and even done a few of them under exam conditions. I was generally able to navigate the CPE (English C2) exam quite comfortably. For Chinese, I haven’t had too much trouble with the HSK 5 (claimed to be between B1 and B2); the HSK 6 (claimed to be between B2 and C1) is somewhat trickier mainly because its writing section looks nasty, though I’ve been able to do the reading and listening sections. Similarly, on the Taiwanese TOCFL I cleared level 4 (B2) quite easily, and scraped a pass from inferring kernels of truth on level 5 (C1), though I would say my listening/reading are definitely not at C1 level (“appreciating distinctions of style” is certainly generous, to put it mildly),

For German, I’ve steered clear of the Goethe-Institut past papers for now as there are very few practice papers available online, and I’ll want to do them when I’m preparing for the actual examination. I found a slightly different source of practice material that seemed to be at an appropriate level – the UK General Certificate of Secondary Education (GCSE). These exams are typically taken by students in England at the end of secondary school. Generally, a good GCSE seems to map to around an A2 (e.g. based on Oxford’s language program a “good but rusty GCSE” would be in line with A2, and a “recent” one with a high grade would be closer to B1; Sussex similarly places it in the A2-B1 range, though Imperial is a bit stricter and lines it up with A1+).

German is offered as one of the modern language GCSEs – others include French, Italian, Mandarin Chinese and Japanese. Interestingly, some of these GCSEs are tiered; that is, students must be entered for either the foundation tier or higher tier. Questions in the foundation tier are easier, but the highest grade one can obtain there is a 5 (passing grades run from 9 to 1 in the UK, 9 being the highest). The higher tier features more material and questions requiring more advanced problem-solving – as its name suggests, it is intended for more capable students. Higher tier exams are graded from 9 to 4; in particular, candidates that fail to obtain a 4 receive a U (with the caveat of a ‘safety net’ grade 3 that only goes down to the midpoint of 3). Typically, some of the questions overlap – these are the questions aimed at a grade 4 or 5 skill level.

I can see why tiering could be advantageous – it allows finer resolution when looking at students’ performance. It may also lead to a better student experience, in that candidates generally won’t find the exam completely intractable (or, conversely, find it trivial). That said, deciding which tier students should be entered at seems a tough problem, and making the wrong choice could lead to results that wouldn’t be representative of a student’s ability (a student who would reasonably score a 3 could get a U if entered on higher; a student who could score a 6 or higher would be limited to 5 on foundation tier). Furthermore, these decisions need to be made in advance, which could lead to issues if a student who would be capable, with effort/studying, perform well on higher tier have his/her motivation and/or progress curtailed because he/she was entered at foundation tier.

To give a sample of the difference in difficulty of the tasks involved, I had a brief look at the AQA German specimen papers:

  • A Foundation-only task involved parsing an SMS from a friend who was running late; key-words in the text included 7 Uhr (meaning 7 o’clock), U-Bahn (subway) and Theaterkasse (ticket office) or Karte (can refer to a ticket) to identify that they planned to go to the cinema.
  • An overlapping task involved identifying words like Ausland (overseas) and wichtiger (more important) to distinguish different friends in a text.
  • A Higher-only task involved reading an interview of a student who enjoys travelling. Questions involved engaging/reasoning with the text, and seemed less reliant on directly identifying keywords. For example, the first question there asked why she needed a holiday every year for ten years (the answer being that she went on holiday after her exams, and she studied hard for a month for these exams).

This system isn’t explicitly used in Singapore for the O Levels which students take at the end of secondary school (perhaps apart from Elementary and Additional Mathematics, and Higher Mother Tongue options – but even then, these are considered distinct subjects). I’m not sure I’ve actually seen this system used before.

Above the Inclined Bar (Q3 2019 Review)

Work has been fine, though I’ve noticed my hours have been growing longer. I guess some of this has been me trying to adapt to and work well in areas that I’m not sure are historically in my wheelhouse (mainly around prioritisation; most of my other work concerns decomp-ing larger features, which I think is something I can do reasonably well especially in the context of AtlasDB). I do appreciate the challenge here though. The theme I’m going for, as it remains, is superlinear growth; which involves enabling others to work more effectively and guiding them as needed. My interactions with the AtlasDB team thus far and comparing notes with others trying to guide teams suggest that I have a tendency to be relatively hands-off with design but strict with reviews, perhaps in both cases more than I should be.

I had two major trips this quarter (Palo Alto for work, and then Singapore with a stopover in Zürich), which feels slightly above average. There wasn’t much in the way of short trips. I think I enjoyed the change of routine each of these trips provided; work has kept me pretty busy, perhaps because I’m pushing for overly tight quality controls, as I’ve been advised.

I’m unlikely to re-qualify for KrisFlyer Elite Gold this year. I’ve been travelling quite a lot, but I’m in this position for two reasons. Firstly, my flights to the US are mostly done on Virgin Atlantic, which when credited to KrisFlyer earns redeemable miles but not the elite miles that count for status credit. I’ve actually flown close to 20,000 miles in this way. Secondly, I’ve been flying Economy with an extra legroom seat instead of Premium Economy, which tends to earn fewer miles. A cheap economy ticket usually only counts for 50% of the distance flown (while Premium Economy almost always counts for at least 100%), and extra legroom seats don’t actually give you any more miles. I did think about doing a mileage run to top off the 50,000 miles, but the gap is probably too large; I anticipate finishing the year on around 37,000. The 13,000 gap is around one round trip to Singapore (!) on a ticket class that earns 100% miles.

Following on from the Q2 review, I have indeed been less interested in the gyrations of the market. I actually wouldn’t be able to give a confident answer as to how my portfolio was doing without looking it up.

That’s actually somewhat better than I expected, especially viewed in the context of the Q1 and Q2 results. The LS80’s performance seems a little weak as I thought the bonds (which performed well) would help, but it seems that the UK home bias worked against it.  I guess the pound falling by just over 6 percent over the last 6 months against the dollar does make the numbers look nicer than they should be. To be fair, I should have seen this coming; my portfolio has increased by more than the take-home income I’ve made from work, which is obviously untenable without market gains.

Spending has been higher than normal this quarter; about 60% above Q2, and 25% above Q3 last year. I think some of this is connected to stress at work, and some with no longer chasing pristine balance sheets in general. I don’t ordinarily think of Q3 as particularly spendy (typically Q4 is the most expensive, but there isn’t a consistent ordering between the first three quarters).

In terms of logic puzzles, the last few contests for the Sudoku and Puzzle GPs for this year are done. In Sudoku, I had a pretty weak-ish round 7 (score 325; rank 98/414) and a rather solid round 8 (score 435; rank 60/420). For Puzzles, I had two fairly normal rounds (7: score 341; rank 82/344, 8: score 312; rank 93/315).

Overall rankings are computed based on adding up the top 6 raw scores across rounds. There are a total of 8 rounds, so participation in an additional round (no matter how poor) will never harm one’s overall raw score. I guess getting an accurate measurement does require some balancing between rounds (e.g. two participants of roughly equal skill may have very different scores, if one has an off day on an easy round while the other has an off day on an excessively difficult one, since everyone might discard the difficult round anyway), but I’m not sure how to do that. The other obvious mechanism (normalising scores, so that the first-place scorer scores 1 contest-point, say, and everyone’s score is scaled to that) is probably too sensitive to the people at the top of the leaderboard having an off day. Maybe some kind of mechanism where the median scorer scores 1 contest-point, instead, could work.

My overall rank in Sudoku was 66/886, and for Puzzles 92/656. I set a target at the beginning of the year to have a top-100 finish in both, though I was more confident in the Sudoku contest. I missed one round of puzzles and had some pretty poor rounds, so I wasn’t sure if I would clear that mark. I finished 428 points over the bar for Sudoku (which is probably just over what I would score in one round on a good day), but just 61 for Puzzles (I’ve solved single puzzles worth more than 61 points). That should be it until next year; people are preparing for the World Sudoku and Puzzle Championships now. I’m sadly not good enough for those (yet!).

German lessons continue; my teacher went on holiday for 5 weeks but lessons have resumed since. I’m making some progress, though the range of things I’m able to discuss still largely lie in the realm of the concrete (like Ich war in Singapur für eine Woche or Ich muss etwas essen and so on, which mean I was in Singapore for a week and I must eat something). I’ve been reading through the Dino lernt Deutsch series – I’m mid-way through Karneval in Köln, the third book. I also worked on some grammar and writing exercises in both the official textbook we’re using (Begegnungen A1) and another book suggested by the teacher (studio [21] A1).

I’m still enjoying learning as well, though there are some concepts that sometimes seem rather arbitrary. One I’ve run into recently is that of separable verbs. For example, waking up is referred to by the verb aufstehen (literally “up” + “standing”; not too different from “get up” in English, to be fair). However, this verb is separable and thus instead of writing or saying something like Ich aufstehe jeden Morgen um 7.30 Uhr (wrong), I would have to write/say Ich stehe jeden Morgen um 7.30 Uhr auf. However, not all verbs that are compounds have this property (e.g. besuchen, to visit, has be- as a prefix of suchen, to search), so something like Ich suche Singapur be would be wrong; determining whether something is separable or not seems to involve memorizing a bunch of seemingly arbitrary prefixes. I think the grammatical rules once one has identified a verb as separable or inseparable (similar to noun genders) make sense, at least.

Grgur introduced me to Spirit Island, a somewhat heavier cooperative board game. Players play as spirits which aim to protect an island from colonial invaders. The invaders explore the island, build larger settlements and then ravage the land (reflecting pollution/damage brought about by their construction); spirits play powers to directly destroy invaders, move them around, or enhance the strength of the indigenous people to fight them off.

The game takes place in turns, and each turn has two phases for powers (one, for fast powers, happens before invaders take actions; the other happens after). Powers are resolved one at a time, but can take place in any order that the players agree on. This often allows for synergistic plays (e.g. gathering invaders into a land and then hitting that land with a powerful power). Interestingly, finding the best powers makes me think about finding the most advantageous serialization of a bunch of database transactions. Some powers have conditions (e.g. invaders must be present/absent, the land must suffer from Blight or not, etc.) but don’t actually change these states of the land, so they are effectively performing a read of that state of that land; others might affect these traits and would thus be writing to such a key.

I do enjoy the game quite a bit. I’ve played a few times in a group and maybe around ten solo games (though usually playing two-handed), and have won games up to a 9 out of 10 on the difficulty scale. I think a good challenge level for me is probably around 7-8; below that, it seemed like winning was never really in doubt, while the level 9 game was a nail-biter and I won on the very last possible turn.

I usually conclude each quarter’s review with some insight into the music that I’ve been listening to, though this quarter has seemed a bit dry. I think finding new music can be hard; flights on Singapore Airlines are usually a good opportunity for me to discover things, as the IFE usually has a good selection – however this seems to be less true on Virgin Atlantic and on Swiss. My more conventional pick here would probably be Jonah Baker’s cover of Ariana Grande’s thank u, next (this was published in November last year, but I admittedly don’t frequently actively seek out new music). The second and third verses in the original worked well and I would say I’m supportive of the general messages there (take care of oneself, have self-confidence). These were mostly retained in the cover (swapping genders and the name self-insert, as reasonably expected). I would say that the main issues I had with the original were some possibly gratuitous swearing and the first verse being too specific – it’s relevant to her circumstances but naturally limits the extent to which listeners can identify with the song. These were addressed here, and the execution was pleasant and enjoyable.

Separately, I’ve been listening to a fair bit of video-game music to power me through long implementation sessions; songs with lyrics tend to be too distracting, and I tend to reserve the classical music or solo piano pieces to times when I need deep focus. I’ve posted about the Touhou 2D shooter game series before, and one aspect of that that I enjoy is the music. These tracks tend to be upbeat and have strong, catchy melodic patterns, which I enjoy; two I’ve been listening to quite a lot have been Golden Hymn ~ Ibis Trismegistus and Tracks of the Snow Rabbit ~ Nowhere but Everywhere. The shooting games often have bullet patterns designed to partly follow the music, but I find that they still work well without context. That said, having played the boss battles where the music was sourced from, I’m not sure how much of the context I can strip from each of these tracks.

Learning German 2: Einfach Texten

Meine Deutschlehrerin war fünf Wochen in Urlaub. Wir müssen uns selbst lernen. Sie gibt uns fakultativ Hausaufgaben; ich lese ein einfaches Buch, Café in Berlin und mache ein paar Online-Übungen. Das Buch ist ein Sammlung von Kurzgeschichten über Dinos Leben. Dino komme aus Sizilien, aber er studiert Deutsch in Berlin. Das Buch ist meistens einfach, aber es gibt ein paar neues Worter. Die Grammatik ist schwieriger – das Buch benutzt die Genitiv und der Dativ. Das haben wir noch nicht im Unterricht gelernt.

My German teacher was on holiday for five weeks; we thus must learn on our own. She gives us optional homework; I read a simple book, Café in Berlin and did a few online exercises. The book is a collection of short stories about Dino’s life. Dino comes from Sicily, but he studies German in Berlin. The book is mostly straightforward, but there are a few new words. Grammar is more difficult. The book uses the genitive and dative cases. We haven’t covered these in class yet.


Two common strategies for language learning are extensive reading and intensive reading. As the names suggest, extensive reading involves covering a wide breadth of material while intensive reading involves studying texts in greater detail, translating words that are unknown, unpacking difficult grammatical constructions and perhaps attempting to discern the rationale for the author’s stylistic choices as well. Often, intensive reading demands a large amount of mental focus and concentration, so the amount of text that can be covered is smaller.

My memories of language learning are fairly faint, as I last formally studied English and Mandarin more than 10 years ago. That was at the end of high school, and most of what I covered at the time was aimed at a C1/C2 level for English, and probably B2 for Mandarin. By that point, the courses focused primarily on understanding longer texts and, for English, figuring out how literary devices may have been used; my memories about learning more fundamental topics like grammar or conjugation would thus be even fainter. Lessons in school were largely focused on intensive reading; there were a few odd assignments that sought to prompt students to read more extensively, but these were rarely assessed which sadly often meant that more attention was paid elsewhere. I don’t particularly recall having a passion for or even an interest in reading when I was young (I remember being more interested in computer games and mathematics at the time), so perhaps the intensive reading done in class was mostly sufficient!

I have more recently learned programming languages. I picked up fragments of Java and C++ over the years starting from Secondary 1 or so (year 7; I was 13 or 14 years old then), and started refining these more carefully as I started at Imperial. Most of the reading I had done up to that point would probably be better classified as extensive; I think the control flow structures were covered in class over a few lessons, but after that I could mostly code up algorithms with practice and experience. The Software Engineering (Design) course and my internships at Google and Palantir were probably pushes towards the more intensive direction, as I learned more about principles that could lead to better code. Since then, I think code reading has been mostly ‘extensive’, especially recently (I review quite a lot of code, more than I write), with the occasional intensive deep-dive (e.g. reading parts of the Java standard library HashMap, or more recently Cassandra’s StorageProxy).

For learning German, I plan to use a mixture of both strategies, though perhaps at least initially leaning more towards the intensive side of things. There are some concepts like grammatical case and declension which I could assimilate through extensive reading, though I think it would be a lot faster or easier to pick these up by learning the relevant concepts directly. To quote an example from the book,

Ein eisiger Wind blies über den Asphalt.

I knew enough from the context to easily figure out that this means “An icy wind blows over the asphalt” (the story mentions earlier that it was snowing, and everything was white). However, it’s dangerous to generalise this to say that it is always correct to use eisiger to mean icy – it is correct here, because wind is in the nominative case, and wind has a masculine gender. If either of these is no longer true, the correct form might change, and it may take a while before the correct patterns are inferred (e.g. Ein Wind blies über den eisigen Asphalt – asphalt is in the accusative case, or Ein eisiges Auto fahrt über den Asphalt – cars have neuter gender – respectively).

This naturally meshes well with the lessons – naturally there isn’t that much that can be covered in the two hours or so of class time we have each week. Although it is a light book, I think my treatment of Café in Berlin has been largely intensive as well, or at least more focused than how I would read a book as part of the extensive reading assignments I used to have in school. Each chapter of the book is followed by a few questions that test reading comprehension; I do these. I also copy out some of the new vocabulary terms and some important words or phrases, often drawing pictures of the scenes and labelling items in them with the relevant words. Sometimes, I will also pick out a few harder sentences and attempt to determine why they are grammatically correct. Starting with extensive reading can be tricky at my (very basic) level, because there probably aren’t many texts that are suitable – and texts that are readable are likely to focus more on relatively simpler narratives, which may be less likely to be able to sustain my interest.

Algorithmic Modelling – Touhou Project 11 (Subterranean Animism)

The Touhou Project is a series of “bullet hell” shoot-em-up games. In these games, the player controls a character within a 2D plane and needs to dodge large quantities of bullets. These games tend to be fairly difficult, testing players’ reflexes and in some cases logic as well (for example, many patterns are aimed at or relative to the player’s position; misdirecting such patterns can be useful).

I wouldn’t say my reflexes are very good. Nonetheless, good progress can be made using careful resource management; players are given tools in the form of lives (extra chances after getting hit) and bombs (single-use abilities that clear the screen and deal damage to enemies). The eleventh installment of the series is called Subterranean Animism (SA), and I’m choosing to look at it for this post because it is widely regarded as the hardest game in the series to clear on normal difficulty. For most of these games (on normal), I can just sit down, play the game, dodge bullets and win. There were two exceptions – the fifteenth entry Legacy of Lunatic Kingdom (but even then that only took about five attempts), and SA. SA required a nontrivial amount of planning – I had to learn some of the specific patterns, and also chose a shot type I wouldn’t normally pick.

I generally play Touhou games on normal with an aim to complete the game on a single credit; this is called a “1 Credit Clear” or 1CC. I’m generally somewhere in between difficulties; I’m fairly comfortable with Normal in most cases, but Hard is hard (the game also has an even harder Lunatic mode). I’ve successfully completed 1CCs of most of the games in the series on Normal, and a few of the easier ones (7, 8, 10) on Hard. SA was the toughest game in the series for me to 1CC; it is also the last one I did, at least from installments 6 through 16.

Resource Management

Touhou games usually start the player with two spare lives; this is true in SA as well. However, the bomb mechanic is different from other games, which give the character a fixed number of bombs per life. In SA, players sacrifice some of their shot power when using a bomb. A character’s shot power usually ranges from 0.00 to 4.00; this is increased by collecting powerups when fighting stages or bosses. Firing off a bomb costs 1.00 shot power (and cannot be done if one is below 1.00). This can be frustrating, as some patterns become more than proportionally harder if the player’s shot power is low. When a character is hit, she (the games feature an all-female cast) will drop powerup items such that shot power will be reset to at least 2.25 (higher if shot power was at least 3.00). There is an exception – if it is the character’s last life, a full powerup item will drop that sets shot power to maximum.

The game also has mechanics for earning additional lives. In SA, boss enemies have a staged health-bar with multiple patterns; if the player defeats a pattern within the time limit and is not hit, a life fragment will drop; five life fragments result in an extra life. Bombs are allowed.

A Touhou game is divided into six stages; typically stages 1 through 3 are mostly a non-event for me. That said, for SA, the boss of Stage 3 has a few fairly nasty attacks. Most of my aforementioned “blind” or casual 1CCs involve racking up large stocks of lives and bombs on these stages, and then utilising these aggressively in the later stages. We can see this on SA, as well as on what is often regarded as one of the easier entries in the series, Imperishable Night (IN); the first death on SA is at the end of stage 4 while that on IN is at the end of stage 5. That said, I’m actually already failing to dodge patterns as early as stage 3 or 4. It’s important to be willing to use bombs to deal with difficult patterns, as they are much easier to recover (by subsequently picking up powerup items) in SA. This becomes even more important in other games like IN, where bombs that are unused when a player is hit just go away.

Character Selection

Touhou games usually give the player a choice of multiple player characters, and sometimes for each character different weaponry. Typically, different characters have different movement speed and possibly some other advantages or disadvantages, like having a smaller hit-box or extra bombs. In terms of weaponry, players may select from different normal shots and bombs, which usually have balanced trade-offs. For example, one may pick a homing shot which does less damage but can hit enemies anywhere on the screen, or a shot that only shoots straight ahead but does more damage.

Earlier, I mentioned being able to sit down and just play the game; in most cases this involves the main character of the series, called Reimu, who usually (and in SA) has relatively slower movement and a small hit box. I also normally use her homing shots for a first playthrough, even though I usually prefer straight shots after I get more comfortable with the game. These don’t quite exist in SA.

Apart from slightly different shooting and movement mechanics, many Touhou games also feature a medium to late stage boss (often on Stage 4) which adapts her patterns to the player’s character selection. This is on full display in SA as well; the Stage 4 (out of 6) boss has a relatively easy warm-up battle that is static, before reading the player character’s mind and creating patterns from that (which differ depending on the character and shot type).

Most of the time, the different variants of patterns the boss uses are quite balanced. However, this isn’t the case in SA and thus influenced my selection. Although I find ReimuA (with straight shots) is best equipped to handle the Stage 5 and 6 bosses, the Stage 4 fight one has if one makes this choice is extremely difficult, I’d say possibly even harder than the later bosses. Pictured above is Double Black Death Butterfly; it isn’t apparent from the picture, but some of the butterfly bullets are rotating inwards (and so one needs to dodge bullets possibly coming from behind as well). I thus picked ReimuB (which has a weakly homing shot, a relatively easy Stage 4 fight and a special ability to gather powerups from anywhere on the screen) for my 1CC.

Learning the Patterns

Of course, even with careful resource management it’s unlikely that one can perform a 1CC if one’s dodging skills are too far below the bar. While some of the patterns are random and/or based mainly on reflexes, others have a certain trick to them that makes the pattern a lot easier once figured out. With experience, one can figure out common elements and ways to deal with them (for example, a stream of bullets fired at the character’s position; move slowly, but to change directions make a sudden quick movement to open up a gap in the stream) – this drives most of the “sight-read” clears.

In a sense, good resource management is less critical (consider that one can completely ignore the resource system if one can reliably dodge every single pattern in the game) if one can dodge the patterns. That said, it’s actually possible to clear one these games even if one is quite poor at dodging them, if one makes good use of the resources one has.

Learning German 1: Ich lerne jetzt Deutsch

When I was in middle school and high school, I struggled a lot with learning both English and Chinese. In the end, I performed reasonably well in the relevant summative assessments (I obtained a 6 in English A1 SL and 7 in Mandarin B SL for my IB certificate), but it was always a struggle. I don’t think I struggled particularly with understanding or writing as far as English was concerned; I had more difficulty with decoding literary devices and interpreting poems and related themes. I found learning Chinese challenging, perhaps because I didn’t speak or listen to it much at home, and also because all other lessons were conducted in English.

I’m not sure if this has had a negative effect on my preference for language learning, though to some extent I certainly associate this with stress and difficulty. Nonetheless, about two months ago I decided to start learning German a bit more seriously.

I downloaded the Lingvist app after a colleague recommended it to me. The app performs pretty aggressive vocabulary drills – it’s been useful for plugging basic gaps and discovering new words. According to the app, I’ve learned about 1100 words; the app allows you to learn at most an additional 20 per day, though that’s usually enough to keep my hands full. I’ve been using up this quota most days.

However, the app doesn’t cover the principles underlying grammar, and of course the ability to train listening, speaking or writing is somewhat limited. I thus took an opportunity at work to start more formal lessons, which should help me get better at these skills. The teacher, Katja, has been great – I do understand a fair bit more now, and (hopefully!) sound better and clearer when I speak. I’ve found the lessons to go at a pretty decent pace; they can be demanding, but I like that.

Why German specifically? Firstly, it is a practical choice. German is relatively widely spoken especially considering the countries I might consider moving to, or at least plan on visiting for holidays in the future (which would include Germany and Switzerland).

Secondly, I’ve certainly picked up a few words from my time in Zurich, mainly “Ich spreche kein Deutsch” and how to navigate shops (imagine someone knowing that Rechnung means invoice or Insgesamt means total, but not knowing words like Vater – father – or Tschüss – goodbye), so I’m not exactly starting from zero in terms of vocabulary, even if my knowledge of the grammar and fundamentals may be lacking.

Finally, I find the way words are constructed or varied quite pleasing. I recently came across the word Nachfolger in Lingvist, which means “successor”; the parts mean “after” and “follower”. I’ve come across quite a number of words where the meaning makes sense considering the components, which is nice – Zeitpunkt (point in time) or Verantwortung (responsibility, but Antwort means answer – in a sense of being answerable for something) come to mind.

I anticipate that the grammar may be quite difficult to pick up – declension is considerably more prevalent in German than in English, where tricky cases are mainly in the pronouns, or Chinese. Gender for nouns that don’t obviously seem to have a biological or possibly identity gender is often arbitrary – for example, tables are male, flasks are female, and babies are neuter! In English, he and she are rarely used outside of these ‘clear’ cases (there are a few exceptions, e.g. ships or countries are sometimes feminine, though it generally still feels more natural to me to use ‘it’).

Grammatical cases seem to be another sticky point; articles and adjectives may be written differently depending on whether a noun is the subject or object.  Das ist ein alter Drucker means ‘that is an old printer’, but I’d write Ich habe einen alten Drucker for ‘I have an old printer’ (printers are masculine). However, if I was talking about a lamp (feminine), I would have to write Das ist eine alte Lampe.

Furthermore, sentence structure is different. English and Chinese generally follow subject-verb-object ordering in a sentence. However, German features V2 order, where the verb usually must come second, but other than that things are more relaxed. For example, Every Saturday I read a book is fine as a sentence in English; 每个星期六我读一本书 would work in Chinese. However, the straight translation Jeden Samstag ich lese ein Buch is not OK in German; the verb has to be in position two, so it would have to be Jeden Samstag lese ich ein Buch (or Ich lese ein Buch jeden Samstag, or Ein Buch lese ich jeden Samstag depending on what is intended to be emphasised).

My formal knowledge of grammatical structures within English is also fairly lacking, even though I think I am able to differentiate between grammatical and ungrammatical sentences in English. I had to refresh myself on what an infinitive was during the German course. German also has quite a few more constructs (e.g. accusative and dative cases) which will take some getting used to. Nonetheless, I’ve enjoyed learning so far, and plan on continuing to learn it, hopefully to at least a B1 level.

17:9 (Q2 2019 Review)

This quarter felt particularly tough for me, for various reasons. I remember being tasked as a 16-year old back in middle school to, for a philosophy class, write an essay on the meaning of life. I don’t remember the content of that essay particularly well; I remember that I took an existentialist approach to the problem. Essentially, it is up to oneself to create some semblance of meaning. I think I found the quarter more draining than normal because I was confronted with situations that made me re-evaluate some of the underlying principles I use to guide my decisions.

I’m still on the AtlasDB team. The transactions2 project I’ve been driving has finally been (mostly) completed. It has been almost nine months since this started, and it’s the largest and probably the most difficult project I’ve done professionally. I see quite a few parallels with MCMAS-Dynamic (though transactions2 is probably theoretically easier but more difficult in terms of implementation). There’s always a bit of burnout after launching these large projects, perhaps because of the substantial time and effort invested in them.

Looking forward, the lead stuff now means that I’m helping with scoping and guiding work on pretty much all the major things the team is doing – which also means that for a change I’m not actually directly leading an individual project. I’ve also continued to interview and (I hope) further refine my skills – I like the debugging facet and have kept plugging away at it.

I normally write a healthy section on finance, but it hasn’t featured as prominently this quarter. I normally update my tracker spreadsheets twice a month, on the 10th and 25th, but I missed the 10th June update completely. It’s perhaps a reflection on the importance of different things; as much as I would like to champion financial responsibility or support the FIRE movement, there are many more important things once one’s affairs are mostly in order. This was a pretty normal quarter in terms of saving and spending – there were many things that felt luxurious as I holidayed in Belgium and Japan, but a good chunk of that was prepaid in Q1. Investments seemed to pretty steadily push their way higher up the charts (I’m up a few percentage points); this is probably in part due to a fall in Sterling, though.

One thing that got more serious for me this quarter was learning German – or, as I should say, Ich lerne jetzt Deutsch. It’s a privilege to take lessons at Palantir and the instructor is excellent; besides that, I’ve also been using Lingvist (a flash-card app) to expand my vocabulary. I’ve found the grammar to be quite challenging; the myriad ways in which nouns and adjectives get declined is not something my past experience with English or Mandarin helps with very much. I often use strange mnemonics to keep track of noun gender (such as little Bobby Tables for der Tisch, a Brutalist town centre for das Zentrum, and Minnie Mouse for die Maus). Ich habe leider keine Konfidenz auf Deutsch zu schreiben – that is, I unfortunately don’t have the confidence to write in German (beyond simple phrases and isolated statements).

I travelled quite a bit this quarter, balanced between work and leisure. I visited Boston for the Palantir puzzlehunt. I also visited Singapore for Daniel’s wedding, and Brussels and Tokyo for holidays. It can be quite expensive, but I’ve been finding I need a bit more relief from the pressures of work and general administration than normal. I enjoyed these trips, to some extent in spite of very packed schedules. The Brussels and Japan trips were mainly food-focused (though the Musical Instruments Museum and Sankei-en Garden, respectively, were also standouts; I think we spent about two or three hours in each of these places, but if I was on my own I could imagine spending the whole day there). Satou Steakhouse (teppanyaki), Ginza Tamai (a restaurant specialising in sea eels, or anago) and even the somewhat more humble Toriyoshi (grilled chicken skewers or yakitori, and fried chicken or karaage) were all excellent. I’d like to go back, schedule allowing; I had a really good time.

This quarter also features a fairly large number of bank holidays in the UK, meaning that I had a number of three-day weekends (and four, in the case of Easter). I’ve started to take more interest in enjoying these extended holidays by trying to do different things (as opposed to focusing on reading, logic puzzles or things along those lines). It seems like I end up going on longer walks, and staring at coffee cups in cafes; past me would have decried this as a waste of money – and while I intellectually can’t deny that it is frivolous, I do still enjoy this.

In terms of logic puzzles, the WPF Sudoku and Puzzle GPs are almost over. The seventh round of the Sudoku GP ended last week, and it felt absolutely brutal (I scraped 325 points and a 98/414 rank). It wasn’t my worst round (that was the fourth round), but in round 4 I made steady progress while breaking a few puzzles while this time I struggled to tackle the puzzles at all. I had two good rounds in between (round 5: 51/502; round 6: 57/476). I had two decent rounds for the Puzzle GP – I’d say I’m weaker there, and I ranked a reasonable 90/384 in round 4 and 83/383 in round 5; conversely, round 6 was an absolute mess for me though and I ranked 207/349, which is my first sub-median score in a good while!

I played a lot of Slay the Spire in Q1 but this slowed down; in fact I haven’t spent very much time at all on computer games this quarter. I didn’t play very much in the way of board games as well, though I distinctly remember a Pictionary session where I managed to guess CURRY off a bunch of lambda expressions, and a few Codenames Duet clues – an AIRBASE, 3 clue for MESS, FLAG and APRON which landed perfectly, and a game which went wrong when I tried to be smart and gave a STEEL, 5 clue for a bunch of vaguely metal-related words not noticing that BEAM was an assassin – or rather, noticing that it was there, but having my mind filled with images of laser or wireless signal beams.

Musically I’m not sure where things were going this quarter. I did listen to more instrumental pieces. A good number of these were piano-focused, both classical (like Liszt’s Hungarian Rhapsody No. 2) and relatively modern (like Rush A and other entries in that series). Some of these also come from video games (like Fantastic Light, Ancient Flowers from the Touhou series). A common theme here might be speed – many of these pieces are very fast. Perhaps I find music to be an outlet for dissatisfaction when things are not going quickly enough.

On the flight back to Singapore, in between rounds of Tetris I listened to Calum Scott’s debut album Only Human. I think I recognised his name from his Dancing On My Own cover, though I really don’t watch much TV or listen to the radio so I didn’t know what kind of music he produced. It was mostly very listenable, though a bit on the heavier side (I guess in my opinion at least this fits his voice much better, though).

I particularly enjoyed three of the tracks on the album, though I think only one of them can reasonably qualify for my song of the quarter. The opener If Our Love Is Wrong is well put together, though more specific to Scott’s situation; the closer Not Dark Yet (a Bob Dylan cover) works well but is a bit too dark for me to enjoy – which is probably the point. My winner is the much more straightforward You Are The Reason; it’s a clean and well-executed piano ballad that seems to carry a certain gravitas. The line in the chorus about fixing what one has broken also appeals to me; I think if I look back at the songs I’ve chosen, failure and subsequent correction is a pretty common theme (e.g. Starting Over, These Days, Back from the Edge). Scott’s vocal line does get pretty difficult to follow, but it makes sense given the subject matter.

Death by Cubes (Algorithmic Modelling: Pandemic)

“So the probability we lose is 2/3, multiplied by 5/23, or 10/69. It’s pretty much a 6 in 7 shot.”

I met a friend for dinner and board games a while back, and one of the games we played was Pandemic. Designed by Matt Leacock, the game is themed around managing and discovering cures for diseases before they spread across the world.

Diseases are modelled using cubes, and they spread across a network of cities (which are nodes in a graph). On players’ turns, they perform actions to contain the spread of diseases, research cures for these diseases or share knowledge with other players. After they are done with their actions, players draw cards from an infection deck, where each city (node) is represented once. For each card, players need to add a disease cube of the city’s colour to the city. For example, considering a simplified network:

  • If D is drawn, one yellow cube will be added to D. Similarly, if E is drawn, one red cube will be added to E; if F is drawn, one blue cube will be added to F.
  • A city is allowed to have a maximum of three disease cubes of each type; if a fourth cube of the same type needs to be placed, an outbreak happens. Instead of placing the fourth cube, all connected cities receive one cube of the relevant colour. For example, if C is drawn, a blue outbreak occurs in C, and one blue cube is added to both B and F.
  • The rules on having at most three cubes of each type still apply when placing additional cubes, meaning that outbreaks can cause chain reactions. For example, if A is drawn, a red outbreak occurs in A. This causes one red cube to be added to B, D and E. However, B already has three cubes, meaning that a chain outbreak occurs in B; this causes one red cube to be added to A, C, E and F.
  • This looks like it would loop infinitely, but there is some mercy; in a given chain reaction, each city may only outbreak once. Thus, instead of adding a red cube and triggering an outbreak again in A, no red cube is added.

The game ramps up steadily in pace, by increasing the infection rate (number of cards drawn) over time. Players lose the game when the eighth outbreak occurs, when they need to place disease cubes but can’t (these are component-limited), or when the deck of player cards runs out.

Separately, the goal of the game is to research a cure for each of the four diseases in the game, which requires collecting data on the spread of the diseases. There is a deck of player cards which contains twelve city cards associated with each disease; players need to collect five of them (in one player’s hand) and bring them to a research station. This can be tricky, as players draw cards independently, and giving cards is restricted (I can only give you a card if we’re both in the one city that is associated with that card, and if it’s my turn). At the end of each player’s turn, players draw two cards from this deck (if they can’t, the game is lost).

The deck of player cards also contains a few special event cards which help players, and more interestingly several Epidemic cards which are disruptive. The number of Epidemic cards to include is variable (4 are used in an easy game, 6 for a difficult one). When an Epidemic card is drawn, players resolve a three-step process:

  1. “Increase”: The infection rate marker moves along its track, possibly increasing the infection rate (number of infection cards to draw at the end of each player’s turn). This begins at 2, but eventually becomes 4.
  2. “Infect”: There is a sudden wave of disease in a new city. Players draw the bottom card of the infection deck, and the city in question receives 3 disease cubes of its colour. The usual Outbreak rules apply, though thankfully only one Outbreak occurs even if the city already has two or three cubes.
  3. “Intensify”: The infection discard pile is shuffled (including the just-revealed card from the bottom of the infection deck). These cities are likely to suffer from more disease soon, especially since this happens as part of players drawing cards (before the infect phase of the current player’s turn).

Going back to the initial calculation, we were on the second last turn of a game with six Epidemic cards, five of which had already been drawn. There were three cards left in the player deck. We already had seven outbreaks occur, meaning that one more would lose the game. However, we had also cured three diseases, and the Medic which I was playing was sitting in a research station with all of the cards to cure the last disease on the next turn. Furthermore, my friend who was playing the Operations Expert held the One Quiet Night Event card, which allows skipping of the Infection phase.

Thus, the only risk of losing was drawing the last Epidemic card, and then in the Infect step revealing a city on the board which already had disease cubes of its colour (from outbreaks in adjacent cities). These events draw cards from separate decks, so their probability should be independent.

The first term is easy – there were three player cards remaining, one of which was the last Epidemic card, so there would be a 2/3 chance we would draw it. For the second term, we looked through the infection discard pile, which at that time had 24 cards (along with Sydney, which we removed from the deck using a special event card). There were thus 23 unseen infection cards; six of them corresponded to locations on the board which had disease cubes. On my friend’s last turn, we were able to defuse one of these locations, leaving a final loss probability of (2/3) * (5/23).

It turned out that we got lucky as we didn’t draw the Epidemic card, and even then the card at the bottom of the deck would have been safe. I wasn’t initially keen on doing too much of the calculation, figuring that clearing one risky place was easy but two was hard, but my friend (who is a statistician) decided to go ahead with the calculation.

On Set Collecting

When I hear the word ‘set’, the first thing I think of is the computing data structure, and then the mathematical construct that that data structure is trying to model. Essentially, a set is an unordered collection of distinct objects. I’d probably then think of the Egyptian deity before thinking of the card game, or failing at a contract in bridge. That said, we recently had some interesting discussions about the card game over lunch at work.

The game consists of a deck of 81 distinct cards which each show a number of shapes. Each card has four attributes, and each of these attributes can take on three values – number of shapes (one, two or three), colour (red, purple or green), shading (shaded, striped or unshaded) and shape (diamond, rounded rectangle, ‘S’).

Initially, twelve cards are dealt to the table; players compete in real-time to identify a set of three cards where, for each attribute, the cards are either all the same or all different. The player collects these cards, and the dealer replenishes the cards on the table.

It is possible that no set is possible with twelve cards. In physical games, the dealer will, after a while, deal three more cards to the table if no one can identify a Set. We were playing on an app, though; this app waits for players to claim that there is no set available, and penalises players if they make an erroneous claim. More often than not, even though all of us were looking carefully at the board, we were too quick to declare no-set with 12 cards. However, we had one round where even with 15 cards (after one declaration of no-set), no one found anything. After a long while, someone pressed the no-set button, and indeed there wasn’t a set!

After the game, discussion turned towards finding the maximum number of cards where no set was possible. We quickly settled on 16 as a lower bound; this is possible if you only use two of the values for each of the four attributes (e.g. by throwing out all cards that have three symbols, are red, are shaded or are diamonds). Now it becomes impossible to perform matches along any attributes being different, since you need one occurrence of each of the three values; also, because cards are unique there is no set of three cards where all four attributes are the same (that would be three copies of the same card). This arrangement has 2^4 = 16 cards.

Going beyond this is tricky, mainly because the number of possible groups of cards you have to pick from is large. There are 81 ways of selecting the first card, and 80 ways of selecting the second. The third would have 78 ways, since there is one specific card that won’t go with the first and second. However, later on you can’t just deduct one card for each already selected card; for a simple counterexample, suppose I have already selected:

  • (1) one red shaded diamond
  • (2) one green shaded rectangle
  • (3) one green shaded S

Now suppose I try and add the card (4) with one red shaded rectangle. This means that the card with one purple shaded rectangle would now become ineligible for selection, because it would form a set with (2) and (4). However, we have already eliminated this card from consideration, because it would form a set anyway with (1) and (3).

I turned to writing a quick program here. This is a standard algorithm based on depth-first search.

  • Each card is represented as a vector with four components.
  • There is an initial set of 81 vectors created.
  • To guide our search, whenever we consider adding a card to a working set, we iterate over the elements of the existing working set and determine which cards would, together with the new card, create a set. This relies on an observation that for any pair of (distinct) cards, there is one and only one card that would form a set with the first two. We then prune these set-creating cards from the search tree.

This found sets of size 17 quite quickly, but knowing that the bound was 20, I knew that wasn’t good enough. There were several implementation tricks that I used to help speed up the search.

  • This search is easily parallelisable; each branch of the search tree may be explored in parallel. A simple implementation (and what I used) could rely on Java’s parallel streams when doing the recursion, for instance. The orchestration around keeping track of the best answer needs a few small changes to be thread-safe, of course.
  • If the goal is merely to find some set of size 20, then we can exploit the symmetry of the problem and fix the first card to be any card (I used 0,0,0,0), since any cap set could be re-expressed as one that contains 0,0,0,0 by permuting the assignment of attributes to variable values. There may be more clever symmetry to exploit here than what I did.
  • Computing the last element of a set involves a bunch of jumps, branches and math; the result of this computation is deterministic, and can be cached so that it can be reused along different branches of the search tree. There’s probably something more clever I can do regarding overlapping sub-problems (this improves the runtime only by a constant factor).

This was sufficient to get the tool to spit out many sets of size 20, though I unfortunately didn’t churn through every possible selection, so this doesn’t show that 20 is an optimum.

Notes from a Nervous Engineer (2019 Q1 Review)

I think the first time I came across the concept of a scarcity mindset (where one approaches problems believing resources are finite) when I was around 14 or so. This was in The 7 Habits of Highly Effective People. To quote Covey:

Most people are deeply scripted in what I call the Scarcity Mentality. They see life as having only so much, as though there were only one pie out there. And if someone were to get a big piece of the pie, it would mean less for everybody else.

Covey recommends its counterpart, the abundance mindset, which is the idea that there are enough resources out there for everyone. That said, I don’t buy in to the idea of abundance being superior, because resources and opportunities often are scarce. I’d bring in the Bruce Lee “I fear the man who has practiced one kick 10,000 times” quote here; bearing scarcity in mind forces prioritisation, and that if done well is really useful. This may be dangerous, but I’d hazard that scarcity can lead to fear that one is stagnating. This, if managed well, can drive one to, to use Covey’s terms, aggressively “sharpen the saw” (pursue self-improvement) as well.

There are sides of the scarcity mindset that are certainly dark. There is a danger of casting things that are not zero-sum games as zero-sum games. Aggressively focusing on scarcity can lead to excessive stress and blind short-term optimisation (manifesting in things like money dysmorphia as described in this Guardian article). I’m also somewhat guilty of this, but it can lead to hoarding. That said, in my experience a scarcity mindset is often unfairly tarred and feathered – it indeed can often be dangerous, but it has its uses.

Software Engineering

Things changed direction; I expected to move off AtlasDB, but instead became the tech lead (admittedly with a bit of dithering and some convincing from other storage experts – and a few non-storage ones too). My responsibilities have changed somewhat in that I have been spending more time maintaining context and reviewing code. I don’t think there are benchmarks, but I suspect the amount of individual development work that I do is still high relative to other TLs (in any case it’s a spectrum – I’ve worked with one in the past who did more work than I did).

I also got started on studying Designing Data-Intensive Applications after recommendation from some engineers whom I respect. Having spent almost two and a half years on AtlasDB, most of the material is not particularly new to me – that said, this would have been an excellent read when I just started on the team. I’d recommend the book for people working with distributed systems (even if they’re not necessarily working directly on distributed systems – e.g. if doing support).

Finances

With Brexit looming, the pound has been extremely volatile. I was a bit of an uneasy Remainer during the 2016 referendum. In any case, the way things have panned out since has sent me very firmly in the Remain direction now. I’d say my exposure to sterling cash is at relatively low levels. I tend to be somewhat risk-averse, and although GBP is probably undervalued, the danger of no-deal is there.

I haven’t been tracking the markets very closely; from what I remember things went up in January (after getting smashed at the end of December) and then have mostly gone sideways. It’s also coming to the end of the 2018/2019 tax year; I’ve seen the ISA ads around, though not so many for ‘use your capital gains allowance’ which is something I should look at this week.

Expenses-wise, Q1 has been awkwardly high; some of this is because of one-off expenses for activities that’ll actually take place in Q2 (travel and holidays). My overall savings rate is still decent, as income was higher because of bonuses.

Travelling

I had just two trips out of the UK this quarter, and interestingly both were to visit specific friends in the context of specific events. I went back to Singapore in January for Isaac’s wedding – that was a very short trip as I only had close to a day or so to actually spend with family. The other trip was to Zurich for a weekend trip in February to meet Stan.

Hobbies

The logic puzzle train has been chugging along. I took part in most of the WPF Sudoku and Puzzle GPs, though I missed one round of the puzzles as I was in Zurich that weekend. I’ve always been stronger at sudoku and it shows – I’m on overall rank 60/774, with rankings 82/599, 139/598 and 47/541 in the three rounds. I thought round 2 went pretty well, though I broke an easy Classic Sudoku and, more significantly, a (I think still easy) Braille Sudoku that was worth a lot of points. Round 3 was good – all three of the ‘weird’ variants at the end were disposed of quickly. For puzzles I’m on overall 167/557, with rankings of 102/434 and 93/405 in the two rounds I participated in. We’ll see how Sudoku Round 4 goes, though I think it went poorly for me.

I’ve been reading a fair bit too – some readers may recognise that the title of this post is inspired by Matt Haig’s Notes on a Nervous Planet. I first came across his earlier work Reasons to Stay Alive randomly in a Popular bookshop in Singapore late last year, when waiting to meet a friend. I found the book pretty captivating, though I didn’t buy it then – instead, I placed an order for the book to be delivered to me in London. Both of the books held my interest; the former was raw and pretty compelling, while the latter is more familiar territory for me and I think I could to some extent identify with his perspectives.

I also found James Clear’s Atomic Habits to be a very practical read; I’ve been following his emails for a while. I appreciated the principled approach the book presents. He first establishes that things that become habits tend to be obvious, attractive, easy and satisfying; he then explores how to influence behaviours to increase or decrease how much they show each of these traits.

General Thoughts

It’s been a stressful quarter; there has been a lot of change at work, unease in my financial situation, and discontent with things in general. Perhaps this is something worth thinking about; there’s a passage near the end of Notes on a Nervous Planet on diminishing returns, where Haig observes that many people have tendencies to repeatedly move the goalposts when successful. For me, “be good at math” became “top my class in math”, then “top my cohort in high school in math” (I failed this one, though unexpectedly got Physics instead), then “get a first at Imperial”, then “get the first at Imperial”… “with a 90 average”… “while running a club and working part time 20 hours per week”. Similarly, “be a good dev”… can quickly spiral into “with patents”, “building large features”, “be a principal engineer” and so on. It’s important to maintain perspective as to whether the repeated escalation of these goals is something one really wants to do.

There’s usually a song I associate with each quarter. This time around I’ve been listening a fair bit to Drunk Me by Mitchell Tenpenny. He’s a country artist and I don’t listen to country very much, but this is pretty much a straightforward pop song. There are some awkward metaphors in there, but generally I find the production pleasant, and the A4s he hits in the chorus are nice enough. The message involves giving up habits that are likely to lead the singer back to his ex, which is a pretty logical response.

I’ve been sober
‘Cause there ain’t no hangover like you girl
“Baby, can you come over?”
I always find those words at the bottom of a hundred proof

I don’t drink much alcohol, though I do drink quite a bit of coffee and chocolate. In a sense, my ‘alcohol’ would be activities or behaviours I find addictive that are likely to lead to ruin or negative consequences. This could include things like obsessive fear over how the markets are doing or how Brexit is going, or spending time procrastinating. I don’t think there is an object of spite here, unlike in the song, but nonetheless the idea that one may find value in cleaning up one’s life is something I can get behind.