I recently added another repo illustrating how the same type of analysis could be performed server-side in Node/Express. Only summary information is sent to the client. A detailed writeup of the process is available on the Github repo and I know you want to check out the source, so click on that link and enjoy!

This development illustrates the benefit of authoring in one language (Typescript) and being able to deploy either client- or server-side, depending on the specific needs of each application.

]]>There is a good writeup on the Github repo and I know you want the code anyway, so point your friendly neighborhood browser here and have fun

]]>I am releasing early versions of each data structure on Github for testing and API feedback. Here is the post on LinkedIn that provides permanent links to the repo for each data structure.

https://www.linkedin.com/pulse/typescript-math-toolkit-data-structures-jim-armstrong

Recent additions since last post include Binary Heap and Graph classes.

Enjoy!

]]>https://github.com/theAlgorithmist/TSBinaryTreeLibrary

Enjoy … and drink lots of coffee

]]>Another item in the request department was a flyout panel. Now, I don’t care for animation for the sake of animation, but I do concede that some (albeit limited) valid use cases exist for such a UI element.

Finally, I wanted to take the Angular2 CLI for one final ride before production release and the update to Angular 4 later this week. So, it’s time for another example

Since the topic of the first request is a 2D table (which would be better implemented with a 3rd party datagrid in a larger application), I decided to do some spreadsheet-style analytics on a dataset that was made popular in the book ‘Machine Learning in R’ by Lantz. This is accomplished with the Typescript Math Toolkit and the analytic results are displayed in a flyout panel.

I also wanted to add one more item to the ‘how to’ part of the application, namely custom attribute Directives. This application illustrates the use of a ‘make clickable’ Directive. This custom attribute Directive allows a simple attribute to be used to transform a DOM element such as a paragraph or H1 tag into a clickable element, i.e.

<h1 makeClickable (onClick)=”__onShowClicked()” [innerHTML]=”summaryString”></h1>

Now, this could be accomplished with an anchor or injecting custom script inside the Component’s code-behind. The use of an attribute Directive allows existing markup and styling to remain largely unaltered and the intent is clearly displayed in a template as opposed to code (which takes time for another developer to deconstruct). The Directive is also highly reusable.

The application reads data from a PHP file that is provided with the code distribution. It is necessary to move this file to a server and alter one line of code in the model in order to build and run the application. A CORS header is provided that allows the application to be served locally through the Angular 2 CLI.

The opening screen is rather basic:

Click on the “> Show Summary Statistics” text to display the flyout panel with summary statistics obtained from the Typescript Math Toolkit. Ah, a nice mix of code and math. Just what I like

Click on “> Hide Summary Statistics” to close the flyout panel and restore the original display.

Then, deconstruct the code and have fun. On the subject of code, you probably want to know here to get it, so point your friendly neighborhood browser to this Github repo.

Enjoy!

Although I wanted to be in line with the A2/Leaflet starter, I also wanted to go in a completely different direction, so a separate project seemed like the best approach. My goals for this project include:

- Use the Angular2 CLI as the build tool
- Create a complete micro-application as the demonstration environment
- Adhere to concepts from Flux and Redux w/o 3rd party software
- Classes adhere to principles such as single responsibility
- Provide progress and error indication for services
- Illustrate production-quality features such as preventing side effects from repeatedly clicking the same button
- Provide an example of working with the component change detector
- Use the Typescript Math Toolkit Location class for location data
- Only minimal understanding of Leaflet is required

Although a simple ‘loading’ component is provided with the code distribution, tile loading is sufficiently fast that it is unlikely to be seen. After building and running the project, the application appears as shown below.

The map is initially centered on Carrollton, TX where I currently live.

Enter an address (which could be as simple as ‘Austin, TX’) or click ‘Show Current Location’ to move the map based on current IP address. Third-party services are used to geocode either the IP or physical address and progress indications are provided in the navigator component. A result of moving to Austin, TX is shown below.

