InterviewPitch
Objective-J interview questions

Objective-J Interview Questions with Answers

Most Asked Objective-J Interview Questions for Software Engineer Roles

100+ QuestionsDetailed AnswersCode ExamplesUpdated for 2026

Introduction

Objective‑J is a dynamic programming language that brings the elegant syntax of Objective‑C to the web, running on top of JavaScript's runtime. It is designed to build rich, desktop‑like web applications using the Cappuccino framework, which provides a comprehensive AppKit‑like API for UI components, event handling, and data binding. With its message‑passing syntax, categories, protocols, and key‑value observing (KVO) and coding (KVC), Objective‑J enables developers to write clean, maintainable, and highly interactive web applications. It is particularly well‑suited for large‑scale single‑page applications and complex client‑side logic. This comprehensive guide collects the most frequently asked Objective‑J interview questions – from the basics of syntax and data types to advanced topics like KVO, KVC, design patterns, and coding challenges. Whether you are a frontend developer exploring Cappuccino or preparing for a specialised role, these questions will deepen your understanding and help you succeed in your next interview.

Why Objective‑J?

  • Objective‑C syntax – familiar and expressive for iOS/macOS developers
  • JavaScript runtime – runs natively in all modern web browsers
  • Cappuccino framework – comprehensive UI components and application architecture
  • Dynamic features – message sending, categories, and protocols
  • KVO/KVC – advanced data binding and observation
  • Cross‑platform – works on any browser without plugins

Most Asked Objective‑J Interview Questions

Beginner
1. What is Objective-J?

Objective-J is a programming language that combines Objective-C syntax with JavaScript's runtime. It's primarily used with the Cappuccino framework for web application development.

  • Objective-C syntax: Familiar syntax for iOS/macOS developers
  • JavaScript runtime: Runs in browsers and Node.js
  • Cappuccino framework: AppKit-like framework for web
  • Dynamic runtime: Message sending, dynamic typing
  • Cross-platform: Works on all modern web browsers
objective-j
// Hello World in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    console.log("Hello, World!");
}

@end
Beginner
2. How to declare variables in Objective-J?

Variables in Objective-J use JavaScript's var, let, or const syntax, with instance variables declared in the class definition.

  • Instance variables: Declared in class definition
  • Local variables: var, let, const
  • Primitive types: int, float, BOOL
  • Object types: CPString, CPArray, CPDictionary
  • id: Generic object type
objective-j
// Variables in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
    // Instance variables
    CPString mutableVar;
    CPString immutableVar;
    id inferred;
    int intVal;
    float floatVal;
    BOOL isActive;
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    mutableVar = "Hello";
    immutableVar = "World";
    inferred = 42;
    intVal = 10;
    floatVal = 3.14;
    isActive = YES;
    
    console.log(mutableVar);
    console.log(immutableVar);
    console.log(inferred);
    console.log(intVal);
}

@end
Beginner
3. What are the data types in Objective-J?

Objective-J supports JavaScript primitive types plus Cappuccino framework object types.

  • Primitive: int, float, double, BOOL
  • Cappuccino objects: CPString, CPArray, CPDictionary
  • Numbers: CPNumber, CPInteger, CPUInteger
  • Collections: CPArray, CPDictionary, CPMutableArray, CPMutableDictionary
  • Null: nil, NSNull
objective-j
// Data Types in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
    // Numeric types
    int intNum;
    float floatNum;
    double doubleNum;
    CPInteger integerNum;
    CPUInteger uIntegerNum;
    
    // Boolean
    BOOL isActive;
    
    // String
    CPString str;
    
    // Arrays (CPArray - immutable)
    CPArray array;
    
    // Mutable arrays
    CPMutableArray mutableArray;
    
    // Dictionaries (CPDictionary - immutable)
    CPDictionary dict;
    
    // Mutable dictionaries
    CPMutableDictionary mutableDict;
    
    // Null
    id nullValue;
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    intNum = 10;
    floatNum = 3.14;
    doubleNum = 3.14159;
    integerNum = 100;
    uIntegerNum = 100;
    isActive = YES;
    str = "Hello Objective-J";
    array = [1, 2, 3, 4, 5];
    mutableArray = [1, 2, 3];
    dict = @{@"name": @"Alice", @"age": @25};
    mutableDict = @{@"name": @"Alice", @"age": @25};
    nullValue = nil;
    
    console.log(str);
    console.log(array);
    console.log(dict);
}

@end
Beginner
4. How to define functions in Objective-J?

Functions in Objective-J use JavaScript function syntax, with methods defined in classes using Objective-C syntax.

  • JavaScript functions: function name(params)
  • Class methods: - (returnType)methodName:(paramType)paramName
  • Class functions: + (returnType)methodName
  • Blocks: function(params)
  • Multiple return values: Using arrays
objective-j
// Functions in Objective-J
@import <Foundation/Foundation.j>

// Basic function
function add(a, b) {
    return a + b;
}

// Function with multiple return values using array
function divide(a, b) {
    return [a / b, a % b];
}

// Higher-order function
function operate(a, b, operation) {
    return operation(a, b);
}

// Block (lambda equivalent)
var multiply = function(a, b) {
    return a * b;
};

// Method in class
@implementation Calculator : CPObject
{
}

- (int)add:(int)a with:(int)b
{
    return a + b;
}

- (CPArray)divide:(int)a by:(int)b
{
    return [a / b, a % b];
}

- (int)operate:(int)a with:(int)b usingBlock:(Function)operation
{
    return operation(a, b);
}

@end

// Usage
console.log(add(5, 3));
var result = divide(10, 3);
console.log("Quotient: " + result[0] + ", Remainder: " + result[1]);
console.log(operate(6, 7, multiply));
Beginner
5. What are arrays in Objective-J?

Objective-J uses CPArray (immutable) and CPMutableArray (mutable) for array operations, built on top of JavaScript arrays.

  • CPArray: [1, 2, 3]
  • CPMutableArray: [1, 2, 3] with methods
  • Access: array[0] or [array objectAtIndex:0]
  • Methods: addObject:, removeObject:, map, filter
  • Operations: length, indexOf, push
objective-j
// Arrays in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
    CPArray numbers;
    CPArray strings;
    CPMutableArray mutableNumbers;
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    numbers = [1, 2, 3, 4, 5];
    strings = ["Apple", "Banana", "Orange"];
    mutableNumbers = [1, 2, 3];
    
    // Access
    var num = numbers[2];
    console.log(num);
    
    // Modify (CPMutableArray)
    mutableNumbers[2] = 10;
    [mutableNumbers addObject:6];
    [mutableNumbers removeLastObject];
    
    // Iteration
    for (var i = 0; i < numbers.length; i++) {
        console.log(numbers[i]);
    }
    
    // Using for-in
    for (var num in numbers) {
        console.log(num);
    }
    
    // Array operations
    var count = numbers.length;
    var doubled = numbers.map(function(x) { return x * 2; });
    var filtered = numbers.filter(function(x) { return x > 2; });
    var sum = numbers.reduce(function(a, b) { return a + b; }, 0);
    
    console.log(doubled);
    console.log(filtered);
    console.log(sum);
}

@end
Beginner
6. What are collections in Objective-J?

Objective-J provides various collection classes including CPArray, CPSet, CPDictionary, and their mutable counterparts.

  • CPArray: Ordered collection
  • CPSet: Unordered collection, no duplicates
  • CPDictionary: Key-value pairs
  • Mutable versions: CPMutableArray, CPMutableSet, CPMutableDictionary
  • Operations: Filtering, mapping, reducing
objective-j
// Collections in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
    CPArray immutableArray;
    CPMutableArray mutableArray;
    CPMutableSet mutableSet;
    CPDictionary immutableDict;
    CPMutableDictionary mutableDict;
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    // CPArray (immutable)
    immutableArray = [1, 2, 3, 4, 5];
    
    // CPMutableArray
    mutableArray = [1, 2, 3];
    [mutableArray addObject:4];
    [mutableArray removeObject:2];
    
    // CPMutableSet
    mutableSet = [1, 2, 3];
    [mutableSet addObject:4];
    
    // CPDictionary (immutable)
    immutableDict = @{@"key1": @"value1", @"key2": @"value2"};
    
    // CPMutableDictionary
    mutableDict = @{@"key1": @"value1"};
    mutableDict[@"key2"] = @"value2";
    delete mutableDict[@"key1"];
    
    // Collection operations
    var numbers = [1, 2, 3, 4, 5, 6];
    var evens = numbers.filter(function(x) { return x % 2 === 0; });
    var doubled = numbers.map(function(x) { return x * 2; });
    var sum = numbers.reduce(function(a, b) { return a + b; }, 0);
    var exists = numbers.some(function(x) { return x > 10; });
    var allEven = numbers.every(function(x) { return x % 2 === 0; });
    
    console.log(evens);
    console.log(doubled);
    console.log(sum);
}

@end
Beginner
7. What are data classes in Objective-J?

Objective-J classes with properties and methods serve as data containers, similar to data classes in other languages.

  • Class definition: @implementation Person : CPObject
  • Instance variables: Declared in class definition
  • Initializer: - (id)initWithName:(CPString)name
  • Copying: Implement copy method
  • Description: Override description method
objective-j
// Data Classes in Objective-J
@import <Foundation/Foundation.j>

// Class definition
@implementation Person : CPObject
{
    CPString name;
    CPInteger age;
    CPString city;
}

- (id)initWithName:(CPString)aName age:(CPInteger)anAge city:(CPString)aCity
{
    self = [super init];
    if (self) {
        name = aName;
        age = anAge;
        city = aCity ? aCity : @"Unknown";
    }
    return self;
}

- (CPString)description
{
    return "Person(name=" + name + ", age=" + age + ", city=" + city + ")";
}

// Copy method
- (id)copy
{
    return [[Person alloc] initWithName:name age:age city:city];
}

@end

// Usage
var person1 = [[Person alloc] initWithName:@"Alice" age:25 city:@"NYC"];
var person2 = [person1 copy];
person2.age = 26;

console.log(person1);
console.log(person2);
console.log("Name: " + person1.name);
console.log("Age: " + person1.age);
Beginner
8. What are sealed classes in Objective-J?

Objective-J uses protocols and class clusters for sealed-like behavior, similar to Objective-C.

  • Protocols: Define interfaces
  • Class clusters: Private subclasses
  • Abstract classes: Using CPObject
  • Type checking: isKindOfClass:
  • Protocol adoption: @protocol Result
objective-j
// Protocol-based Sealed Classes in Objective-J
@import <Foundation/Foundation.j>

// Protocol definition
@protocol Result
@end

// Concrete implementations
@implementation Success : CPObject <Result>
{
    CPString data;
}

- (id)initWithData:(CPString)aData
{
    self = [super init];
    if (self) {
        data = aData;
    }
    return self;
}

- (CPString)data
{
    return data;
}

@end

@implementation Error : CPObject <Result>
{
    CPString message;
}

- (id)initWithMessage:(CPString)aMessage
{
    self = [super init];
    if (self) {
        message = aMessage;
    }
    return self;
}

- (CPString)message
{
    return message;
}

@end

@implementation Loading : CPObject <Result>
@end

// Shape protocol
@protocol Shape
- (double)area;
@end

// Circle implementation
@implementation Circle : CPObject <Shape>
{
    double radius;
}

- (id)initWithRadius:(double)aRadius
{
    self = [super init];
    if (self) {
        radius = aRadius;
    }
    return self;
}

- (double)area
{
    return Math.PI * radius * radius;
}

@end

// Rectangle implementation
@implementation Rectangle : CPObject <Shape>
{
    double width;
    double height;
}

- (id)initWithWidth:(double)aWidth height:(double)aHeight
{
    self = [super init];
    if (self) {
        width = aWidth;
        height = aHeight;
    }
    return self;
}

- (double)area
{
    return width * height;
}

@end

// Helper function
function handleResult(result) {
    if ([result isKindOfClass:[Success class]]) {
        return "Success: " + result.data;
    } else if ([result isKindOfClass:[Error class]]) {
        return "Error: " + result.message;
    } else if ([result isKindOfClass:[Loading class]]) {
        return "Loading...";
    }
    return "Unknown";
}

// Usage
var result = [[Success alloc] initWithData:@"Data loaded"];
console.log(handleResult(result));

var circle = [[Circle alloc] initWithRadius:5.0];
console.log("Circle area: " + circle.area());
Beginner
9. What is null safety in Objective-J?

Objective-J uses nil and null for null values, with JavaScript's truthy/falsy behavior for null checks.

  • nil: Represents null object
  • null: JavaScript null
  • Nil messaging: Safe to send messages to nil
  • NSNull: Used in collections for null values
  • Null checks: if (object === nil)
objective-j
// Null Safety in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
    CPString nullableString;
    CPString nonNullableString;
    id nullValue;
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    nullableString = nil;
    nonNullableString = "Hello";
    nullValue = nil;
    
    // Check for nil
    if (nullableString === nil) {
        console.log("String is nil");
    }
    
    // Elvis operator equivalent
    var result = nullableString ? nullableString : "default";
    console.log(result);
    
    // Safe method call
    if (nullableString) {
        console.log("String is: " + nullableString);
        console.log("Length: " + nullableString.length);
    }
    
    // Using typeof for null check
    if (typeof nullableString === "undefined" || nullableString === null) {
        console.log("String is null or undefined");
    }
    
    // NSNull for dictionary values
    var dict = @{@"key": [NSNull null]};
    var value = dict[@"key"];
    if (value === [NSNull null]) {
        console.log("Value is null");
    }
}

@end
Beginner
10. What are control flow statements in Objective-J?

Objective-J supports JavaScript control flow statements including if-else, switch, for, while, and do-while loops.

  • If-else: if (condition) else
  • Switch: switch (value) { case: ... }
  • For loop: for (var i = 0; i < n; i++)
  • For-in: for (var item in array)
  • While: while (condition)
objective-j
// Control Flow in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    // If-else
    var age = 25;
    var status;
    if (age < 18) {
        status = "Minor";
    } else {
        status = "Adult";
    }
    console.log(status);
    
    // Switch statement
    var grade = 'A';
    var result;
    switch (grade) {
        case 'A':
            result = "Excellent";
            break;
        case 'B':
            result = "Good";
            break;
        case 'C':
            result = "Fair";
            break;
        default:
            result = "Needs Improvement";
            break;
    }
    console.log(result);
    
    // For loop
    for (var i = 0; i < 5; i++) {
        console.log(i);
    }
    
    // For-in loop
    var items = ["A", "B", "C"];
    for (var i in items) {
        console.log(items[i]);
    }
    
    // While loop
    var i = 0;
    while (i < 5) {
        console.log(i);
        i++;
    }
    
    // Do-while loop
    i = 0;
    do {
        console.log(i);
        i--;
    } while (i > 0);
}

@end
Beginner
11. What are classes and inheritance in Objective-J?

Objective-J supports object-oriented programming with classes, inheritance, method overriding, and protocols.

  • Class definition: @implementation ClassName : SuperClass
  • Method overriding: Redefine method in subclass
  • Protocols: Similar to interfaces
  • Categories: Add methods to existing classes
  • Multiple inheritance: Achieved through protocols
objective-j
// Classes and Inheritance in Objective-J
@import <Foundation/Foundation.j>

// Base class
@implementation Animal : CPObject
{
    CPString name;
}

- (id)initWithName:(CPString)aName
{
    self = [super init];
    if (self) {
        name = aName;
    }
    return self;
}

- (void)makeSound
{
    console.log("Animal sound");
}

@end

// Derived class
@implementation Dog : Animal
{
    CPString breed;
}

- (id)initWithName:(CPString)aName breed:(CPString)aBreed
{
    self = [super initWithName:aName];
    if (self) {
        breed = aBreed;
    }
    return self;
}

- (void)makeSound
{
    console.log("Woof!");
}

@end

// Interface (protocol)
@protocol Flyable
- (void)fly;
- (void)land;
@end

@protocol Swimmable
- (void)swim;
@end

// Duck class implementing protocols
@implementation Duck : CPObject <Flyable, Swimmable>
{
}

- (void)fly
{
    console.log("Flying");
}

- (void)land
{
    console.log("Landing...");
}

- (void)swim
{
    console.log("Swimming");
}

@end

// Usage
var dog = [[Dog alloc] initWithName:@"Rex" breed:@"German Shepherd"];
[dog makeSound];
console.log(dog.name);
console.log(dog.breed);

var duck = [[Duck alloc] init];
[duck fly];
[duck swim];
Beginner
12. What are properties in Objective-J?

Properties in Objective-J are implemented as instance variables with custom getter and setter methods.

  • Instance variables: CPString _name
  • Custom getter: - (CPString)name
  • Custom setter: - (void)setName:(CPString)aName
  • Read-only: Only implement getter
  • Lazy properties: Compute on first access
objective-j
// Properties in Objective-J
@import <Foundation/Foundation.j>

@implementation Person : CPObject
{
    CPString _name;
    CPInteger _age;
    CPString _email;
    CPString _expensiveData;
}

- (id)init
{
    self = [super init];
    if (self) {
        _name = "";
        _age = 0;
        _email = "";
        _expensiveData = nil;
    }
    return self;
}

// Custom getter for name
- (CPString)name
{
    return _name.toUpperCase();
}

// Custom setter for name
- (void)setName:(CPString)aName
{
    _name = aName.trim();
}

// Custom setter for age (validation)
- (void)setAge:(CPInteger)anAge
{
    if (anAge >= 0) {
        _age = anAge;
    }
}

// Read-only property
- (CPString)fullName
{
    return _name + " (Age: " + _age + ")";
}

// Lazy property
- (CPString)expensiveData
{
    if (!_expensiveData) {
        console.log("Computing expensive data...");
        _expensiveData = "Expensive Result";
    }
    return _expensiveData;
}

@end

// Usage
var person = [[Person alloc] init];
person.name = "  Alice  ";
console.log(person.name);  // ALICE

person.age = 25;
console.log(person.age);

console.log(person.fullName);
console.log(person.expensiveData);  // Computes
console.log(person.expensiveData);  // Returns cached
Intermediate
13. What are class methods in Objective-J?

Class methods are declared with + and are called on the class itself. They use static variables in JavaScript.

  • + methods: Class-level methods
  • Singleton pattern: sharedInstance method
  • Factory methods: + (id)create
  • Class variables: JavaScript static variables
  • Singleton initialization: Lazy initialization
objective-j
// Class Methods in Objective-J
@import <Foundation/Foundation.j>

@implementation MyClass : CPObject
{
}

// Class variable (static)
var counter = 0;

// Class constants
+ (CPString)tag
{
    return "MyClass";
}

// Factory method
+ (id)create
{
    counter++;
    return [[self alloc] init];
}

// Class method
+ (void)classMethod
{
    console.log("Class method called, counter: " + counter);
}

// Instance method
- (void)instanceMethod
{
    console.log("Instance method called");
}

@end

// Usage
console.log([MyClass tag]);

var obj1 = [MyClass create];
var obj2 = [MyClass create];

[MyClass classMethod];

[obj1 instanceMethod];
[obj2 instanceMethod];
Intermediate
14. How to handle exceptions in Objective-J?

Objective-J uses JavaScript's try-catch-finally for exception handling. Custom exceptions can be created by extending Error.

  • try-catch: try catch (e)
  • finally: Cleanup block
  • Custom exceptions: function MyError() MyError.prototype = new Error()
  • throw: throw new Error("message")
  • Error types: Check with instanceof
objective-j
// Exception Handling in Objective-J
@import <Foundation/Foundation.j>

// Custom exception
function InvalidAgeException(age) {
    this.age = age;
    this.message = "Invalid age: " + age;
}

InvalidAgeException.prototype = new Error();

// Try-catch block
function divide(a, b) {
    try {
        return a / b;
    } catch (e) {
        if (e.message.indexOf("division by zero") !== -1) {
            console.log("Division by zero!");
            return 0;
        }
        throw e;
    }
}

function validateAge(age) {
    if (age < 0 || age > 150) {
        throw new InvalidAgeException(age);
    }
    return age;
}

// Usage
try {
    console.log(divide(10, 2));
    console.log(divide(10, 0));
} catch (e) {
    console.log("Error: " + e.message);
} finally {
    console.log("Finally block");
}

// Custom exception
try {
    validateAge(200);
} catch (e) {
    if (e instanceof InvalidAgeException) {
        console.log("Caught: " + e.message + ", Age: " + e.age);
    }
}

// Finally for cleanup
try {
    // Some operation
} catch (e) {
    console.log("Error: " + e);
} finally {
    console.log("Cleaning up resources...");
}
Intermediate
15. What are blocks/closures in Objective-J?

