There are a few different versions of this question. Sometimes it is crystal balls, or eggs or something else.

There is a 100 story building. We have two magic glass orbs. The orbs will only break at or above floor X. We need to find what floor X is, in as few drops as possible. No matter how many times we drop an orb, it will only break at or above floor X. We are given two orbs. What is the fewest drops to find the floor no matter what the floor is? We are trying to minimize the worst case here.

What make this problem unique is that we have limited failed tries, 2, and must optimize for the worst case-scenario more than the average runtime. I think that is an important concept to highlight.

If we only had one ball, then we’d just have to start at the bottom floor and work our way up. If we had infinite balls, we could just do a binary search and we’d only need log(n) balls at most (7 balls for 100 floor) But 2? HMM. So obviously, once the second orb breaks, we’ll be falling back to the floor-by-floor algorithm.

Most will first think about cutting the floors in half. So let’s do that. Give a building with N floor, n=100 here, we start at floor 50 (n/2), if the ball breaks, then we check from 1-49. If the ball doesn’t break, then we check 51-100. So we broke the building into 2 sections of size 50. The worst case is 50+2-1=51.

We might realize we could break the building up into differently sized sections.

If we break it into 4 sections of 25 then our worst case is 25+4-1 = 28 (27 if we use inference).

WE can see the pattern and make a formula. sections, S, and section size B. So tries, T make is

$$where \ S \ and \ B \ are \ factors \ of \ N$$ $$T=S+B-1$$

So we can manually find a **good** solution

```
2,50 = 51
4,25 = 28
5,20 = 24
10,10 = 19
```

After 10,10 it just gets worse again. You might even realize since S and B are the same, we could think of that as `sqrt n`

. Which is a *good* answer. Not the *ideal* answer but a decent one.

Our generalized worst case would be to jump by

$$ \sqrt(n) $$

So for any building size N. We can solve it in

$$ 2 \sqrt(n) - 1$$

tries. For N=100, that is 19 (18 with inference).

If X = 99 then we try 10,20,30,40,50,60,70,80,90,100,91,92,93,94,95,96,97,98.

The ideal solution comes from understanding that as we check the top of each section, we have already dropped for each previous section.

For example, if we jump by 10 each time then at floor 30 we have already jumped 2 times, 10,20. If the ball breaks we still have to check 10 places, 21-30 which make our total 12, not 10. Ideally that number would be consistent. We need to find an equalibrium. We would jump by 10 then by 9 because then we’d have a max of 10 jumps. We can try this but 10 doesn’t quite work. We end at 55. So we need a bigger number. 55 is the sum of 1 to 10. We could manually find that 14 + 13 + 12 + 11.. is 104 which is enough! But as computer scientists, we should look for the generalized solution.

So each jump must be one less than the previous. All jumps must add up to 100 (or more). We get the following formula that you’ll see in other blog posts.

$$n+n-1+n-2+n-3+n-4…=100$$

I’ve seen this formula on many blog posts that don’t explain it clearly for the beginners. This formula is really the same as

$$ \sum_{i=1}^n i $$

Which just means *“Add all numbers from 1 to N”*.

With a little thinking we realize that is is going to go down to 1. So really we are adding 1 to N and the sum being 100. We were just defining it in a backwards sense.

So we can figure out the sum off all numbers 1 to n with the following formula that is easy to figure out on your own.

Adding 1 to 10, we can make 10 pairs that add up to 10. There are always $ n \over 2 $ pairs. The middle number doesn’t pair up so we add that.

10 + 0 = 10 9 + 1 = 10 8 + 2 = 10 7 + 3 = 10 6 + 4 = 10

$$ n (n + 1) \over 5 $$

Which can be simplified to

$$ .5n^2 + .5n = floors $$

Or in our case of 100 floors

$$ .5n^2 + .5n = 100 $$

Then make it all equal 0 for balance

$$ .5n^2 + .5n - 100 = 0 $$

BOOM! we have a quadratic formula we can solve.