The Typescript Math Toolkit Location class is used for location data and service errors are seamlessly reported to the user.

Very little Leaflet knowledge is required to deconstruct and expand upon the code. If you have gone through the Leaflet ‘Getting Started’ guide, then you know enough about that package to deconstruct the code.

And, speaking of code, I know you want it so point your friendly neighborhood browser to the Github repository here and have fun!

]]>*Problem: You are given an array, A, of numbers of length N. You are also given a function, F, that accepts a single number as an argument and it returns a boolean. The function body is not relevant; it returns true if a certain condition is met and false otherwise. It is known that if the function returns true for A[j], j = 0, 1, … N-1, then it returns true for j+1, … N-1. Suggest a strategy that identifies the smallest index, j, such that F( A[j] ) is true with no more than two calls to F where the function returns true. F may return false as many times as needed for the algorithm to work. Return -1 if no such index exists. The strategy for this problem should be designed to minimize the worst-case complexity. Your presentation should include at least detailed pseudocode for your suggested algorithm (bonus points for actual code and specs).*

Although the stated problem may sound highly artificial, I did work on an application some time ago in which a complex true/false test was involved. In some cases, a couple conditions could be tested and false could be quickly proven. Proving true or false was much more computationally intense in absence of those conditions. We ended up strategically re-ordering the data so that it was possible to eliminate large chunks of data from the analysis. So, the problem may be less outlandish that it appears on first reading.

The person submitting the problem came to the conclusion that the ‘two true returns’ requirement be relaxed to three and use binary search to identify a smaller interval, followed by a linear search to locate the exact index.

It is natural for a good programmer to think of binary search when scanning an array for a condition in which an order relationship is known to hold in advance. In terms of worst case for the stated problem, it will not generally be possible to locate the required index and make no more than two calls to F where the return is true.

For purposes of the discussion, array elements are referred to as first, second, … Nth in terms of one-based indices, so a_{j} refers to the jth element, j = 1, 2, … N. The function is referenced in lowercase, i.e. f().

A simple implementation of a linear search is as follows:

1 – Test a_{N}. If f returns false, then return -1

2 – Otherwise, start at a_{1} and test each element in sequence through N-1. If f returns true for any index, return either that index or -1 if all array elements test false.

In terms of worst-case complexity, the worst case is when f(a_{N-1}) is true. Although only one true return is required, all N array elements are tested.

The linear search may be improved by using a constant step size, k. In this case, the array is broken into intervals and a ‘forward sweep’ is performed by skipping over k elements each test. The goal is to find any array element in which the test is true by ‘leaping’ over many in which it is false. Once a true test is discovered, the previous k-1 array elements must be tested in sequence to isolate the first index for which the test is true.

This approach is guaranteed to have no more than two true results and it will always locate the required index. The worst case for this algorithm occurs when the minimum array index is next to last. Let’s temporarily presume that k is chosen to divide N evenly so that the chosen step size produces exactly N/k = Nk^{-1} intervals. The expected number of function evaluations, e(k), is given by

e(k) = Nk^{-1} + k – 1

Although this is a problem in discrete math, we can use a continuous model to obtain some insight into the best choice for k. A necessary condition for a minmimum of e is that the first derivative is zero,

e'(k) = -Nk^{-2} + 1 = 0 => k^{-2} = N^{-1}

or k = sqrt(N).

The second derivative, e”(k), is 2Nk^{-3} which is everywhere positive for k > 0, which indicates that the extreme point is a minimum. Now, it may be that sqrt(N) is not exactly integral; take N = 50, for example. sqrt(50) ~ 7.07, so we might surmise that k = 7 is a good choice, although this leaves an interval of width 1 at the end. The ones-based array elements tested are 7, 14, 21, 28, 35, 42, 49, 50 (there are actually 8 intervals). The worst case occurs at array element 48. This requires testing 7 (F), 14 (F), 21 (F), 28 (F), 35 (F), 42 (F), 49 (T), 43 (F), 44 (F), 45 (F), 46 (F), 47 (F), 48 (T), or a total of 13 tests.

