This commit is contained in:
Egor Deev 2025-11-23 14:00:44 +03:00 committed by GitHub
parent b90fea83f5
commit 079f6f1047
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 831 additions and 0 deletions

View file

@ -0,0 +1,40 @@
function cesar(str, shift, action) {
const alphabet = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
const alphabetUpper = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
let result = '';
for (let i = 0; i < str.length; i++) {
let char = str[i];
let isUpper = false;
let index = -1;
if (alphabetUpper.indexOf(char) !== -1) {
isUpper = true;
index = alphabetUpper.indexOf(char);
} else if (alphabet.indexOf(char) !== -1) {
index = alphabet.indexOf(char);
}
if (index !== -1) {
let newIndex;
if (action === 'encode') {
newIndex = (index + shift) % alphabet.length;
} else {
newIndex = (index - shift + alphabet.length) % alphabet.length;
}
if (isUpper) {
result += alphabetUpper[newIndex];
} else {
result += alphabet[newIndex];
}
} else {
result += char;
}
}
return result;
}
// Расшифровка сообщения "эзтыхз фзъзъз" с различными сдвигами:
// При shift = 8: "хакуна матата"

View file

@ -0,0 +1,15 @@
function fibb(n) {
if (n === 0) return 0;
if (n === 1) return 1;
let prev = 0;
let current = 1;
for (let i = 2; i <= n; i++) {
let next = prev + current;
prev = current;
current = next;
}
return current;
}

View file

@ -0,0 +1,8 @@
function gcd(a, b) {
while (b !== 0) {
let temp = b;
b = a % b;
a = temp;
}
return a;
}

View file