Remember your quadratics? Yeah! That’s just a quadratic formula that we can solve!

$$(ax^2 + bx + c = 0)$$

Our formula is

$$a = .5$$ $$b = .5$$ $$c = -100$$

and the quadratic formula.

$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$

So solve this formula (just use an online solver)

$$x = {-.5 \pm \sqrt{.5^2-4(.5)(-100)} \over 2*.5} $$

$$x = {-.5 \pm \sqrt{(.25)-(-200)} \over 1} $$

$$x = {-.5 \pm \sqrt{200.25}} $$

So if we do that, we get `13.650971698085`

for the positive solution. We can ignore the negative solution.

Now, we can only have a whole floor number so we round to the nearest number and that is `14`

.

I used demos to chart the formula out. You can see the chart here. Or enjoy the screenshot below.

So `n=14`

. Which means that we start at floor n, `14`

then move `n-1`

floors to `27`

. We continue moving one less floor each time.

I.E if we try `14,27`

then the ball breaks at 27,
we have to try 15-26 which is 12 tries plus the two from before = 14! Each time we have one less try for the in-between floors.

`14,27,39,50,60,69,77,84,90,95,99,100`

We have solved the problem and did the math. Now it is time to translate this into code. I’m going to write this in javascript, the language I typically use for interviews.

We don’t need to solve the quadratic equation in code. Remember the reverse formula? `n+n-1+n-2...`

? We can just start at the top and subtract 1, then 2, then 3 etc. Until we get to 0 or less.

```
function findFloor(floors) {
let steps = [];
let step = 1;
while (floor > 0) {
steps.unshift(floor);
floor = floor - step;
steps += 1;
}
return steps;
}
```

You’ll notice this gives us a different answer! We have a different sequence of floors.

```
[9, 22, 34, 45, 55, 64, 72, 79, 85, 90, 94, 97, 99, 100];
```

Still, the worst case is `14`

. This one is ever so slightly more efficient because if the ball breaks on
floor 9, then we only have 9 tries, everything else is 13 or 14. (13 because if we try 97 then 99 breaks we can infer that 98 is the floor).

That was just a fun detour. We *can* code it to get the same floors. We would have to solve the quadratic formula THEN start at
that floor and jumping by one less each time.

```
function findFloor(n) {
const a = 0.5;
const b = 0.5;
const c = -n;
// solve quadratic
let floor = Math.ceil(-b + Math.sqrt((b ^ 2) - 4 * a * c));
// walk the floors
let steps = [floor];
let step = floor;
while (floor <= n) {
floor += --step;
steps.push(floor >= n ? n : floor);
}
return steps;
}
```

I know that was a *REALLY* long explanation but I think it was much more thorough than any other blog post about it.

`this`

keyword. In my opinion, virtually all of them fall short and
fail to even mention `dispatch`

or `binding`

.
As always, I encourage polyglot programming. So I’ll be showing examples is Javascript, C#, Go and Rust.

First, let us cover some *really* basic but critical Javascript.

```
function greet(name) {
console.log(`hello, ${name}`);
}
function greet() {
console.log(`hello, stranger`);
}
greet("natescode");
```

**Which function is called?**

If you said the first function, that is *incorrect*.

Javascript *ONLY* cares about the function name, not the parameters. In the case of duplicate function names, the last one defined wins; just like CSS.

Now, when we get to methods, somethings change. Let us make our previous example use methods.

```
const Alice = {
greet: function (name) {
console.log(`hello, ${name}`);
},
};
const Bob = {
greet: function greet() {
console.log(`hello, stranger`);
},
};
var person = Alice;
person.Greet("natescode");
```

Now, even though `Alice`

and `Bob`

both have `greet`

functions, there is no longer a name conflict! Hey, I though Javascript functions had to have unique names? They do, but not methods! Because methods are functions that are related to a specific function. They have their own scope / context.

Now let’s change the example to use the object’s context.

```
const Alice = {
name: "Alysan",
};
const Bob = {
name: "Robert",
};
function greet() {
console.log(`hello, stranger. I am ${this.name}`);
}
// they'll both use the same function as a method
Alice.greet = greet;
Bob.greet = greet;
Alice.greet("NatesCode");
```

You’ll see I changed the `greet`

methods back to a single function. I did this to highlight the fact that methods are just functions executed within an specific object’s context. Technically, ALL javascript functions are methods since everything is on the `window`

object. The plain `greet`

function will *not* return `null`

or `undefined`

because the `name`

exists as `window.name`

; it is usually an empty string though.

You’ll the two lines that associate the `Greet`

function with both the `Alice`

and `Bob`

objects.

When we call their respecitve `greet`

methods, the output changes based on the object the function was called on. Methods, unlike functions, have a special parameter called the *receiver*. This is *really* obvious in `Go`

where the receiver parameter comes before the method name, the same order we call it in.

```
// 'this' could be called anything since it is just a parameter.
// normally it would be called `person` by convention
func (this Person) greet(name string){
fmt.Println("hello, " + this.name)
}
```

To clear up how `this`

works. I show you an example in English. Here
is a script for you to read.

```
Hello, my name is [your name], and today . . .
```

Did you say “your name” or did you say your actual name? “you” and “me” and “my” are relative! They don’t refer to the same person all the time. It depends *WHO* says it!

Let’s change the code example to read more like English and say “my name is Alice”

```
const Alice = {
name: "Alysan",
greet: function () {
const my = this;
console.log(`My name is ${my.name}`);
},
};
const Bob = {
name: "Robert",
greet: function () {
const my = this;
console.log(`My name is ${my.name}`);
},
};
Alice.greet(); // My name is Alysan
Bob.greet(); // My name is Robert
```

So `this`

refers to the object that we are calling the function on, *the reciever* again. `this`

is really just a special parameter as we saw in `Go`

. We can think of
the following two code snippets as being conceptually equivalent.

`this`

```
function greet() {
console.log(`my name is ${this.name}`);
}
```

```
function greet(receiver) {
console.log(`my name is ${receiver.name}`);
}
```

I hope that clears up at least the basic understanding of `this`

.

Ok. So hopefully now `this`

is starting to make sense. We are now going to take the minecar into the cave of deeper knowledge! Let’s talk about dispatch!

First a code example. Can you tell me which method will be run?

```
const Alice = {
name: "Alysan",
greet: function () {
const my = this;
console.log(`My name is ${my.name}`);
},
};
const Bob = {
name: "Robert",
greet: function () {
const my = this;
console.log(`My name is ${my.name}`);
},
};
// we are picking Alice or Bob at random.
// Nothing else important about this code
var friend = Math.random() > 0.5 ? Alice : Bob;
friend.greet();
```

Hopefully, you answered `no, I cannot predict something inherently random!`

. My point exactly. This is called `dynamic dispatch`

or `late binding`

. Those are just fancy terms for `Let's figure out which method to call on which object when we RUN the code, not before`

In statically typed languages, we know for 100% certainty which type `friend`

will be, before the code runs.

Let’s translate that example into C#

```
class Alice {
string name = "Alysan";
public Alice(){
}
public void greet(){
const my = this;
Console.Writeline($"My name is {my.name}")
}
}
class Bob {
string name = "Robert";
public Bob(){
}
public void greet(){
const my = this;
Console.Writeline($"My name is {my.name}")
}
}
// csharp does have VAR but that just infers the type
// it isn't dynamic
var friend = Math.random() > 0.5 ? Alice : Bob;
friend.greet();
```

This code won’t even compile. We’ll get an `` error. Because we don’t know which type friend is going to be. The most direct translation would change the last two lines to look like this.

`dynamic`

** NEVER DO THIS **

```
// NEVER, EVER, EVER, for the love of keeping your job
// and not being replaced by AI, NEVER EVER DO THIS!!!!
dynamic friend = Math.random() > 0.5 ? Alice : Bob;
friend.greet();
```