Note that we could have taken the ceiling of sqrt(N) in this case and achieved the same result. With k = 8, the worst-case scenario is the first true test at the 47-th element. Tests are 8 (F), 16 (F), 24 (F), 32 (F), 40 (F), 48 (T), 41 (F), 42 (F), 43 (F), 44 (F), 45 (F), 46 (F), 47 (T), for a total of 13.

Although this heuristic provides a ‘good’ value for the constant step-size model, nothing has been shown to indicate that this is the best possible model out of all possible models for this problem. Consider, for example, the following variable step-size model,

k_{i} = k_{i-1} + d

where d is a non-zero integer. In this case, a starting value of k is chosen and then subsequent step sizes become larger or smaller by a fixed amount. For d > 0, the first interval is of width k, the second is of width k+d, the third is of width k+2d, etc. This trades jumping through large parts of the array that hopefully return false for an increasing linear search interval. The latter tradeoff is the problem with such a model in terms of worst-case scenario. Consider an example with N = 50, k = 8, and d = 1. Initial elements tested are 8, 17, 27, 38, 50. The worst-case scenario is when the first true result occurs at the 49th element. This requires 5 tests to locate the interval, followed by testing elements 39 through 49 in sequence for a total of 16 tests. The situation does not improve by increasing the initial value. Take 10, for example. Initial elements tested are 10, 21, 33, 46, 50. Worst case scenario is at element 45 for a total of 4 + 13 or 17 tests.

While not a conclusive proof, these counter-examples illustrate the problem with positive step-size increases, even with the smallest-possible value of d = 1. The problem is only exacerbated with larger values of d, so let’s discard that part of the model and consider negative values of d. Again, we begin with the smallest-magnitude value, d = -1, which yields intervals of widths k, k-1, k-2, k-3, …

Suppose that k is chosen so that there are exactly m intervals (and this may not always be true in the general case).

In that instance,

k + (k-1) + (k-2) + (k-3) + … + (k-m-1) = N

mk – (1 + 2 + … + (m-1)) = N

The second term on the left-hand side is the sum of the first m-1 integers which is (m-1)m/2 , so

mk – ((m-1)m)/2 = N or mk – m^{2} + m = 2N

This yields a quadratic equation just to isolate the number of intervals and that is only in the ideal case. Analyzing the optimal choice for initial k with a continuous model is a rabbit hole for which we do not wish to discover the depth

There is some potential value with this model as we could start with a larger choice of k than sqrt(N). Since the interval width decreases by one each step, each successive ‘forward’ step is balanced by a corresponding reduction in the number of sequential tests required in that interval. The ideal starting value of k, however, is still an open question.

In many cases such as this, we can gain some insight by a analyzing a good choice for successive values of N and see if a pattern emerges. If such a heuristic holds for expected values of N, then we have a reasonable starting point for the problem that is commensurate with a proper timebox for this type of analysis. Remember that the goal is to investigate a problem and prepare a report, not write a paper for a referred journal. Demonstrating how you timebox and apply yourself to such an analysis is likely to be an important part of the interview process.

For N = 1, k = 1. For N = 2 and 3, k = 2. The following sequence uses a value of k that is optimal based on explicit enumeration. The interval width is decreased by one until it is not possible to decrease any further without exceeding N or the interval width is reduced to one. There are as many of these singleton intervals as needed to reach the end of the array.

e^{*} is the expected number of worst-case function evaluations to solve the problem.

N = 4

k = 2

intervals: 2, 1, 1

e^{*} = 3

—–

N = 4

k = 3

intervals: 3, 1

e^{*} = 3

N = 5

k = 3

intervals: 3, 2

e^{*} = 3

N = 6

k = 3

intervals: 3, 2, 1

