Hone logo
Hone
Problems

Chronomorphic Types in TypeScript: Temporal Data Structures

Chronomorphisms, in the context of types, allow us to associate a timestamp with a value, effectively creating a "versioned" or "temporal" data structure. This challenge asks you to implement a system that allows you to track changes to a value over time, retrieving the value as it existed at a specific point in the past. This is useful for auditing, version control, and implementing features like "undo/redo" functionality.

Problem Description

You need to create a generic ChronomorphicType that can wrap any TypeScript type T. This type should allow you to store multiple versions of the value T, each associated with a timestamp (represented as a number, where higher numbers represent later times). The ChronomorphicType should provide a method to retrieve the value of the type T at a given timestamp. If no version exists at the specified timestamp, it should return undefined.

Key Requirements:

  • Generic Type: The ChronomorphicType must be generic, accepting any type T as a parameter.
  • Timestamped Values: Store values along with their timestamps.
  • Retrieval by Timestamp: Provide a method getValueAt(timestamp: number): T | undefined to retrieve the value at a specific timestamp.
  • Immutability: The internal state of the ChronomorphicType should be immutable after creation. Adding new versions should not modify existing versions.
  • No External Dependencies: The solution should not rely on external libraries.

Expected Behavior:

  • When a new value is added, it should be stored with the current timestamp.
  • getValueAt() should return the value associated with the latest timestamp that is less than or equal to the provided timestamp.
  • If no value exists at or before the given timestamp, getValueAt() should return undefined.
  • The order of values should be maintained based on their timestamps.

Edge Cases to Consider:

  • Empty ChronomorphicType: What happens when getValueAt() is called on an empty ChronomorphicType?
  • Timestamp before any stored values: What happens when getValueAt() is called with a timestamp earlier than any stored timestamp?
  • Multiple values with the same timestamp: Which value should be returned? (The problem doesn't specify, so you can choose a reasonable behavior, but document your choice.)
  • Large number of versions: Consider the performance implications of retrieving values from a large number of stored versions. (While optimization isn't the primary focus, be mindful of potential inefficiencies.)

Examples

Example 1:

Input:
const chronomorphicNumber = new ChronomorphicType<number>();
chronomorphicNumber.addValue(10, Date.now());
chronomorphicNumber.addValue(20, Date.now() + 1000);
chronomorphicNumber.addValue(30, Date.now() + 2000);

Output:
chronomorphicNumber.getValueAt(Date.now() + 1500); // 20
Explanation: The value 20 was added at a timestamp between Date.now() + 1000 and Date.now() + 2000, which is the latest value before Date.now() + 1500.

Example 2:

Input:
const chronomorphicString = new ChronomorphicType<string>();
chronomorphicString.addValue("hello", Date.now());
chronomorphicString.addValue("world", Date.now() + 500);

Output:
chronomorphicString.getValueAt(Date.now() - 100); // undefined
Explanation: No value exists before Date.now() - 100.

Example 3:

Input:
const chronomorphicBoolean = new ChronomorphicType<boolean>();
chronomorphicBoolean.addValue(true, Date.now());
chronomorphicBoolean.addValue(false, Date.now());

Output:
chronomorphicBoolean.getValueAt(Date.now()); // false
Explanation:  When timestamps are equal, the latest added value (false) is returned. This behavior is documented in the Notes section.

Constraints

  • Timestamp Type: Timestamps must be represented as numbers.
  • Value Type: The value T can be any valid TypeScript type.
  • Time Complexity: While not a primary focus, avoid excessively inefficient algorithms. A linear search through the stored versions is acceptable for this challenge.
  • Memory Usage: The solution should be reasonably memory-efficient.

Notes

  • You will need to create a class or a similar structure to implement the ChronomorphicType.
  • Consider how you will store the timestamped values internally (e.g., an array, a map).
  • When multiple values have the same timestamp, the most recently added value should be returned by getValueAt(). This is a design choice, and you should document it.
  • Error handling is not required for this challenge. Assume valid input.
  • Focus on clarity and correctness over extreme optimization. The goal is to demonstrate understanding of the concept and ability to implement it in TypeScript.
Loading editor...
typescript