Every other week, the Principle Studios engineering team gets together and we challenge ourselves to accomplish a tiny task given by another team member. When we’re done, we share the results of the challenge and try to learn from each other - since there’s rarely one “right” way to accomplish even technical tasks. Sometimes these are simple, such as “write the types for this concept in TypeScript”, “use this feature in C# to accomplish this task”… and sometimes they’re a bit more open-ended.
This week, we tackled generator functions:
Dynamically generating a list of values that can be iterated upon until completion (or interrupted in the middle) is a powerful tool that both C# and JS have, but we rarely use. In JS, they’re called “generator functions”, and in C# they’re called “iterator methods”… but they both use the
yield
keyword. (Other languages may have these, too, but please start with one of these two!)Write a function along these lines to implement the Fibonacci Sequence or the Collatz Conjecture (or one for each!).
Entries
Fibonacci
The Fibonacci sequence is often used in coding challenges, but it’s often in the vein of “output the first N numbers”. This challenge takes a twist by allowing the function caller to limit the output.
TypeScript Solutions
The TS solutions for the Fibonacci sequence were all nearly identical; the following is Amit Bansil’s solution:
function* fibonacci() {
let pre = 0,
cur = 1;
yield pre;
while (true) {
yield cur;
[pre, cur] = [cur, pre + cur];
}
}
Aaron White, Ben Cohen-Chen, and Daniel Kurfirst also all submitted fibonacci functions.
C# Solutions
Along similar lines were the C# solutions. This one is Andrew Owen’s:
public IEnumerable<double> Fibbionaci(double target) {
double previous = 0;
double current = 1;
while (previous <= target) {
yield return previous;
double old_current = current;
current = current + previous;
previous = old_current;
}
}
Josh Berres’s solution was almost identical.
The Collatz Conjecture
The Collatz Conjecture is a fun use of generator functions; given the input, it is unclear how long it will run. In fact, the Collatz Conjecture is unproven as to whether all entries have a stopping point.
TypeScript Solutions
At their core, there were two types of Collatz implementations. Ben Cohen-Chen and Daniel Kurfirst both submitted solutions that were similar to the Fibbionaci solutions. This one is Daniel’s:
function* collatz(num) {
while (num != 1) {
yield num % 2 === 0 ? (num = num / 2) : (num = num * 3 + 1);
}
}
Amit Bansil also provided a recursive function; modern JS seems to use tail recursion for generators so doesn’t run out of stack size.
function* collatz(n: number) {
yield n;
if (n === 1) {
return;
} else {
yield* collatz(n % 2 === 0 ? n / 2 : n * 3 + 1);
}
}
C# Solutions
Josh Berres also provided a C# solution:
IEnumerable<int> GetCollatz(int startingNumber)
{
yield return startingNumber;
int current = startingNumber;
while (current != 1)
{
if (current % 2 == 0)
{
current /= 2;
yield return current;
}
else
{
current = 3 * current + 1;
yield return current;
}
}
}
Thanks to all our participants!
Thanks to Amit Bansil, Tony Mishler, Josh Berres, Aaron White, Ben Cohen-Chen, Dan Kurfirst, and Andrew Owen for submitting solutions this week!
Thanks for reading, and I hope everyone learned something. I didn’t know JS
allowed yield*
with tail recursion - which is a huge discovery by Amit!