869 private links
Treat an A/B test as an multi-armed bandit problem. First we need to record the performance for each option. Then every time we are faced with a decision, calculate the reward for each option, pick the best one. Leave a small chance (e.g. 10%) for exploration where a random option is selected.
Here's how I did it: with the example images on screen (~10cm wide), stare at it from around 25cm away. Cross your eyes until the images overlap. To cross your eyes you should keep the distance to the screen around the same but actively tries to move the focus. Do so until the image overlaps and merge. Now adjust the distance to the screen very slowly while keeping the focus so the merged image don't split, until the merged image become sharp. The merged image may never become as sharp as viewed directly, but that's enough for us. Now notice the spots where the image appears semi-transparent/flickering/bloty. You may not be able to tell in detail what the differences exactly are, but you should be able to tell the relative locations. Note that depending on the focusing, nearby spots may merge as one. Also I found the "hard mode" challenge easier than the "easy mode" in the sense that the difference stands out more clearly.
TIL VoxelSpace, a simple algorithm for rendering terrain map in high detail. The terrain is described by two identical sized textures: the height map and the color map. The color map is preshaded to contain shadows/other features. The rendering is performed from back to front at the viewer's perspective (painter's algorithm). For each depth, calculate a line corresponding to the given depth, use the line to sample textures on the height map and the color map. For each rasterized point of such line, render a vertical line into the view port from the given height to 0 with the given color. Repeat this process until the depth reaches the near z-plane. The algorithm can be optimized by drawing from front to back to avoid drawing unnecessary vertical line segments at the cost of an extra z-buffer.
This blog post discusses something that I myself wanted to write about for a long time. The so-called "clean code", "best practice", "abstraction" are ultimately mere tricks to make our puny monkey brains comprehend complex concepts and logic.
Use a cipher to biject between the index and the uuid (make sure it's valid). Make a custom scrollbar to render a row of uuids from any given index. The search function is done by finding out all possible positions the patterns can be at, then generate a list of valid uuids that adhere to the pattern and jump through them in order. The search is not perfect because it doesn't find the actual "next" matching pattern, which is likely impossible due to the cipher used. A brilliant piece of art!
Free DDNS service that doesn't require an account.
A temp-mail service provided by AdGuard.
Techniques and tools for reverse engineering private/undocumented APIs for websites.
Reversing Conway's game of life is famously hard to compute. However, it's possible to approximate the inverse using gradient descent if we formulate GoL as a continuous computation.
Here's how it works. We represent the board as a grid of continuous values in [0,1]. To compute the next step, we first take a convolution with a 3x3 kernel equivalent to the summation of the neighboring living cells. Then we map the result into [0, 1] range using a continuous function corresponding to the alive rule. In this article it uses a narrow Gaussian centered at n=3. Then we can compute the gradient descent to figure out an approximation of inverse step.
Creating a git commit from scratch. Covers blob, tree, and commit.
Using linear optimization to calculate movement of pong paddles based on the rhythm of music so that each beat lies on a ball hit. Brilliant idea. https://www.cvxpy.org/ is a python library for modeling convex optimization problem.
Search upscaler models for various purposes.
Rotors are a rotation representation generalized from Quaternions and Complex numbers that works in any numbers of dimensions.
The article starts by pointing out that rotation is defined as a scalar property on a plane. The canonical representation of a plane is a bivector representing the outer product of two vectors. The bivector is in principle a fundamental concept just like the vector. Similar to how a vector represents a point with a scalar length, a bivector represents a plane with a scalar area (signed). The area of a bivector a∧b is |a||b|sin(angle). The reason we also see the term |a||b|sin(angle) from cross product is because cross product actually gives rise to a bivector instead a vector! Historically we've been confusing bivectors with vectors because they have the same representation in 3D.
The inner and outer product completes a geometric product of two vectors: ab=a⋅b+a∧b. Reflection R(a,v) is defined elegantly using geometric product: R(a,v)=-ava. Then it's noted that two reflections is equivalent to a rotation by twice the angle between a and b: R(a,R(b,v))=ba v ab. The "ab" here is known as a rotor. Applying a rotor on both sides of a vector rotates this vector in the plane a∧b by twice the angle between a and b. Quaternion is just a representation of Rotors in 3d: i:=y∧z, j:=z∧x, k:=k∧y. The scalar part (w in w+xi+yj+zk) corresponds to the inner product.
Keywords: bivector, geometric product, rotor, quaternion, rotation, geometric-algebra
The naive collision detection algorithm takes O(n^2) by checking pairwise intersection. To improve the performance, sort the objects by x coordinates, scan from left to right and only check intersection if a.right < b.left. This method can be extended into 2D to further eliminate the necessary comparisons. Finally, note that insertion sort is more performant on mostly sorted lists than quick sorts, so it's more suitable in this case.
A comprehensive guide on various types of linux virtual networking interfaces. keywords: vlan, vxlan, macvlan, ipvlan, macvtap, ipvtap, veth, vcan, vxcan, ipoib, nlmon, dummy interface, ifb.
In short:
- outline recursively
- speedrun each item
- do not perfect anything until done
pairs = [ (x,y) | x <- [0..], y <- [0..] ]
This program doesn't really enumerate all "valid" pairs in finite time. For example (0, 1) is never reached because the list will not halt traversing the first component. How can we enumerate the space of all indexable pairs of integers? Moreover, given a recursive context-free grammar, how to write a program that enumerates all valid expressions?
This type of enumeration problems is where the Omega Monad can be useful. It acts like a "breadth-first" search for list comprehension. I recall finding the conde
primitive (sometimes known as condi
) from miniKanren fascinating. Now I learned the Omega Monad is exactly the same thing.
A comprehensive listing of internet search engines out there.
Each element can be styled with multiple box shadows. By programmatically controlling the positions and sizes of each individual box shadow, it's possible to make up a something like a pixel display.
Given a linked list which happens to sit on consecutive memory, traversing it can take advantage of L1 cache. However it's possible to squeeze more performance by hinting the branch predictor to allow speculative execution, resulting in better parallelism with cpu pipelining. This is a simple and interesting trick although I can't think of much practical uses except for specific scenarios.