Skip to main content
0:03est. 30 min

Carousell

// https://javascript.info/promise-basics

/**
* Given a collection of intervals, merge all overlapping intervals.
* Intervals are not guaranteed to be sorted in any order.
*
* Input: [[3, 5], [1, 3], [7, 9]]
* Output: [[1, 5], [7, 9]]
* Explanation:
* [1, 3] and [3, 5] overlap to give [1, 5].
*
* Input: [[7, 10], [1, 5], [12, 13], [2, 6], [7, 11]]
* Output: [[[1, 6], [7, 11], [12, 13]]
* Explanation:
* [1, 5] and [2, 6] overlap to give [1, 6].
* [7, 10] and [7, 11] overlap to give [7, 11].
*/
// [x0, y0], [x1, y1], [x2, y2]
// [[1, 3], [3, 5], [7, 9]]
function mergeIntervals(intervals) {
// console.log(intervals)
// 1. itreate over all the elements
// 2. find start and end
// min = 3
let sortedIntervals = intervals.sort((a, b) => a[0] - b[0]); //lognn

console.log("sortedIntervals", sortedIntervals);
let min = 0;
let max = 0;
let result = [];
for (let i = 0; i < intervals.length; i++) { //n*(n-1) = n^2
min = sortedIntervals[i][0];
max = sortedIntervals[i][1];
for (let j = i + 1; j < intervals.length; j++) {
if (sortedIntervals[j][0] > max) {
result.push([max, min]);
i = j;
min = sortedIntervals[i][0];
max = sortedIntervals[i][1];
break;
}
min = Math.min(min, sortedIntervals[j][0]);
max = Math.max(max, sortedIntervals[j][1]);
}
}
result.push([max, min]);
console.log("result", result);
}

let arr = [
[3, 5], // min 3, max 5
[1, 3],
[7, 9]
];
arr = [[7, 10], [1, 5], [12, 13], [2, 6], [7, 11]]
mergeIntervals(arr);
// ------------------

import "./styles.css";

document.getElementById("app").innerHTML = `
<h1>Hello Vanilla!</h1>
<div>
We use the same configuration as Parcel to bundle this sandbox, you can find more
info about Parcel
<a href="https://parceljs.org" target="_blank" rel="noopener noreferrer">here</a>.
</div>
`;

function b() {
// -- TODO: Edit as appropriate below this line --
for (let i = 0; i < 10; i++) {
// block i created
// block
setTimeout(() => {
console.log(i);
}, 0);
}
// -- TODO: Edit as appropriate above this line --
}

var a = 1; // window global
let b1 = 2;
const c = 3;
b();

// ----------


// https://codesandbox.io/u/jsliang/sandboxes

import "./styles.css";

/*

This coding session aims to test your competencies of the web front-end
fundamentals. It consists of 2 parts.

Part I: Optimising API calls
Part II: Working with DOM

* You have 50 minutes to finish both parts.

* Please use native HTML, CSS and JS.

* You are encouraged to perform Google lookups for any HTML, CSS or JS specs
that you are not familiar with.

*/

/*

[ PART I: Searchbar ]

Your task for this part is to improve the API calls of the searchbar.

Please trace the code first, and then complete the implementations for
1. the Cache class
2. the debouncedInputChange function

*/

class Cache {
/*
Please implement the following 2 methods:
* set(key, value) which stores the cache with the given key and value
* get(key) which returns the cached value of the specified key

Aside from the required methods above,
feel free to add constructors or more methods as you see fit.
*/

// -- TODO: Your JavaScript code below this line --

constructor() {
this.cacheMap = {};
}

set(key, value) {
this.cacheMap[key] = value;
}

get(key) {
return this.cacheMap[key];
}

// -- TODO: Your JavaScript code above this line --
}

const myCache = new Cache();

function clearTable() {
const tbody = document.querySelector("#companies > tbody");

// fastest way to clear html, better than innerHTML = ""
while (tbody.lastChild) {
tbody.removeChild(tbody.lastChild);
}
}

function callAPI(API) {
return new Promise(function (resolve, reject) {
window.api.abort();

window.api.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
const response = JSON.parse(this.responseText);
resolve(response);
}
};

window.api.open("GET", API, true);
window.api.send();
});
}

