Skip to content

Solved snake-ladder/split-wise #157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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
17 changes: 17 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"name": "machine-coding-feedback",
"version": "1.0.0",
"description": "Get your [practice machine coding](https://workat.tech/machine-coding/practice) solutions reviewed by [Gaurav Chandak](https://www.linkedin.com/in/gcnit/) and get feedback before your machine coding round.",
"main": "index.js",
"type": "commonjs",
"directories": {
"doc": "docs"
},
"scripts": {
"snake-ladder": "node snake-ladder/src/main.js",
"split-wise": "node split-wise/src/main.js"
},
"keywords": [],
"author": "",
"license": "ISC"
}
22 changes: 22 additions & 0 deletions snake-ladder/resources/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
9
62 5
33 6
49 9
88 16
41 20
56 53
98 64
93 73
95 75
8
2 37
27 46
10 32
51 68
61 79
65 84
71 91
81 100
2
Gaurav
Sagar
3 changes: 3 additions & 0 deletions snake-ladder/src/consts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
endPoint: 100,
}
17 changes: 17 additions & 0 deletions snake-ladder/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const fs = require('fs');
const path = require('path');
const { readInput, isGameOver, getWinningPos, announceWinner, nextMove } = require('./utils/index.js');

const inputFilePath = path.resolve(__dirname, '../resources/input.txt');
const input = fs.readFileSync(inputFilePath, { encoding: 'utf-8'});
const { snakes, ladders, players: { names, positions } } = readInput(input);
const numPlayers = positions.length;

let turn = 0;
while(!isGameOver(positions)) {
nextMove(turn, positions, names, snakes, ladders);
turn = (turn+1)%numPlayers
}

const winInd = getWinningPos(positions);
announceWinner(names[winInd]);
3 changes: 3 additions & 0 deletions snake-ladder/src/utils/announce-winner.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.default = (name) => {
console.log(`${name} wins the game`);
}
9 changes: 9 additions & 0 deletions snake-ladder/src/utils/get-next-pos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const { endPoint } = require('../consts.js');

exports.default = (currPosition, snakes, ladders, diceNum) => {
let nextPosition = currPosition + diceNum > endPoint ? currPosition : currPosition + diceNum;
while(snakes[nextPosition] || ladders[nextPosition]) {
nextPosition = snakes[nextPosition] || ladders[nextPosition];
}
return nextPosition;
}
3 changes: 3 additions & 0 deletions snake-ladder/src/utils/get-winning-pos.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const { endPoint } = require('../consts.js');

exports.default = (positions) => positions.findIndex(position => position === endPoint);
10 changes: 10 additions & 0 deletions snake-ladder/src/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = {
readInput: require('./read-input.js').default,
isGameOver: require('./is-game-over.js').default,
rollDice: require('./roll-dice.js').default,
getWinningPos: require('./get-winning-pos.js').default,
getNextPosition: require('./get-next-pos.js').default,
announceWinner: require('./announce-winner.js').default,
logMove: require('./log-move.js').default,
nextMove: require('./next-move.js').default
}
3 changes: 3 additions & 0 deletions snake-ladder/src/utils/is-game-over.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const { endPoint } = require('../consts.js');

exports.default = (positions) => positions.some(position => position === endPoint);
3 changes: 3 additions & 0 deletions snake-ladder/src/utils/log-move.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.default = (name, diceValue, currPosition, nextPosition) => {
console.log(`${name} rolled a ${diceValue} and moved from ${currPosition} to ${nextPosition}`);
}
12 changes: 12 additions & 0 deletions snake-ladder/src/utils/next-move.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const getNextPosition = require('./get-next-pos.js').default;
const rollDice = require('./roll-dice.js').default;
const logMove = require('./log-move.js').default;

exports.default = (turn, positions, names, snakes, ladders) => {
const currPosition = positions[turn];
const name = names[turn];
const diceValue = rollDice();
const nextPosition = getNextPosition(currPosition, snakes, ladders, diceValue);
logMove(name, diceValue, currPosition, nextPosition);
positions[turn] = nextPosition;
}
26 changes: 26 additions & 0 deletions snake-ladder/src/utils/read-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
exports.default = (input) => {
const inputToArr = input.split('\n');
const numSnake = Number(inputToArr[0]);
const numLadder = Number(inputToArr[numSnake+1]);
const snakes = {};
const ladders = {};
const players = { names: [], positions: [] };

for(let i=1;i<=numSnake;i++) {
const snake = inputToArr[i].split(' ');
snakes[Number(snake[0])] = Number(snake[1]);
}

for(let i=numSnake+2;i<numSnake+numLadder+2;i++) {
const ladder = inputToArr[i].split(' ');
ladders[Number(ladder[0])] = Number(ladder[1]);
}

for(let i=numSnake+numLadder+3;i<inputToArr.length;i++) {
const player = inputToArr[i];
players.names.push(player);
players.positions.push(0);
}

return { snakes, ladders, players };
}
4 changes: 4 additions & 0 deletions snake-ladder/src/utils/roll-dice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
exports.default = () => {
const nextNum = Math.ceil((1+Math.random()*10))%7;
return nextNum === 0 ? 1 : nextNum;
}
10 changes: 10 additions & 0 deletions split-wise/resources/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
SHOW
SHOW u1
EXPENSE u1 1000 4 u1 u2 u3 u4 EQUAL
SHOW u4
SHOW u1
EXPENSE u1 1250 2 u2 u3 EXACT 370 880
SHOW
EXPENSE u4 1200 4 u1 u2 u3 u4 PERCENT 40 20 20 20
SHOW u1
SHOW
48 changes: 48 additions & 0 deletions split-wise/src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
const fs = require('fs');
const path = require('path');
const { readInput, initializeExpense, showExpense, showExpenseByUser, twoPlaces } = require('./utils/index.js');