Now friend’s type is not set until we run the code. This will work. Just don’t do it! Promise? Okay.

`interface`

```
// we define an interface that has a greet method
interface IGreetable{
void greet();
}
class Alice: IGreetable {
string name = "Alysan";
public Alice(){
}
public void greet(){
const my = this;
Console.Writeline($"My name is {my.name}")
}
}
class Bob: IGreetable {
string name = "Robert";
public Bob(){
}
public void greet(){
const my = this;
Console.Writeline($"My name is {my.name}")
}
}
// csharp does have VAR but that just infers the type
// it isn't dynamic
IGreetable friend = Math.random() > 0.5 ? Alice : Bob;
friend.greet();
```

Now, friend is of a shared type `iGreetable`

. An interface is a type that defines which methods should exist on an object. Now we don’t care if we get an `Alice`

or `Bob`

, we are *ONLY* looking for any object that fits
the `IGreetable`

interface, in this case that means anything with a `greet`

method that take no parameters and returns nothing.

NOTE: statically typed languages do differentiate between methods/functions with different number of parameters, parameter types and return types.

`greet`

with a return type or parameter of`string name`

would be a different method all together

```
// we define an interface that has a greet method
class Person {
public void greet(){
const my = this;
Console.Writeline($"My name is {my.name}")
}
}
class Alice: Person {
string name = "Alysan";
public Alice(){
super();
}
}
class Bob: Person {
string name = "Robert";
public Bob(){
super();
}
}
// csharp does have VAR but that just infers the type
// it isn't dynamic
Person friend = Math.random() > 0.5 ? Alice : Bob;
friend.greet();
```

Inheritance look similar to interfaces. `Bob`

and `Alice`

both inherit from the `Person`

object. You can think of inheritance as a compiler-assisted copy-paste. So Alice doesn’t have her own `greet`

method anymore but that is okay because her parent does! Similar to have Javascript’s prototypal inheritance works.

I wasn’t going to include this one, but man it is too good to pass up. I’m going to write this example in language of the gods, `Rust`

.

```
// define a Person struct with a greet method
struct Person {
name: String,
}
impl Person {
fn greet(&self) {
println!("My name is {}", self.name);
}
}
// define an enum for friend type
enum Friend {
Alice,
Bob,
}
// create Alice and Bob structs
let alice = Person { name: String::from("Alysan") };
let bob = Person { name: String::from("Robert") };
// randomly choose between Alice and Bob
let friend = if rand::random() { Friend::Alice } else { Friend::Bob };
// call greet method on chosen friend
match friend {
Friend::Alice => alice.greet(),
Friend::Bob => bob.greet(),
}
```

** BTW the above Rust code was generated by Chat GPT. I had it translate the previous C# code into rust but use enums for the friend type. The FUUUUTUUURE!

So let’s explain the Rust code for those unfamiliar. We define a `struct`

which is like a `class`

in many ways. It only has data though, no methods.
We then define an `impl`

block which just defines the methods for that `struct`

separately. Unlike Javascript, Rust and other languages allow us to define our own
actual types. Even if we define a `class Person`

in Javascript, the type will always be `object`

and we’d have to use the `Object.prototype.isPrototypeOf()`

method to see if something is from a `Person`

object.

The `enum`

in a type that combines types. So `friend`

can either be of type `Alice`

or type `Bob`

.
We create new object literals of type `Person`

for both Alice and Bob. The enum is our ticket for the train to `polymophism`

.

You’ll see that Rust defines an enum type which is just a type that combines two more types, type addition aka Algebraic Data Types.

Friend is of the shared type. Then at runtime, we check which variant of Friend we have and call the approprait method. This isn’t dynmic dispatch because we KNOW the type of Friend before the code runs. There is some *dynamic* checking however which comes with a small performance overhead. The enum is like a C union but with a bit that tells us which variant we currently have.

Effectively, enums make types into values. Like a `string name`

in C# must always be a string but can change to different values.

`Polymorphism`

is a tough term to define. I’m going to define it as the following.

