Sunday, November 15, 2020

Day 0 - Beginning of a journey

I have a new goal. The goal is to build up a home development infrastructure that is similar to what's available at most software companies. Here's what I want to have.

  1. Source control server
  2. Build system
  3. Build farm
  4. Submit tests
  5. Continuous tests

For source control server I decided to use git over ssh. It is simple to setup and works well for for small number of developers, which in my case is just one, maybe two in a blue moon. The git server will use a mono repository since that's what I am used to at work, and I am too lazy to set up multiple repos for the many hello world projects I plan to ship.

As for the build system, I have decided to use Bazel. It is more complicated than Make, but I feel the tradeoff is worth it, especially since I use it at work. Bazel is nice since it also supports remote builds, so it is relatively easy to setup a build farm, or in my case a lonely build workstation (maybe two?) and scale up from there. The eventual goal is to have a pool of build machines that includes Intel i7, AMD Ryzen, and Raspberry Pi 4s. Why RPi4? Because they are cheap and I want to play around with clusters.

The submit tests and continuous integration tests will be done by integrating the Bazel test rules with Git hooks. I haven't really given much thought yet, but the idea is to use Bazel to query for tests and run them. For submit tests, there are two tests that will be done. First, I'll use reverse dependency query to determine all targets that will be affected by the commit and see if the build breaks. Second, if all downstream targets build correctly, then all tests that depends on the affected targets will be executed to verify that all tests still pass. If the number of tests are large, which will happen sooner or later as the repo grows, a random (perhaps weighted) sample of the tests will be tested. The random sampling will also apply to build checks if the number of affected build targets grow too large as well.

The continuous integration tests are Bazel tests that may be too large/long to be run at every commit to the repo, so they'll be executed at a fixed time interval, most likely at night when activities are low. The results will be logged and users notified if any of the tests break.

That's it for now. Tomorrow (not wall clock but more of a "journey" perspective) I'll start with the Git server.

Thursday, January 28, 2016

Coding Challenge: water collected between towers, part 2

This is continuation of part 1.

In this post, we will solve this challenge using dynamic programming techniques and property observers.

Dynamic programming approach with property observers

This approach solves the challenge by dividing the problem into small chunks.  For each tower, the height of tallest tower to the right is determined by comparing the tower's own height and reported height of tallest tower of the right neighbor, i.e. 

tallest2right = max(self.height, rightTower. tallest2right)

And the height of tallest tower to the left is determined in a similar fashion.  Each tower does not scan the entire array to determine tallest tower heights to either direction--it simply uses the reported value from neighbor towers to evaluate their own answers.  The neighboring towers may use pre-calculated value or perform calculation on as-needed basis.  In this implementation, the values are calculated and stored for each topography change (i.e. modifications to leftTower or rightTower), and the change is propagated by notifying neighbor towers.

The initial value of tallest tower to either direction is set to own height.  As each tower connects to its neighbors, messages are sent to appropriate towers to update their value of tallest towers in both direction via property observer didSet().  Here's definition for Tower class.

Coding Challenge: water collected between towers, part 1

I came across a post on StackOverflow on an interview question asked by Amazon, and wanted to share my solution.  The question goes like this:

You are given an array representing heights of towers.  It starts raining.  Determine how much water is collected between the towers, assuming each tower has width of 1.

Example:
Input: [3, 4, 2, 7, 4, 3, 8, 2, 4]
Expected Output: 11 units of water

            *     
      * W W *     
      * W W *     
      * W W *     
  * W * * W * W * 
* * W * * * * W * 
* * * * * * * * * 
* * * * * * * * * 


The problem can be solved in two ways, either iteratively or recursively with dynamic programming. Both rely on the observation that the amount of water collected atop any tower is determined by the shortest of the tallest tower to the left and right of itself.  The iterative solution is presented.