Blocks in Objective-J are implemented using JavaScript closures. They capture variables from their surrounding scope.

  • Closure syntax: function(params)
  • Arrow functions: (params) => { }
  • Capturing variables: Lexical scoping
  • Block as parameter: function(block)
  • Block as return: return function()
objective-j
// Blocks/Closures in Objective-J
@import <Foundation/Foundation.j>

@implementation AppController : CPObject
{
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    // Basic block/closure
    var square = function(x) {
        return x * x;
    };
    
    // Block with multiple parameters
    var add = function(a, b) {
        return a + b;
    };
    
    // Block as parameter
    var result = [self performOperation:10 y:20 operation:function(a, b) {
        return a * b;
    }];
    console.log(result);
    
    // Block with multiple lines
    var complexOperation = function(x) {
        var y = x * 2;
        return y + 10;
    };
    
    // Using block with array
    var numbers = [1, 2, 3, 4, 5];
    var doubled = numbers.map(function(x) { return x * 2; });
    console.log(doubled);
    
    // Block with enumeration
    numbers.forEach(function(obj, idx) {
        console.log("Index " + idx + ": " + obj);
    });
    
    // Block with completion handler
    var completionHandler = function(result, error) {
        if (error) {
            console.log("Error: " + error);
        } else {
            console.log("Result: " + result);
        }
    };
    
    completionHandler("Success", null);
}

- (int)performOperation:(int)x y:(int)y operation:(Function)operation
{
    return operation(x, y);
}

@end
Intermediate
16. What are categories in Objective-J?

Categories add methods to existing classes without subclassing. They are implemented using JavaScript's prototype system.

  • Category syntax: @implementation CPString (StringExtensions)
  • Adding methods: Add instance and class methods
  • Method overriding: Can override existing methods
  • Prototype extension: JavaScript prototype
  • Class extensions: @implementation ClassName ()
objective-j
// Categories in Objective-J
@import <Foundation/Foundation.j>

// String category
@implementation CPString (StringExtensions)

- (BOOL)isEmail
{
    return this.indexOf('@') !== -1 && this.indexOf('.') !== -1;
}

- (CPString)addPrefix:(CPString)prefix
{
    return prefix + this;
}

- (int)wordCount
{
    return this.split(' ').length;
}

@end

// Number category
@implementation CPNumber (NumberExtensions)

- (BOOL)isEven
{
    return this % 2 === 0;
}

- (BOOL)isOdd
{
    return this % 2 !== 0;
}

@end

// Array category
@implementation CPArray (ArrayExtensions)

- (id)secondOrNil
{
    if (this.length >= 2) {
        return this[1];
    }
    return nil;
}

@end

// Usage
var email = "test@example.com";
console.log(email.isEmail());  // true

var greeting = "Hello".addPrefix("Greeting: ");
console.log(greeting);

var num = 5;
console.log(num.isEven());  // false

var sentence = "Hello World";
console.log(sentence.wordCount());

var array = [1, 2, 3];
console.log(array.secondOrNil());
Intermediate
17. What are protocols in Objective-J?

Protocols define interfaces that classes can adopt. They are similar to JavaScript interfaces.

  • @protocol: Define protocol
  • @required: Required methods
  • @optional: Optional methods
  • Adoption: @implementation Class < Protocol >
  • respondsToSelector: Check for method support
objective-j
// Protocols in Objective-J
@import <Foundation/Foundation.j>

// Protocol definition
@protocol Printable
- (void)print;
- (void)printWithPrefix:(CPString)prefix;
@end

// Protocol with multiple methods
@protocol DataSource
- (int)numberOfItems;
- (id)itemAtIndex:(int)index;
@end

// Class implementing protocol
@implementation MyDocument : CPObject <Printable, DataSource>
{
    CPArray items;
}

- (id)init
{
    self = [super init];
    if (self) {
        items = ["Item 1", "Item 2", "Item 3"];
    }
    return self;
}

- (void)print
{
    console.log("Printing document");
}

- (void)printWithPrefix:(CPString)prefix
{
    console.log(prefix + ": Printing document");
}

- (int)numberOfItems
{
    return items.length;
}

- (id)itemAtIndex:(int)index
{
    return items[index];
}

@end

// Protocol for delegation
@protocol MyDelegate
- (void)didFinishTask;
- (void)didFailWithError:(Error)error;
@end

// Class using delegate
@implementation TaskManager : CPObject
{
    id <MyDelegate> delegate;
}

- (void)setDelegate:(id <MyDelegate>)aDelegate
{
    delegate = aDelegate;
}

- (void)startTask
{
    // Simulate task
    var success = YES;
    if (success) {
        if ([delegate respondsToSelector:@selector(didFinishTask)]) {
            [delegate didFinishTask];
        }
    } else {
        var error = new Error("Task failed");
        if ([delegate respondsToSelector:@selector(didFailWithError:)]) {
            [delegate didFailWithError:error];
        }
    }
}

@end

// Usage
var doc = [[MyDocument alloc] init];
[doc print];
[doc printWithPrefix:@"PREFIX"];

console.log([doc numberOfItems]);
console.log([doc itemAtIndex:1]);
Intermediate
18. What are type aliases in Objective-J?

Type aliases in Objective-J are created using JavaScript's variable assignments for functions and objects.

  • Function aliases: var Operation = Function
  • Object aliases: var UserMap = Object
  • Callback aliases: var ResultCallback = Function
  • Complex types: Use JavaScript objects
  • Type checking: typeof and instanceof
objective-j
// Type Aliases in Objective-J
@import <Foundation/Foundation.j>

// Type alias using var
var Operation = Function;
var UserMap = Object;
var ResultCallback = Function;

// Using type alias
var add = function(a, b) {
    return a + b;
};

var multiply = function(a, b) {
    return a * b;
};

function execute(op, a, b) {
    return op(a, b);
}

// Complex type alias
var User = {
    name: String,
    age: Number
};

// Usage
console.log(execute(add, 5, 3));
console.log(execute(multiply, 5, 3));

var users = {
    "user1": {name: "Alice", age: 25},
    "user2": {name: "Bob", age: 30}
};

console.log(users["user1"].name);

// Using callback
var callback = function(result, error) {
    if (error) {
        console.log("Error: " + error);
    } else {
        console.log("Result: " + result);
    }
};

callback("Success", null);
Intermediate
19. What are inline functions in Objective-J?

Inline functions in Objective-J are implemented using JavaScript functions and closures for performance-critical operations.

  • Function declarations: function square(x) { return x*x; }
  • Arrow functions: const square = (x) => x * x
  • Function expressions: var square = function(x) { return x * x; }
  • Performance: Reduced function call overhead
  • Type safety: JavaScript's dynamic typing
objective-j
// Inline Functions in Objective-J
@import <Foundation/Foundation.j>

// Inline function using function
function square(x) {
    return x * x;
}

function add(a, b) {
    return a + b;
}

// Function-like macro
function SQUARE(x) { return x * x; }
function ADD(a, b) { return a + b; }

// Inline function with block
function measureTime(block) {
    var start = new Date();
    block();
    var end = new Date();
    console.log("Time: " + (end - start) + "ms");
}

// Usage
console.log(square(5));
console.log(add(5, 3));

console.log(SQUARE(5));
console.log(ADD(5, 3));

measureTime(function() {
    // Some operation
    console.log("Operation completed");
});
Intermediate
20. What are higher-order functions in Objective-J?

Higher-order functions in Objective-J are implemented using JavaScript's first-class functions.

  • Function parameters: function applyOperation(a, b, operation)
  • Returning functions: function getMultiplier(factor) { return function(x) { } }
  • Array operations: map, filter, reduce
  • Composition: function compose(f, g)
  • Callbacks: Async operations
objective-j
// Higher-Order Functions in Objective-J
@import <Foundation/Foundation.j>

// Function that takes a function as parameter
function applyOperation(a, b, operation) {
    return operation(a, b);
}

// Function that returns a function
function getMultiplier(factor) {
    return function(x) {
        return x * factor;
    };
}

// Function composition
function compose(f, g) {
    return function(x) {
        return f(g(x));
    };
}

// Usage
var result = applyOperation(10, 20, function(a, b) {
    return a + b;
});
console.log(result);

var double = getMultiplier(2);
console.log(double(5));

var square = function(x) {
    return x * x;
};
var addTen = function(x) {
    return x + 10;
};
var squareThenAddTen = compose(addTen, square);
console.log(squareThenAddTen(5));

// Using named function
function add(a, b) {
    return a + b;
}
console.log(applyOperation(10, 20, add));

// Array operations with functions
var numbers = [1, 2, 3, 4, 5];
var squared = numbers.map(function(x) { return x * x; });
var even = numbers.filter(function(x) { return x % 2 === 0; });
var sum = numbers.reduce(function(a, b) { return a + b; }, 0);
console.log(squared);
console.log(even);
console.log(sum);
Advanced
21. What is asynchronous programming in Objective-J?

Asynchronous programming in Objective-J uses JavaScript's setTimeout, Promises, and async/await patterns.

  • setTimeout: setTimeout(function() , delay)
  • setInterval: setInterval(function() , interval)
  • Promises: new Promise(function(resolve, reject) )
  • async/await: async function() { await promise }
  • Deferred: Custom promise-like patterns
objective-j
// Asynchronous Programming in Objective-J
@import <Foundation/Foundation.j>

// Async fetch using setTimeout
function fetchData(callback) {
    setTimeout(function() {
        callback("Data loaded");
    }, 1000);
}

// Multiple async tasks
function parallelTasks(callback) {
    var results = [];
    var completed = 0;
    
    function taskComplete(result) {
        results.push(result);
        completed++;
        if (completed === 2) {
            callback(results);
        }
    }
    
    setTimeout(function() {
        taskComplete("Task 1");
    }, 1000);
    
    setTimeout(function() {
        taskComplete("Task 2");
    }, 500);
}

// Timeout
function withTimeout(block, timeoutMs) {
    var timeoutId = setTimeout(function() {
        console.log("Timed out!");
    }, timeoutMs);
    
    var result = block();
    clearTimeout(timeoutId);
    return result;
}

// Promise-like implementation
function createDeferred() {
    var callbacks = [];
    var state = "pending";
    var result = null;
    
    return {
        resolve: function(value) {
            if (state === "pending") {
                state = "resolved";
                result = value;
                callbacks.forEach(function(cb) { cb(value); });
            }
        },
        reject: function(error) {
            if (state === "pending") {
                state = "rejected";
                result = error;
                callbacks.forEach(function(cb) { cb(error); });
            }
        },
        then: function(callback) {
            if (state === "pending") {
                callbacks.push(callback);
            } else if (state === "resolved") {
                callback(result);
            }
            return this;
        }
    };
}

// Usage
fetchData(function(result) {
    console.log(result);
});

parallelTasks(function(results) {
    console.log("Results: " + results);
});

var deferred = createDeferred();
deferred.then(function(value) {
    console.log("Resolved: " + value);
});
setTimeout(function() {
    deferred.resolve("Success!");
}, 1000);
Advanced
22. What is event handling in Objective-J?

Event handling in Objective-J uses Target-Action pattern, delegates, and notification centers similar to Cocoa.

  • Target-Action: setTarget:, setAction:
  • Delegates: setDelegate:
  • Notifications: [[CPNotificationCenter defaultCenter] addObserver:...]
  • Event objects: CPEvent
  • Responder chain: respondsToSelector:
objective-j
// Event Handling in Objective-J
@import <Foundation/Foundation.j>
@import <AppKit/AppKit.j>

@implementation AppController : CPObject
{
    CPButton button;
    CPTextField textField;
}

- (void)applicationDidFinishLaunching:(CPNotification)aNotification
{
    var window = [[CPWindow alloc] initWithContentRect:CGRectMake(0, 0, 400, 300)
        styleMask:CPWindowTitled | CPWindowClosable | CPWindowResizable];
    
    // Button
    button = [[CPButton alloc] initWithFrame:CGRectMake(100, 100, 100, 30)];
    [button setTitle:@"Click Me"];
    [button setTarget:self];
    [button setAction:@selector(buttonClicked:)];
    [[window contentView] addSubview:button];
    
    // Text field
    textField = [[CPTextField alloc] initWithFrame:CGRectMake(100, 50, 200, 30)];
    [textField setStringValue:@"Hello"];
    [[window contentView] addSubview:textField];
    
    // Delegate
    [window setDelegate:self];
    
    [window orderFront:nil];
}

- (void)buttonClicked:(id)sender
{
    console.log("Button clicked!");
    [textField setStringValue:@"Button clicked!"];
}

- (void)windowWillClose:(CPNotification)aNotification
{
    console.log("Window closing");
}

@end
Advanced
23. What is KVO in Objective-J?

Key-Value Observing (KVO) allows objects to be notified when properties of other objects change, similar to Objective-C.

  • addObserver: addObserver:forKeyPath:options:context:
  • observeValueForKeyPath: observeValueForKeyPath:ofObject:change:context:
  • willChangeValueForKey: willChangeValueForKey:
  • didChangeValueForKey: didChangeValueForKey:
  • removeObserver: removeObserver:forKeyPath:
objective-j
// KVO in Objective-J
@import <Foundation/Foundation.j>

// Observable class
@implementation Person : CPObject
{
    CPString name;
    CPInteger age;
}

- (void)setName:(CPString)aName
{
    [self willChangeValueForKey:@"name"];
    name = aName;
    [self didChangeValueForKey:@"name"];
}

- (CPString)name
{
    return name;
}

- (void)setAge:(CPInteger)anAge
{
    [self willChangeValueForKey:@"age"];
    age = anAge;
    [self didChangeValueForKey:@"age"];
}

- (CPInteger)age
{
    return age;
}

@end

// Observer class
@implementation PersonObserver : CPObject
{
    Person person;
}

- (id)initWithPerson:(Person)aPerson
{
    self = [super init];
    if (self) {
        person = aPerson;
        [person addObserver:self
                 forKeyPath:@"name"
                    options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld
                    context:NULL];
        
        [person addObserver:self
                 forKeyPath:@"age"
                    options:CPKeyValueObservingOptionNew | CPKeyValueObservingOptionOld
                    context:NULL];
    }
    return self;
}

- (void)observeValueForKeyPath:(CPString)keyPath
                      ofObject:(id)object
                        change:(CPDictionary)change
                       context:(void)context
{
    if (keyPath === "name") {
        var old = change[CPKeyValueChangeOldKey];
        var new = change[CPKeyValueChangeNewKey];
        console.log("Name changed from " + old + " to " + new);
    } else if (keyPath === "age") {
        var old = change[CPKeyValueChangeOldKey];
        var new = change[CPKeyValueChangeNewKey];
        console.log("Age changed from " + old + " to " + new);
    }
}

- (void)dealloc
{
    [person removeObserver:self forKeyPath:@"name"];
    [person removeObserver:self forKeyPath:@"age"];
}

@end

// Usage
var person = [[Person alloc] init];
var observer = [[PersonObserver alloc] initWithPerson:person];

person.name = "Alice";
person.age = 25;
person.name = "Bob";
person.age = 30;
Advanced
24. What is KVC in Objective-J?

Key-Value Coding (KVC) allows accessing object properties by name using string keys, similar to Objective-C.

  • valueForKey: valueForKey:
  • setValue:forKey: setValue:forKey:
  • Collection operators: @sum, @avg, @max
  • Key paths: @"employees.@sum.salary"
  • Validation: validateValue:forKey:
objective-j
// KVC in Objective-J
@import <Foundation/Foundation.j>

// Class with properties
@implementation Employee : CPObject
{
    CPString name;
    CPInteger age;
    double salary;
    CPString department;
}
@end

// Class with nested objects
@implementation Department : CPObject
{
    CPString name;
    CPArray employees;
}
@end

// Usage
var emp1 = [[Employee alloc] init];
[emp1 setValue:@"Alice" forKey:@"name"];
[emp1 setValue:25 forKey:@"age"];
[emp1 setValue:50000 forKey:@"salary"];
[emp1 setValue:@"Engineering" forKey:@"department"];

var emp2 = [[Employee alloc] init];
[emp2 setValue:@"Bob" forKey:@"name"];
[emp2 setValue:30 forKey:@"age"];
[emp2 setValue:60000 forKey:@"salary"];
[emp2 setValue:@"Engineering" forKey:@"department"];

// Department
var dept = [[Department alloc] init];
[dept setValue:@"Engineering" forKey:@"name"];
[dept setValue:[emp1, emp2] forKey:@"employees"];

// KVC access
console.log("Employee name: " + [emp1 valueForKey:@"name"]);
console.log("Department name: " + [dept valueForKey:@"name"]);

// KVC collection operators
var totalSalary = [dept valueForKeyPath:@"employees.@sum.salary"];
var avgSalary = [dept valueForKeyPath:@"employees.@avg.salary"];
var maxSalary = [dept valueForKeyPath:@"employees.@max.salary"];
var minSalary = [dept valueForKeyPath:@"employees.@min.salary"];

console.log("Total salary: " + totalSalary);
console.log("Average salary: " + avgSalary);
console.log("Max salary: " + maxSalary);
console.log("Min salary: " + minSalary);

// Array of values
var names = [dept valueForKeyPath:@"employees.name"];
console.log("Names: " + names);
Advanced
25. What are generics in Objective-J?

Objective-J uses JavaScript's dynamic typing for generics. Type checking can be implemented with typeof and instanceof.

  • Generic classes: JavaScript classes with dynamic types
  • Type checking: typeof, instanceof
  • Type safety: Runtime type checking
  • Generic functions: Functions that work with any type
  • Template pattern: Using JavaScript's prototype
objective-j
// Generics in Objective-J
@import <Foundation/Foundation.j>

// Generic class using JavaScript
function Box(value) {
    this.value = value;
}

Box.prototype.getValue = function() {
    return this.value;
};

// Generic collection
function GenericDictionary() {
    this.dictionary = {};
}

GenericDictionary.prototype.setObject = function(object, key) {
    this.dictionary[key] = object;
};

GenericDictionary.prototype.objectForKey = function(key) {
    return this.dictionary[key];
};

// Usage
var stringBox = new Box("Hello");
console.log(stringBox.getValue());

var numberBox = new Box(42);
console.log(numberBox.getValue());

var dict = new GenericDictionary();
dict.setObject(25, "age");
dict.setObject(30, "score");
console.log(dict.objectForKey("age"));

// Array methods
var array = [1, 2, 3];
var reversed = array.slice().reverse();
console.log(reversed);
console.log(array[0]);

// Custom generic class with type checking
function TypedBox(type) {
    this.type = type;
    this.value = null;
}

TypedBox.prototype.setValue = function(value) {
    if (typeof value !== this.type) {
        throw new Error("Invalid type: expected " + this.type);
    }
    this.value = value;
};

TypedBox.prototype.getValue = function() {
    return this.value;
};

var stringTypedBox = new TypedBox("string");
stringTypedBox.setValue("Hello");
console.log(stringTypedBox.getValue());
Advanced
26. What is delegation in Objective-J?

Delegation is a design pattern where one object delegates responsibilities to another, using protocols and weak references.

  • Delegate protocol: Define protocol
  • Delegate property: id <Protocol> delegate
  • respondsToSelector: Check for method support
  • Multiple delegates: Array of delegates
  • Common uses: Data sources, event handling
objective-j
// Delegation Pattern in Objective-J
@import <Foundation/Foundation.j>

// Delegate protocol
@protocol DataSourceDelegate
@optional
- (void)dataDidLoad:(CPArray)data;
- (void)dataDidFailWithError:(Error)error;
@end

// Class that uses delegate
@implementation DataSource : CPObject
{
    id <DataSourceDelegate> delegate;
}

- (void)setDelegate:(id <DataSourceDelegate>)aDelegate
{
    delegate = aDelegate;
}

- (void)loadData
{
    // Simulate async data loading
    setTimeout(function() {
        if ([delegate respondsToSelector:@selector(dataDidLoad:)]) {
            [delegate dataDidLoad:["Item 1", "Item 2", "Item 3"]];
        }
    }, 500);
}

@end

// Delegate implementation
@implementation ViewController : CPObject <DataSourceDelegate>
{
    DataSource dataSource;
}

- (void)setupDataSource
{
    dataSource = [[DataSource alloc] init];
    [dataSource setDelegate:self];
    [dataSource loadData];
}

- (void)dataDidLoad:(CPArray)data
{
    console.log("Data loaded: " + data);
}

- (void)dataDidFailWithError:(Error)error
{
    console.log("Error: " + error);
}

@end

// Multiple delegates
@protocol MultiDelegate
- (void)handleEvent:(CPString)event;
@end

@implementation EventManager : CPObject
{
    CPArray delegates;
}

