Skip to content

Instantly share code, notes, and snippets.

@JackyChiu
Last active July 17, 2018 00:14
Show Gist options
  • Save JackyChiu/05d9516f1824073d9380d4cc6357e444 to your computer and use it in GitHub Desktop.
Save JackyChiu/05d9516f1824073d9380d4cc6357e444 to your computer and use it in GitHub Desktop.
// Requirements
//
//
// Read all orders from the paginated API.
// Any order without cookies can be fulfilled.
// Prioritize fulfilling orders with the highest amount of cookies.
// If orders have the same amount of cookies, prioritize the order with the lowest ID.
// If an order has an amount of cookies bigger than the remaining cookies, skip the order.
//
//
//
// What to submit:
//
// Output (in JSON)
//
// {
// "remaining_cookies": "Amount of cookies remaining after trying to fulfill orders",
// "unfulfilled_orders": [ "IDs of the order that couldn't be fulfilled in ascending order" ]
// }
//
//
//
// *Example Answer Output
//
// {
// "remaining_cookies": 0,
// "unfulfilled_orders": [ 3, 5 ]
// }
const rp = require('request-promise')
const BASE_URI = 'https://backend-challenge-fall-2017.herokuapp.com/orders.json'
const options = {
uri: BASE_URI,
qs: {},
json: true,
}
let remainingCookies
// Makes a get request to the base uri and
// adds a query string for pagnation
function getPage(page, index = 0) {
const pageOptions = Object.assign(
options,
{ qs: { page: index + 1 } }
)
return rp(pageOptions)
}
// Returns a new order object that contains
// cookie order details and id
function cookiesOnly(order) {
return Object.assign(
order.products.find(product => product.title === 'Cookie') || {},
{ id: order.id }
)
}
// Sorts orders in decending order based
// off amounts, then id
function decendingSort(a, b) {
if (b.amount === a.amount) return a.id - b.id
return b.amount - a.amount
}
// Gets the results of pages
const pages = getPage()
.then((res) => {
const { total } = res.pagination
const pages = []
pages.length = total
remainingCookies = res.available_cookies
return pages
})
.map(getPage)
// Maps out all the orders
const orders = pages
.map(page => page.orders)
.reduce((prev = [], current) => prev.concat(current), [])
// Finds only the cookie orders
const cookieOrders = orders
.filter(order => !order.fulfilled)
.map(cookiesOnly)
.filter(order => order.amount)
// Finds the orders that cannot be furfilled
const unfulfilledOrders = cookieOrders
.then(order => order.sort(decendingSort))
.reduce((orders, order) => {
if (order.amount > remainingCookies) return orders.concat(order)
remainingCookies -= order.amount
return orders
}, [])
// Creates the respones for unfurfilled orders
unfulfilledOrders
.map(order => order.id)
.then((ids) => {
const result = {
remaining_cookies: remainingCookies,
unfulfilled_orders: ids,
}
console.log(JSON.stringify(result, null, 2))
})
// RESULTS
// {
// "remaining_cookies": 0,
// "unfulfilled_orders": [
// 8,
// 7,
// 11
// ]
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment