Skip to content

Commit

Permalink
add solution
Browse files Browse the repository at this point in the history
  • Loading branch information
yaroslav1177 committed Oct 23, 2024
1 parent b9eb4f1 commit d20e460
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 16 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/test.yml-template
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Test

on:
pull_request:
branches: [ master ]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
18 changes: 14 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"license": "GPL-3.0",
"devDependencies": {
"@mate-academy/eslint-config": "latest",
"@mate-academy/scripts": "^1.8.6",
"@mate-academy/scripts": "^1.9.12",
"eslint": "^8.57.0",
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-node": "^11.1.0",
Expand All @@ -27,5 +27,8 @@
},
"mateAcademy": {
"projectType": "javascript"
},
"dependencies": {
"readline": "^1.3.0"
}
}
38 changes: 37 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,39 @@
'use strict';

// Write your code here
'use strict';

const readline = require('readline');
const { generateRandomNumber } = require('./generateRandomNumber');
const { checkIsValidUserInput } = require('./checkIsValidUserInput');
const { getBullsAndCows } = require('./getBullsAndCows');

const terminal = readline.createInterface({
input: process.stdin,
output: process.stdout,
});

function playGame() {
const secretNumber = generateRandomNumber().toString();

function askGuess() {
terminal.question('Enter your number: ', (userInput) => {
if (!checkIsValidUserInput(userInput)) {
return askGuess();
}

const { bulls } = getBullsAndCows(secretNumber, userInput);

if (bulls === 4) {
terminal.close();
} else {
askGuess();
}
});
}

askGuess();
}

module.exports = {
playGame,
};
22 changes: 19 additions & 3 deletions src/modules/checkIsValidUserInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,27 @@
* Valid user input is a 4-digit number that does not start with 0
* and does not contain any duplicate digits.
*
* @param {string} userInput - The user input
* @return {boolean} - True if the user input is valid, false otherwise
* @param {string} userInput
* @return {boolean}
*/
function checkIsValidUserInput(userInput) {
/* Write your code here */
if (userInput.length !== 4) {
return false;
}

const numbers = userInput.split('');

if (!numbers.every((num) => /^\d$/.test(num))) {
return false;
}

if (userInput[0] === '0') {
return false;
}

const uniqueNumber = new Set(numbers);

return uniqueNumber.size === 4;
}

module.exports = {
Expand Down
16 changes: 14 additions & 2 deletions src/modules/generateRandomNumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,22 @@
* Generate a random 4-digit number that does not start with 0
* and does not contain any duplicate digits.
*
* @return {number} A random 4-digit number
* @return {number}
*/
function generateRandomNumber() {
/* Write your code here */
const numbers = [];

numbers.push(Math.floor(Math.random() * 9) + 1);

while (numbers.length < 4) {
const randomNumber = Math.floor(Math.random() * 10);

if (!numbers.includes(randomNumber)) {
numbers.push(randomNumber);
}
}

return Number(numbers.join(''));
}

module.exports = {
Expand Down
36 changes: 31 additions & 5 deletions src/modules/getBullsAndCows.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,39 @@
* Assume that the user input and the number to guess
* are always 4-digit numbers.
*
* @param {number} userInput - The user input
* @param {number} numberToGuess - The number to guess
* @return {object} An object containing the number of bulls and cows.
* Example: { bulls: 1, cows: 2 }
* @param {string} userInput
* @param {string} numberToGuess
* @return {object}
*/
function getBullsAndCows(userInput, numberToGuess) {
/* Write your code here */
const fixedUserInput = String(userInput);
const fixedNumberToGuess = String(numberToGuess);

let bulls = 0;
let cows = 0;

const userNumbers = [];
const guessNumbers = [];

for (let i = 0; i < 4; i++) {
if (fixedUserInput[i] === fixedNumberToGuess[i]) {
bulls++;
} else {
userNumbers.push(fixedUserInput[i]);
guessNumbers.push(fixedNumberToGuess[i]);
}
}

guessNumbers.forEach((number) => {
const cowIndex = userNumbers.indexOf(number);

if (cowIndex !== -1) {
cows++;
userNumbers.splice(cowIndex, 1);
}
});

return { bulls, cows };
}

module.exports = {
Expand Down

0 comments on commit d20e460

Please sign in to comment.