Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
132 changes: 125 additions & 7 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,128 @@
# 99Tech Code Challenge #1 #
# Code Challenge Solutions

Note that if you fork this repository, your responses may be publicly linked to this repo.
Please submit your application along with the solutions attached or linked.
This repository contains solutions to 3 coding challenges demonstrating proficiency in JavaScript, TypeScript, React, and software engineering best practices.

It is important that you minimally attempt the problems, even if you do not arrive at a working solution.
---

## Submission ##
You can either provide a link to an online repository, attach the solution in your application, or whichever method you prefer.
We're cool as long as we can view your solution without any pain.
## πŸ“‹ Table of Contents

- [Problem 1: Sum to N - Three Ways](#problem-1-sum-to-n---three-ways)
- [Problem 2: Fancy Form - Currency Swap Application](#problem-2-fancy-form---currency-swap-application)
- [Problem 3: Messy React - Code Analysis & Refactoring](#problem-3-messy-react---code-analysis--refactoring)

---

## Problem 1: Sum to N - Three Ways

**Location:** [`src/problem1/index.js`](./src/problem1/index.js)

### πŸ“ Challenge
Provide 3 unique implementations to compute the sum of numbers from 1 to n.

### βœ… Solutions

| Method | Approach | Time Complexity | Space Complexity |
|--------|----------|-----------------|------------------|
| **sum_to_n_a** | Mathematical formula: `n Γ— (n + 1) / 2` | O(1) | O(1) |
| **sum_to_n_b** | Iterative loop accumulation | O(n) | O(1) |
| **sum_to_n_c** | Recursive calculation | O(n) | O(n) |

### 🎯 Key Features
- βœ… Edge case handling (n ≀ 0)
- βœ… JSDoc documentation
- βœ… Three distinct algorithmic approaches
- βœ… Optimal solution using arithmetic series formula

### πŸ’‘ Best Practice
**sum_to_n_a** is the most efficient solution with constant time and space complexity.

---

## Problem 2: Fancy Form - Currency Swap Application

**Location:** [`src/problem2/`](./src/problem2/)

### πŸ“ Challenge
Build a responsive, user-friendly currency swap interface with real-time exchange rates.

### πŸš€ Live Demo
https://code-challenge-steel.vercel.app/

### ✨ Features

#### Core Functionality
- **Real-time Exchange Rates** - Live price data from CoinGecko API
- **Token Swapping** - Swap between USD, ETH, BLUR, bNEO, BUSD, ATOM, LUNA
- **Balance Validation** - Prevents swaps exceeding available balance (mocked data for USD and ATOM)
- **Auto-calculation** - Instant conversion as you type
- **Exchange Rate Display** - Clear rate information

#### User Experience
- **Modern Dark UI** - Sleek slate-themed design
- **Smooth Animations** - Fade-ins, loading states, transitions
- **Fully Responsive** - Mobile, tablet, desktop optimized
- **Accessible** - Semantic HTML, ARIA labels, keyboard navigation
- **Auto-focus** - Smart input focusing for better UX

#### Technical Features
- **Form Validation** - React Hook Form with custom rules
- **Type Safety** - Full TypeScript implementation
- **Component Architecture** - Modular, reusable components
- **Loading States** - Skeleton loaders, spinners
- **Error Handling** - Graceful error messages
- **Confirmation Modal** - Preview before swap


---

## Problem 3: Messy React - Code Analysis & Refactoring

**Location:** [`src/problem3/`](./src/problem3/)

### πŸ“ Challenge
Identify computational inefficiencies and anti-patterns in a React TypeScript component, then provide a refactored version following strict best practices.

### πŸ“ Files

- **[README.md](./src/problem3/README.md)** - Detailed analysis with tables, code comparisons, and explanations
- **[RefactoredComponent.tsx](./src/problem3/RefactoredComponent.tsx)** - Production-ready implementation

### πŸŽ“ Key Learnings

#### Anti-Patterns Identified
1. ❌ Using array index as React key
2. ❌ Memoizing JSX creation with `useMemo`
3. ❌ Incorrect dependency arrays
4. ❌ Double iteration over same data
5. ❌ Functions defined inside component body

#### Correct Patterns
1. βœ… Use unique, stable identifiers for keys
2. βœ… Render JSX directly (React optimizes via reconciliation)
3. βœ… Only memoize expensive calculations
4. βœ… Single-pass data transformations
5. βœ… Pure functions outside component or in constants

---

## 🎯 Overall Highlights

### Technical Skills Demonstrated
- βœ… **Algorithm Design** - Multiple approaches with complexity analysis
- βœ… **React Expertise** - Hooks, forms, state management, performance optimization
- βœ… **TypeScript Proficiency** - Strict typing, interfaces, type safety
- βœ… **Code Quality** - Clean code, documentation, best practices
- βœ… **Performance** - Optimization, memoization, efficient algorithms
- βœ… **UX/UI** - Responsive design, accessibility, smooth interactions
- βœ… **Architecture** - Component design, separation of concerns
- βœ… **Problem Solving** - Debugging, refactoring, analysis

### Best Practices
- πŸ“ Comprehensive documentation
- πŸ§ͺ Type safety throughout
- β™Ώ Accessibility compliance
- 🎨 Modern, responsive UI
- ⚑ Performance optimization
- πŸ”§ Maintainable code structure

---
33 changes: 33 additions & 0 deletions src/problem1/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@

/**
* Uses the arithmetic series formula: n Γ— (n + 1) / 2
* @param {number} n
* @returns {number}
*/
var sum_to_n_a = function (n) {
if (n <= 0) return 0;
return n * (n + 1) / 2;
};

/**
* Uses a for loop to accumulate the sum.
* @param {number} n
* @returns {number}
*/
var sum_to_n_b = function (n) {
var sum = 0;
for (var i = 1; i <= n; i++) {
sum += i;
}
return sum;
};

/**
* Uses recursion to calculate the sum.
* @param {number} n
* @returns {number}
*/
var sum_to_n_c = function (n) {
if (n <= 0) return 0;
return n + sum_to_n_c(n - 1);
};
24 changes: 24 additions & 0 deletions src/problem2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
73 changes: 73 additions & 0 deletions src/problem2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# React + TypeScript + Vite

This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.

Currently, two official plugins are available:

- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

## React Compiler

The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).

## Expanding the ESLint configuration

If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:

```js
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...

// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,

// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```

You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:

```js
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
```
23 changes: 23 additions & 0 deletions src/problem2/eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'

export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
reactHooks.configs.flat.recommended,
reactRefresh.configs.vite,
],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
},
},
])
30 changes: 10 additions & 20 deletions src/problem2/index.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,17 @@
<html>
<!doctype html>
<html lang="en">

<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fancy Form</title>

<!-- You may add more stuff here -->
<link href="style.css" rel="stylesheet" />
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Swap cryptocurrency assets instantly with real-time exchange rates" />
<title>Currency Swap - Exchange Crypto Assets</title>
</head>

<body>

<!-- You may reorganise the whole HTML, as long as your form achieves the same effect. -->
<form onsubmit="return !1">
<h5>Swap</h5>
<label for="input-amount">Amount to send</label>
<input id="input-amount" />

<label for="output-amount">Amount to receive</label>
<input id="output-amount" />

<button>CONFIRM SWAP</button>
</form>
<script src="script.js"></script>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>

</html>
</html>
33 changes: 33 additions & 0 deletions src/problem2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "problem2",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"@tailwindcss/vite": "^4.1.18",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-hook-form": "^7.68.0",
"tailwindcss": "^4.1.18"
},
"devDependencies": {
"@eslint/js": "^9.39.1",
"@types/node": "^24.10.1",
"@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
"eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.24",
"globals": "^16.5.0",
"typescript": "~5.9.3",
"typescript-eslint": "^8.46.4",
"vite": "^7.2.4"
}
}
Loading