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
57 changes: 57 additions & 0 deletions src/problem1/sum_to_n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* Problem: Summation from 1 to n.
* Input: n — integer (result assumed < Number.MAX_SAFE_INTEGER).
* Output: 1 + 2 + ... + n (e.g. sum_to_n(5) === 15).
*
* Edge cases handled:
* - n < 1: returns 0 (empty sum).
* - Non-integer n: truncated via Math.floor for predictable behavior.
*/

/**
* Implementation A: Closed-form formula.
* Uses the identity: 1 + 2 + ... + n = n * (n + 1) / 2.
*
* Time: O(1)
* Space: O(1)
*/
var sum_to_n_a = function (n) {
var k = Math.floor(Number(n));
if (k < 1) return 0;
return (k * (k + 1)) / 2;
};

/**
* Implementation B: Iterative loop (for).
* Accumulates the sum in a single variable.
*
* Time: O(n)
* Space: O(1)
*/
var sum_to_n_b = function (n) {
var k = Math.floor(Number(n));
if (k < 1) return 0;
var sum = 0;
for (var i = 1; i <= k; i++) {
sum += i;
}
return sum;
};

/**
* Implementation C: Recursion.
* Base case: n < 1 → 0. Otherwise: n + sum_to_n_c(n - 1).
*
* Time: O(n)
* Space: O(n) — call stack depth
*/
var sum_to_n_c = function (n) {
var k = Math.floor(Number(n));
if (k < 1) return 0;
return k + sum_to_n_c(k - 1);
};

// Export for tests and reuse
if (typeof module !== "undefined" && module.exports) {
module.exports = { sum_to_n_a, sum_to_n_b, sum_to_n_c };
}
51 changes: 51 additions & 0 deletions src/problem1/sum_to_n.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Tests for sum_to_n implementations.
* Run with: node sum_to_n.test.js
*/

var assert = require("assert");
var { sum_to_n_a, sum_to_n_b, sum_to_n_c } = require("./sum_to_n.js");

var implementations = [
{ name: "sum_to_n_a", fn: sum_to_n_a },
{ name: "sum_to_n_b", fn: sum_to_n_b },
{ name: "sum_to_n_c", fn: sum_to_n_c },
];

function runTests() {
var passed = 0;
var failed = 0;

function test(description, n, expected) {
implementations.forEach(function (impl) {
try {
var result = impl.fn(n);
assert.strictEqual(
result,
expected,
impl.name + "(" + n + ") expected " + expected + ", got " + result
);
passed++;
} catch (err) {
console.error("FAIL " + impl.name + ": " + description + " — " + err.message);
failed++;
}
});
}

// Normal cases
test("sum to 5", 5, 15);
test("sum to 1", 1, 1);
test("sum to 10", 10, 55);
test("sum to 100", 100, 5050);

// Edge cases
test("n = 0", 0, 0);
test("n negative", -5, 0);
test("non-integer (floor)", 5.9, 15);

console.log("Tests: " + passed + " passed, " + failed + " failed");
process.exit(failed > 0 ? 1 : 0);
}

runTests();
File renamed without changes.
10 changes: 10 additions & 0 deletions src/problem2/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";
import { SwapForm } from "./src/components/SwapForm";

export default function App() {
return (
<div className="app">
<SwapForm />
</div>
);
}
46 changes: 46 additions & 0 deletions src/problem2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Problem 2: Currency Swap Form

Form đổi token dùng **Vite** + **React**. Logic viết bằng **TypeScript** (services, hooks, utils, types); UI giữ bằng JSX trong `src/components`.

## Chạy

```bash
cd src/problem2
npm install
npm run dev
```

Mở http://localhost:5173

## Nguồn dữ liệu

- **Giá token:** https://interview.switcheo.com/prices.json
- **Icon token:** https://github.com/Switcheo/token-icons/tree/main/tokens (vd: SWTH.svg)

---

## Cấu trúc (components, logic = TS)

```
src/
├── components/ # UI (JSX)
│ ├── SwapForm.jsx
│ ├── SwapCard.jsx
│ ├── TokenSelect.jsx
│ ├── TokenIcon.jsx
│ └── SwapFormStyles.jsx
├── hooks/ # Logic (TypeScript)
│ ├── useTokensWithPrices.ts
│ └── useSwapForm.ts
├── services/ # API (TypeScript)
│ └── priceService.ts
├── utils/ # Hàm thuần (TypeScript)
│ ├── tokenIcon.ts
│ ├── exchange.ts
│ └── validation.ts
└── types/ # Định nghĩa type (TypeScript)
└── index.ts
```

- **Logic (TS):** `types`, `services`, `hooks`, `utils` — toàn bộ file `.ts`.
- **UI (JSX):** `components` — file `.jsx`, chỉ render và nhận props, gọi hooks từ container.
51 changes: 51 additions & 0 deletions src/problem2/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
:root {
--bg-primary: #0d0f14;
--bg-card: #151922;
--bg-input: #1a1e28;
--border: #2a3142;
--text-primary: #e6e8ec;
--text-secondary: #8b92a5;
--accent: #00d395;
--accent-dim: #00a876;
--error: #ff5c5c;
--radius: 14px;
--radius-sm: 10px;
--shadow: 0 12px 40px rgba(0, 0, 0, 0.4);
--font-sans: "DM Sans", -apple-system, BlinkMacSystemFont, sans-serif;
}

*,
*::before,
*::after {
box-sizing: border-box;
}

body {
margin: 0;
min-height: 100vh;
background: var(--bg-primary);
color: var(--text-primary);
font-family: var(--font-sans);
font-size: 16px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}

.app {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
width: 100%;
}

#root {
width: 100%;
max-width: 520px;
margin: 0 auto;
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
}
41 changes: 15 additions & 26 deletions src/problem2/index.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,16 @@
<html>

<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" />
</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>
</body>

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Currency Swap</title>
<link rel="preconnect" href="https://raw.githubusercontent.com" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,400;0,9..40,600&display=swap" rel="stylesheet" />
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.jsx"></script>
</body>
</html>
10 changes: 10 additions & 0 deletions src/problem2/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./index.css";

ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Loading