- (id)init
{
    self = [super init];
    if (self) {
        delegates = [];
    }
    return self;
}

- (void)addDelegate:(id <MultiDelegate>)delegate
{
    delegates.push(delegate);
}

- (void)triggerEvent
{
    for (var i = 0; i < delegates.length; i++) {
        var delegate = delegates[i];
        if ([delegate respondsToSelector:@selector(handleEvent:)]) {
            [delegate handleEvent:@"Event triggered"];
        }
    }
}

@end

// Usage
var vc = [[ViewController alloc] init];
[vc setupDataSource];
Advanced
27. What is the singleton pattern in Objective-J?

Singleton pattern ensures a class has only one instance. It's implemented using static variables and lazy initialization.

  • sharedInstance: Class method
  • Static variable: static var sharedInstance = nil
  • Lazy initialization: Create on first access
  • Thread safety: Single-threaded environment
  • Common uses: AppConfig, DataManager
objective-j
// Singleton Pattern in Objective-J
@import <Foundation/Foundation.j>

// Singleton class
@implementation AppConfig : CPObject
{
    CPString apiUrl;
    CPInteger timeout;
}

+ (id)sharedInstance
{
    static var sharedInstance = nil;
    if (!sharedInstance) {
        sharedInstance = [[self alloc] init];
        sharedInstance.apiUrl = "https://api.example.com";
        sharedInstance.timeout = 5000;
    }
    return sharedInstance;
}

- (void)printConfig
{
    console.log("API URL: " + apiUrl);
    console.log("Timeout: " + timeout);
}

@end

// UserManager singleton with state
@implementation UserManager : CPObject
{
    CPArray users;
}

+ (id)sharedManager
{
    static var sharedManager = nil;
    if (!sharedManager) {
        sharedManager = [[self alloc] init];
        sharedManager.users = [];
    }
    return sharedManager;
}

- (void)addUser:(CPString)user
{
    users.push(user);
}

- (void)removeUser:(CPString)user
{
    var index = users.indexOf(user);
    if (index !== -1) {
        users.splice(index, 1);
    }
}

@end

// Usage
var config1 = [AppConfig sharedInstance];
var config2 = [AppConfig sharedInstance];

console.log(config1 === config2);  // true
[config1 printConfig];

var manager = [UserManager sharedManager];
[manager addUser:@"Alice"];
[manager addUser:@"Bob"];
console.log("Users: " + manager.users);

var manager2 = [UserManager sharedManager];
[manager2 addUser:@"Charlie"];
console.log("Users: " + manager.users);
Advanced
28. What is the factory pattern in Objective-J?

Factory pattern is implemented using class methods that create and return instances of different classes.

  • Factory method: + (id)createWithType:(CPString)type
  • Object creation: Based on parameters
  • Abstract factory: Factory of factories
  • Common uses: Creating different object types
  • Benefits: Decoupling creation logic
objective-j
// Factory Pattern in Objective-J
@import <Foundation/Foundation.j>

// Base classes
@implementation User : CPObject
{
    CPString name;
}

- (CPString)getRole
{
    return "user";
}

@end

@implementation Admin : User
{
}

- (CPString)getRole
{
    return "admin";
}

@end

@implementation Guest : User
{
}

- (CPString)getRole
{
    return "guest";
}

@end

// Factory class
@implementation UserFactory : CPObject
{
}

+ (User)createUserWithType:(CPString)type name:(CPString)name
{
    var user = nil;
    
    if (type === "admin") {
        user = [[Admin alloc] init];
    } else if (type === "guest") {
        user = [[Guest alloc] init];
    } else {
        user = [[User alloc] init];
    }
    
    user.name = name;
    return user;
}

@end

// Abstract factory with protocols
@protocol Widget
- (void)draw;
@end

@implementation Button : CPObject <Widget>
{
}

- (void)draw
{
    console.log("Drawing Button");
}

@end

@implementation TextField : CPObject <Widget>
{
}

- (void)draw
{
    console.log("Drawing TextField");
}

@end

@implementation WidgetFactory : CPObject
{
}

+ (id <Widget>)createWidget:(CPString)type
{
    if (type === "button") {
        return [[Button alloc] init];
    } else if (type === "textfield") {
        return [[TextField alloc] init];
    }
    return nil;
}

@end

// Usage
var admin = [UserFactory createUserWithType:@"admin" name:@"Alice"];
var guest = [UserFactory createUserWithType:@"guest" name:@"Bob"];

console.log(admin.name + " role: " + [admin getRole]);
console.log(guest.name + " role: " + [guest getRole]);

var button = [WidgetFactory createWidget:@"button"];
var textField = [WidgetFactory createWidget:@"textfield"];

[button draw];
[textField draw];
Advanced
29. What is the strategy pattern in Objective-J?

Strategy pattern defines a family of algorithms and makes them interchangeable using protocols and composition.

  • Strategy protocol: Define algorithm interface
  • Concrete strategies: Implement protocol
  • Context class: Uses strategy
  • Runtime switching: Change strategy at runtime
  • Benefits: Encapsulate algorithms
objective-j
// Strategy Pattern in Objective-J
@import <Foundation/Foundation.j>

// Strategy protocol
@protocol PaymentStrategy
- (void)pay:(double)amount;
@end

// Concrete strategies
@implementation CreditCardStrategy : CPObject <PaymentStrategy>
{
}

- (void)pay:(double)amount
{
    console.log("Paid $" + amount + " with Credit Card");
}

@end

@implementation PayPalStrategy : CPObject <PaymentStrategy>
{
}

- (void)pay:(double)amount
{
    console.log("Paid $" + amount + " with PayPal");
}

@end

@implementation CryptoStrategy : CPObject <PaymentStrategy>
{
}

- (void)pay:(double)amount
{
    console.log("Paid $" + amount + " with Crypto");
}

@end

// Context class
@implementation PaymentContext : CPObject
{
    id <PaymentStrategy> strategy;
}

- (id)initWithStrategy:(id <PaymentStrategy>)aStrategy
{
    self = [super init];
    if (self) {
        strategy = aStrategy;
    }
    return self;
}

- (void)setStrategy:(id <PaymentStrategy>)aStrategy
{
    strategy = aStrategy;
}

- (void)executePayment:(double)amount
{
    [strategy pay:amount];
}

@end

// Usage
var context = [[PaymentContext alloc] initWithStrategy:[[CreditCardStrategy alloc] init]];
[context executePayment:100.0];

[context setStrategy:[[PayPalStrategy alloc] init]];
[context executePayment:50.0];

[context setStrategy:[[CryptoStrategy alloc] init]];
[context executePayment:75.0];
Advanced
30. What is the observer pattern in Objective-J?

Observer pattern in Objective-J is implemented using protocols, notifications, or KVO.

  • Observer protocol: Define update method
  • Subject: Maintains observers
  • Attach/Detach: Add/remove observers
  • Notify: Call update on all observers
  • Benefits: Loose coupling, event-driven architecture
objective-j
// Observer Pattern in Objective-J
@import <Foundation/Foundation.j>

// Observer protocol
@protocol Observer
- (void)update:(CPString)data;
@end

// Subject class
@implementation Subject : CPObject
{
    CPString state;
    CPArray observers;
}

- (id)init
{
    self = [super init];
    if (self) {
        observers = [];
        state = "";
    }
    return self;
}

- (void)attach:(id <Observer>)observer
{
    observers.push(observer);
}

- (void)detach:(id <Observer>)observer
{
    var index = observers.indexOf(observer);
    if (index !== -1) {
        observers.splice(index, 1);
    }
}

- (void)setState:(CPString)aState
{
    state = aState;
    [self notifyObservers];
}

- (void)notifyObservers
{
    for (var i = 0; i < observers.length; i++) {
        var observer = observers[i];
        [observer update:state];
    }
}

@end

// Concrete observer
@implementation ConcreteObserver : CPObject <Observer>
{
    CPString name;
}

- (id)initWithName:(CPString)aName
{
    self = [super init];
    if (self) {
        name = aName;
    }
    return self;
}

- (void)update:(CPString)data
{
    console.log(name + " received: " + data);
}

@end

// Usage
var subject = [[Subject alloc] init];
var observer1 = [[ConcreteObserver alloc] initWithName:@"Observer1"];
var observer2 = [[ConcreteObserver alloc] initWithName:@"Observer2"];

[subject attach:observer1];
[subject attach:observer2];

[subject setState:@"Hello World"];

[subject detach:observer1];
[subject setState:@"Hello again"];
Coding Round
31. Reverse a string

Reverse a string using JavaScript methods or manual iteration.

  • Built-in: str.split('').reverse().join('')
  • Manual: Iterate from end to start
  • Using spread: [...str].reverse().join('')
  • Complexity: O(n) time
objective-j
// Reverse a string in Objective-J
@import <Foundation/Foundation.j>

function reverseString(str) {
    return str.split('').reverse().join('');
}

console.log(reverseString("hello"));  // "olleh"

// Using spread operator
function reverseStringSpread(str) {
    return [...str].reverse().join('');
}

console.log(reverseStringSpread("hello"));  // "olleh"

// Manual implementation
function reverseStringManual(str) {
    var result = "";
    for (var i = str.length - 1; i >= 0; i--) {
        result += str[i];
    }
    return result;
}

console.log(reverseStringManual("hello"));  // "olleh"
Coding Round
32. Check palindrome

Check if a string is a palindrome using JavaScript methods or two-pointer approach.

  • Built-in: str === str.split('').reverse().join('')
  • Two-pointer: Compare from both ends
  • Case insensitive: toLowerCase()
  • Ignoring non-alphanumeric: replace(/[^a-z0-9]/g, '')
objective-j
// Check palindrome in Objective-J
@import <Foundation/Foundation.j>

function isPalindrome(str) {
    var cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, '');
    return cleaned === cleaned.split('').reverse().join('');
}

console.log(isPalindrome("racecar"));  // true
console.log(isPalindrome("hello"));   // false

// Two-pointer approach
function isPalindromeTwoPointer(str) {
    var cleaned = str.toLowerCase().replace(/[^a-z0-9]/g, '');
    var left = 0;
    var right = cleaned.length - 1;
    while (left < right) {
        if (cleaned[left] !== cleaned[right]) {
            return false;
        }
        left++;
        right--;
    }
    return true;
}

console.log(isPalindromeTwoPointer("A man a plan a canal Panama"));  // true
Coding Round
33. Find max in array

Find maximum value using Math.max or manual iteration.

  • Built-in: Math.max.apply(null, arr)
  • Spread: Math.max(...arr)
  • Manual: Iterate and track max
  • Complexity: O(n) time
objective-j
// Find max in array in Objective-J
@import <Foundation/Foundation.j>

function findMax(arr) {
    if (arr.length === 0) return null;
    return Math.max.apply(null, arr);
}

console.log(findMax([1, 5, 3, 9, 2]));  // 9

// Manual implementation
function findMaxManual(arr) {
    if (arr.length === 0) return null;
    var maxVal = arr[0];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] > maxVal) {
            maxVal = arr[i];
        }
    }
    return maxVal;
}

console.log(findMaxManual([1, 5, 3, 9, 2]));  // 9

// Using reduce
function findMaxReduce(arr) {
    return arr.reduce(function(a, b) {
        return Math.max(a, b);
    });
}

console.log(findMaxReduce([1, 5, 3, 9, 2]));  // 9
Coding Round
34. Remove duplicates

Remove duplicates using Set or filter method.

  • Set: [...new Set(arr)]
  • Filter: arr.filter((item, index) => arr.indexOf(item) === index)
  • Preserve order: Set preserves insertion order
  • Complexity: O(n) time
objective-j
// Remove duplicates in Objective-J
@import <Foundation/Foundation.j>

function removeDuplicates(arr) {
    return [...new Set(arr)];
}

console.log(removeDuplicates([1, 2, 2, 3, 3, 4]));  // [1, 2, 3, 4]

// Preserving order
function removeDuplicatesOrder(arr) {
    var seen = new Set();
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        if (!seen.has(arr[i])) {
            seen.add(arr[i]);
            result.push(arr[i]);
        }
    }
    return result;
}

console.log(removeDuplicatesOrder([1, 2, 2, 3, 3, 4]));

// Using filter
function removeDuplicatesFilter(arr) {
    return arr.filter(function(item, index) {
        return arr.indexOf(item) === index;
    });
}

console.log(removeDuplicatesFilter([1, 2, 2, 3, 3, 4]));
Coding Round
35. Merge arrays

Merge arrays using concat or spread operator.

  • concat: arr1.concat(arr2)
  • Spread: [...arr1, ...arr2]
  • Unique merge: [...new Set([...arr1, ...arr2])]
  • Complexity: O(n) time
objective-j
// Merge arrays in Objective-J
@import <Foundation/Foundation.j>

function mergeArrays(arr1, arr2) {
    return arr1.concat(arr2);
}

console.log(mergeArrays([1, 2], [3, 4]));  // [1, 2, 3, 4]

// Using spread operator
function mergeArraysSpread(arr1, arr2) {
    return [...arr1, ...arr2];
}

console.log(mergeArraysSpread([1, 2], [3, 4]));

// Merge and remove duplicates
function mergeUnique(arr1, arr2) {
    return [...new Set([...arr1, ...arr2])];
}

console.log(mergeUnique([1, 2, 3], [3, 4, 5]));  // [1, 2, 3, 4, 5]
Coding Round
36. Convert string to number

Convert string to number using parseInt, parseFloat, or Number.

  • parseInt: parseInt(str, 10)
  • parseFloat: parseFloat(str)
  • Number: Number(str)
  • Safe conversion: Check with isNaN
objective-j
// Convert string to number in Objective-J
@import <Foundation/Foundation.j>

function stringToNumber(str) {
    return parseInt(str, 10);
}

console.log(stringToNumber("42"));  // 42

// Safe conversion
function stringToNumberSafe(str) {
    var num = parseFloat(str);
    return isNaN(num) ? null : num;
}

console.log(stringToNumberSafe("42"));  // 42
console.log(stringToNumberSafe("invalid"));  // null

// Using Number constructor
function stringToNumberNumber(str) {
    return Number(str);
}

console.log(stringToNumberNumber("42"));  // 42

// With radix
function stringToNumberRadix(str, radix) {
    return parseInt(str, radix || 10);
}

console.log(stringToNumberRadix("42"));  // 42
console.log(stringToNumberRadix("1010", 2));  // 10
Coding Round
37. Loop through dictionary

Iterate through object using for...in, Object.keys, or Object.entries.

  • for...in: for (var key in dict)
  • Object.keys: Object.keys(dict).forEach
  • Object.entries: Object.entries(dict).forEach
  • hasOwnProperty: Check for own properties
objective-j
// Loop through dictionary in Objective-J
@import <Foundation/Foundation.j>

function loopDict(dict) {
    for (var key in dict) {
        if (dict.hasOwnProperty(key)) {
            console.log(key + " => " + dict[key]);
        }
    }
}

var data = {name: "Alice", age: 25, city: "NYC"};
loopDict(data);

// Using Object.keys
function loopDictKeys(dict) {
    Object.keys(dict).forEach(function(key) {
        console.log(key + " => " + dict[key]);
    });
}

loopDictKeys(data);

// Using Object.entries
function loopDictEntries(dict) {
    Object.entries(dict).forEach(function(entry) {
        console.log(entry[0] + " => " + entry[1]);
    });
}

loopDictEntries(data);

// Using for-in with hasOwnProperty
function loopDictSafe(dict) {
    for (var key in dict) {
        if (Object.prototype.hasOwnProperty.call(dict, key)) {
            console.log(key + " => " + dict[key]);
        }
    }
}

loopDictSafe(data);
Coding Round
38. Delay function execution

Delay execution using setTimeout, setInterval, or Promises.

  • setTimeout: setTimeout(fn, delay)
  • setInterval: setInterval(fn, interval)
  • Promise: new Promise(resolve => setTimeout(resolve, delay))
  • async/await: await delay(1000)
objective-j
// Delay function execution in Objective-J
@import <Foundation/Foundation.j>

// Using setTimeout
function delayedExecution(delayMs, fn) {
    setTimeout(fn, delayMs);
}

delayedExecution(2000, function() {
    console.log("After 2 seconds");
});

// Using setInterval
function intervalExecution(intervalMs, fn) {
    return setInterval(fn, intervalMs);
}

var intervalId = intervalExecution(1000, function() {
    console.log("Repeating execution");
});

// Clear interval
setTimeout(function() {
    clearInterval(intervalId);
    console.log("Interval stopped");
}, 5000);

// Using Promise
function delayedPromise(delayMs) {
    return new Promise(function(resolve) {
        setTimeout(resolve, delayMs);
    });
}

delayedPromise(2000).then(function() {
    console.log("After 2 seconds (Promise)");
});

// Async/await
async function asyncDelay() {
    await delayedPromise(2000);
    console.log("After 2 seconds (async/await)");
}

asyncDelay();
Coding Round
39. HTTP GET request

Make HTTP GET requests using fetch, XMLHttpRequest, or axios.

  • fetch: fetch(url).then(response => response.json())
  • XMLHttpRequest: new XMLHttpRequest()
  • async/await: await fetch(url)
  • Error handling: Check response status
objective-j
// HTTP GET request in Objective-J
@import <Foundation/Foundation.j>

// Using XMLHttpRequest
function fetchData(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', url, true);
    xhr.onreadystatechange = function() {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                callback(null, JSON.parse(xhr.responseText));
            } else {
                callback(new Error('Request failed: ' + xhr.status), null);
            }
        }
    };
    xhr.send();
}

// Using fetch (modern)
function fetchDataModern(url) {
    return fetch(url)
        .then(function(response) {
            if (!response.ok) {
                throw new Error('HTTP error ' + response.status);
            }
            return response.json();
        });
}

// Usage
fetchData('https://api.example.com/data', function(error, data) {
    if (error) {
        console.log('Error: ' + error.message);
    } else {
        console.log('Data: ' + JSON.stringify(data));
    }
});

// Using fetch with async/await
async function fetchDataAsync(url) {
    try {
        var response = await fetch(url);
        if (!response.ok) {
            throw new Error('HTTP error ' + response.status);
        }
        var data = await response.json();
        console.log('Data: ' + JSON.stringify(data));
    } catch (error) {
        console.log('Error: ' + error.message);
    }
}

fetchDataAsync('https://api.example.com/data');
Coding Round
40. Create a promise-like Deferred

Create a Deferred using Promises or custom implementation.

  • Promise: new Promise((resolve, reject) => {})
  • Custom Deferred: resolve and reject functions
  • then method: Handle fulfillment and rejection
  • Chain: then().catch()
objective-j
// Create a promise-like Deferred in Objective-J
@import <Foundation/Foundation.j>

function createDeferred() {
    var callbacks = [];
    var state = "pending";
    var result = null;
    var error = null;
    
    return {
        resolve: function(value) {
            if (state === "pending") {
                state = "resolved";
                result = value;
                callbacks.forEach(function(cb) {
                    if (cb.onFulfilled) cb.onFulfilled(value);
                });
            }
        },
        reject: function(err) {
            if (state === "pending") {
                state = "rejected";
                error = err;
                callbacks.forEach(function(cb) {
                    if (cb.onRejected) cb.onRejected(err);
                });
            }
        },
        then: function(onFulfilled, onRejected) {
            if (state === "pending") {
                callbacks.push({onFulfilled: onFulfilled, onRejected: onRejected});
            } else if (state === "resolved") {
                onFulfilled(result);
            } else if (state === "rejected") {
                onRejected(error);
            }
            return this;
        }
    };
}

// Usage
var deferred = createDeferred();

deferred.then(function(value) {
    console.log("Resolved: " + value);
}, function(error) {
    console.log("Rejected: " + error);
});

setTimeout(function() {
    deferred.resolve("Success!");
}, 1000);

// Alternative with Promise
function createPromise(shouldResolve) {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            if (shouldResolve) {
                resolve("Success!");
            } else {
                reject(new Error("Failed!"));
            }
        }, 1000);
    });
}

createPromise(true).then(function(result) {
    console.log(result);
}).catch(function(error) {
    console.log("Caught: " + error.message);
});
Coding Round
41. Factorial

Calculate factorial using recursion or iteration.

  • Recursive: n * factorial(n-1)
  • Iterative: Loop with multiplication
  • Base case: n <= 1
  • Edge cases: 0! = 1
objective-j
// Factorial in Objective-J
@import <Foundation/Foundation.j>