e^{*} = 3

—–

N = 7

k = 4

intervals: 4, 3

e^{*} = 4

N = 8

k = 4

intervals: 4, 3, 1

e^{*} = 4

N = 9

k = 4

intervals: 4, 3, 2

e^{*} = 4

N = 10

k = 4

intervals: 4, 3, 2,1

e^{*} = 4

—–

N = 11

k = 5

intervals: 5, 4, 2

e^{*} = 5

N = 12

k = 5

intervals: 5, 4, 3

e^{*} = 5

.

.

.

N = 20

k = 6

intervals: 6, 5, 4, 3, 2

e^{*} = 6

.

.

.

N = 50

k = 10

intervals: 10, 9, 8, 7, 6, 5, 4, 1

e^{*} = 10

The noticeable pattern from these enumerations is that k is to be chosen such that the sum of the first k integers is greater than or equal to N. This value also happens to be the number of worst-case evaluations to locate the required index.

No proof is supplied; the analysis is completely heuristic. In any event,

k(k+1)/2 ≥ N

k^{2} + k ≥ 2N or k^{2} + k – 2N ≥ 0 [1]

If N = 100, for example, k = 14, which yields e^{*} = 14. This is better than e^{*} = 19, which is the best result from a constant step size. In general, one step of refinement of a direct solution may be required to satisfy the inequality since k is constrained to be integral.

The next consideration is a variable step size model. Choose some initial interval width, k_{0}. The i-th interval width is given by k_{i} = k_{i-1} + d_{i}, where d_{i} is a nonero integer. You should have observed by now that the worst-case complexity associated with each interval is the number of steps to get to the interval endpoint plus the interval width minus one. Based on this observation, k_{0} should be less than that indicated by eq. [1]. No subsequent interval width could equal the optimal value of k from [1], otherwise the worst-case complexity would be no better than the (constant) decreasing interval model. With this restriction on k_{0}, the number of steps to reach the final interval increases, which means that it is likely that no variable step size could improve upon the minimal worst-case complexity from the constant decreasing step-size model. This is an intuitive argument – not a prooof – which is suitable for an initial presentation on a topic such as this one.

The conclusion of this brief analysis is that the constant, decreasing step-size model is the best one to apply for the task of minimizing worst-case complexity for the stated problem. The bonus code is available from the TS Programming Test Problems Github repo.