const inputFilePath = path.resolve(__dirname, '../resources/input.txt');
const input = fs.readFileSync(inputFilePath, { encoding: 'utf-8' });
const parsedInput = readInput(input);
const users = ['u1', 'u2', 'u3', 'u4'];
const expense = initializeExpense(users);

for(let i=0;i<parsedInput.length;i++) {
const { command, user } = parsedInput[i];
if(command === 'SHOW') {
if(user) showExpenseByUser(expense, user);
else showExpense(expense, users);
} else {
const { totalAmount, otherUsersCount, otherUsers, method, shares } = parsedInput[i];
if(method === 'PERCENT') {
if(shares.reduce((acc, num) => acc+num) != 100) throw new Error('Count of all shares do not evaluate to 100 percent for input:', parsedInput[i]);
let amount = 0;
for(let j=1;j<shares.length;j++) {
shares[j] = twoPlaces(((shares[j]/100)*totalAmount));
if(otherUsers[j] != user) {
expense[user][otherUsers[j]] += shares[j];
expense[otherUsers[j]][user] -= shares[j];
}
amount+=shares[j];
}
shares[0] = totalAmount-amount;
if(otherUsers[0] != user) {
expense[user][otherUsers[0]] += shares[0];
expense[otherUsers[0]][user] -= shares[0];
}
} else if(method === 'EXACT') {
if(shares.reduce((acc, num) => acc+num) != totalAmount) throw new Error('Count of all shares do not evaluate to total amount for input:', parsedInput[i]);
for(let j=0;j<shares.length;j++) {
expense[user][otherUsers[j]] += shares[j];
expense[otherUsers[j]][user] -= shares[j];
}
} else {
const share = twoPlaces(totalAmount/(otherUsersCount));
for(let j=0;j<otherUsers.length;j++) {
expense[user][otherUsers[j]] += share;
expense[otherUsers[j]][user] -= share;
}
}
}
}
7 changes: 7 additions & 0 deletions split-wise/src/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
readInput: require('./read-input.js').default,
twoPlaces: require('./two-places.js').default,
initializeExpense: require('./initialize-expense.js').default,
showExpense: require('./show-expense.js').default,
showExpenseByUser: require('./show-expense-user.js').default
}
11 changes: 11 additions & 0 deletions split-wise/src/utils/initialize-expense.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
exports.default = (users) => {
return users.reduce((acc, user) => {
acc[user] = users.reduce((acc1, user1) => {
if(user1 != user) {
acc1[user1] = 0;
}
return acc1
}, {});
return acc;
}, {})
}
28 changes: 28 additions & 0 deletions split-wise/src/utils/read-input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const twoPlaces = require('./two-places').default;

exports.default = (input) => {
const inputArr = input.split('\n');
for(let i=0;i<inputArr.length;i++) {
const currInput = inputArr[i].split(' ');
const parsedInput = {}
switch (currInput[0]) {
case 'EXPENSE':
parsedInput.command = currInput[0];
parsedInput.user = currInput[1];
parsedInput.totalAmount = twoPlaces(Number(currInput[2]));
parsedInput.otherUsersCount = Number(currInput[3]);
parsedInput.otherUsers = currInput.slice(4, 4+parsedInput.otherUsersCount);
parsedInput.method = currInput[4+parsedInput.otherUsersCount];
if(parsedInput.method === 'PERCENT' || parsedInput.method === 'EXACT') {
parsedInput.shares = currInput.slice([4+parsedInput.otherUsersCount+1]).map(num => twoPlaces(Number(num)));
}
case 'SHOW':
parsedInput.command = currInput[0];
if(currInput[1]) {
parsedInput.user = currInput[1];
}
}
inputArr[i] = parsedInput
}
return inputArr;
}
14 changes: 14 additions & 0 deletions split-wise/src/utils/show-expense-user.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
exports.default = (expense, user) => {
let didShow = false;
Object.keys(expense[user]).map((user1) => {
if(expense[user][user1] > 0) {
console.log(`${user1} owes ${user}: ${expense[user][user1]}`);
} else if(expense[user][user1]<0) {
console.log(`${user} owes ${user1}: ${Math.abs(expense[user][user1])}`);
}
didShow = didShow || expense[user][user1];
})
if(!didShow) {
console.log('No balances')
}
}
15 changes: 15 additions & 0 deletions split-wise/src/utils/show-expense.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
exports.default = (expense, users) => {
let didShow = false;
users.forEach((user) => {
const userExpense = expense[user];
Object.keys(userExpense).map(user1 => {
if(userExpense[user1] > 0) {
didShow = true;
console.log(`${user1} owes ${user}: ${userExpense[user1]}`);
}
})
})
if(!didShow) {
console.log('No balances')
}
}
3 changes: 3 additions & 0 deletions split-wise/src/utils/two-places.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
exports.default = (num) => {
return parseFloat(num.toFixed(2));
}