function factorial(n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

console.log(factorial(5));  // 120

// Iterative version
function factorialIterative(n) {
    var result = 1;
    for (var i = 2; i <= n; i++) {
        result *= i;
    }
    return result;
}

console.log(factorialIterative(5));  // 120

// Using reduce
function factorialReduce(n) {
    return Array.from({length: n}, function(_, i) { return i + 1; })
        .reduce(function(a, b) { return a * b; }, 1);
}

console.log(factorialReduce(5));  // 120
Coding Round
42. Fibonacci

Calculate Fibonacci using recursion, iteration, or memoization.

  • Recursive: fib(n-1) + fib(n-2)
  • Iterative: Loop with variables
  • Memoization: Cache results in object
  • Complexity: O(n) with memoization
objective-j
// Fibonacci in Objective-J
@import <Foundation/Foundation.j>

function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

console.log(fibonacci(8));  // 21

// Iterative version
function fibonacciIterative(n) {
    if (n <= 1) return n;
    var a = 0, b = 1;
    for (var i = 2; i <= n; i++) {
        var temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

console.log(fibonacciIterative(8));  // 21

// Memoized version
var fibMemo = {};
function fibonacciMemo(n) {
    if (n <= 1) return n;
    if (fibMemo[n]) return fibMemo[n];
    fibMemo[n] = fibonacciMemo(n - 1) + fibonacciMemo(n - 2);
    return fibMemo[n];
}

console.log(fibonacciMemo(8));  // 21
Coding Round
43. FizzBuzz

FizzBuzz using if-else or switch statement.

  • Modulo: i % 15 === 0
  • Order: Check 15 first
  • Range: for (var i = 1; i <= n; i++)
  • Return array: Collect results
objective-j
// FizzBuzz in Objective-J
@import <Foundation/Foundation.j>

function fizzbuzz(n) {
    for (var i = 1; i <= n; i++) {
        if (i % 15 === 0) {
            console.log("FizzBuzz");
        } else if (i % 3 === 0) {
            console.log("Fizz");
        } else if (i % 5 === 0) {
            console.log("Buzz");
        } else {
            console.log(i);
        }
    }
}

fizzbuzz(15);

// Return as array
function fizzbuzzArray(n) {
    var result = [];
    for (var i = 1; i <= n; i++) {
        if (i % 15 === 0) {
            result.push("FizzBuzz");
        } else if (i % 3 === 0) {
            result.push("Fizz");
        } else if (i % 5 === 0) {
            result.push("Buzz");
        } else {
            result.push(String(i));
        }
    }
    return result;
}

console.log(fizzbuzzArray(15));
Coding Round
44. Find missing number

Find missing number using formula or XOR method.

  • Formula: total - sum
  • XOR: XOR all numbers and indices
  • Complexity: O(n) time
  • Edge cases: Empty array, missing first or last
objective-j
// Find missing number in Objective-J
@import <Foundation/Foundation.j>

function findMissing(arr) {
    var n = arr.length + 1;
    var total = n * (n + 1) / 2;
    var sum = arr.reduce(function(a, b) { return a + b; }, 0);
    return total - sum;
}

console.log(findMissing([1, 2, 4, 5, 6]));  // 3

// Using XOR
function findMissingXOR(arr) {
    var n = arr.length + 1;
    var xorSum = 0;
    for (var i = 1; i <= n; i++) {
        xorSum ^= i;
    }
    for (var i = 0; i < arr.length; i++) {
        xorSum ^= arr[i];
    }
    return xorSum;
}

console.log(findMissingXOR([1, 2, 4, 5, 6]));  // 3
Coding Round
45. Find duplicates

Find duplicates using Set or filter method.

  • Set: Track seen elements
  • Filter: arr.filter((item, index) => arr.indexOf(item) !== index)
  • Counter: Object to count occurrences
  • Complexity: O(n) time
objective-j
// Find duplicates in Objective-J
@import <Foundation/Foundation.j>

function findDuplicates(arr) {
    var seen = new Set();
    var duplicates = new Set();
    for (var i = 0; i < arr.length; i++) {
        if (seen.has(arr[i])) {
            duplicates.add(arr[i]);
        } else {
            seen.add(arr[i]);
        }
    }
    return Array.from(duplicates);
}

console.log(findDuplicates([1, 2, 3, 2, 4, 3]));  // [2, 3]

// Using filter
function findDuplicatesFilter(arr) {
    return arr.filter(function(item, index) {
        return arr.indexOf(item) !== index;
    });
}

console.log(findDuplicatesFilter([1, 2, 3, 2, 4, 3]));

// Using object counter
function findDuplicatesCounter(arr) {
    var counter = {};
    var duplicates = [];
    for (var i = 0; i < arr.length; i++) {
        counter[arr[i]] = (counter[arr[i]] || 0) + 1;
    }
    for (var key in counter) {
        if (counter[key] > 1) {
            duplicates.push(Number(key));
        }
    }
    return duplicates;
}

console.log(findDuplicatesCounter([1, 2, 3, 2, 4, 3]));
Coding Round
46. Sum of array

Calculate sum using reduce or manual iteration.

  • reduce: arr.reduce((a, b) => a + b, 0)
  • Manual: Iterate and accumulate
  • forEach: arr.forEach(num => total += num)
  • Complexity: O(n) time
objective-j
// Sum of array in Objective-J
@import <Foundation/Foundation.j>

function sumArray(arr) {
    return arr.reduce(function(a, b) { return a + b; }, 0);
}

console.log(sumArray([1, 2, 3, 4, 5]));  // 15

// Manual implementation
function sumArrayManual(arr) {
    var total = 0;
    for (var i = 0; i < arr.length; i++) {
        total += arr[i];
    }
    return total;
}

console.log(sumArrayManual([1, 2, 3, 4, 5]));  // 15

// Using forEach
function sumArrayForEach(arr) {
    var total = 0;
    arr.forEach(function(num) {
        total += num;
    });
    return total;
}

console.log(sumArrayForEach([1, 2, 3, 4, 5]));
Coding Round
47. Average of array

Calculate average using reduce or manual division.

  • reduce: arr.reduce((a, b) => a + b, 0) / arr.length
  • Manual: Sum then divide
  • Empty array: Return 0
  • Precision: Returns number
objective-j
// Average of array in Objective-J
@import <Foundation/Foundation.j>

function averageArray(arr) {
    if (arr.length === 0) return 0;
    return arr.reduce(function(a, b) { return a + b; }, 0) / arr.length;
}

console.log(averageArray([1, 2, 3, 4, 5]));  // 3

// Manual implementation
function averageArrayManual(arr) {
    if (arr.length === 0) return 0;
    var total = 0;
    for (var i = 0; i < arr.length; i++) {
        total += arr[i];
    }
    return total / arr.length;
}

console.log(averageArrayManual([1, 2, 3, 4, 5]));  // 3

// Using forEach
function averageArrayForEach(arr) {
    if (arr.length === 0) return 0;
    var total = 0;
    arr.forEach(function(num) {
        total += num;
    });
    return total / arr.length;
}

console.log(averageArrayForEach([1, 2, 3, 4, 5]));
Coding Round
48. Sort array ascending

Sort using sort with comparison function.

  • Sort: arr.slice().sort((a, b) => a - b)
  • In-place: arr.sort((a, b) => a - b)
  • Strings: sort((a, b) => a.localeCompare(b))
  • Complexity: O(n log n)
objective-j
// Sort array ascending in Objective-J
@import <Foundation/Foundation.j>

function sortAscending(arr) {
    return arr.slice().sort(function(a, b) {
        return a - b;
    });
}

console.log(sortAscending([5, 2, 8, 1, 9]));  // [1, 2, 5, 8, 9]

// In-place sorting
function sortAscendingInPlace(arr) {
    arr.sort(function(a, b) {
        return a - b;
    });
    return arr;
}

var arr = [5, 2, 8, 1, 9];
console.log(sortAscendingInPlace(arr));

// Sort with localeCompare for strings
function sortStringsAscending(arr) {
    return arr.slice().sort(function(a, b) {
        return a.localeCompare(b);
    });
}

console.log(sortStringsAscending(["banana", "apple", "cherry"]));
Coding Round
49. Sort array descending

Sort descending by reversing comparison.

  • Sort: arr.slice().sort((a, b) => b - a)
  • In-place: arr.sort((a, b) => b - a)
  • Strings: sort((a, b) => b.localeCompare(a))
  • Complexity: O(n log n)
objective-j
// Sort array descending in Objective-J
@import <Foundation/Foundation.j>

function sortDescending(arr) {
    return arr.slice().sort(function(a, b) {
        return b - a;
    });
}

console.log(sortDescending([5, 2, 8, 1, 9]));  // [9, 8, 5, 2, 1]

// In-place sorting
function sortDescendingInPlace(arr) {
    arr.sort(function(a, b) {
        return b - a;
    });
    return arr;
}

var arr = [5, 2, 8, 1, 9];
console.log(sortDescendingInPlace(arr));

// Sort with localeCompare for strings
function sortStringsDescending(arr) {
    return arr.slice().sort(function(a, b) {
        return b.localeCompare(a);
    });
}

console.log(sortStringsDescending(["banana", "apple", "cherry"]));
Coding Round
50. Flatten nested array

Flatten nested arrays using recursion or flat.

  • Recursive: Check if element is array
  • flat: arr.flat(Infinity)
  • reduce: arr.reduce((acc, val) => acc.concat(Array.isArray(val) ? flatten(val) : val), [])
  • Complexity: O(n) time
objective-j
// Flatten nested array in Objective-J
@import <Foundation/Foundation.j>

function flattenArray(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        if (Array.isArray(arr[i])) {
            result = result.concat(flattenArray(arr[i]));
        } else {
            result.push(arr[i]);
        }
    }
    return result;
}

console.log(flattenArray([1, [2, [3, 4], 5], 6]));  // [1, 2, 3, 4, 5, 6]

// Using reduce
function flattenArrayReduce(arr) {
    return arr.reduce(function(acc, val) {
        return acc.concat(Array.isArray(val) ? flattenArrayReduce(val) : val);
    }, []);
}

console.log(flattenArrayReduce([1, [2, [3, 4], 5], 6]));

// Using flat (modern JavaScript)
function flattenArrayFlat(arr) {
    return arr.flat(Infinity);
}

console.log(flattenArrayFlat([1, [2, [3, 4], 5], 6]));
Coding Round
51. Chunk array

Split array into chunks using slice in loop.

  • Loop: Iterate with step size
  • slice: arr.slice(i, i + size)
  • Edge case: Handle last chunk
  • Complexity: O(n) time
objective-j
// Chunk array in Objective-J
@import <Foundation/Foundation.j>

function chunkArray(arr, size) {
    var chunks = [];
    for (var i = 0; i < arr.length; i += size) {
        chunks.push(arr.slice(i, i + size));
    }
    return chunks;
}

console.log(chunkArray([1, 2, 3, 4, 5, 6], 2));  // [[1, 2], [3, 4], [5, 6]]

// Using while loop
function chunkArrayWhile(arr, size) {
    var chunks = [];
    var i = 0;
    while (i < arr.length) {
        chunks.push(arr.slice(i, i + size));
        i += size;
    }
    return chunks;
}

console.log(chunkArrayWhile([1, 2, 3, 4, 5, 6], 2));

// With padding
function chunkArrayPadding(arr, size, padValue) {
    var chunks = chunkArray(arr, size);
    if (chunks.length > 0 && chunks[chunks.length - 1].length < size) {
        var last = chunks[chunks.length - 1];
        while (last.length < size) {
            last.push(padValue);
        }
    }
    return chunks;
}

console.log(chunkArrayPadding([1, 2, 3, 4, 5], 3, 0));
Coding Round
53. Quick sort

Quick sort using recursion and partitioning.

  • Algorithm: Choose pivot, partition, recurse
  • Time: O(n log n) average
  • In-place: Implement for performance
  • Pivot: First element or random
objective-j
// Quick sort in Objective-J
@import <Foundation/Foundation.j>

function quickSort(arr) {
    if (arr.length <= 1) return arr;
    var pivot = arr[0];
    var left = [];
    var right = [];
    for (var i = 1; i < arr.length; i++) {
        if (arr[i] < pivot) {
            left.push(arr[i]);
        } else {
            right.push(arr[i]);
        }
    }
    return quickSort(left).concat([pivot], quickSort(right));
}

console.log(quickSort([5, 3, 8, 4, 2, 7, 1, 6]));

// In-place quick sort
function quickSortInPlace(arr, low, high) {
    if (low === undefined) low = 0;
    if (high === undefined) high = arr.length - 1;
    if (low < high) {
        var pi = partition(arr, low, high);
        quickSortInPlace(arr, low, pi - 1);
        quickSortInPlace(arr, pi + 1, high);
    }
    return arr;
}

function partition(arr, low, high) {
    var pivot = arr[high];
    var i = low - 1;
    for (var j = low; j < high; j++) {
        if (arr[j] <= pivot) {
            i++;
            var temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    var temp = arr[i + 1];
    arr[i + 1] = arr[high];
    arr[high] = temp;
    return i + 1;
}

console.log(quickSortInPlace([5, 3, 8, 4, 2, 7, 1, 6]));
Coding Round
54. Merge sort

Merge sort using divide-and-conquer and merging.

  • Algorithm: Divide, sort, merge
  • Time: O(n log n)
  • Stable: Maintains relative order
  • Space: O(n) auxiliary space
objective-j
// Merge sort in Objective-J
@import <Foundation/Foundation.j>

function mergeSort(arr) {
    if (arr.length <= 1) return arr;
    var mid = Math.floor(arr.length / 2);
    var left = mergeSort(arr.slice(0, mid));
    var right = mergeSort(arr.slice(mid));
    return merge(left, right);
}

function merge(left, right) {
    var result = [];
    var i = 0, j = 0;
    while (i < left.length && j < right.length) {
        if (left[i] <= right[j]) {
            result.push(left[i++]);
        } else {
            result.push(right[j++]);
        }
    }
    while (i < left.length) {
        result.push(left[i++]);
    }
    while (j < right.length) {
        result.push(right[j++]);
    }
    return result;
}

console.log(mergeSort([5, 3, 8, 4, 2, 7, 1, 6]));
Coding Round
55. Bubble sort

Bubble sort with early termination optimization.

  • Algorithm: Compare adjacent, swap
  • Time: O(n²) worst case
  • Optimization: Stop if no swaps
  • In-place: Modifies original array
objective-j
// Bubble sort in Objective-J
@import <Foundation/Foundation.j>

function bubbleSort(arr) {
    var sorted = arr.slice();
    for (var i = 0; i < sorted.length - 1; i++) {
        for (var j = 0; j < sorted.length - 1 - i; j++) {
            if (sorted[j] > sorted[j + 1]) {
                var temp = sorted[j];
                sorted[j] = sorted[j + 1];
                sorted[j + 1] = temp;
            }
        }
    }
    return sorted;
}

console.log(bubbleSort([5, 3, 8, 4, 2, 7, 1, 6]));

// Optimized bubble sort
function bubbleSortOptimized(arr) {
    var sorted = arr.slice();
    for (var i = 0; i < sorted.length - 1; i++) {
        var swapped = false;
        for (var j = 0; j < sorted.length - 1 - i; j++) {
            if (sorted[j] > sorted[j + 1]) {
                var temp = sorted[j];
                sorted[j] = sorted[j + 1];
                sorted[j + 1] = temp;
                swapped = true;
            }
        }
        if (!swapped) break;
    }
    return sorted;
}

console.log(bubbleSortOptimized([5, 3, 8, 4, 2, 7, 1, 6]));
Coding Round
56. Intersection of arrays

Find common elements using Set or filter.

  • Set: new Set(arr2) and filter
  • filter: arr1.filter(item => arr2.includes(item))
  • reduce: Accumulate common elements
  • Complexity: O(n) time with Set
objective-j
// Intersection of arrays in Objective-J
@import <Foundation/Foundation.j>

function intersection(arr1, arr2) {
    var set2 = new Set(arr2);
    return arr1.filter(function(item) {
        return set2.has(item);
    });
}

console.log(intersection([1, 2, 3, 4], [3, 4, 5, 6]));  // [3, 4]

// Using filter and includes
function intersectionFilter(arr1, arr2) {
    return arr1.filter(function(item) {
        return arr2.includes(item);
    });
}

console.log(intersectionFilter([1, 2, 3, 4], [3, 4, 5, 6]));

// Using reduce
function intersectionReduce(arr1, arr2) {
    var set2 = new Set(arr2);
    return arr1.reduce(function(acc, val) {
        if (set2.has(val)) {
            acc.push(val);
        }
        return acc;
    }, []);
}

console.log(intersectionReduce([1, 2, 3, 4], [3, 4, 5, 6]));
Coding Round
57. Union of arrays

Combine arrays with unique elements using Set.

  • Set: [...new Set([...arr1, ...arr2])]
  • concat: arr1.concat(arr2) then Set
  • Preserve order: Set preserves insertion order
  • Complexity: O(n) time
objective-j
// Union of arrays in Objective-J
@import <Foundation/Foundation.j>

function union(arr1, arr2) {
    return [...new Set([...arr1, ...arr2])];
}

console.log(union([1, 2, 3], [3, 4, 5]));  // [1, 2, 3, 4, 5]

// Using concat and Set
function unionConcat(arr1, arr2) {
    return Array.from(new Set(arr1.concat(arr2)));
}

console.log(unionConcat([1, 2, 3], [3, 4, 5]));

// Preserving order
function unionOrder(arr1, arr2) {
    var result = arr1.slice();
    for (var i = 0; i < arr2.length; i++) {
        if (!result.includes(arr2[i])) {
            result.push(arr2[i]);
        }
    }
    return result;
}

console.log(unionOrder([1, 2, 3], [3, 4, 5]));
Coding Round
58. Difference of arrays

Find elements in first array not in second using Set.

  • Set: new Set(arr2) and filter
  • filter: arr1.filter(item => !arr2.includes(item))
  • Symmetric difference: Union of differences
  • Complexity: O(n) time
objective-j
// Difference of arrays in Objective-J
@import <Foundation/Foundation.j>

function difference(arr1, arr2) {
    var set2 = new Set(arr2);
    return arr1.filter(function(item) {
        return !set2.has(item);
    });
}

console.log(difference([1, 2, 3, 4], [3, 4, 5, 6]));  // [1, 2]

// Symmetric difference
function symmetricDifference(arr1, arr2) {
    var set1 = new Set(arr1);
    var set2 = new Set(arr2);
    var result = [];
    for (var item of set1) {
        if (!set2.has(item)) result.push(item);
    }
    for (var item of set2) {
        if (!set1.has(item)) result.push(item);
    }
    return result;
}

console.log(symmetricDifference([1, 2, 3], [3, 4, 5]));  // [1, 2, 4, 5]

// Using filter
function differenceFilter(arr1, arr2) {
    return arr1.filter(function(item) {
        return !arr2.includes(item);
    });
}

console.log(differenceFilter([1, 2, 3, 4], [3, 4, 5, 6]));
Coding Round
59. Group by property

Group objects by property using reduce or for loop.

  • reduce: Accumulate into object
  • for loop: Manual grouping
  • Key: Property value as key
  • Complexity: O(n) time
objective-j
// Group by property in Objective-J
@import <Foundation/Foundation.j>

function groupByProperty(items, key) {
    var groups = {};
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        var keyValue = item[key];
        if (!groups[keyValue]) {
            groups[keyValue] = [];
        }
        groups[keyValue].push(item);
    }
    return groups;
}

// Usage
var data = [
    {type: "fruit", name: "apple"},
    {type: "fruit", name: "banana"},
    {type: "veg", name: "carrot"}
];

var groups = groupByProperty(data, "type");
console.log(groups);

// Using reduce
function groupByPropertyReduce(items, key) {
    return items.reduce(function(groups, item) {
        var keyValue = item[key];
        if (!groups[keyValue]) {
            groups[keyValue] = [];
        }
        groups[keyValue].push(item);
        return groups;
    }, {});
}

console.log(groupByPropertyReduce(data, "type"));

// Group with count
function groupByPropertyCount(items, key) {
    var groups = groupByProperty(items, key);
    var result = {};
    for (var k in groups) {
        result[k] = groups[k].length;
    }
    return result;
}

console.log(groupByPropertyCount(data, "type"));
Coding Round
60. Deep clone object

Deep clone using recursion or JSON methods.

  • JSON: JSON.parse(JSON.stringify(obj))
  • Recursive: Copy nested structures
  • Spread: {...obj} (shallow)
  • Object.assign: Object.assign(, obj) (shallow)
objective-j
// Deep clone object in Objective-J
@import <Foundation/Foundation.j>

function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') return obj;
    if (Array.isArray(obj)) {
        return obj.map(function(item) {
            return deepClone(item);
        });
    }
    var cloned = {};
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            cloned[key] = deepClone(obj[key]);
        }
    }
    return cloned;
}