Polymorphism is the process of treating code (objects, data, types) based on their shared similarities

In all the previous examples, we were simply trying to `abstract`

away the differences and focus on the similarites between `bob`

and `alice`

so
that we could treat them equally; even code can be inclusive!

Abstraction is another term we need to define since *polymorphism* is a from of *abstraction*. Most, if not all, definiton talk about *hiding* details.
I think, at least in software, it isn’t about hiding unneeded details but *ignoring* them. Furthermore, *abstraction*, is really about trying to describe the
essense of the thing that doesn’t only apply to one thing. For example, my nephew told my daughter Luna something about his `iPad`

and she called it a `tablet`

. He
corrected her that it is an `iPad`

. They were both correct. He was being more concrete or exact while Luna was using a more abstract, less accurate, term.

So for instance, if you know how to drive a vehicle then it doesn’t matter if the vehicle’s make is a **Ford** , **Chevy**, or **Dodge** because all you care is that
it has two pedals (three for manual), a wheel and shifter. Everything else doesn’t matter and is not a **concern**.

We could go further and start talking about VTABLES and more, but I think that is best saved for another blog post and video. I really hope this helps. Constructive feedback is encouraged and welcome.

Until next time

`return 0;`

TYPES

- ADTs that use
`@sum`

keyword not`enum`

or`union`

- Typeclasses / Traits
- Interfaces that are structurally typed
- Monads with Monad Trait
- Type constraints

- ADTs that use
OOP

`@struct`

value type, public fields, no constructor, no pointers / references`@class`

reference type, private fields, (de)constructor, pointers / reference types

OPTIMIZATIONS

- Data Oriented Design like
`Zig`

- explicit tail-recursion optimization
`@rec`

- Data Oriented Design like
structural interfaces like

`Go`

built-in testing (unit, ui, fuzzing, benchmark, E2E)

ML FEATURES

- optional partial function application
`Haskell`

- pattern matching with
`@match`

- optional partial function application
generics like

`C#`

structs and classes

File system based module system

MACROS

- language macros liku
`Lisp`

- comptime like
`Zig`

- language macros liku
SYNTAX

- series / range operator
`1..10`

- negative indices
`array[-1]`

- Auto semicolon insertion
- No extra parens
- no
`<>`

for generics. Use`'T`

syntax instead

- series / range operator
ITERATORS & LOOPS

- internal & external iterators like
`Ruby`

- non-local return (keyword, enum or possibly labels via Symbols?) like
`Zig`

- All-Purpose
`@for`

loops with series kinda like`Zig`

or`Go`

- internal & external iterators like
CONCURRENCY

- async with channels (multiple independent call stacks) like
`Go`

- async with channels (multiple independent call stacks) like
MEMORY MANAGEMENT

- locality for stack based memory like
`Janestreet Ocaml`

`@local`

and`@global`

keeps type system easy to use- Reference counting, Unique pointers like
`C++`

and`Rust`

- Optional GC, tracing, generational and arena allocation
- custom allocators like
`Zig`

~~*Lifetimes won’t be types and they’ll all be inferred~~

- locality for stack based memory like
BUILD SYSTEM

- targets WASM & Zig
- FAST builds!
- WEB, Node + Express, WASI(X) and POSIX APIs

- inheritance (later only single inheritance of
`abstract`

classes) - real classes /
`new`

keyword - so async / await all the way
- Borrower Checker

Using internal iterator Symbol. Like labeled-for in Zig but the label name can be passed.

```
/// array, fn -> void
@fn map array,func {
$outer: @for array.length, $item {
// pass current item
// AND the label for the for-loop
func($item, $outer)
}
}
array.map(fn(item,$label){
if item === null {
break $label
}
})
```

Real runtime Generics like C#.

C

```
public void reverse<T>(T[] collection){
// reverse
}
```

Si

Si doesn’t need the Generic Type parameter because it is assumed… is that possible?

```
/// []T -> void
@fn reverse:void collection:[]'T
// code
@
```