@ -0,0 +1,12 @@
function getSortedArray(array, key) {
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1 - i; j++) {
if (array[j][key] > array[j + 1][key]) {
let temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}

View file

@ -0,0 +1,11 @@
function minDigit(x) {
let min = 9;
while (x > 0) {
let digit = x % 10;
if (digit < min) {
min = digit;
}
x = Math.floor(x / 10);
}
return min;
}

View file

@ -0,0 +1,18 @@
function pluralizeRecords(n) {
let recordForm = "записей";
let wasForm = "было найдено";
let lastDigit = n % 10;
let lastTwoDigits = n % 100;
if (lastTwoDigits >= 11 && lastTwoDigits <= 14) {
//pass
} else if (lastDigit === 1) {
recordForm = "запись";
wasForm = "была найдена";
} else if (lastDigit >= 2 && lastDigit <= 4) {
recordForm = "записи";
}
return `В результате выполнения запроса ${wasForm} ${n} ${recordForm}`;
}

View file

@ -0,0 +1,7 @@
function pow(x, n) {
let result = 1;
for (let i = 0; i < n; i++) {
result *= x;
}
return result;
}

234
tasks/math-funcs/index.html Normal file
View file

@ -0,0 +1,234 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="https://deev.space/media/favicon.ico" type="image/x-icon">
<title>Тестирование функций JavaScript</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Тестирование функций JavaScript</h1>
<!-- Возведение в степень -->
<div class="function-block">
<h2>1. Возведение в степень | Exponentiation</h2>
<p class="description">
Функция <strong>pow(x,n)</strong> возвращает <strong>x</strong> в степени <strong>n</strong>. Иначе говоря, умножает <strong>x</strong> на себя <strong>n</strong> раз и возвращает результат. Функция обязана поддерживать только натуральные значения <strong>n</strong>.
</p>
<pre class="code">function pow(x, n) {
let result = 1;
for (let i = 0; i < n; i++) {
result *= x;
}
return result;
}</pre>
<div class="test-section">
<input type="number" id="pow-x" placeholder="x">
<input type="number" id="pow-n" placeholder="n">
<button onclick="testPow()">Вычислить</button>
<div class="result" id="pow-result"></div>
</div>
</div>
<!-- НОД -->
<div class="function-block">
<h2>2. Нахождение НОД | Greatest common divisor (GCD)</h2>
<p class="description">
Функция <strong>gcd(a,b)</strong> возвращает <strong>x</strong> - наибольший общий делитель двух неотрицательных чисел <strong>a</strong> и <strong>b</strong>.
</p>
<pre class="code">function gcd(a, b) {
while (b !== 0) {
let temp = b;
b = a % b;
a = temp;
}
return a;
}</pre>
<div class="test-section">
<input type="number" id="gcd-a" placeholder="a">
<input type="number" id="gcd-b" placeholder="b">
<button onclick="testGcd()">Вычислить</button>
<div class="result" id="gcd-result"></div>
</div>
</div>
<!-- Наименьшая цифра -->
<div class="function-block">
<h2>3. Наименьшая цифра | Minimum digit</h2>
<p class="description">
Функция <strong>minDigit(x)</strong> возвращает наименьшую цифру целого неотрицательного числа <strong>x</strong>.
</p>
<pre class="code">function minDigit(x) {
let min = 9;
while (x > 0) {
let digit = x % 10;
if (digit < min) {
min = digit;
}
x = Math.floor(x / 10);
}
return min;
}</pre>
<div class="test-section">
<input type="number" id="minDigit-x" placeholder="x">
<button onclick="testMinDigit()">Вычислить</button>
<div class="result" id="minDigit-result"></div>
</div>
</div>
<!-- Pluralization -->
<div class="function-block">
<h2>4. Pluralization</h2>
<p class="description">
Функция <strong>pluralizeRecords(n)</strong> для любого целого неотрицательного значения <strong>n</strong> вернёт строку "В результате выполнения запроса было найдено <strong>n</strong> записей", в которой для каждого слова будет образована правильная форма множественного числа, в зависимости от конкретного значения <strong>n</strong>.
</p>
<pre class="code">function pluralizeRecords(n) {
let recordForm = "записей";
let wasForm = "было найдено";
let lastDigit = n % 10;
let lastTwoDigits = n % 100;
if (lastTwoDigits >= 11 && lastTwoDigits <= 14) {
//pass
} else if (lastDigit === 1) {
recordForm = "запись";
wasForm = "была найдена";
} else if (lastDigit >= 2 && lastDigit <= 4) {
recordForm = "записи";
}
return `В результате выполнения запроса ${wasForm} ${n} ${recordForm}`;
}</pre>
<div class="test-section">
<input type="number" id="pluralize-n" placeholder="n">
<button onclick="testPluralize()">Проверить</button>
<div class="result" id="pluralize-result"></div>
</div>
</div>
<!-- Числа Фибоначчи -->
<div class="function-block">
<h2>5. Числа Фибоначчи | Fibonacci numbers</h2>
<p class="description">
Функция <strong>fibb(n)</strong> для любого целого неотрицательного числа <strong>n <= 1000</strong> вернёт n-ое число из последовательности Фибоначчи.
</p>
<pre class="code">function fibb(n) {
if (n === 0) return 0;
if (n === 1) return 1;
let prev = 0;
let current = 1;
for (let i = 2; i <= n; i++) {
let next = prev + current;
prev = current;
current = next;
}
return current;
}</pre>
<div class="test-section">
<input type="number" id="fibb-n" placeholder="n">
<button onclick="testFibb()">Вычислить</button>
<div class="result" id="fibb-result"></div>
</div>
</div>
<!-- Сортировка объектов -->
<div class="function-block">
<h2>6. Сортировка объектов | Sorting objects</h2>
<p class="description">
Функция <strong>getSortedArray(array, key)</strong> сортирует массив объектов. У функции два параметра: <strong>array</strong> - массив объектов, оторый нужно отсортировать, и <strong>key</strong> - ключ, по значению которого нужно произвести сортировку. Порядок сортировки - по возрастанию.
</p>
<pre class="code">function getSortedArray(array, key) {
for (let i = 0; i < array.length; i++) {
for (let j = 0; j < array.length - 1 - i; j++) {
if (array[j][key] > array[j + 1][key]) {
let temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}</pre>
<div class="test-section">
<textarea id="sort-array" placeholder='[{"name":"Иван","age":25},{"name":"Мария","age":20}]' rows="3"></textarea>
<input type="text" id="sort-key" placeholder="key (например: age)">
<button onclick="testSort()">Сортировать</button>
<div class="result" id="sort-result"></div>
</div>
</div>
<!-- Шифр Цезаря -->
<div class="function-block">
<h2>7. Шифр Цезаря | Caesar's cipher</h2>
<p class="description">
Функция <strong>cesar(str, shift, action)</strong> производит шифрование и дешифровку строки <strong>str</strong> с использованием шифра Цезаря. В качестве алфавита используется русский алфавит. Параметр <strong>shift</strong> отвечает за сдвиг алфавита. Если <strong>action == 'encode'</strong>, функция производит шифрование, а если <strong>action == 'decode'</strong> - дешифровку.
</p>
<pre class="code">function cesar(str, shift, action) {
const alphabet = 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя';
const alphabetUpper = 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ';
let result = '';
for (let i = 0; i < str.length; i++) {
let char = str[i];
let isUpper = false;
let index = -1;
if (alphabetUpper.indexOf(char) !== -1) {
isUpper = true;
index = alphabetUpper.indexOf(char);
} else if (alphabet.indexOf(char) !== -1) {
index = alphabet.indexOf(char);
}
if (index !== -1) {
let newIndex;
if (action === 'encode') {
newIndex = (index + shift) % alphabet.length;
} else {
newIndex = (index - shift + alphabet.length) % alphabet.length;
}
if (isUpper) {
result += alphabetUpper[newIndex];
} else {
result += alphabet[newIndex];
}
} else {
result += char;
}
}
return result;
}
// Расшифровка: "эзтыхз фзъзъз" со сдвигом 8 = "хакуна матата"</pre>
<div class="test-section">
<input type="text" id="cesar-str" placeholder="Строка">
<input type="number" id="cesar-shift" placeholder="Сдвиг">
<select id="cesar-action">
<option value="encode">Зашифровать</option>
<option value="decode">Расшифровать</option>
</select>
<button onclick="testCesar()">Выполнить</button>
<div class="result" id="cesar-result"></div>
</div>
</div>
</div>
<script src="funcs/pow.js"></script>
<script src="funcs/gcd.js"></script>
<script src="funcs/minDigit.js"></script>
<script src="funcs/pluralizeRecords.js"></script>
<script src="funcs/fibb.js"></script>
<script src="funcs/getSortedArray.js"></script>
<script src="funcs/cesar.js"></script>
<script src="script.js"></script>
</body>
</html>

View file

@ -0,0 +1,51 @@
function testPow() {
let x = parseFloat(document.getElementById('pow-x').value);
let n = parseInt(document.getElementById('pow-n').value);
let result = pow(x, n);
document.getElementById('pow-result').textContent = 'Результат: ' + result;
}
function testGcd() {
let a = parseInt(document.getElementById('gcd-a').value);
let b = parseInt(document.getElementById('gcd-b').value);
let result = gcd(a, b);
document.getElementById('gcd-result').textContent = 'Результат: ' + result;
}
function testMinDigit() {
let x = parseInt(document.getElementById('minDigit-x').value);
let result = minDigit(x);
document.getElementById('minDigit-result').textContent = 'Результат: ' + result;
}
function testPluralize() {
let n = parseInt(document.getElementById('pluralize-n').value);
let result = pluralizeRecords(n);
document.getElementById('pluralize-result').textContent = result;
}
function testFibb() {
let n = parseInt(document.getElementById('fibb-n').value);
let result = fibb(n);
document.getElementById('fibb-result').textContent = 'Результат: ' + result;
}
function testSort() {
try {
let arrayStr = document.getElementById('sort-array').value;
let key = document.getElementById('sort-key').value;
let array = JSON.parse(arrayStr);
let result = getSortedArray(array, key);
document.getElementById('sort-result').textContent = 'Результат: ' + JSON.stringify(result, null, 2);
} catch (e) {
document.getElementById('sort-result').textContent = 'Ошибка: ' + e.message;
}
}
function testCesar() {
let str = document.getElementById('cesar-str').value;
let shift = parseInt(document.getElementById('cesar-shift').value);
let action = document.getElementById('cesar-action').value;
let result = cesar(str, shift, action);
document.getElementById('cesar-result').textContent = 'Результат: ' + result;
}

101
tasks/math-funcs/style.css Normal file
View file

@ -0,0 +1,101 @@
body {
font-family: Arial, sans-serif;
background-color: #f5f5f5;
margin: 0;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
background: white;
padding: 30px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 40px;
}
.function-block {
margin-bottom: 40px;
padding-bottom: 30px;
border-bottom: 2px solid #e0e0e0;
}
.function-block:last-child {
border-bottom: none;
}
h2 {
color: #333;
margin-bottom: 15px;
}
.description {
color: #666;
line-height: 1.6;
margin-bottom: 15px;
}
.code {
background-color: #f8f8f8;
border: 1px solid #ddd;
border-radius: 4px;
padding: 15px;
overflow-x: auto;
font-family: 'Courier New', monospace;
font-size: 14px;
line-height: 1.5;
margin-bottom: 20px;
}
.test-section {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
input, select, textarea {
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 14px;
flex: 1;
min-width: 150px;
}
textarea {
width: 100%;
font-family: 'Courier New', monospace;
resize: vertical;
}
button {
background-color: #4CAF50;
color: white;
padding: 10px 25px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
}
button:hover {
background-color: #45a049;
}
.result {
width: 100%;
margin-top: 10px;
padding: 15px;
background-color: #f0f0f0;
border-radius: 4px;
min-height: 20px;
font-weight: bold;
color: #333;
}

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="https://deev.space/media/favicon.ico" type="image/x-icon">
<title>Math Game</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>Math Game</h1>
<div class="game-info">
<span>Уровень: <strong id="level">Начальный</strong></span>
<span>Время: <strong id="timer">5:00</strong></span>
</div>
<div class="game-stats">
<span>Правильно: <strong id="correct">0</strong></span>
<span>Неправильно: <strong id="wrong">0</strong></span>
<span>Осталось: <strong id="remaining">10</strong></span>
</div>
<div id="question-container">
<h2 id="question"></h2>
<input type="text" id="answer" placeholder="Введите ваш ответ">
<button id="submit" onclick="checkAnswer()">Отправить</button>
</div>
<div id="feedback"></div>
<div id="result-container" style="display: none;">
<h2 id="result-message"></h2>
<button onclick="restartGame()">Начать заново</button>
<button onclick="exitGame()">Выйти</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

195
tasks/math-game/script.js Normal file
View file

@ -0,0 +1,195 @@
let currentLevel = 1;
let correctAnswers = 0;
let wrongAnswers = 0;
let questionsOnLevel = 0;
let currentQuestion = null;
let usedQuestions = [];
let timerInterval = null;
let timeLeft = 300;
const levelNames = {
1: 'Начальный',
2: 'Средний',
3: 'Продвинутый'
};
function startTimer() {
if (timerInterval) {
clearInterval(timerInterval);
}
timeLeft = 300;
updateTimerDisplay();
timerInterval = setInterval(function() {
timeLeft--;
updateTimerDisplay();
if (timeLeft <= 0) {
clearInterval(timerInterval);
showResult('Время вышло! Вы не успели завершить уровень.');
}
}, 1000);
}
function updateTimerDisplay() {
let minutes = Math.floor(timeLeft / 60);
let seconds = timeLeft % 60;
let display = minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
document.getElementById('timer').textContent = display;
}
function generateQuestion() {
let question, answer;
let questionText;
do {
if (currentLevel === 1) {
let num1 = Math.floor(Math.random() * 20) + 1;
let num2 = Math.floor(Math.random() * 20) + 1;
let operators = ['+', '-', '*'];
let operator = operators[Math.floor(Math.random() * operators.length)];
questionText = num1 + ' ' + operator + ' ' + num2;
answer = eval(questionText);
} else if (currentLevel === 2) {
let num1 = Math.floor(Math.random() * 20) + 1;
let num2 = Math.floor(Math.random() * 20) + 1;
let operators = ['>', '<', '=='];
let operator = operators[Math.floor(Math.random() * operators.length)];
questionText = num1 + ' ' + operator + ' ' + num2;
answer = eval(questionText) ? 'true' : 'false';
} else {
let types = ['logical', 'binary'];
let type = types[Math.floor(Math.random() * types.length)];
if (type === 'logical') {
let bool1 = Math.random() > 0.5;
let bool2 = Math.random() > 0.5;
let operators = ['&&', '||'];
let operator = operators[Math.floor(Math.random() * operators.length)];
questionText = bool1 + ' ' + operator + ' ' + bool2;
answer = eval(questionText) ? 'true' : 'false';
} else {
let num = Math.floor(Math.random() * 16);
questionText = 'Двоичное представление числа ' + num;
answer = num.toString(2);
}
}
} while (usedQuestions.includes(questionText));
usedQuestions.push(questionText);
currentQuestion = { text: questionText, answer: String(answer) };
document.getElementById('question').textContent = questionText;
document.getElementById('answer').value = '';
document.getElementById('feedback').textContent = '';
document.getElementById('answer').focus();
}
function checkAnswer() {
let userAnswer = document.getElementById('answer').value.trim();
if (userAnswer === '') {
alert('Пожалуйста, введите ответ');
return;
}
if (userAnswer === currentQuestion.answer) {
correctAnswers++;
document.getElementById('feedback').textContent = 'Правильно!';
document.getElementById('feedback').style.color = '#4CAF50';
} else {
wrongAnswers++;
document.getElementById('feedback').textContent = 'Неправильно! Правильный ответ: ' + currentQuestion.answer;
document.getElementById('feedback').style.color = '#f44336';
}
questionsOnLevel++;
updateDisplay();
if (questionsOnLevel >= 10) {
clearInterval(timerInterval);
checkLevelProgress();
} else {
setTimeout(generateQuestion, 1500);
}
}
function updateDisplay() {
document.getElementById('correct').textContent = correctAnswers;
document.getElementById('wrong').textContent = wrongAnswers;
document.getElementById('remaining').textContent = 10 - questionsOnLevel;
document.getElementById('level').textContent = levelNames[currentLevel];
}
function checkLevelProgress() {
let percentage = (correctAnswers / (correctAnswers + wrongAnswers)) * 100;
if (currentLevel < 3 && percentage >= 80) {
setTimeout(() => {
alert('Поздравляем! Вы переходите на следующий уровень!');
currentLevel++;
questionsOnLevel = 0;
correctAnswers = 0;
wrongAnswers = 0;
usedQuestions = [];
updateDisplay();
startTimer();
generateQuestion();
}, 1500);
} else if (currentLevel === 3 && percentage >= 80) {
setTimeout(() => {
showResult('Поздравляем! Вы успешно завершили все уровни игры!');
}, 1500);
} else {
setTimeout(() => {
showResult('К сожалению, вы не смогли перейти на следующий уровень. Попробуйте еще раз!');
}, 1500);
}
}
function showResult(message) {
clearInterval(timerInterval);
document.getElementById('question-container').style.display = 'none';
document.getElementById('feedback').style.display = 'none';
document.getElementById('result-container').style.display = 'block';
document.getElementById('result-message').textContent = message;
}
function restartGame() {
currentLevel = 1;
correctAnswers = 0;
wrongAnswers = 0;
questionsOnLevel = 0;
usedQuestions = [];
document.getElementById('question-container').style.display = 'block';
document.getElementById('feedback').style.display = 'block';
document.getElementById('result-container').style.display = 'none';
updateDisplay();
startTimer();
generateQuestion();
}
function exitGame() {
if (confirm('Вы уверены, что хотите выйти из игры?')) {
clearInterval(timerInterval);
window.close();
}
}
document.getElementById('answer').addEventListener('keypress', function(event) {
if (event.key === 'Enter') {
checkAnswer();
}
});
window.onload = function() {
updateDisplay();
startTimer();
generateQuestion();
};

103
tasks/math-game/style.css Normal file
View file

@ -0,0 +1,103 @@
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
margin: 0;
background-color: #f5f5f5;
}
.container {
background: white;
padding: 40px;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
max-width: 400px;
width: 100%;
}
h1 {
text-align: center;
margin: 0 0 30px 0;
color: #333;
}
.game-info {
display: flex;
justify-content: space-between;
margin-bottom: 15px;
padding-bottom: 15px;
border-bottom: 1px solid #e0e0e0;
color: #666;
}
.game-stats {
display: flex;
justify-content: space-between;
margin-bottom: 30px;
color: #666;
}
.game-info span,
.game-stats span {
font-size: 14px;
}
#question-container {
text-align: center;
margin-bottom: 20px;
}
#question {
font-size: 32px;
margin-bottom: 25px;
color: #333;
}
#answer {
width: 100%;
padding: 12px;
font-size: 16px;
border: 1px solid #ddd;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 15px;
}
#answer:focus {
outline: none;
border-color: #4CAF50;
}
button {
background-color: #4CAF50;
color: white;
padding: 12px 30px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
margin: 5px;
}
button:hover {
background-color: #45a049;
}
#feedback {
text-align: center;
font-size: 16px;
font-weight: bold;
min-height: 25px;
margin-top: 15px;
}
#result-container {
text-align: center;
}
#result-container h2 {
margin-bottom: 25px;
color: #333;
}