// Usage
var original = {
    name: "Alice",
    address: {
        city: "NYC",
        zip: "10001"
    }
};

var cloned = deepClone(original);
cloned.name = "Bob";
cloned.address.city = "LA";

console.log(original.name);  // Alice
console.log(cloned.name);    // Bob
console.log(original.address.city);  // NYC
console.log(cloned.address.city);    // LA

// Using JSON methods (shallow for complex)
var shallowClone = JSON.parse(JSON.stringify(original));

// Using spread operator (shallow)
var spreadClone = {...original};

// Using Object.assign (shallow)
var assignClone = Object.assign({}, original);
Coding Round
61. Immutable update

Perform immutable updates using spread or Object.assign.

  • Spread: {...obj, [key]: value}
  • Object.assign: Object.assign({}, obj, {[key]: value})
  • Nested: Recursive spread updates
  • Return: New immutable object
objective-j
// Immutable update in Objective-J
@import <Foundation/Foundation.j>

function updateImmutable(obj, path, value) {
    var parts = path.split('.');
    if (parts.length === 1) {
        var newObj = {...obj};
        newObj[parts[0]] = value;
        return newObj;
    }
    var first = parts[0];
    var rest = parts.slice(1).join('.');
    var nested = obj[first] || {};
    var newNested = updateImmutable(nested, rest, value);
    var newObj = {...obj};
    newObj[first] = newNested;
    return newObj;
}

var state = {
    user: {
        name: "Alice",
        age: 25
    }
};

var newState = updateImmutable(state, "user.age", 26);
console.log(state.user.age);      // 25
console.log(newState.user.age);   // 26

// Using spread operator
function updateImmutableSpread(obj, path, value) {
    var parts = path.split('.');
    if (parts.length === 1) {
        return {...obj, [parts[0]]: value};
    }
    var first = parts[0];
    var rest = parts.slice(1).join('.');
    var nested = obj[first] || {};
    return {...obj, [first]: updateImmutableSpread(nested, rest, value)};
}

var newState2 = updateImmutableSpread(state, "user.age", 27);
console.log(newState2.user.age);  // 27
Coding Round
62. Pipe function

Pipe composes functions from left to right.

  • Implementation: fns.reduce((acc, fn) => fn(acc), value)
  • Variadic: Accept multiple functions
  • Return: Function that chains operations
  • Direction: Left to right
objective-j
// Pipe function in Objective-J
@import <Foundation/Foundation.j>

function pipe() {
    var fns = Array.from(arguments);
    return function(value) {
        var result = value;
        for (var i = 0; i < fns.length; i++) {
            result = fns[i](result);
        }
        return result;
    };
}

function double(x) { return x * 2; }
function addTen(x) { return x + 10; }
function square(x) { return x * x; }

var process = pipe(double, addTen, square);
console.log(process(5));  // (5*2+10)^2 = 400

// Using reduce
function pipeReduce() {
    var fns = Array.from(arguments);
    return function(value) {
        return fns.reduce(function(acc, fn) {
            return fn(acc);
        }, value);
    };
}

var process2 = pipeReduce(double, addTen, square);
console.log(process2(5));  // 400

// Pipe with async functions
function pipeAsync() {
    var fns = Array.from(arguments);
    return function(value) {
        return fns.reduce(function(promise, fn) {
            return promise.then(fn);
        }, Promise.resolve(value));
    };
}

var asyncDouble = function(x) { return Promise.resolve(x * 2); };
var processAsync = pipeAsync(asyncDouble, addTen, square);
processAsync(5).then(function(result) {
    console.log(result);  // 400
});
Coding Round
63. Compose function

Compose functions from right to left.

  • Implementation: fns.reduceRight((acc, fn) => fn(acc), value)
  • Variadic: Accept multiple functions
  • Return: Function that chains operations
  • Direction: Right to left
objective-j
// Compose function in Objective-J
@import <Foundation/Foundation.j>

function compose() {
    var fns = Array.from(arguments);
    return function(value) {
        var result = value;
        for (var i = fns.length - 1; i >= 0; i--) {
            result = fns[i](result);
        }
        return result;
    };
}

function double(x) { return x * 2; }
function addTen(x) { return x + 10; }
function square(x) { return x * x; }

var process2 = compose(square, addTen, double);
console.log(process2(5));  // (5*2+10)^2 = 400

// Using reduceRight
function composeReduce() {
    var fns = Array.from(arguments);
    return function(value) {
        return fns.reduceRight(function(acc, fn) {
            return fn(acc);
        }, value);
    };
}

var process3 = composeReduce(square, addTen, double);
console.log(process3(5));  // 400

// Compose with async
function composeAsync() {
    var fns = Array.from(arguments);
    return function(value) {
        return fns.reduceRight(function(promise, fn) {
            return promise.then(fn);
        }, Promise.resolve(value));
    };
}

var asyncSquare = function(x) { return Promise.resolve(x * x); };
var processAsync = composeAsync(asyncSquare, addTen, double);
processAsync(5).then(function(result) {
    console.log(result);  // 400
});
Coding Round
64. Memoization

Cache function results based on arguments using object.

  • Cache: or Map
  • Key: JSON.stringify(args)
  • Return: Cached or computed result
  • Trade-off: Memory for speed
objective-j
// Memoization in Objective-J
@import <Foundation/Foundation.j>

function memoize(fn) {
    var cache = {};
    return function(arg) {
        var key = JSON.stringify(arg);
        if (cache.hasOwnProperty(key)) {
            return cache[key];
        }
        var result = fn(arg);
        cache[key] = result;
        return result;
    };
}

// Fibonacci with memoization
var fibMemo = memoize(function(n) {
    if (n <= 1) return n;
    return fibMemo(n - 1) + fibMemo(n - 2);
});

console.log(fibMemo(10));  // 55

// Memoize with multiple arguments
function memoizeMultiple(fn) {
    var cache = {};
    return function() {
        var key = JSON.stringify(Array.from(arguments));
        if (cache.hasOwnProperty(key)) {
            return cache[key];
        }
        var result = fn.apply(this, arguments);
        cache[key] = result;
        return result;
    };
}

var addMemo = memoizeMultiple(function(a, b) {
    console.log("Computing: " + a + " + " + b);
    return a + b;
});

console.log(addMemo(5, 3));  // Computes
console.log(addMemo(5, 3));  // Returns cached

// Memoize with TTL
function memoizeTTL(fn, ttl) {
    var cache = {};
    return function(arg) {
        var key = JSON.stringify(arg);
        if (cache.hasOwnProperty(key)) {
            var entry = cache[key];
            if (Date.now() - entry.timestamp < ttl) {
                return entry.value;
            }
        }
        var result = fn(arg);
        cache[key] = {value: result, timestamp: Date.now()};
        return result;
    };
}

var expensiveFunction = memoizeTTL(function(n) {
    console.log("Computing expensive: " + n);
    return n * n;
}, 5000);

console.log(expensiveFunction(5));  // Computes
console.log(expensiveFunction(5));  // Returns cached (within TTL)
Coding Round
65. Once function

Ensure a function is called only once using closure.

  • Closure: let called = false
  • Result: Cache the result
  • Return: Function with guard
  • Use case: Initialization
objective-j
// Once function in Objective-J
@import <Foundation/Foundation.j>

function once(fn) {
    var called = false;
    var result = null;
    return function() {
        if (!called) {
            called = true;
            result = fn.apply(this, arguments);
        }
        return result;
    };
}

var initialize = once(function() {
    console.log("Initialized");
    return {id: 1, name: "App"};
});

console.log(initialize());  // Prints "Initialized"
console.log(initialize());  // Returns cached result

// Once with multiple arguments
var onceMulti = once(function(a, b) {
    console.log("Computing: " + a + " + " + b);
    return a + b;
});

console.log(onceMulti(5, 3));  // Computes
console.log(onceMulti(5, 3));  // Returns cached

// Once with promise
function onceAsync(fn) {
    var called = false;
    var result = null;
    return function() {
        if (!called) {
            called = true;
            result = fn.apply(this, arguments);
        }
        return result;
    };
}

var initializeAsync = onceAsync(function() {
    console.log("Initializing async");
    return Promise.resolve({id: 1, name: "App"});
});

initializeAsync().then(function(result) {
    console.log(result);
});
Coding Round
66. Debounce with leading edge

Debounce with leading edge using timer and timestamp.

  • Timer: setTimeout for delayed execution
  • Leading edge: Execute immediately
  • Cooldown: Wait before next execution
  • Use case: Save actions, API calls
objective-j
// Debounce with leading edge in Objective-J
@import <Foundation/Foundation.j>

function debounceLeading(delayMs, fn) {
    var lastCall = 0;
    var timer = null;
    return function() {
        var now = Date.now();
        if (now - lastCall < delayMs) {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(function() {
                lastCall = Date.now();
                fn.apply(this, arguments);
            }, delayMs);
        } else {
            lastCall = now;
            fn.apply(this, arguments);
        }
    };
}

// Usage
var debounced = debounceLeading(1000, function() {
    console.log("Executed");
});

debounced();  // Executes immediately
debounced();  // Scheduled for later
debounced();  // Scheduled for later

// Debounce with leading edge and trailing
function debounceLeadingTrailing(delayMs, fn) {
    var lastCall = 0;
    var timer = null;
    return function() {
        var now = Date.now();
        if (now - lastCall < delayMs) {
            if (timer) {
                clearTimeout(timer);
            }
            timer = setTimeout(function() {
                lastCall = Date.now();
                fn.apply(this, arguments);
            }, delayMs);
        } else {
            lastCall = now;
            fn.apply(this, arguments);
        }
    };
}

var debounced2 = debounceLeadingTrailing(1000, function() {
    console.log("Executed with trailing");
});

debounced2();  // Executes immediately
debounced2();  // Scheduled for later
debounced2();  // Scheduled for later
Coding Round
67. Throttle with leading edge

Throttle with leading edge using timestamp tracking.

  • Timestamp: Track last execution time
  • Leading edge: Execute if enough time passed
  • Rate limiting: At most once per period
  • Use case: Scroll events, resize
objective-j
// Throttle with leading edge in Objective-J
@import <Foundation/Foundation.j>

function throttleLeading(delayMs, fn) {
    var lastCall = 0;
    return function() {
        var now = Date.now();
        if (now - lastCall >= delayMs) {
            lastCall = now;
            fn.apply(this, arguments);
        }
    };
}

// Usage
var throttled = throttleLeading(1000, function() {
    console.log("Executed");
});

throttled();  // Executes
throttled();  // Ignored (within 1 second)
throttled();  // Ignored (within 1 second)

// Throttle with trailing edge
function throttleTrailing(delayMs, fn) {
    var lastCall = 0;
    var timer = null;
    return function() {
        var now = Date.now();
        if (now - lastCall >= delayMs) {
            lastCall = now;
            fn.apply(this, arguments);
        } else if (!timer) {
            timer = setTimeout(function() {
                timer = null;
                lastCall = Date.now();
                fn.apply(this, arguments);
            }, delayMs - (now - lastCall));
        }
    };
}

var throttled2 = throttleTrailing(1000, function() {
    console.log("Executed with trailing");
});

throttled2();  // Executes
throttled2();  // Scheduled for later
throttled2();  // Scheduled for later
Coding Round
68. Deep equal

Deep equality comparison using recursion for nested structures.

  • Recursive: Compare nested structures
  • Base cases: Primitive values
  • Arrays: Compare elements recursively
  • Objects: Compare key-value pairs
objective-j
// Deep equal in Objective-J
@import <Foundation/Foundation.j>

function deepEqual(obj1, obj2) {
    if (obj1 === obj2) return true;
    if (obj1 === null || obj2 === null) return false;
    if (typeof obj1 !== 'object' || typeof obj2 !== 'object') return false;
    if (Array.isArray(obj1) !== Array.isArray(obj2)) return false;
    
    if (Array.isArray(obj1)) {
        if (obj1.length !== obj2.length) return false;
        for (var i = 0; i < obj1.length; i++) {
            if (!deepEqual(obj1[i], obj2[i])) return false;
        }
        return true;
    }
    
    var keys1 = Object.keys(obj1);
    var keys2 = Object.keys(obj2);
    if (keys1.length !== keys2.length) return false;
    
    for (var i = 0; i < keys1.length; i++) {
        var key = keys1[i];
        if (!obj2.hasOwnProperty(key)) return false;
        if (!deepEqual(obj1[key], obj2[key])) return false;
    }
    return true;
}

// Usage
var obj1 = {name: "Alice", address: {city: "NYC"}};
var obj2 = {name: "Alice", address: {city: "NYC"}};
var obj3 = {name: "Bob", address: {city: "LA"}};

console.log(deepEqual(obj1, obj2));  // true
console.log(deepEqual(obj1, obj3));  // false

// Deep equal with arrays
var arr1 = [1, 2, [3, 4]];
var arr2 = [1, 2, [3, 4]];
var arr3 = [1, 2, [3, 5]];

console.log(deepEqual(arr1, arr2));  // true
console.log(deepEqual(arr1, arr3));  // false
Coding Round
69. Observable pattern

Observable pattern with subscribers and notifications.

  • Observable: Maintains subscribers
  • Subscribe: Add callback
  • Notify: Call all subscribers
  • Unsubscribe: Remove callback
objective-j
// Observable pattern in Objective-J
@import <Foundation/Foundation.j>

// Observable class
function Observable() {
    this.subscribers = [];
}

Observable.prototype.subscribe = function(callback) {
    this.subscribers.push(callback);
    return function() {
        var index = this.subscribers.indexOf(callback);
        if (index !== -1) {
            this.subscribers.splice(index, 1);
        }
    }.bind(this);
};

Observable.prototype.notify = function(data) {
    for (var i = 0; i < this.subscribers.length; i++) {
        this.subscribers[i](data);
    }
};

// Usage
var observable = new Observable();
var unsubscribe = observable.subscribe(function(data) {
    console.log("Received: " + data);
});

observable.notify("Hello");  // Received: Hello
unsubscribe();
observable.notify("World");  // Nothing happens

// With multiple subscribers
var observable2 = new Observable();
observable2.subscribe(function(data) {
    console.log("Observer 1: " + data);
});
observable2.subscribe(function(data) {
    console.log("Observer 2: " + data);
});
observable2.notify("Hello World");

// With class observer
function Observer(name) {
    this.name = name;
}

Observer.prototype.update = function(data) {
    console.log(this.name + " received: " + data);
};

var obs1 = new Observer("Observer1");
var obs2 = new Observer("Observer2");

var observable3 = new Observable();
observable3.subscribe(obs1.update.bind(obs1));
observable3.subscribe(obs2.update.bind(obs2));
observable3.notify("Hello again");
Coding Round
70. Singleton pattern

Singleton pattern using closure or class with static instance.

  • Closure: IIFE with private instance
  • Class: Static getInstance method
  • Lazy initialization: Create on first access
  • Global access: Through shared instance
objective-j
// Singleton pattern in Objective-J
@import <Foundation/Foundation.j>

// Using closure
var Singleton = (function() {
    var instance = null;
    
    function createInstance() {
        var data = {};
        return {
            set: function(key, value) {
                data[key] = value;
            },
            get: function(key) {
                return data[key];
            },
            getAll: function() {
                return data;
            }
        };
    }
    
    return {
        getInstance: function() {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

// Usage
var s1 = Singleton.getInstance();
var s2 = Singleton.getInstance();
s1.set("name", "Alice");
console.log(s2.get("name"));  // Alice
console.log(s1 === s2);  // true

// Using class with static
var SingletonClass = (function() {
    var instance = null;
    
    function SingletonClass() {
        this.data = {};
    }
    
    SingletonClass.getInstance = function() {
        if (!instance) {
            instance = new SingletonClass();
        }
        return instance;
    };
    
    SingletonClass.prototype.set = function(key, value) {
        this.data[key] = value;
    };
    
    SingletonClass.prototype.get = function(key) {
        return this.data[key];
    };
    
    return SingletonClass;
})();

var s3 = SingletonClass.getInstance();
var s4 = SingletonClass.getInstance();
s3.set("age", 25);
console.log(s4.get("age"));  // 25
Coding Round
71. Factory pattern

Factory pattern using functions that create objects.

  • Factory function: Creates objects
  • Type parameter: Determines which class
  • Return: Instance of requested type
  • Benefits: Decouples creation logic
objective-j
// Factory pattern in Objective-J
@import <Foundation/Foundation.j>

// Base class
function User(name) {
    this.name = name;
}

User.prototype.getRole = function() {
    return "user";
};

function Admin(name) {
    User.call(this, name);
}

Admin.prototype = Object.create(User.prototype);
Admin.prototype.constructor = Admin;
Admin.prototype.getRole = function() {
    return "admin";
};

function Guest(name) {
    User.call(this, name);
}

Guest.prototype = Object.create(User.prototype);
Guest.prototype.constructor = Guest;
Guest.prototype.getRole = function() {
    return "guest";
};

// Factory
var UserFactory = {
    createUser: function(type, name) {
        switch(type) {
            case 'admin':
                return new Admin(name);
            case 'guest':
                return new Guest(name);
            default:
                return new User(name);
        }
    }
};

// Usage
var admin = UserFactory.createUser('admin', 'Alice');
var guest = UserFactory.createUser('guest', 'Bob');

console.log(admin.name + " role: " + admin.getRole());
console.log(guest.name + " role: " + guest.getRole());

// Abstract factory
function WidgetFactory() {}

WidgetFactory.createWidget = function(type) {
    if (type === 'button') {
        return {
            draw: function() {
                console.log("Drawing Button");
            }
        };
    } else if (type === 'textfield') {
        return {
            draw: function() {
                console.log("Drawing TextField");
            }
        };
    }
    return null;
};

var button = WidgetFactory.createWidget('button');
var textField = WidgetFactory.createWidget('textfield');

button.draw();
textField.draw();
Coding Round
72. Strategy pattern

Strategy pattern using functions or objects with algorithms.

  • Strategy functions: Different algorithms
  • Context: Uses strategy
  • Runtime switching: Change at runtime
  • Benefits: Encapsulate algorithms
objective-j
// Strategy pattern in Objective-J
@import <Foundation/Foundation.j>

// Strategy functions
var CreditCardStrategy = {
    pay: function(amount) {
        console.log("Paid $" + amount + " with Credit Card");
    }
};

var PayPalStrategy = {
    pay: function(amount) {
        console.log("Paid $" + amount + " with PayPal");
    }
};

var CryptoStrategy = {
    pay: function(amount) {
        console.log("Paid $" + amount + " with Crypto");
    }
};

// Context
function PaymentContext(strategy) {
    this.strategy = strategy;
}

PaymentContext.prototype.setStrategy = function(strategy) {
    this.strategy = strategy;
};

PaymentContext.prototype.executePayment = function(amount) {
    this.strategy.pay(amount);
};

// Usage
var context = new PaymentContext(CreditCardStrategy);
context.executePayment(100.0);

context.setStrategy(PayPalStrategy);
context.executePayment(50.0);

context.setStrategy(CryptoStrategy);
context.executePayment(75.0);

// Strategy with parameters
var DiscountStrategy = {
    percentage: function(percent) {
        return function(amount) {
            return amount * (1 - percent / 100);
        };
    },
    fixed: function(discount) {
        return function(amount) {
            return amount - discount;
        };
    }
};

var discount10 = DiscountStrategy.percentage(10);
var discount20 = DiscountStrategy.percentage(20);
var discount50 = DiscountStrategy.fixed(50);

console.log("10% discount: " + discount10(100));
console.log("20% discount: " + discount20(100));
console.log("$50 discount: " + discount50(100));
Coding Round
73. Observer pattern

Observer pattern with subject and observers.

  • Subject: Maintains observers
  • Observer: Defines update method
  • Attach/Detach: Add/remove observers
  • Notify: Call update on all observers
objective-j
// Observer pattern in Objective-J
@import <Foundation/Foundation.j>

// Subject class
function Subject() {
    this.observers = [];
    this.state = "";
}

Subject.prototype.attach = function(observer) {
    this.observers.push(observer);
};

Subject.prototype.detach = function(observer) {
    var index = this.observers.indexOf(observer);
    if (index !== -1) {
        this.observers.splice(index, 1);
    }
};

Subject.prototype.setState = function(state) {
    this.state = state;
    this.notifyObservers();
};

Subject.prototype.notifyObservers = function() {
    for (var i = 0; i < this.observers.length; i++) {
        this.observers[i].update(this.state);
    }
};

// Concrete observer
function ConcreteObserver(name) {
    this.name = name;
}

ConcreteObserver.prototype.update = function(data) {
    console.log(this.name + " received: " + data);
};

// Usage
var subject = new Subject();
var observer1 = new ConcreteObserver("Observer1");
var observer2 = new ConcreteObserver("Observer2");

subject.attach(observer1);
subject.attach(observer2);

subject.setState("Hello World");

subject.detach(observer1);
subject.setState("Hello again");

// Observer with event handling
function EventObserver() {
    this.handlers = {};
}

EventObserver.prototype.on = function(event, callback) {
    if (!this.handlers[event]) {
        this.handlers[event] = [];
    }
    this.handlers[event].push(callback);
};

EventObserver.prototype.emit = function(event, data) {
    if (this.handlers[event]) {
        for (var i = 0; i < this.handlers[event].length; i++) {
            this.handlers[event][i](data);
        }
    }
};

var eventObserver = new EventObserver();
eventObserver.on('click', function(data) {
    console.log("Click event: " + data);
});
eventObserver.on('hover', function(data) {
    console.log("Hover event: " + data);
});

eventObserver.emit('click', 'Button clicked');
eventObserver.emit('hover', 'Mouse over');
Coding Round
74. Decorator pattern

Decorator pattern using wrapper functions or classes.

  • Component: Base object
  • Decorator: Wraps component
  • Chaining: Multiple decorators
  • Benefits: Add behavior dynamically
objective-j
// Decorator pattern in Objective-J
@import <Foundation/Foundation.j>

// Base coffee
function Coffee() {
    this.cost = 5.0;
    this.description = "Coffee";
}

// Decorators
function milkDecorator(coffee) {
    return {
        cost: coffee.cost + 2.0,
        description: coffee.description + ", Milk"
    };
}

function sugarDecorator(coffee) {
    return {
        cost: coffee.cost + 1.0,
        description: coffee.description + ", Sugar"
    };
}

function whippedCreamDecorator(coffee) {
    return {
        cost: coffee.cost + 1.5,
        description: coffee.description + ", Whipped Cream"
    };
}

// Usage
var coffee = new Coffee();
console.log(coffee.description);  // Coffee
console.log(coffee.cost);  // 5.0

coffee = milkDecorator(coffee);
coffee = sugarDecorator(coffee);
coffee = whippedCreamDecorator(coffee);

console.log(coffee.description);  // Coffee, Milk, Sugar, Whipped Cream
console.log(coffee.cost);  // 9.5

// Class-based decorator
function CoffeeDecorator(coffee) {
    this.coffee = coffee;
}

CoffeeDecorator.prototype.getCost = function() {
    return this.coffee.cost;
};

CoffeeDecorator.prototype.getDescription = function() {
    return this.coffee.description;
};

function MilkDecorator(coffee) {
    CoffeeDecorator.call(this, coffee);
}

MilkDecorator.prototype = Object.create(CoffeeDecorator.prototype);
MilkDecorator.prototype.constructor = MilkDecorator;
MilkDecorator.prototype.getCost = function() {
    return this.coffee.cost + 2.0;
};
MilkDecorator.prototype.getDescription = function() {
    return this.coffee.description + ", Milk";
};

function SugarDecorator(coffee) {
    CoffeeDecorator.call(this, coffee);
}

SugarDecorator.prototype = Object.create(CoffeeDecorator.prototype);
SugarDecorator.prototype.constructor = SugarDecorator;
SugarDecorator.prototype.getCost = function() {
    return this.coffee.cost + 1.0;
};
SugarDecorator.prototype.getDescription = function() {
    return this.coffee.description + ", Sugar";
};

var coffee2 = new Coffee();
coffee2 = new MilkDecorator(coffee2);
coffee2 = new SugarDecorator(coffee2);
console.log(coffee2.getDescription());
console.log(coffee2.getCost());
Coding Round
75. Command pattern

Command pattern with execute and undo methods.

  • Command: Execute and undo methods
  • Receiver: Performs actual work
  • Invoker: Executes commands
  • Undo/Redo: Command history
objective-j
// Command pattern in Objective-J
@import <Foundation/Foundation.j>

// Command interface
function Command(execute, undo) {
    this.execute = execute;
    this.undo = undo;
}

// Add command
function AddCommand(receiver, value) {
    this.receiver = receiver;
    this.value = value;
}

AddCommand.prototype.execute = function() {
    this.receiver.push(this.value);
};

AddCommand.prototype.undo = function() {
    var index = this.receiver.indexOf(this.value);
    if (index !== -1) {
        this.receiver.splice(index, 1);
    }
};

// Usage
var receiver = [1, 2, 3];
var cmd = new AddCommand(receiver, 4);
cmd.execute();
console.log(receiver);  // [1, 2, 3, 4]
cmd.undo();
console.log(receiver);  // [1, 2, 3]

// Command manager for undo/redo
function CommandManager() {
    this.history = [];
    this.redoStack = [];
}

CommandManager.prototype.execute = function(command) {
    command.execute();
    this.history.push(command);
    this.redoStack = [];
};

CommandManager.prototype.undo = function() {
    if (this.history.length > 0) {
        var command = this.history.pop();
        command.undo();
        this.redoStack.push(command);
    }
};

CommandManager.prototype.redo = function() {
    if (this.redoStack.length > 0) {
        var command = this.redoStack.pop();
        command.execute();
        this.history.push(command);
    }
};

var manager = new CommandManager();
var cmd2 = new AddCommand(receiver, 5);
manager.execute(cmd2);
console.log(receiver);  // [1, 2, 3, 5]
manager.undo();
console.log(receiver);  // [1, 2, 3]
manager.redo();
console.log(receiver);  // [1, 2, 3, 5]
Coding Round
76. Memento pattern

Memento pattern for state capture and restoration.

  • Originator: Creates and restores mementos
  • Memento: Stores state
  • Caretaker: Manages mementos
  • Undo/Redo: State history
objective-j
// Memento pattern in Objective-J
@import <Foundation/Foundation.j>

// Memento
function Memento(state) {
    this.state = state;
}

// Originator
function Originator() {
    this.state = null;
}

Originator.prototype.saveState = function() {
    return new Memento(JSON.parse(JSON.stringify(this.state)));
};

Originator.prototype.restoreState = function(memento) {
    this.state = memento.state;
    console.log("State restored to: " + JSON.stringify(this.state));
};

// Caretaker
function Caretaker() {
    this.mementos = [];
}

Caretaker.prototype.addMemento = function(memento) {
    this.mementos.push(memento);
};

Caretaker.prototype.getMemento = function(index) {
    return this.mementos[index];
};

// Usage
var originator = new Originator();
var caretaker = new Caretaker();

originator.state = {name: "State 1"};
caretaker.addMemento(originator.saveState());

originator.state = {name: "State 2"};
caretaker.addMemento(originator.saveState());

originator.state = {name: "State 3"};

originator.restoreState(caretaker.getMemento(0));
console.log(originator.state.name);  // State 1

// Memento with automatic backup
function AutoMemento() {
    this.history = [];
    this.currentIndex = -1;
}

AutoMemento.prototype.save = function(state) {
    // Remove future states
    this.history = this.history.slice(0, this.currentIndex + 1);
    this.history.push(JSON.parse(JSON.stringify(state)));
    this.currentIndex = this.history.length - 1;
};

AutoMemento.prototype.undo = function() {
    if (this.currentIndex > 0) {
        this.currentIndex--;
        return this.history[this.currentIndex];
    }
    return null;
};

AutoMemento.prototype.redo = function() {
    if (this.currentIndex < this.history.length - 1) {
        this.currentIndex++;
        return this.history[this.currentIndex];
    }
    return null;
};

var memento = new AutoMemento();
var state = {count: 0};
memento.save(state);
state.count = 1;
memento.save(state);
state.count = 2;
memento.save(state);

console.log(memento.undo());  // {count: 1}
console.log(memento.undo());  // {count: 0}
console.log(memento.redo());  // {count: 1}
Coding Round
77. Mediator pattern

Mediator pattern for centralized communication.

  • Mediator: Encapsulates communication
  • Colleague: Communicates through mediator
  • Benefits: Loose coupling
  • Use case: Chat systems
objective-j
// Mediator pattern in Objective-J
@import <Foundation/Foundation.j>

// Mediator
function Mediator() {
    this.colleagues = [];
}

Mediator.prototype.register = function(colleague) {
    this.colleagues.push(colleague);
    colleague.mediator = this;
};

Mediator.prototype.send = function(message, sender) {
    for (var i = 0; i < this.colleagues.length; i++) {
        if (this.colleagues[i] !== sender) {
            this.colleagues[i].receive(message);
        }
    }
};

// Colleague
function Colleague(name) {
    this.name = name;
    this.mediator = null;
}

Colleague.prototype.send = function(message) {
    if (this.mediator) {
        this.mediator.send(message, this);
    }
};

Colleague.prototype.receive = function(message) {
    console.log(this.name + " received: " + message);
};

// Usage
var mediator = new Mediator();
var alice = new Colleague("Alice");
var bob = new Colleague("Bob");

mediator.register(alice);
mediator.register(bob);

alice.send("Hello Bob!");

// Chat room mediator
function ChatRoom() {
    Mediator.call(this);
    this.history = [];
}

ChatRoom.prototype = Object.create(Mediator.prototype);
ChatRoom.prototype.constructor = ChatRoom;

ChatRoom.prototype.send = function(message, sender) {
    this.history.push(sender.name + ": " + message);
    Mediator.prototype.send.call(this, message, sender);
};

ChatRoom.prototype.getHistory = function() {
    return this.history;
};

var chatRoom = new ChatRoom();
var user1 = new Colleague("User1");
var user2 = new Colleague("User2");

chatRoom.register(user1);
chatRoom.register(user2);

user1.send("Hello everyone!");
console.log(chatRoom.getHistory());
Coding Round
78. Chain of Responsibility

Chain of Responsibility for processing requests sequentially.

  • Handler: Processes or forwards
  • Chain: Linked list of handlers
  • Benefits: Decoupling
  • Use case: Logging, authentication
objective-j
// Chain of Responsibility in Objective-J
@import <Foundation/Foundation.j>

// Handler
function Handler() {
    this.nextHandler = null;
}

Handler.prototype.setNext = function(handler) {
    this.nextHandler = handler;
    return handler;
};

Handler.prototype.handle = function(request) {
    if (this.nextHandler) {
        return this.nextHandler.handle(request);
    }
    return null;
};

// Auth handler
function AuthHandler() {
    Handler.call(this);
}

AuthHandler.prototype = Object.create(Handler.prototype);
AuthHandler.prototype.constructor = AuthHandler;

AuthHandler.prototype.handle = function(request) {
    if (request.token) {
        console.log("Authentication passed");
        return Handler.prototype.handle.call(this, request);
    } else {
        console.log("Authentication failed");
        return null;
    }
};

// Logger handler
function LoggerHandler() {
    Handler.call(this);
}

LoggerHandler.prototype = Object.create(Handler.prototype);
LoggerHandler.prototype.constructor = LoggerHandler;

LoggerHandler.prototype.handle = function(request) {
    console.log("Logging request: " + request.url);
    return Handler.prototype.handle.call(this, request);
};

// Permission handler
function PermissionHandler() {
    Handler.call(this);
}

PermissionHandler.prototype = Object.create(Handler.prototype);
PermissionHandler.prototype.constructor = PermissionHandler;

PermissionHandler.prototype.handle = function(request) {
    if (request.permissions && request.permissions.indexOf('read') !== -1) {
        console.log("Permission granted");
        return Handler.prototype.handle.call(this, request);
    } else {
        console.log("Permission denied");
        return null;
    }
};

// Usage
var auth = new AuthHandler();
var logger = new LoggerHandler();
var permission = new PermissionHandler();

auth.setNext(logger).setNext(permission);
auth.handle({
    token: "valid",
    url: "/api/data",
    permissions: ['read']
});
Coding Round
79. State pattern

State pattern for changing behavior with state.

  • Context: Maintains state
  • State: Defines behavior
  • Transitions: Change between states
  • Benefits: Clean state management
objective-j
// State pattern in Objective-J
@import <Foundation/Foundation.j>

// State interface
function State() {}

State.prototype.handle = function(context) {};

// Concrete states
function ReadyState() {}

ReadyState.prototype = Object.create(State.prototype);
ReadyState.prototype.constructor = ReadyState;
ReadyState.prototype.handle = function(context) {
    console.log("Ready: Waiting for input");
    context.state = new ProcessingState();
};

function ProcessingState() {}

ProcessingState.prototype = Object.create(State.prototype);
ProcessingState.prototype.constructor = ProcessingState;
ProcessingState.prototype.handle = function(context) {
    console.log("Processing: Working on task");
    context.state = new CompletedState();
};

function CompletedState() {}

CompletedState.prototype = Object.create(State.prototype);
CompletedState.prototype.constructor = CompletedState;
CompletedState.prototype.handle = function(context) {
    console.log("Completed: Task finished");
};

// Context
function Context() {
    this.state = new ReadyState();
}

Context.prototype.request = function() {
    this.state.handle(this);
};

// Usage
var context = new Context();
context.request();  // Ready: Waiting for input
context.request();  // Processing: Working on task
context.request();  // Completed: Task finished

// Order state with transitions
function OrderState() {
    this.status = 'pending';
    this.transitions = {
        'pending': ['processing', 'cancelled'],
        'processing': ['shipped', 'cancelled'],
        'shipped': ['delivered', 'returned'],
        'delivered': ['returned']
    };
}

OrderState.prototype.canTransition = function(newState) {
    return this.transitions[this.status] && 
           this.transitions[this.status].indexOf(newState) !== -1;
};

OrderState.prototype.transition = function(newState) {
    if (this.canTransition(newState)) {
        this.status = newState;
        console.log("Order status changed to: " + newState);
        return true;
    }
    console.log("Invalid transition from " + this.status + " to " + newState);
    return false;
};

var order = new OrderState();
order.transition('processing');
order.transition('shipped');
order.transition('delivered');
Coding Round
80. Proxy pattern

Proxy pattern for controlling access to objects.

  • Subject: Real object
  • Proxy: Controls access
  • Lazy loading: Create on demand
  • Benefits: Access control, logging
objective-j
// Proxy pattern in Objective-J
@import <Foundation/Foundation.j>

// Subject interface
function Subject() {}

Subject.prototype.request = function() {};

// Real subject
function RealSubject() {}

RealSubject.prototype = Object.create(Subject.prototype);
RealSubject.prototype.constructor = RealSubject;
RealSubject.prototype.request = function() {
    console.log("RealSubject: Handling request");
};

// Proxy
function Proxy() {
    this.realSubject = null;
}

Proxy.prototype = Object.create(Subject.prototype);
Proxy.prototype.constructor = Proxy;

Proxy.prototype.request = function() {
    if (this.checkAccess()) {
        if (!this.realSubject) {
            this.realSubject = new RealSubject();
        }
        this.realSubject.request();
        this.logAccess();
    }
};

Proxy.prototype.checkAccess = function() {
    console.log("Proxy: Checking access");
    return true;
};

Proxy.prototype.logAccess = function() {
    console.log("Proxy: Logging access");
};

// Usage
var proxy = new Proxy();
proxy.request();

// Virtual proxy (lazy loading)
function VirtualProxy(realClass) {
    this.realClass = realClass;
    this.realSubject = null;
    this.args = Array.prototype.slice.call(arguments, 1);
}

VirtualProxy.prototype = Object.create(Subject.prototype);
VirtualProxy.prototype.constructor = VirtualProxy;

VirtualProxy.prototype.request = function() {
    if (!this.realSubject) {
        console.log("Proxy: Creating real subject");
        this.realSubject = new (Function.prototype.bind.apply(
            this.realClass, [null].concat(this.args)
        ))();
    }
    this.realSubject.request();
};

var proxy2 = new VirtualProxy(RealSubject);
proxy2.request();  // Creates real subject
proxy2.request();  // Uses existing subject
Coding Round
81. Flyweight pattern

Flyweight pattern for sharing objects to save memory.

  • Flyweight: Shared object
  • Factory: Manages flyweights
  • Benefits: Memory optimization
  • Use case: Character rendering
objective-j
// Flyweight pattern in Objective-J
@import <Foundation/Foundation.j>

// Flyweight
function Flyweight(sharedState) {
    this.sharedState = sharedState;
}

Flyweight.prototype.operation = function(uniqueState) {
    console.log("Shared: " + this.sharedState + ", Unique: " + uniqueState);
};

// Flyweight factory
function FlyweightFactory() {
    this.flyweights = {};
}

FlyweightFactory.prototype.getFlyweight = function(sharedState) {
    if (!this.flyweights[sharedState]) {
        this.flyweights[sharedState] = new Flyweight(sharedState);
        console.log("Creating new flyweight for: " + sharedState);
    }
    return this.flyweights[sharedState];
};

// Usage
var factory = new FlyweightFactory();
var fw1 = factory.getFlyweight("state1");
var fw2 = factory.getFlyweight("state1");
var fw3 = factory.getFlyweight("state2");

fw1.operation("unique1");
fw2.operation("unique2");
fw3.operation("unique3");

// Character flyweight for text rendering
function Character(char) {
    this.char = char;
}

Character.prototype.display = function(fontSize) {
    console.log("Character: " + this.char + ", Size: " + fontSize);
};

function CharacterFactory() {
    this.characters = {};
}

CharacterFactory.prototype.getCharacter = function(char) {
    if (!this.characters[char]) {
        this.characters[char] = new Character(char);
    }
    return this.characters[char];
};

var charFactory = new CharacterFactory();
var text = "hello";
for (var i = 0; i < text.length; i++) {
    var c = charFactory.getCharacter(text[i]);
    c.display(12);
}
Coding Round
82. Bridge pattern

Bridge pattern for separating abstraction from implementation.

  • Abstraction: High-level interface
  • Implementation: Low-level operations
  • Benefits: Separation of concerns
  • Use case: Cross-platform
objective-j
// Bridge pattern in Objective-J
@import <Foundation/Foundation.j>

// Implementation interface
function Implementation() {}

Implementation.prototype.operationImpl = function() {};

// Concrete implementations
function ConcreteImplementationA() {}

ConcreteImplementationA.prototype = Object.create(Implementation.prototype);
ConcreteImplementationA.prototype.constructor = ConcreteImplementationA;
ConcreteImplementationA.prototype.operationImpl = function() {
    console.log("ConcreteImplementationA: Operation");
};

function ConcreteImplementationB() {}

ConcreteImplementationB.prototype = Object.create(Implementation.prototype);
ConcreteImplementationB.prototype.constructor = ConcreteImplementationB;
ConcreteImplementationB.prototype.operationImpl = function() {
    console.log("ConcreteImplementationB: Operation");
};

// Abstraction
function Abstraction(impl) {
    this.impl = impl;
}

Abstraction.prototype.operation = function() {
    console.log("Abstraction: Additional logic");
    this.impl.operationImpl();
};

// Usage
var implA = new ConcreteImplementationA();
var implB = new ConcreteImplementationB();
var abstraction1 = new Abstraction(implA);
var abstraction2 = new Abstraction(implB);

abstraction1.operation();
abstraction2.operation();

// Extended abstraction
function ExtendedAbstraction(impl) {
    Abstraction.call(this, impl);
}

ExtendedAbstraction.prototype = Object.create(Abstraction.prototype);
ExtendedAbstraction.prototype.constructor = ExtendedAbstraction;
ExtendedAbstraction.prototype.operation = function() {
    console.log("ExtendedAbstraction: More logic");
    Abstraction.prototype.operation.call(this);
};

var extended = new ExtendedAbstraction(implA);
extended.operation();
Coding Round
83. Adapter pattern

Adapter pattern for converting interfaces.

  • Target: Expected interface
  • Adaptee: Existing interface
  • Adapter: Bridges interfaces
  • Benefits: Reusability
objective-j
// Adapter pattern in Objective-J
@import <Foundation/Foundation.j>

// Target
function Target() {}

Target.prototype.request = function() {
    console.log("Target: Request");
};

// Adaptee
function Adaptee() {}

Adaptee.prototype.specificRequest = function() {
    console.log("Adaptee: Specific Request");
};

// Adapter
function Adapter(adaptee) {
    this.adaptee = adaptee;
}

Adapter.prototype = Object.create(Target.prototype);
Adapter.prototype.constructor = Adapter;
Adapter.prototype.request = function() {
    this.adaptee.specificRequest();
};

// Usage
var adaptee = new Adaptee();
var adapter = new Adapter(adaptee);
adapter.request();

// Object adapter (using composition)
function ObjectAdapter(adaptee) {
    this.adaptee = adaptee;
}

ObjectAdapter.prototype.request = function() {
    this.adaptee.specificRequest();
};

// Class adapter (using mixin)
function ClassAdapter() {
    Adaptee.call(this);
}

ClassAdapter.prototype = Object.create(Adaptee.prototype);
ClassAdapter.prototype.constructor = ClassAdapter;
ClassAdapter.prototype.request = function() {
    this.specificRequest();
};

var adapter2 = new ClassAdapter();
adapter2.request();

// Adapter for incompatible interfaces
function OldSystem() {}
OldSystem.prototype.oldMethod = function() {
    return "Old system data";
};

function NewSystem() {}
NewSystem.prototype.newMethod = function() {
    return "New system data";
};

function SystemAdapter(system) {
    this.system = system;
}

SystemAdapter.prototype.getData = function() {
    if (this.system.oldMethod) {
        return this.system.oldMethod();
    } else if (this.system.newMethod) {
        return this.system.newMethod();
    }
    return null;
};

var oldSystem = new OldSystem();
var newSystem = new NewSystem();
var adapter3 = new SystemAdapter(oldSystem);
console.log(adapter3.getData());  // Old system data
Coding Round
84. Facade pattern

Facade pattern for simplifying complex subsystems.

  • Facade: Simplified interface
  • Subsystem: Complex components
  • Benefits: Simplified interface
  • Use case: Library APIs
objective-j
// Facade pattern in Objective-J
@import <Foundation/Foundation.j>

// Subsystems
function SubsystemA() {}

SubsystemA.prototype.operationA = function() {
    console.log("SubsystemA: Operation");
};

function SubsystemB() {}

SubsystemB.prototype.operationB = function() {
    console.log("SubsystemB: Operation");
};

function SubsystemC() {}

SubsystemC.prototype.operationC = function() {
    console.log("SubsystemC: Operation");
};

// Facade
function Facade() {
    this.subsystemA = new SubsystemA();
    this.subsystemB = new SubsystemB();
    this.subsystemC = new SubsystemC();
}

Facade.prototype.operation = function() {
    console.log("Facade: Complex operation");
    this.subsystemA.operationA();
    this.subsystemB.operationB();
    this.subsystemC.operationC();
};

Facade.prototype.simplifiedOperation = function() {
    console.log("Facade: Simplified operation");
    this.subsystemA.operationA();
};

// Usage
var facade = new Facade();
facade.operation();
facade.simplifiedOperation();

// Database facade
function DatabaseFacade() {
    this.connection = null;
}

DatabaseFacade.prototype.connect = function() {
    console.log("Connecting to database");
    this.connection = "Connected";
};

DatabaseFacade.prototype.query = function(sql) {
    if (this.connection) {
        console.log("Executing: " + sql);
        return "Query results";
    }
    return null;
};

DatabaseFacade.prototype.disconnect = function() {
    console.log("Disconnecting");
    this.connection = null;
};

var db = new DatabaseFacade();
db.connect();
var result = db.query("SELECT * FROM users");
db.disconnect();
Coding Round
85. Composite pattern

Composite pattern for tree structures.

  • Component: Interface for all
  • Leaf: Individual object
  • Composite: Container
  • Benefits: Uniform interface
objective-j
// Composite pattern in Objective-J
@import <Foundation/Foundation.j>

// Component interface
function Component() {}

Component.prototype.operation = function() {};

// Leaf
function Leaf(name) {
    this.name = name;
}

Leaf.prototype = Object.create(Component.prototype);
Leaf.prototype.constructor = Leaf;
Leaf.prototype.operation = function() {
    console.log("Leaf " + this.name + ": Operation");
};

// Composite
function Composite(name) {
    this.name = name;
    this.children = [];
}

Composite.prototype = Object.create(Component.prototype);
Composite.prototype.constructor = Composite;

Composite.prototype.add = function(component) {
    this.children.push(component);
};

Composite.prototype.remove = function(component) {
    var index = this.children.indexOf(component);
    if (index !== -1) {
        this.children.splice(index, 1);
    }
};

Composite.prototype.operation = function() {
    console.log("Composite " + this.name + ": Operation");
    for (var i = 0; i < this.children.length; i++) {
        this.children[i].operation();
    }
};

// Usage
var leaf1 = new Leaf("A");
var leaf2 = new Leaf("B");
var composite = new Composite("Root");
composite.add(leaf1);
composite.add(leaf2);
composite.operation();

// File system example
function File(name, size) {
    this.name = name;
    this.size = size;
}

File.prototype = Object.create(Component.prototype);
File.prototype.constructor = File;
File.prototype.operation = function() {
    console.log("File: " + this.name + " (" + this.size + " bytes)");
};

function Directory(name) {
    Composite.call(this, name);
}

Directory.prototype = Object.create(Composite.prototype);
Directory.prototype.constructor = Directory;

Directory.prototype.getSize = function() {
    var total = 0;
    for (var i = 0; i < this.children.length; i++) {
        if (this.children[i] instanceof File) {
            total += this.children[i].size;
        } else if (this.children[i] instanceof Directory) {
            total += this.children[i].getSize();
        }
    }
    return total;
};

Directory.prototype.operation = function() {
    console.log("Directory: " + this.name + " (" + this.getSize() + " bytes)");
    for (var i = 0; i < this.children.length; i++) {
        this.children[i].operation();
    }
};

var root = new Directory("Root");
var file1 = new File("file1.txt", 100);
var file2 = new File("file2.txt", 200);
var subDir = new Directory("SubDir");
subDir.add(new File("file3.txt", 300));

root.add(file1);
root.add(file2);
root.add(subDir);
root.operation();
Coding Round
86. Visitor pattern

Visitor pattern for adding operations without modifying elements.

  • Visitor: Defines operations
  • Element: Accepts visitors
  • Benefits: Adding operations without modifying
  • Use case: Compilers, AST
objective-j
// Visitor pattern in Objective-J
@import <Foundation/Foundation.j>

// Visitor interface
function Visitor() {}

Visitor.prototype.visitElementA = function(element) {};
Visitor.prototype.visitElementB = function(element) {};

// Element interface
function Element() {}

Element.prototype.accept = function(visitor) {};

// Concrete elements
function ElementA(data) {
    this.data = data;
}

ElementA.prototype = Object.create(Element.prototype);
ElementA.prototype.constructor = ElementA;
ElementA.prototype.accept = function(visitor) {
    visitor.visitElementA(this);
};

function ElementB(data) {
    this.data = data;
}

ElementB.prototype = Object.create(Element.prototype);
ElementB.prototype.constructor = ElementB;
ElementB.prototype.accept = function(visitor) {
    visitor.visitElementB(this);
};

// Concrete visitor
function ConcreteVisitor() {}

ConcreteVisitor.prototype = Object.create(Visitor.prototype);
ConcreteVisitor.prototype.constructor = ConcreteVisitor;

ConcreteVisitor.prototype.visitElementA = function(element) {
    console.log("Visiting ElementA with data: " + element.data);
};

ConcreteVisitor.prototype.visitElementB = function(element) {
    console.log("Visiting ElementB with data: " + element.data);
};

// Usage
var visitor = new ConcreteVisitor();
var elementA = new ElementA("A data");
var elementB = new ElementB("B data");

elementA.accept(visitor);
elementB.accept(visitor);

// Visitor with multiple operations
function PrintVisitor() {}

PrintVisitor.prototype = Object.create(Visitor.prototype);
PrintVisitor.prototype.constructor = PrintVisitor;

PrintVisitor.prototype.visitElementA = function(element) {
    console.log("Print: ElementA - " + element.data);
};

PrintVisitor.prototype.visitElementB = function(element) {
    console.log("Print: ElementB - " + element.data);
};

function CountVisitor() {
    this.count = 0;
}

CountVisitor.prototype = Object.create(Visitor.prototype);
CountVisitor.prototype.constructor = CountVisitor;

CountVisitor.prototype.visitElementA = function(element) {
    this.count++;
};

CountVisitor.prototype.visitElementB = function(element) {
    this.count++;
};

var elements = [new ElementA("A1"), new ElementB("B1"), new ElementA("A2")];
var printVisitor = new PrintVisitor();
var countVisitor = new CountVisitor();

for (var i = 0; i < elements.length; i++) {
    elements[i].accept(printVisitor);
    elements[i].accept(countVisitor);
}

console.log("Total elements: " + countVisitor.count);
Coding Round
87. Iterator pattern

Iterator pattern for sequential access to collections.

  • Iterator: Traverses collection
  • Aggregate: Creates iterator
  • Benefits: Uniform traversal
  • Use case: Collection traversal
objective-j
// Iterator pattern in Objective-J
@import <Foundation/Foundation.j>

// Iterator
function Iterator(collection) {
    this.collection = collection;
    this.index = 0;
}

Iterator.prototype.next = function() {
    if (this.hasNext()) {
        return this.collection[this.index++];
    }
    return null;
};

Iterator.prototype.hasNext = function() {
    return this.index < this.collection.length;
};

// Collection
function CustomCollection() {
    this.items = [];
}

CustomCollection.prototype.add = function(item) {
    this.items.push(item);
};

CustomCollection.prototype.getIterator = function() {
    return new Iterator(this.items);
};

// Usage
var collection = new CustomCollection();
collection.add("A");
collection.add("B");
collection.add("C");

var iterator = collection.getIterator();
while (iterator.hasNext()) {
    console.log(iterator.next());
}

// Fibonacci iterator (using generator)
function fibonacciIterator(n) {
    var a = 0, b = 1;
    var count = 0;
    
    return {
        next: function() {
            if (count >= n) return null;
            var result = a;
            var temp = a + b;
            a = b;
            b = temp;
            count++;
            return result;
        },
        hasNext: function() {
            return count < n;
        }
    };
}

var fibIterator = fibonacciIterator(10);
while (fibIterator.hasNext()) {
    console.log(fibIterator.next());
}

// Iterator with step
function StepIterator(collection, step) {
    this.collection = collection;
    this.step = step || 1;
    this.index = 0;
}

StepIterator.prototype.next = function() {
    if (this.hasNext()) {
        var result = this.collection[this.index];
        this.index += this.step;
        return result;
    }
    return null;
};

StepIterator.prototype.hasNext = function() {
    return this.index < this.collection.length;
};

var stepIterator = new StepIterator([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 2);
while (stepIterator.hasNext()) {
    console.log(stepIterator.next());  // 1, 3, 5, 7, 9
}
Coding Round
88. Template Method pattern

Template Method for algorithm skeletons.

  • AbstractClass: Defines template
  • ConcreteClass: Implements steps
  • Benefits: Code reuse
  • Use case: Frameworks
objective-j
// Template Method pattern in Objective-J
@import <Foundation/Foundation.j>

// Abstract class
function AbstractClass() {}

AbstractClass.prototype.templateMethod = function() {
    this.step1();
    this.step2();
    this.step3();
};

AbstractClass.prototype.step1 = function() {
    console.log("Step 1");
};

AbstractClass.prototype.step2 = function() {
    // Abstract - to be overridden
};

AbstractClass.prototype.step3 = function() {
    console.log("Step 3");
};

// Concrete class
function ConcreteClass() {}

ConcreteClass.prototype = Object.create(AbstractClass.prototype);
ConcreteClass.prototype.constructor = ConcreteClass;

ConcreteClass.prototype.step2 = function() {
    console.log("Concrete Step 2");
};

// Usage
var concrete = new ConcreteClass();
concrete.templateMethod();

// Data processor template
function DataProcessor() {}

DataProcessor.prototype.process = function(data) {
    this.validate(data);
    this.transform(data);
    this.save(data);
    this.notify(data);
};

DataProcessor.prototype.validate = function(data) {
    if (!data) {
        throw new Error("Data cannot be empty");
    }
    console.log("Data validated");
};

DataProcessor.prototype.transform = function(data) {
    // Abstract - to be overridden
};

DataProcessor.prototype.save = function(data) {
    console.log("Data saved: " + JSON.stringify(data));
};

DataProcessor.prototype.notify = function(data) {
    console.log("Notification sent for: " + JSON.stringify(data));
};

// JSON processor
function JSONProcessor() {}

JSONProcessor.prototype = Object.create(DataProcessor.prototype);
JSONProcessor.prototype.constructor = JSONProcessor;

JSONProcessor.prototype.transform = function(data) {
    console.log("Transforming JSON: " + JSON.stringify(data));
};

// XML processor
function XMLProcessor() {}

XMLProcessor.prototype = Object.create(DataProcessor.prototype);
XMLProcessor.prototype.constructor = XMLProcessor;

XMLProcessor.prototype.transform = function(data) {
    console.log("Transforming XML: " + data);
};

var jsonProcessor = new JSONProcessor();
jsonProcessor.process({name: "Alice"});

var xmlProcessor = new XMLProcessor();
xmlProcessor.process("<user>Bob</user>");
Coding Round
89. Builder pattern

Builder pattern for constructing complex objects.

  • Builder: Constructs parts
  • Director: Orchestrates construction
  • Product: Constructed object
  • Benefits: Step-by-step construction
objective-j
// Builder pattern in Objective-J
@import <Foundation/Foundation.j>

// Product
function Product() {
    this.parts = [];
}

Product.prototype.add = function(part) {
    this.parts.push(part);
};

Product.prototype.listParts = function() {
    console.log(this.parts.join(", "));
};

// Builder
function Builder() {
    this.product = new Product();
}

Builder.prototype.reset = function() {
    this.product = new Product();
};

Builder.prototype.buildStepA = function() {
    this.product.add("Part A");
};

Builder.prototype.buildStepB = function() {
    this.product.add("Part B");
};

Builder.prototype.getResult = function() {
    return this.product;
};

// Director
function Director(builder) {
    this.builder = builder;
}

Director.prototype.buildMinimal = function() {
    this.builder.buildStepA();
};

Director.prototype.buildFull = function() {
    this.builder.buildStepA();
    this.builder.buildStepB();
};

// Usage
var builder = new Builder();
var director = new Director(builder);
director.buildMinimal();
var product = builder.getResult();
product.listParts();  // Part A

// Fluent builder
function FluentBuilder() {
    this.product = {};
}

FluentBuilder.prototype.name = function(name) {
    this.product.name = name;
    return this;
};

FluentBuilder.prototype.age = function(age) {
    this.product.age = age;
    return this;
};

FluentBuilder.prototype.email = function(email) {
    this.product.email = email;
    return this;
};

FluentBuilder.prototype.build = function() {
    return this.product;
};

var user = new FluentBuilder()
    .name("Alice")
    .age(25)
    .email("alice@example.com")
    .build();

console.log(user);

// Query builder
function QueryBuilder() {
    this.query = {select: '*', from: '', where: '', orderBy: '', limit: ''};
}

QueryBuilder.prototype.select = function(fields) {
    this.query.select = fields;
    return this;
};

QueryBuilder.prototype.from = function(table) {
    this.query.from = table;
    return this;
};

QueryBuilder.prototype.where = function(condition) {
    this.query.where = "WHERE " + condition;
    return this;
};

QueryBuilder.prototype.orderBy = function(field, direction) {
    this.query.orderBy = "ORDER BY " + field + " " + (direction || "ASC");
    return this;
};

QueryBuilder.prototype.limit = function(count) {
    this.query.limit = "LIMIT " + count;
    return this;
};

QueryBuilder.prototype.build = function() {
    var q = "SELECT " + this.query.select + " FROM " + this.query.from;
    if (this.query.where) q += " " + this.query.where;
    if (this.query.orderBy) q += " " + this.query.orderBy;
    if (this.query.limit) q += " " + this.query.limit;
    return q;
};

var query = new QueryBuilder()
    .select("name, age")
    .from("users")
    .where("age > 18")
    .orderBy("name", "ASC")
    .limit(10)
    .build();

console.log(query);
Coding Round
90. Prototype pattern

Prototype pattern for cloning objects using copy methods.

  • Clone method: Creates a copy
  • Shallow copy: Object.assign()
  • Deep copy: Recursive copy or JSON
  • Benefits: Object reuse, performance
objective-j
// Prototype pattern in Objective-J
@import <Foundation/Foundation.j>

// Prototype
function Prototype(name, nested) {
    this.name = name;
    this.nested = nested || {};
}

Prototype.prototype.clone = function() {
    return new Prototype(this.name, this.nested);
};

Prototype.prototype.deepClone = function() {
    return new Prototype(
        this.name,
        JSON.parse(JSON.stringify(this.nested))
    );
};

// Usage
var original = new Prototype("Original", {value: 42});
var copy = original.clone();
copy.name = "Copy";
copy.nested.value = 99;

console.log(original.name);  // Original
console.log(original.nested.value);  // 42 (shallow copy)

var deepCopy = original.deepClone();
deepCopy.nested.value = 100;
console.log(original.nested.value);  // 42 (deep copy)

// Prototype registry
function PrototypeRegistry() {
    this.prototypes = {};
}

PrototypeRegistry.prototype.register = function(key, prototype) {
    this.prototypes[key] = prototype;
};

PrototypeRegistry.prototype.get = function(key) {
    var proto = this.prototypes[key];
    if (proto) {
        return proto.clone();
    }
    return null;
};

var registry = new PrototypeRegistry();
registry.register("user", new Prototype("User", {name: "Default"}));

var user1 = registry.get("user");
user1.name = "Alice";

var user2 = registry.get("user");
user2.name = "Bob";

console.log(user1);
console.log(user2);

// Prototype with inheritance
function VehiclePrototype() {
    this.type = "vehicle";
    this.wheels = 4;
}

VehiclePrototype.prototype.clone = function() {
    var clone = Object.create(this);
    clone.wheels = this.wheels;
    return clone;
};

function CarPrototype() {
    VehiclePrototype.call(this);
    this.type = "car";
    this.doors = 4;
}

CarPrototype.prototype = Object.create(VehiclePrototype.prototype);
CarPrototype.prototype.constructor = CarPrototype;

CarPrototype.prototype.clone = function() {
    var clone = Object.create(this);
    clone.wheels = this.wheels;
    clone.doors = this.doors;
    return clone;
};

var carPrototype = new CarPrototype();
var car1 = carPrototype.clone();
car1.doors = 2;
var car2 = carPrototype.clone();

console.log(car1);
console.log(car2);
Coding Round
91. Archiving and Serialization

Archiving using JSON serialization methods.

  • JSON.stringify: Serialize to JSON
  • JSON.parse: Deserialize from JSON
  • Custom serialization: toJSON method
  • Versioning: Handle schema changes
objective-j
// Archiving and Serialization in Objective-J
@import <Foundation/Foundation.j>

// Class that supports archiving
function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.toJSON = function() {
    return {
        name: this.name,
        age: this.age
    };
};

Person.fromJSON = function(data) {
    return new Person(data.name, data.age);
};

// Serialization
function serialize(obj) {
    return JSON.stringify(obj);
}

function deserialize(str) {
    return JSON.parse(str);
}

// Usage
var person = new Person("Alice", 25);
var json = JSON.stringify(person);
console.log(json);

var parsed = JSON.parse(json);
console.log(parsed);

// Custom serialization
Person.prototype.serialize = function() {
    return JSON.stringify(this.toJSON());
};

Person.prototype.deserialize = function(data) {
    var parsed = JSON.parse(data);
    return Person.fromJSON(parsed);
};

var person2 = new Person("Bob", 30);
var serialized = person2.serialize();
console.log(serialized);

var deserialized = person2.deserialize(serialized);
console.log(deserialized);

// Archiving with versioning
function Archive() {
    this.version = 1;
    this.data = null;
}

Archive.prototype.save = function(obj) {
    this.data = {
        version: this.version,
        timestamp: Date.now(),
        data: obj
    };
    return JSON.stringify(this.data);
};

Archive.prototype.load = function(json) {
    var parsed = JSON.parse(json);
    if (parsed.version !== this.version) {
        console.log("Version mismatch!");
        return null;
    }
    return parsed.data;
};

var archive = new Archive();
var saved = archive.save({name: "Alice", age: 25});
console.log(saved);
var loaded = archive.load(saved);
console.log(loaded);
Coding Round
92. JSON Serialization

JSON serialization using JSON.stringify and JSON.parse.

  • stringify: Convert object to JSON string
  • parse: Convert JSON string to object
  • Replacer: Custom serialization
  • Reviver: Custom deserialization
objective-j
// JSON Serialization in Objective-J
@import <Foundation/Foundation.j>

// Create object
var obj = {
    name: "Alice",
    age: 25,
    city: "NYC",
    hobbies: ["reading", "gaming"]
};

// Convert to JSON
var json = JSON.stringify(obj, null, 2);
console.log(json);

// Parse JSON
var jsonString = '{"name":"Bob","age":30,"city":"LA"}';
var parsed = JSON.parse(jsonString);
console.log(parsed);
console.log("Name: " + parsed.name);

// JSON with date handling
function jsonWithDates() {
    var data = {
        name: "Alice",
        createdAt: new Date()
    };
    
    // Custom replacer
    var json = JSON.stringify(data, function(key, value) {
        if (value instanceof Date) {
            return value.toISOString();
        }
        return value;
    });
    console.log(json);
    
    // Custom reviver
    var parsed = JSON.parse(json, function(key, value) {
        if (typeof value === "string" && /^d{4}-d{2}-d{2}Td{2}:d{2}:d{2}.d{3}Z$/.test(value)) {
            return new Date(value);
        }
        return value;
    });
    console.log(parsed.createdAt instanceof Date);
}

jsonWithDates();

// JSON with error handling
function safeJSONParse(str) {
    try {
        return JSON.parse(str);
    } catch (e) {
        console.log("Invalid JSON: " + e.message);
        return null;
    }
}

console.log(safeJSONParse('{"name":"Alice"}'));  // Valid
console.log(safeJSONParse('{invalid}'));  // Invalid
Coding Round
93. Property List Serialization

Property list serialization using JSON or custom format.

  • JSON: Store as JSON
  • Custom format: XML-like structure
  • LocalStorage: Save to browser storage
  • Load/Save: File operations
objective-j
// Property List Serialization in Objective-J
@import <Foundation/Foundation.j>

// Property list serialization
function serializeToPList(obj) {
    return JSON.stringify(obj);
}

function deserializeFromPList(str) {
    return JSON.parse(str);
}

// Usage
var dict = {
    name: "Alice",
    age: 25,
    city: "NYC"
};

var plist = serializeToPList(dict);
console.log(plist);

var parsed = deserializeFromPList(plist);
console.log(parsed);

// Property list with types
function PropertyList() {
    this.data = {};
}

PropertyList.prototype.set = function(key, value) {
    this.data[key] = value;
};

PropertyList.prototype.get = function(key) {
    return this.data[key];
};

PropertyList.prototype.serialize = function() {
    return JSON.stringify(this.data);
};

PropertyList.prototype.deserialize = function(str) {
    this.data = JSON.parse(str);
};

PropertyList.prototype.saveToFile = function(filename) {
    var json = this.serialize();
    // In browser, use localStorage or IndexedDB
    try {
        localStorage.setItem(filename, json);
        return true;
    } catch (e) {
        console.log("Save failed: " + e.message);
        return false;
    }
};

PropertyList.prototype.loadFromFile = function(filename) {
    try {
        var json = localStorage.getItem(filename);
        if (json) {
            this.deserialize(json);
            return true;
        }
        return false;
    } catch (e) {
        console.log("Load failed: " + e.message);
        return false;
    }
};

var plist2 = new PropertyList();
plist2.set("name", "Alice");
plist2.set("age", 25);
plist2.saveToFile("user_data");
console.log(plist2.data);

var plist3 = new PropertyList();
plist3.loadFromFile("user_data");
console.log(plist3.data);
Coding Round
94. Threading

Threading using Web Workers, setTimeout, and setInterval.

  • setTimeout: Async execution
  • setInterval: Repeated execution
  • Web Workers: Background threads
  • Promises: Async/await
objective-j
// Threading in Objective-J
@import <Foundation/Foundation.j>

// setTimeout (async)
function asyncTask(callback) {
    setTimeout(function() {
        callback("Task completed");
    }, 1000);
}

asyncTask(function(result) {
    console.log(result);
});

// setInterval (repeating)
var counter = 0;
var intervalId = setInterval(function() {
    counter++;
    console.log("Tick: " + counter);
    if (counter >= 5) {
        clearInterval(intervalId);
        console.log("Interval stopped");
    }
}, 1000);

// Web Workers (for heavy computation)
function createWorker(script) {
    var blob = new Blob([script], {type: 'application/javascript'});
    var url = URL.createObjectURL(blob);
    var worker = new Worker(url);
    return worker;
}

// Worker script
var workerScript = `
    self.onmessage = function(e) {
        var result = e.data * 2;
        self.postMessage(result);
    };
`;

var worker = createWorker(workerScript);
worker.onmessage = function(e) {
    console.log("Worker result: " + e.data);
};
worker.postMessage(10);

// Promise-based async
function asyncPromise() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve("Promise resolved");
        }, 1000);
    });
}

