Stock Ticker

Stocks can be identified by a specific abbreviation: for example, the company Intel has the ticker symbol INTC. Each company can be uniquely identified by its ticker symbol.

Stocks prices change throughout the day. The change is expressed with plus or minus signs in front of the change: e.g., INTC +7.25 or INTC −0.25.

Write a program that simulates a stock ticker. It will be pre-seeded with data from a file provided on the command line, and then stock updates will come in. It will then display the results of all the changes.

Sample Output

> ./ticker companies.txt
AAPL +11.00
PWC +7.50
T +89.25
PWC -1.25
^D
AAL 38.14 American Airlines Group Inc.
NKE 61.20 Nike, Inc.
WMT 64.22 Wal-Mart Stores Inc.
T 89.25
AAPL 98.95 Apple Inc.
PWC 113.25 PricewaterhouseCoopers
GOOG 730.96 Alphabet, Inc.
BRK-A 188300.00 Berkshire Hathaway Inc.

Requirements

The input file format is one company per line, with the elements separated by a single space: the ticker symbol, the price-per-share, and the rest of the line is the name of the company (which is optional). You may safely assume that the longest possible company name would be under 64 ASCII characters. The longest stock ticker symbol would be five ASCII characters long, and the price-per-share will always be positive, and no more than $1 million.

AAPL 87.95 Apple Inc.
PWC 107.00 PricewaterhouseCoopers
GOOG 730.96 Alphabet, Inc.
NKE 61.20 Nike, Inc.
WMT 64.22 Wal-Mart Stores Inc.
AAL 38.14 American Airlines Group Inc.
BRK-A 188300.00 Berkshire Hathaway Inc.

The program should then accept (on standard input) a series of stock ticker changes, one per line. Any data after a ticker change on the line may be safely ignored. If an unknown ticker symbol is encountered, it should be added to the stock market with an initial price-per-share of the update. Any adjustment that would take the stock below $0.01 should be considered an error; it should not be completed, and an error message should be printed to standard error. Adjustments involving fractions of cents can ignore or round any fractions.

Each change should alter the current price-per-share of the given stock, up or down.

When the input is terminated (Ctrl+D), the stocks should be printed in order from least to most expensive, in the same format as the input file.

Because this involves money, you must not store it in floating-point numbers (but using them temporarily for printing/reading is allowed).

The name of the program should be ticker. Your project should support the following make targets: ticker, debug, and profile.

Starter Code

Consider this a suggestion only; you are welcome to develop or discard this as you need.


struct company {
	char symbol[6];
	size_t cents;
	char *name;
};

struct tree {
	struct company *data;
	struct tree *left, *right;
};

// `cmp` allows a tree to be built with any sorting mechanism,
// such as by symbol or by price.
typedef struct {
	struct tree *root;
	int (*cmp)(const struct company *, const struct company *);
} market;

bool tree_insert(struct tree *t, struct company *comp,
	int (*cmp)(const struct company *, const struct company *)
{
	if(cmp(comp, t->data) < 1) {
		if(t->left) {
			return tree_insert(t->left, comp);
		} else {
			t->left = tree_create(comp);
			return t->left;
		}
	} else {
		if(t->right) {
			return tree_insert(t->right, comp);
		} else {
			t->right = tree_create(comp);
			return t->right;
		}
	}
}


struct company *stock_create(char *symbol, char *name, double price)
{
	struct company *new_stock = malloc(sizeof(*new_stock));
	if(!new_stock) {
		return NULL;
	}

	new_stock->name = strdup(name);
	if(!new_stock->name) {
		free(new_stock);
		return NULL;
	}

	strncpy(new_stock->symbol, symbol, sizeof(new_stock->symbol)-1);
	new_stock->symbol[sizeof(new_stock->symbol)-1] = '\0';

	new_stock->cents = 100 * price;

	return new_stock;
}

Flourishes

Challenge: Make the implementation a Splay tree.