I sure hope the bonus is a Starbucks gift card

]]>I enjoyed having access to Templates in C++ (now called Generics in C# and Typescript). The availability of Generics in Typescript allows the creation of a single class that accommodates multiple data types. The specific implementation of the Priority Queue also illustrates some more advanced features of Typescript, so I thought it would be worthy of a more detailed blog post.

The TSMT Priority Queue is based on my past usage of a priority queue over the years. It consists of an array of prioritizable items, each of which has three properties, a *priority*, a *timestamp*, and a *data* reference. If we allow the data to be of arbitrary type, the contract may be specified in a simple interface.

export interface IPrioritizable<T> { priority: Number; // priority, integer>= 0 timestamp: Number; // optional timestamp, expected to be an integer >= 0 data: T; // arbitrary, but constructable data type such as Object or a Class }

A prioritizable item implements this interface. In my past usage, data associated with the prioritizable item was an Object or class, such as

class PItem { protected _name: string = "name"; protected _id: number = 0; protected _value: number = 0; constructor() {} // accessors/mutators removed to save space public computeValue(someData: Object): void { // compute value from supplied data } }

I would construct the data along with the item and set the data reference in the prioritizable item. A discussion with a couple of developers interested in using this Priority Queue yielded a different use case. They wanted the option of constructing the data type when the prioritizable item was constructed. They would access and set the data at a later point in the application.

While not the way I would approach the problem, it was a use case I wanted to at least try to support in the alpha release. This led to the following implementation of the Prioritizable class.

export class Prioritizable<T> implements IPrioritizable<T> { protected _priority: number; protected _timestamp: number; protected _data: T; /** * Construct a new Prioritizable item * * @param TConstructor : { new (): T } (optional) Reference to a constructable object * * @return Nothing Constructs the supplied data type (if provided) and sets the internal data reference. Priority and timestamp are initialized to zero. */ constructor( TConstructor?: { new (): T } ) { this._priority = 0; this._timestamp = 0; // pre-construct the data type? if (TConstructor) this._data = new TConstructor(); } /** * Access the priority * * @return number Current priority value */ public get priority(): number { return this._priority; } /** * Assign the priority * * @param value: number Priority value (must be greater than or equal to zero) - expected to be integer, but this is not currently enforced * * @return Nothing Assigns the priority if the input is a valid number */ public set priority(value: number) { if (!isNaN(value) && value === value && value >= 0) this._priority = value; } /** * Access the timestamp value * * @return number Current timestamp value */ public get timestamp(): number { return this._timestamp; } /** * Assign the timestamp value * * @param value: number Timestamp value (must be greater than or equal to zero) - expected to be integer, but this is not currently enforced * * @return Nothing Assigns the timestamp if the input is a valid number */ public set timestamp(value: number) { if (!isNaN(value) && value === value && value >= 0) this._timestamp = value; } /** * Access the data item * * @return T Direct reference to the data item; the data is not currently required to be cloneable, so a direct reference is provided. Use this method with caution. */ public get data(): T { return this._data; } /** * Assign the data item * * @param value: T Reference to a data value of type T * * @return Nothing Directly assigns the supplied reference to the internal data value. Use caution to not make further modifications to the supplied value. */ public set data(value: T) { if (value) this._data = value; } }

The constructor is rather unusual and requires an optional constructable object to be passed. For example,

*let __pObject: Prioritizable<Object> = new Prioritizable<Object>(Object);*

(creates new prioritizable item with *Object* data, constructs a new *Object*, and sets the internal data reference)

*let __pObject: Prioritizable<Object> = new Prioritizable<Object>();*

(creates new prioritizable item with *Object* data; internal data reference is null and must be set later using mutator)

This implementation allows both use cases to be implemented, but is currently experimental.

Suppose a class, *PItem*, is available that represents the data to be associated with a prioritizable item. My preferred use case to add items to the queue is:

let queue: TSMT$PriorityQueue<PItem> = new TSMT$PriorityQueue<PItem>(); let item1: Prioritizable<PItem> = new Prioritizable<PItem>(); let pItem1: PItem = new PItem(); item1.priority = 1; item1.timestamp = 1001; item1.data = pItem1; . . . queue.addItem(item1);

The TSMT Priority Queue uses priority as a default, primary sort key. A timestamp value (typically another integer greater than or equal to zero) may be used as a secondary key. A type alias is defined with the priority queue,

export type SortType = 'priority' | 'timestamp';

Sort criteria are specified by a mutator that accepts an array of *SortType* values. A type guard is also used to ensure validity of each individual item in the mutator. A type guard is a runtime check to ensure validity of a passed type since there is no runtime checking after export to JS. The syntax uses a return type that is a predicate, which evaluates to a boolean, as shown in this internal method,

protected __isSortType(value: string, acceptable: Array): value is SortType

Usage is illustrated in the *setCriteria* mutator

valid = valid && this.__isSortType(criteria[i], values);

The TSMT Priority Queue supports addition and removal of items, removal of the first/last item in the queue, and clearing of the queue. By default, a sort is performed on each addition to the queue. The sort may be delayed by use of the *delay* mutator. Lazy validation is used in the class, so sorting may be delayed until calling a method that requires the queue to be in sorted order.

A generous set of specs is provided with the source distribution on Github and this is probably the best way to become familiar with using the priority queue. Even if you do not directly use the code, I hope you can borrow some of the Tyepscript techniques used in its development.

Enjoy!

]]>