function updateTable(items) {
clearTable();

const tbody = document.querySelector("#companies > tbody");
items.forEach((item) => {
const listItem = document.createElement("tr");
const company = document.createElement("td");
const domain = document.createElement("td");
const logo = document.createElement("td");
const img = document.createElement("img");

company.innerHTML = item.name;

domain.innerHTML = item.domain;

img.src = item.logo;
img.height = 42;
img.width = 42;
logo.appendChild(img);

listItem.appendChild(company);
listItem.appendChild(domain);
listItem.appendChild(logo);

tbody.appendChild(listItem);
});
}

function onInputChange(e) {
const { value } = e.target;

if (value.length === 0) {
clearTable();
} else if (value.length > 0) {
const cachedItems = myCache.get(value);
if (cachedItems) {
console.debug(`Cache hit: ${value}`);
updateTable(cachedItems);
} else {
console.debug(`Cache miss: ${value}`);
callAPI(
"https://autocomplete.clearbit.com/v1/companies/suggest?query=" + value
).then((items) => {
myCache.set(value, items);
updateTable(items);
});
}
}
}

function debounced(func) {
// debounced(func) return a function that, as long as it continues to be
// invoked, it will not trigger `func`. Call `func` only after it stops
// being called for 300ms.

// -- TODO: Your JavaScript code below this line --

let timer = null;
return function (e) {
clearTimeout(timer);
timer = setTimeout(() => func(e), 300);
};

// -- TODO: Your JavaScript code above this line --
}

document
.getElementById("input")
.addEventListener("input", debounced(onInputChange));

window.api = new XMLHttpRequest();

/*

[ Part II: Interactive Table ]

Your task for this part is to add event handlers to a table.

Update this codepen so that when you click on a row, it becomes highlighted
(i.e. its background color is changed).

If you click on a new row, it should remove the highlight from the old row and
highlight the new one.

If you press cmd or ctrl while clicking, you should be able to highlight
multiple rows.

Tip - Selecting elements:

const node = document.querySelector("#companies");

Tip - Using event listeners:

node.addEventListener("click", function (event) {
console.log("A " + event.type + " event was fired.");
});

*/

// -- TODO: Your JavaScript code for Part Ii below this line --

let prev = [];
document
.getElementById("companies")
.addEventListener("click", function (event) {
if (event.target.tagName === "TD") {
const parent = event.target.parentNode;
parent.style.backgroundColor = "#a8d1ff";
if (event.metaKey) {
prev.push(parent);
} else {
prev.forEach((node) => {
if (node !== parent) {
node.style.backgroundColor = "";
}
});
prev = [parent];
}
}
});

// -- TODO: Your JavaScript code for Part Ii above this line --

/**
* Part 1: What do you think will get printed out when we run the following snippet? Why?
*
* Note: Do *NOT* run this snippet until told to do so!
*/


function b() {
// -- TODO: Edit as appropriate below this line --
for (var i = 0; i < 10; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}
// -- TODO: Edit as appropriate above this line --
}

b();

// SugaryMammothCoderesource
// https://repl.it/repls/SugaryMammothCoderesource#main.js



// Q1
import "./styles.css";

/*

This coding session aims to test your competencies of the web front-end
fundamentals. It consists of 2 parts.

Part I: Working with DOM
Part II: XMLHTTPRequest/Fetch

* You have 50 minutes to finish both parts. It doesn't matter whether you work
on part I or II first. Feel free to start with the part that you're more
confident with.

* Please use native HTML, CSS and JS.

* You are encouraged to perform Google lookups for any HTML, CSS or JS specs
that you are not familiar with.

*/

/*

[ Part I: Interactive Table ]

Your task for this part is to add event handlers to a table.

Update this codepen so that when you click on a row, it becomes highlighted
(i.e. its background color is changed).

If you click on a new row, it should remove the highlight from the old row and
highlight the new one.

If you press cmd or ctrl while clicking, you should be able to highlight
multiple rows.

Tip - Selecting elements:

const node = document.querySelector("#companies");

Tip - Using event listeners:

node.addEventListener("click", function (event) {
console.log("A " + event.type + " event was fired.");
});

*/

// -- TODO: Your JavaScript code for Part I below this line --



// -- TODO: Your JavaScript code for Part I above this line --

/*

[ PART II: Searchbar ]

Your task for this part is to implement a searchbar.

Add JavaScript codes such that whenever the user types into the input, the
search results appear in the table below.

It would be preferred if you did not use libraries such as React and jQuery.

Here's the search API for retrieving a list of companies:
"https://autocomplete.clearbit.com/v1/companies/suggest?query="

Copy and paste it into your URL browser (and include a query string).
For example, you can try something like:
"https://autocomplete.clearbit.com/v1/companies/suggest?query=abc"

*/