asyncPromise().then(function(result) {
    console.log(result);
});

// Async/await
async function asyncAwaitExample() {
    var result = await asyncPromise();
    console.log("Async/await: " + result);
}

asyncAwaitExample();
Coding Round
95. Predicate filtering

Filtering using predicate functions.

  • Predicate function: Returns boolean
  • filter: arr.filter(predicate)
  • Compound predicates: Combine predicates
  • Object predicates: Filter objects by properties
objective-j
// Filtering with predicates in Objective-J
@import <Foundation/Foundation.j>

// Predicate function
function predicate(filterFn) {
    return function(arr) {
        return arr.filter(filterFn);
    };
}

// Usage
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Filter even numbers
var evenPredicate = predicate(function(x) { return x % 2 === 0; });
var evens = evenPredicate(numbers);
console.log("Evens: " + evens);

// Filter greater than 5
var greaterPredicate = predicate(function(x) { return x > 5; });
var greater = greaterPredicate(numbers);
console.log("Greater than 5: " + greater);

// Compound predicate
function compoundPredicate(predicates) {
    return function(arr) {
        return arr.filter(function(item) {
            return predicates.every(function(pred) {
                return pred(item);
            });
        });
    };
}

var betweenPredicate = compoundPredicate([
    function(x) { return x > 3; },
    function(x) { return x < 8; }
]);

var between = betweenPredicate(numbers);
console.log("Between 3 and 8: " + between);

// Predicate with objects
var people = [
    {name: "Alice", age: 25},
    {name: "Bob", age: 30},
    {name: "Charlie", age: 35}
];

var agePredicate = predicate(function(person) {
    return person.age > 28;
});

var filteredPeople = agePredicate(people);
console.log("People over 28: " + JSON.stringify(filteredPeople));

// Contains predicate
var namePredicate = predicate(function(person) {
    return person.name.indexOf('li') !== -1;
});

var nameFiltered = namePredicate(people);
console.log("Names containing 'li': " + JSON.stringify(nameFiltered));
Coding Round
96. Sorting with descriptors

Sorting using sort descriptors for key-based sorting.

  • SortDescriptor: Define sort criteria
  • Key: Property to sort by
  • Ascending: true/false
  • Multiple descriptors: Sort by multiple keys
objective-j
// Sorting with sort descriptors in Objective-J
@import <Foundation/Foundation.j>

// Sort descriptor
function SortDescriptor(key, ascending) {
    this.key = key;
    this.ascending = ascending !== false;
}

SortDescriptor.prototype.compare = function(obj1, obj2) {
    var val1 = obj1[this.key];
    var val2 = obj2[this.key];
    
    if (val1 < val2) return this.ascending ? -1 : 1;
    if (val1 > val2) return this.ascending ? 1 : -1;
    return 0;
};

// Usage
var people = [
    {name: "Alice", age: 25, city: "NYC"},
    {name: "Bob", age: 30, city: "LA"},
    {name: "Charlie", age: 20, city: "Chicago"},
    {name: "David", age: 35, city: "NYC"}
];

// Sort by age
var ageDescriptor = new SortDescriptor("age", true);
var sortedByAge = people.slice().sort(function(a, b) {
    return ageDescriptor.compare(a, b);
});
console.log("Sorted by age: " + JSON.stringify(sortedByAge));

// Sort by age descending
var ageDescDescriptor = new SortDescriptor("age", false);
var sortedByAgeDesc = people.slice().sort(function(a, b) {
    return ageDescDescriptor.compare(a, b);
});
console.log("Sorted by age descending: " + JSON.stringify(sortedByAgeDesc));

// Multiple sort descriptors
function SortDescriptors(descriptors) {
    this.descriptors = descriptors;
}

SortDescriptors.prototype.compare = function(obj1, obj2) {
    for (var i = 0; i < this.descriptors.length; i++) {
        var result = this.descriptors[i].compare(obj1, obj2);
        if (result !== 0) {
            return result;
        }
    }
    return 0;
};

var multiDescriptor = new SortDescriptors([
    new SortDescriptor("city", true),
    new SortDescriptor("age", false)
]);

var sortedMulti = people.slice().sort(function(a, b) {
    return multiDescriptor.compare(a, b);
});
console.log("Sorted by city then age: " + JSON.stringify(sortedMulti));
Coding Round
97. KVC Advanced

Advanced Key-Value Coding with collection operators.

  • valueForKey: Get property by name
  • setValueForKey: Set property by name
  • Collection operators: sum, avg, max, min
  • Key paths: Nested property access
objective-j
// KVC Advanced in Objective-J
@import <Foundation/Foundation.j>

// Person class
function Person(name, age, salary) {
    this.name = name;
    this.age = age;
    this.salary = salary;
}

// Department class
function Department(name, employees) {
    this.name = name;
    this.employees = employees || [];
}

// KVC functions
function valueForKey(obj, key) {
    if (typeof key === 'string' && key.indexOf('.') !== -1) {
        return valueForKeyPath(obj, key);
    }
    return obj[key];
}

function setValueForKey(obj, key, value) {
    if (typeof key === 'string' && key.indexOf('.') !== -1) {
        return setValueForKeyPath(obj, key, value);
    }
    obj[key] = value;
    return obj;
}

function valueForKeyPath(obj, keyPath) {
    var parts = keyPath.split('.');
    var current = obj;
    for (var i = 0; i < parts.length; i++) {
        if (!current) return null;
        current = current[parts[i]];
    }
    return current;
}

function setValueForKeyPath(obj, keyPath, value) {
    var parts = keyPath.split('.');
    var current = obj;
    for (var i = 0; i < parts.length - 1; i++) {
        if (!current[parts[i]]) {
            current[parts[i]] = {};
        }
        current = current[parts[i]];
    }
    current[parts[parts.length - 1]] = value;
    return obj;
}

// Usage
var p1 = new Person("Alice", 25, 50000);
var p2 = new Person("Bob", 30, 60000);
var p3 = new Person("Charlie", 35, 70000);

var dept = new Department("Engineering", [p1, p2, p3]);

// KVC operations
console.log("Name: " + valueForKey(p1, "name"));
console.log("Dept name: " + valueForKey(dept, "name"));

// Collection operators
function sumValues(collection, key) {
    var sum = 0;
    for (var i = 0; i < collection.length; i++) {
        sum += collection[i][key];
    }
    return sum;
}

function avgValues(collection, key) {
    if (collection.length === 0) return 0;
    return sumValues(collection, key) / collection.length;
}

function maxValues(collection, key) {
    if (collection.length === 0) return null;
    var max = collection[0][key];
    for (var i = 1; i < collection.length; i++) {
        if (collection[i][key] > max) {
            max = collection[i][key];
        }
    }
    return max;
}

function minValues(collection, key) {
    if (collection.length === 0) return null;
    var min = collection[0][key];
    for (var i = 1; i < collection.length; i++) {
        if (collection[i][key] < min) {
            min = collection[i][key];
        }
    }
    return min;
}

console.log("Total salary: " + sumValues(dept.employees, "salary"));
console.log("Average salary: " + avgValues(dept.employees, "salary"));
console.log("Max salary: " + maxValues(dept.employees, "salary"));
console.log("Min salary: " + minValues(dept.employees, "salary"));

// Array of values
var names = dept.employees.map(function(emp) { return emp.name; });
console.log("Names: " + names);
Coding Round
98. KVO Advanced

Advanced Key-Value Observing with manual notifications.

  • addObserver: Register observer
  • observeValueForKeyPath: Handle changes
  • willChangeValueForKey: Before change
  • didChangeValueForKey: After change
objective-j
// KVO Advanced in Objective-J
@import <Foundation/Foundation.j>

// Observable class
function Observable() {
    this.observers = {};
}

Observable.prototype.addObserver = function(obj, keyPath, options, context) {
    if (!this.observers[keyPath]) {
        this.observers[keyPath] = [];
    }
    this.observers[keyPath].push({
        observer: obj,
        options: options || {},
        context: context
    });
};

Observable.prototype.removeObserver = function(obj, keyPath) {
    if (this.observers[keyPath]) {
        this.observers[keyPath] = this.observers[keyPath].filter(function(obs) {
            return obs.observer !== obj;
        });
    }
};

Observable.prototype.willChangeValueForKey = function(keyPath) {
    // Called before value changes
};

Observable.prototype.didChangeValueForKey = function(keyPath) {
    if (this.observers[keyPath]) {
        var change = {
            oldValue: this._oldValue,
            newValue: this[keyPath]
        };
        for (var i = 0; i < this.observers[keyPath].length; i++) {
            var obs = this.observers[keyPath][i];
            if (obs.options.new || obs.options.old) {
                obs.observer.observeValueForKeyPath(keyPath, this, change, obs.context);
            }
        }
    }
};

// Person class with KVO
function Person(name, age) {
    this.name = name;
    this.age = age;
    this._oldValue = null;
}

Person.prototype = Object.create(Observable.prototype);
Person.prototype.constructor = Person;

Person.prototype.setName = function(name) {
    this.willChangeValueForKey('name');
    this._oldValue = this.name;
    this.name = name;
    this.didChangeValueForKey('name');
};

Person.prototype.setAge = function(age) {
    this.willChangeValueForKey('age');
    this._oldValue = this.age;
    this.age = age;
    this.didChangeValueForKey('age');
};

// Observer class
function Observer() {}

Observer.prototype.observeValueForKeyPath = function(keyPath, object, change, context) {
    console.log(keyPath + " changed from " + change.oldValue + " to " + change.newValue);
};

// Usage
var person = new Person("Alice", 25);
var observer = new Observer();

person.addObserver(observer, 'name', {new: true, old: true}, null);
person.addObserver(observer, 'age', {new: true, old: true}, null);

person.setName("Bob");
person.setAge(30);

person.removeObserver(observer, 'name');
person.removeObserver(observer, 'age');

// Automatic KVO with Object.defineProperty
function AutoObservable(obj) {
    var observers = {};
    
    return new Proxy(obj, {
        get: function(target, key) {
            return target[key];
        },
        set: function(target, key, value) {
            var oldValue = target[key];
            if (oldValue !== value) {
                target[key] = value;
                if (observers[key]) {
                    observers[key].forEach(function(callback) {
                        callback(value, oldValue);
                    });
                }
            }
            return true;
        }
    });
}

var autoPerson = AutoObservable({name: "Alice", age: 25});
autoPerson.on = function(key, callback) {
    if (!this._observers) this._observers = {};
    if (!this._observers[key]) this._observers[key] = [];
    this._observers[key].push(callback);
};

autoPerson.on('name', function(newVal, oldVal) {
    console.log("Name changed from " + oldVal + " to " + newVal);
});

autoPerson.name = "Bob";  // Triggers observer
Coding Round
99. Categories Advanced

Advanced categories with multiple methods and prototypes.

  • Prototype extension: Add methods to built-in types
  • String methods: email, phone, truncate
  • Array methods: average, chunk, intersect
  • Number methods: isEven, factorial
objective-j
// Categories Advanced in Objective-J
@import <Foundation/Foundation.j>

// String category with multiple methods
Object.defineProperties(String.prototype, {
    isValidEmail: {
        value: function() {
            return /^[A-Z0-9._%+-]+@[A-Z0-9.-]+.[A-Z]{2,}$/i.test(this);
        }
    },
    isValidPhone: {
        value: function() {
            return /^d{3}-d{3}-d{4}$/.test(this);
        }
    },
    truncate: {
        value: function(length) {
            if (this.length <= length) return this.toString();
            return this.substring(0, length) + "...";
        }
    },
    words: {
        value: function() {
            return this.split(/s+/);
        }
    },
    reverse: {
        value: function() {
            return this.split('').reverse().join('');
        }
    }
});

// Array category
Object.defineProperties(Array.prototype, {
    second: {
        value: function() {
            return this.length >= 2 ? this[1] : null;
        }
    },
    average: {
        value: function() {
            if (this.length === 0) return 0;
            return this.reduce(function(a, b) { return a + b; }, 0) / this.length;
        }
    },
    chunk: {
        value: function(size) {
            var chunks = [];
            for (var i = 0; i < this.length; i += size) {
                chunks.push(this.slice(i, i + size));
            }
            return chunks;
        }
    },
    intersect: {
        value: function(other) {
            var set = new Set(other);
            return this.filter(function(item) {
                return set.has(item);
            });
        }
    }
});

// Number category
Object.defineProperties(Number.prototype, {
    isEven: {
        value: function() {
            return this % 2 === 0;
        }
    },
    isOdd: {
        value: function() {
            return this % 2 !== 0;
        }
    },
    factorial: {
        value: function() {
            if (this <= 1) return 1;
            var result = 1;
            for (var i = 2; i <= this; i++) {
                result *= i;
            }
            return result;
        }
    }
});

// Usage
console.log("test@example.com".isValidEmail());  // true
console.log("123-456-7890".isValidPhone());  // true
console.log("Hello World".truncate(5));  // "Hello..."
console.log("Hello World".words());  // ["Hello", "World"]
console.log("hello".reverse());  // "olleh"

var arr = [1, 2, 3, 4, 5];
console.log(arr.second());  // 2
console.log(arr.average());  // 3
console.log(arr.chunk(2));  // [[1,2], [3,4], [5]]
console.log(arr.intersect([2, 4, 6]));  // [2, 4]

console.log(4.isEven());  // true
console.log(5.isOdd());  // true
console.log(5..factorial());  // 120 (note double dot for number literal)
Coding Round
100. Prototype pattern

Prototype pattern for cloning objects using JavaScript's prototype or copy methods.

  • Object.create: Create from prototype
  • Object.assign: Shallow copy
  • JSON methods: JSON.parse(JSON.stringify(obj))
  • Custom copy: Implement copy methods
objective-j
// Blocks and Closures in Objective-J
@import <Foundation/Foundation.j>

// Basic block/closure
var simpleBlock = function() {
    console.log("Simple block executed");
};
simpleBlock();

// Block with parameters
var greetingBlock = function(name) {
    return "Hello, " + name + "!";
};
console.log(greetingBlock("Alice"));

// Block with return value
var addBlock = function(a, b) {
    return a + b;
};
console.log(addBlock(5, 3));

// Block capturing variables
var multiplier = 2;
var multiplyBlock = function(x) {
    return x * multiplier;
};
console.log(multiplyBlock(5));  // 10

// Block with __block variable (modifiable)
var counter = 0;
var incrementBlock = function() {
    counter++;
};
incrementBlock();
incrementBlock();
console.log("Counter: " + counter);  // 2

// Block as completion handler
var completionHandler = function(result, error) {
    if (error) {
        console.log("Error: " + error);
    } else {
        console.log("Result: " + result);
    }
};
completionHandler("Success", null);

// Block in array
var blocks = [
    function() { console.log("Block 1"); },
    function() { console.log("Block 2"); },
    function() { console.log("Block 3"); }
];
for (var i = 0; i < blocks.length; i++) {
    blocks[i]();
}

// Block returning block
var getMultiplier = function(factor) {
    return function(x) {
        return x * factor;
    };
};
var doubleBlock = getMultiplier(2);
console.log(doubleBlock(5));  // 10

// Block with closure scope
function createCounter() {
    var count = 0;
    return {
        increment: function() {
            count++;
            return count;
        },
        decrement: function() {
            count--;
            return count;
        },
        get: function() {
            return count;
        }
    };
}

var counterObj = createCounter();
console.log(counterObj.increment());  // 1
console.log(counterObj.increment());  // 2
console.log(counterObj.decrement());  // 1

// Block with setTimeout
setTimeout(function() {
    console.log("Delayed execution");
}, 1000);

// Block with async operation
function asyncOperation(callback) {
    setTimeout(function() {
        var result = "Operation completed";
        callback(result);
    }, 500);
}

asyncOperation(function(result) {
    console.log(result);
});

// Block with promise
function promiseOperation() {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve("Promise resolved");
        }, 500);
    });
}

promiseOperation().then(function(result) {
    console.log(result);
});

// Block with reduce
var numbers = [1, 2, 3, 4, 5];
var sum = numbers.reduce(function(acc, val) {
    return acc + val;
}, 0);
console.log("Sum: " + sum);

// Block with filter
var evens = numbers.filter(function(x) {
    return x % 2 === 0;
});
console.log("Evens: " + evens);

// Block with map
var doubled = numbers.map(function(x) {
    return x * 2;
});
console.log("Doubled: " + doubled);