// -- TODO: Your JavaScript code for Part II below this line --



// -- TODO: Your JavaScript code for Part II above this line --

// SOL 1
import "./styles.css";

/*

This coding session aims to test your competencies of the web front-end
fundamentals. It consists of 2 parts.

Part I: Optimising API calls
Part II: Working with DOM

* You have 50 minutes to finish both parts.

* Please use native HTML, CSS and JS.

* You are encouraged to perform Google lookups for any HTML, CSS or JS specs
that you are not familiar with.

*/

/*

[ PArt I: Searchbar ]

Your task for this part is to improve the API calls of the searchbar.

Please trace the code first, and then complete the implementations for
1. the Cache class
2. the debouncedInputChange function

*/

class Cache {
/*
Please implement the following 2 methods:
* set(key, value) which stores the cache with the given key and value
* get(key) which returns the cached value of the specified key

Aside from the required methods above,
feel free to add constructors or more methods as you see fit.
*/
// -- TODO: Your JavaScript code below this line --
// -- TODO: Your JavaScript code above this line --
}

const myCache = new Cache();

function clearTable() {
const tbody = document.querySelector("#companies > tbody");

// fastest way to clear html, better than innerHTML = ""
while (tbody.lastChild) {
tbody.removeChild(tbody.lastChild);
}
}

function callAPI(API) {
return new Promise(function (resolve, reject) {
window.api.abort();

window.api.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
const response = JSON.parse(this.responseText);
resolve(response);
}
};

window.api.open("GET", API, true);
window.api.send();
});
}

function updateTable(items) {
clearTable();

const tbody = document.querySelector("#companies > tbody");
items.forEach((item) => {
const listItem = document.createElement("tr");
const company = document.createElement("td");
const domain = document.createElement("td");
const logo = document.createElement("td");
const img = document.createElement("img");

company.innerHTML = item.name;

domain.innerHTML = item.domain;

img.src = item.logo;
img.height = 42;
img.width = 42;
logo.appendChild(img);

listItem.appendChild(company);
listItem.appendChild(domain);
listItem.appendChild(logo);

tbody.appendChild(listItem);
});
}

function onInputChange(e) {
const { value } = e.target;

if (value.length === 0) {
clearTable();
} else if (value.length > 0) {
const cachedItems = myCache.get(value);
if (cachedItems) {
console.debug(`Cache hit: ${value}`);
updateTable(cachedItems);
} else {
console.debug(`Cache miss: ${value}`);
callAPI(
"https://autocomplete.clearbit.com/v1/companies/suggest?query=" + value
).then((items) => {
myCache.set(value, items);
updateTable(items);
});
}
}
}

function debounced(func) {
/*
debounced(func) return a function that, as long as it continues to be
invoked, it will not trigger `func`. Call `func` only after it stops
being called for 300ms.
*/
// -- TODO: Your JavaScript code below this line --
// -- TODO: Your JavaScript code above this line --
}

document
.getElementById("input")
.addEventListener("input", debounced(onInputChange));

window.api = new XMLHttpRequest();

/*

[ Part II: Interactive Table ]

Your task for this part is to add event handlers to a table.

Update this codepen so that when you click on a row, it becomes highlighted
(i.e. its background color is changed).

If you click on a new row, it should remove the highlight from the old row and
highlight the new one.

If you press cmd or ctrl while clicking, you should be able to highlight
multiple rows.

Tip - Selecting elements:

const node = document.querySelector("#companies");

Tip - Using event listeners:

node.addEventListener("click", function (event) {
console.log("A " + event.type + " event was fired.");
});

*/

// -- TODO: Your JavaScript code for Part II below this line --

document
.getElementById("companies")
.addEventListener("click", function (event) {
// -- TODO: Your JavaScript code --
});


// Q2

/**
* Given a collection of intervals, merge all overlapping intervals.
* Intervals are not guaranteed to be sorted in any order.
*
* Input: [[3, 5], [1, 3], [7, 9]]
* Output: [[1, 5], [7, 9]]
* Explanation:
* [1, 3] and [3, 5] overlap to give [1, 5].
*
* Input: [[7, 10], [1, 5], [12, 13], [2, 6], [7, 11]]
* Output: [[[1, 6], [7, 11], [12, 13]]
* Explanation:
* [1, 5] and [2, 6] overlap to give [1, 6].
* [7, 10] and [7, 11] overlap to give [7, 11].
*/

function mergeIntervals(intervals) {
// TODO: Your code here
}

// -------

import "./styles.css";

/*

This coding session aims to test your competencies of the web front-end
fundamentals. It consists of 2 parts.

Part I: Optimising API calls
Part II: Working with DOM

* You have 50 minutes to finish both parts.

* Please use native HTML, CSS and JS.

* You are encouraged to perform Google lookups for any HTML, CSS or JS specs
that you are not familiar with.

*/

/*

[ Part I: Searchbar ]

Your task for this part is to improve the API calls of the searchbar.

Please trace the code first, and then complete the implementations for
1. the Cache class
2. the debouncedInputChange function

*/

class Cache {
/*
Please implement the following 2 methods:
* set(key, value) which stores the cache with the given key and value
* get(key) which returns the cached value of the specified key

Aside from the required methods above,
feel free to add constructors or more methods as you see fit.
*/

// -- TODO: Your JavaScript code below this line --

constructor() {
this.cacheMap = {};
}

set(key, value) {
this.cacheMap[key] = value;
}

get(key) {
return this.cacheMap[key];
}

// -- TODO: Your JavaScript code above this line --
}

const myCache = new Cache();

function clearTable() {
const tbody = document.querySelector("#companies > tbody");

// fastest way to clear html, better than innerHTML = ""
while (tbody.lastChild) {
tbody.removeChild(tbody.lastChild);
}
}

function callAPI(API) {
return new Promise(function (resolve, reject) {
window.api.abort();

window.api.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
const response = JSON.parse(this.responseText);
resolve(response);
}
};

window.api.open("GET", API, true);
window.api.send();
});
}

function updateTable(items) {
clearTable();

const tbody = document.querySelector("#companies > tbody");
items.forEach((item) => {
const listItem = document.createElement("tr");
const company = document.createElement("td");
const domain = document.createElement("td");
const logo = document.createElement("td");
const img = document.createElement("img");

company.innerHTML = item.name;

domain.innerHTML = item.domain;

img.src = item.logo;
img.height = 42;
img.width = 42;
logo.appendChild(img);

listItem.appendChild(company);
listItem.appendChild(domain);
listItem.appendChild(logo);

tbody.appendChild(listItem);
});
}

function onInputChange(e) {
const { value } = e.target;

if (value.length === 0) {
clearTable();
} else if (value.length > 0) {
const cachedItems = myCache.get(value);
if (cachedItems) {
console.debug(`Cache hit: ${value}`);
updateTable(cachedItems);
} else {
console.debug(`Cache miss: ${value}`);
callAPI(
"https://autocomplete.clearbit.com/v1/companies/suggest?query=" + value
).then((items) => {
myCache.set(value, items);
updateTable(items);
});
}
}
}

function debounced(func) {
// debounced(func) return a function that, as long as it continues to be
// invoked, it will not trigger `func`. Call `func` only after it stops
// being called for 300ms.

// -- TODO: Your JavaScript code below this line --

let timer = null;
return function (e) {
clearTimeout(timer);
timer = setTimeout(() => func(e), 300);
};

// -- TODO: Your JavaScript code above this line --
}

document
.getElementById("input")
.addEventListener("input", debounced(onInputChange));

window.api = new XMLHttpRequest();

/*

[ Part II: Interactive Table ]

Your task for this part is to add event handlers to a table.

Update this codepen so that when you click on a row, it becomes highlighted
(i.e. its background color is changed).

If you click on a new row, it should remove the highlight from the old row and
highlight the new one.

If you press cmd or ctrl while clicking, you should be able to highlight
multiple rows.

Tip - Selecting elements:

const node = document.querySelector("#companies");

Tip - Using event listeners:

node.addEventListener("click", function (event) {
console.log("A " + event.type + " event was fired.");
});

*/

// -- TODO: Your JavaScript code for Part II below this line --

let prev = [];
document
.getElementById("companies")
.addEventListener("click", function (event) {
if (event.target.tagName === "TD") {
const parent = event.target.parentNode;
parent.style.backgroundColor = "#a8d1ff";
if (event.metaKey) {
prev.push(parent);
} else {
prev.forEach((node) => {
if (node !== parent) {
node.style.backgroundColor = "";
}
});
prev = [parent];
}
}
});

// -- TODO: Your JavaScript code for Part II above this line --