Search
Write a publication
Pull to refresh

Comments 16

А можете сами собрать в квен и дипсик. Я бы посмотрел с удовольствием. )

Вы хорошо понимаете концепт, по этому вы сможете валидировать данные, которые чаты выдают.

Сделайте на java script type module es6 html

Я бы с удовольствием, попробовал, но самому сейчас надо собрать свой проект и времени нет совсем.

Спасибо, что откликнулись. Если бы я знал, что такое "квен и дипсик" и  java script type, то тогда да. Это не срочно, так что я могу Вас "подождать".

Машина крутого мужика
Машина крутого мужика


Вот он сразу выдает что то. Я не могу это провалидировать.

<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Машина Слонимского для умножения (1844)</title>
    <style>
        body {
            font-family: 'Courier New', monospace;
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .machine {
            background-color: white;
            border: 2px solid #333;
            border-radius: 10px;
            padding: 20px;
            box-shadow: 0 0 15px rgba(0,0,0,0.1);
        }
        .display {
            font-size: 24px;
            margin: 20px 0;
            padding: 10px;
            background-color: #eee;
            border: 1px solid #ccc;
            text-align: right;
            min-height: 40px;
        }
        .controls {
            display: grid;
            grid-template-columns: repeat(4, 1fr);
            gap: 10px;
        }
        button {
            padding: 15px;
            font-size: 18px;
            background-color: #4a4a4a;
            color: white;
            border: none;
            border-radius: 5px;
            cursor: pointer;
            transition: background-color 0.3s;
        }
        button:hover {
            background-color: #333;
        }
        .operator {
            background-color: #2c3e50;
        }
        .equals {
            background-color: #27ae60;
        }
        .clear {
            background-color: #c0392b;
        }
        .history {
            margin-top: 20px;
            padding: 10px;
            background-color: #eee;
            border: 1px solid #ccc;
            min-height: 100px;
        }
        h1 {
            color: #2c3e50;
            text-align: center;
        }
    </style>
</head>
<body>
    <div class="machine">
        <h1>Машина Слонимского (1844)</h1>
        <div class="display" id="display">0</div>
        <div class="controls">
            <button class="clear" onclick="calculator.clear()">C</button>
            <button onclick="calculator.inputDigit(7)">7</button>
            <button onclick="calculator.inputDigit(8)">8</button>
            <button onclick="calculator.inputDigit(9)">9</button>
            <button class="operator" onclick="calculator.inputOperator('*')">×</button>
            <button onclick="calculator.inputDigit(4)">4</button>
            <button onclick="calculator.inputDigit(5)">5</button>
            <button onclick="calculator.inputDigit(6)">6</button>
            <button class="operator" onclick="calculator.inputOperator('-')">-</button>
            <button onclick="calculator.inputDigit(1)">1</button>
            <button onclick="calculator.inputDigit(2)">2</button>
            <button onclick="calculator.inputDigit(3)">3</button>
            <button class="operator" onclick="calculator.inputOperator('+')">+</button>
            <button onclick="calculator.inputDigit(0)">0</button>
            <button onclick="calculator.inputDecimal()">.</button>
            <button class="equals" onclick="calculator.calculate()">=</button>
            <button class="operator" onclick="calculator.inputOperator('/')">÷</button>
        </div>
        <div class="history" id="history"></div>
    </div>

    <script type="module">
        class SlonimskyCalculator {
            constructor() {
                this.currentInput = '0';
                this.previousInput = null;
                this.operation = null;
                this.resetInput = false;
                this.history = [];
            }

            updateDisplay() {
                const display = document.getElementById('display');
                display.textContent = this.currentInput;
            }

            updateHistory() {
                const historyElement = document.getElementById('history');
                historyElement.innerHTML = this.history.map(item => 
                    `<div>${item}</div>`
                ).join('');
            }

            inputDigit(digit) {
                if (this.resetInput) {
                    this.currentInput = digit.toString();
                    this.resetInput = false;
                } else {
                    this.currentInput = this.currentInput === '0' 
                        ? digit.toString() 
                        : this.currentInput + digit;
                }
                this.updateDisplay();
            }

            inputDecimal() {
                if (this.resetInput) {
                    this.currentInput = '0.';
                    this.resetInput = false;
                    this.updateDisplay();
                    return;
                }

                if (!this.currentInput.includes('.')) {
                    this.currentInput += '.';
                    this.updateDisplay();
                }
            }

            inputOperator(operator) {
                const inputValue = parseFloat(this.currentInput);

                if (this.operation && !this.resetInput) {
                    this.calculate();
                }

                this.previousInput = this.currentInput;
                this.operation = operator;
                this.resetInput = true;

                this.history.push(`${this.previousInput} ${this.operation}`);
                this.updateHistory();
            }

            calculate() {
                if (this.operation === null || this.resetInput) return;

                const prev = parseFloat(this.previousInput);
                const current = parseFloat(this.currentInput);
                let result;

                switch (this.operation) {
                    case '+':
                        result = prev + current;
                        break;
                    case '-':
                        result = prev - current;
                        break;
                    case '*':
                        result = prev * current;
                        break;
                    case '/':
                        result = prev / current;
                        break;
                    default:
                        return;
                }

                // Реализация оригинального алгоритма Слонимского для умножения
                if (this.operation === '*') {
                    result = this.slonimskyMultiply(prev, current);
                }

                this.currentInput = result.toString();
                this.operation = null;
                this.resetInput = true;
                
                this.history.push(`${this.previousInput} ${this.operation || ''} ${current} = ${result}`);
                this.history = this.history.slice(-5); // Сохраняем последние 5 операций
                this.updateHistory();
                this.updateDisplay();
            }

            // Алгоритм умножения по методу Слонимского
            slonimskyMultiply(a, b) {
                // Оригинальный метод использовал таблицы и последовательное сложение
                // Здесь упрощенная реализация для демонстрации
                let result = 0;
                const isNegative = (a < 0) ^ (b < 0);
                a = Math.abs(a);
                b = Math.abs(b);
                
                // Метод повторного сложения (как в оригинальной машине)
                for (let i = 0; i < b; i++) {
                    result += a;
                }
                
                return isNegative ? -result : result;
            }

            clear() {
                this.currentInput = '0';
                this.previousInput = null;
                this.operation = null;
                this.updateDisplay();
            }
        }

        // Создаем экземпляр калькулятора и делаем его глобально доступным
        const calculator = new SlonimskyCalculator();
        window.calculator = calculator;
        calculator.updateDisplay();
    </script>
</body>
</html>
или так
или так


Или так ещё может быть. Все зависит от степени детализации того, что требуется.

Скрытый текст
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Машина Слонимского (Демонстрация)</title>
    <style>
        :root {
            --primary-color: #2c3e50;
            --secondary-color: #3498db;
            --accent-color: #e74c3c;
            --success-color: #2ecc71;
            --background-color: #ecf0f1;
            --card-bg: #ffffff;
            --border-color: #bdc3c7;
            --text-color: #2c3e50;
            --step-bg: #f8f9fa;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            margin: 0;
            padding: 0;
            background-color: var(--background-color);
            color: var(--text-color);
            line-height: 1.6;
        }

        .container {
            max-width: 900px;
            margin: 0 auto;
            padding: 20px;
        }

        header {
            text-align: center;
            margin-bottom: 30px;
            padding: 20px;
            background: linear-gradient(135deg, var(--primary-color), #4a6484);
            color: white;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
        }

        h1 {
            margin: 0;
            font-size: 2.2em;
        }

        .subtitle {
            font-size: 1.1em;
            opacity: 0.9;
            margin-top: 10px;
        }

        .calculator-container {
            background-color: var(--card-bg);
            border-radius: 10px;
            box-shadow: 0 4px 15px rgba(0,0,0,0.08);
            padding: 25px;
            margin-bottom: 30px;
        }

        .input-group {
            margin-bottom: 20px;
            text-align: left;
        }

        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            color: #34495e;
        }

        input[type="number"] {
            width: 100%;
            padding: 12px;
            border: 1px solid var(--border-color);
            border-radius: 5px;
            box-sizing: border-box;
            font-size: 16px;
        }

        button {
            background-color: var(--secondary-color);
            color: white;
            border: none;
            padding: 12px 25px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 1em;
            font-weight: bold;
            transition: background-color 0.3s ease;
            width: 100%;
            margin-top: 10px;
        }

        button:hover {
            background-color: #2980b9;
        }

        button:disabled {
            background-color: #bdc3c7;
            cursor: not-allowed;
        }

        .result-section {
            margin-top: 25px;
            padding: 20px;
            background-color: var(--step-bg);
            border-radius: 8px;
            border: 1px solid var(--border-color);
        }

        .result-title {
            font-size: 1.2em;
            font-weight: bold;
            margin-bottom: 15px;
            color: var(--primary-color);
        }

        .final-result {
            font-size: 1.5em;
            font-weight: bold;
            color: var(--success-color);
            text-align: center;
            padding: 15px;
            background-color: #e8f5e9;
            border-radius: 5px;
            margin-bottom: 20px;
        }

        .process-steps {
            margin-top: 20px;
        }

        .step {
            background-color: #fff;
            border: 1px solid #eee;
            border-radius: 4px;
            padding: 15px;
            margin-bottom: 15px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.05);
        }

        .step-header {
            font-weight: bold;
            margin-bottom: 8px;
            color: var(--secondary-color);
        }

        .explanation {
            margin-top: 30px;
            padding: 20px;
            background-color: #fef9e7;
            border-left: 5px solid #f1c40f;
            border-radius: 4px;
            font-size: 0.95em;
        }

        .explanation h3 {
            margin-top: 0;
            color: #f39c12;
        }

        .counter-display {
            font-family: monospace;
            background-color: #2c3e50;
            color: #2ecc71;
            padding: 10px;
            border-radius: 4px;
            text-align: center;
            font-size: 1.2em;
            margin: 10px 0;
            min-height: 2em;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        .status {
            padding: 8px;
            border-radius: 4px;
            text-align: center;
            font-weight: bold;
            margin-top: 10px;
        }

        .status-processing {
            background-color: #fff3cd;
            color: #856404;
        }

        .status-done {
            background-color: #d4edda;
            color: #155724;
        }

        .hidden {
            display: none;
        }

        .mechanism-animation {
            text-align: center;
            margin: 20px 0;
            min-height: 50px;
        }

        .gear {
            display: inline-block;
            font-size: 2em;
            animation: rotate 2s linear infinite;
            margin: 0 10px;
        }

        @keyframes rotate {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }

        .carriage-move {
            animation: moveCarriage 1s ease-in-out;
        }

        @keyframes moveCarriage {
            0% { transform: translateX(0); }
            50% { transform: translateX(20px); }
            100% { transform: translateX(0); }
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>Машина Слонимского (1844)</h1>
            <p class="subtitle">Интерактивная демонстрация принципа механического умножения</p>
        </header>

        <main>
            <section class="calculator-container">
                <div class="input-group">
                    <label for="multiplicand">Множимое (A):</label>
                    <input type="number" id="multiplicand" placeholder="Введите множимое" value="123" min="0">
                </div>

                <div class="input-group">
                    <label for="multiplier">Множитель (B):</label>
                    <input type="number" id="multiplier" placeholder="Введите множитель" value="45" min="0">
                </div>

                <button id="multiply-btn">Запустить Машину Слонимского</button>

                <div class="mechanism-animation hidden" id="animation-area">
                    <div class="gear">⚙️</div>
                    <div class="gear">⚙️</div>
                    <div class="gear">⚙️</div>
                </div>

                <div class="result-section">
                    <div class="result-title">Результат вычисления</div>
                    <div class="final-result" id="final-result">Результат: ?</div>
                    
                    <div class="status hidden" id="status-message"></div>
                    
                    <div class="process-steps">
                        <div class="step-header">Этапы работы машины:</div>
                        <div class="step">
                            <div class="step-header">1. Подготовка</div>
                            <div>Машина настраивается на множимое <strong id="prep-a">-</strong> и множитель <strong id="prep-b">-</strong>.</div>
                        </div>
                        <div class="step">
                            <div class="step-header">2. Позиционирование каретки</div>
                            <div>Каретка с цифрами множимого сдвигается в положение, соответствующее цифре множителя.</div>
                        </div>
                        <div class="step">
                            <div class="step-header">3. Механическое сложение</div>
                            <div>Происходит сложение с промежуточным результатом через вращение рукоятки.</div>
                            <div class="counter-display" id="accumulator">0</div>
                        </div>
                        <div class="step">
                            <div class="step-header">4. Сдвиг и повторение</div>
                            <div>Каретка сдвигается на одну позицию, и процесс повторяется для следующей цифры множителя.</div>
                        </div>
                    </div>
                </div>
            </section>

            <section class="explanation">
                <h3>Как работала Машина Слонимского</h3>
                <p><strong>Принцип действия:</strong></p>
                <ol>
                    <li><strong>Настройка:</strong> Множимое (например, 123) устанавливалось на каретке с помощью циферблатов или штырей.</li>
                    <li><strong>Циклическое сложение:</strong> Для каждой цифры множителя (например, 4 и 5 в числе 45):
                        <ul>
                            <li>Каретка сдвигалась влево на соответствующее количество разрядов (единицы, десятки и т.д.).</li>
                            <li>Рукоятка поворачивалась столько раз, какова цифра множителя (4 раза для цифры 4, 5 раз для цифры 5).</li>
                            <li>При каждом повороте множимое прибавлялось к накапливаемому результату через систему зубчатых колес.</li>
                        </ul>
                    </li>
                    <li><strong>Результат:</strong> После обработки всех цифр множителя на счетных колесах отображался окончательный результат.</li>
                </ol>
                <p><strong>Пример вычисления 123 × 45:</strong></p>
                <ul>
                    <li>123 × 5 = 615 (сдвиг 0 разрядов)</li>
                    <li>123 × 4 = 492 (сдвиг 1 разряд влево → 4920)</li>
                    <li>615 + 4920 = 5535</li>
                </ul>
            </section>
        </main>
    </div>

    <script type="module">
        // --- Модуль "Машина Слонимского" ---
        /**
         * @module SlonimskyMachine
         * @description Модуль, имитирующий работу оригинальной Машины Слонимского.
         */

        /**
         * @function multiplySlonimskyCore
         * @description Имитирует механическое умножение на Машине Слонимского.
         *              Реализует циклы сложения и сдвиги каретки.
         * @param {number} multiplicand - Множимое (A)
         * @param {number} multiplier - Множитель (B)
         * @param {Function} onStep - Callback для обновления UI на каждом шаге
         * @returns {Promise<number>} Произведение A и B
         */
        async function multiplySlonimskyCore(multiplicand, multiplier, onStep) {
            // Начальное состояние "счетного механизма" (аккумулятора)
            let accumulator = 0;
            const multiplicandStr = String(multiplicand);
            const multiplierStr = String(multiplier);
            
            onStep('start', { multiplicand, multiplier });

            // Проходим по цифрам множителя справа налево (от младших разрядов)
            for (let i = multiplierStr.length - 1; i >= 0; i--) {
                const digit = parseInt(multiplierStr[i], 10);
                const placeValue = Math.pow(10, multiplierStr.length - 1 - i); // 1, 10, 100...
                
                onStep('digit_start', { digit, placeValue, step: multiplierStr.length - i });

                // Для каждой цифры множителя выполняем сложение столько раз, какова её величина
                // Это имитирует поворот рукоятки
                for (let turn = 1; turn <= digit; turn++) {
                    // Вычисляем промежуточное слагаемое (множимое * цифру * разряд)
                    const addend = multiplicand * digit * (placeValue / Math.pow(10, multiplierStr.length - 1 - i));
                    
                    // Имитация механического сложения
                    accumulator += multiplicand * placeValue;
                    
                    onStep('turn', { 
                        turn, 
                        digit, 
                        placeValue, 
                        addend: multiplicand * placeValue, 
                        accumulator 
                    });
                    
                    // Небольшая задержка для демонстрации
                    await new Promise(resolve => setTimeout(resolve, 300));
                }
                
                onStep('digit_end', { digit, placeValue });
            }
            
            onStep('done', { result: accumulator });
            return accumulator;
        }

        // --- Логика пользовательского интерфейса ---
        document.addEventListener('DOMContentLoaded', () => {
            const multiplicandInput = document.getElementById('multiplicand');
            const multiplierInput = document.getElementById('multiplier');
            const multiplyButton = document.getElementById('multiply-btn');
            const finalResultDiv = document.getElementById('final-result');
            const accumulatorDisplay = document.getElementById('accumulator');
            const statusMessage = document.getElementById('status-message');
            const animationArea = document.getElementById('animation-area');
            const prepADisplay = document.getElementById('prep-a');
            const prepBDisplay = document.getElementById('prep-b');

            // Функция для обновления UI в процессе вычисления
            function updateUI(event, data) {
                switch(event) {
                    case 'start':
                        prepADisplay.textContent = data.multiplicand;
                        prepBDisplay.textContent = data.multiplier;
                        statusMessage.textContent = `Подготовка: множимое=${data.multiplicand}, множитель=${data.multiplier}`;
                        statusMessage.className = 'status status-processing';
                        statusMessage.classList.remove('hidden');
                        animationArea.classList.remove('hidden');
                        finalResultDiv.textContent = 'Результат: вычисляется...';
                        break;
                    case 'digit_start':
                        statusMessage.textContent = `Обработка цифры ${data.digit} (разряд ${data.placeValue})...`;
                        accumulatorDisplay.parentElement.classList.add('carriage-move');
                        setTimeout(() => {
                            accumulatorDisplay.parentElement.classList.remove('carriage-move');
                        }, 1000);
                        break;
                    case 'turn':
                        accumulatorDisplay.textContent = data.accumulator;
                        statusMessage.textContent = `Поворот ${data.turn}/${data.digit} для цифры ${data.digit}. Добавлено: ${data.addend}`;
                        break;
                    case 'digit_end':
                        statusMessage.textContent = `Цифра ${data.digit} обработана.`;
                        break;
                    case 'done':
                        finalResultDiv.textContent = `Результат: ${data.result}`;
                        statusMessage.textContent = 'Вычисление завершено!';
                        statusMessage.className = 'status status-done';
                        animationArea.classList.add('hidden');
                        break;
                }
            }

            // Обработчик нажатия кнопки
            multiplyButton.addEventListener('click', async () => {
                const multiplicand = parseInt(multiplicandInput.value, 10);
                const multiplier = parseInt(multiplierInput.value, 10);

                // Валидация ввода
                if (isNaN(multiplicand) || isNaN(multiplier) || multiplicand < 0 || multiplier < 0) {
                    finalResultDiv.textContent = 'Ошибка: Введите неотрицательные целые числа.';
                    finalResultDiv.style.color = '#e74c3c';
                    return;
                }

                multiplyButton.disabled = true;
                finalResultDiv.style.color = '#2c3e50';

                try {
                    // Запуск "машины"
                    const product = await multiplySlonimskyCore(multiplicand, multiplier, updateUI);
                    console.log(`[Слонимский] Результат: ${multiplicand} × ${multiplier} = ${product}`);
                } catch (error) {
                    console.error("[Ошибка] Не удалось выполнить умножение:", error);
                    finalResultDiv.textContent = `Ошибка вычисления: ${error.message}`;
                    finalResultDiv.style.color = '#e74c3c';
                    statusMessage.textContent = `Ошибка: ${error.message}`;
                    statusMessage.className = 'status status-error';
                    statusMessage.classList.remove('hidden');
                } finally {
                    multiplyButton.disabled = false;
                }
            });
        });
    </script>
</body>
</html>

Все три варианта - хлам. Не имеют никакого отношения к сабжу.

Если Вы о комментариях откликнувшегося пользователя, то я согласен...

внешний вид
внешний вид
Скрытый текст
<!DOCTYPE html>
<html lang="ru">
<head>
    <meta charset="UTF-8">
    <title>Машина Слонимского для умножения (1844) - Точная реплика</title>
    <style>
        body {
            font-family: 'Times New Roman', serif;
            background-color: #f0e6d2;
            margin: 0;
            padding: 20px;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
        }
        
        .machine-container {
            background-color: #8B4513;
            border: 15px solid #5D4037;
            border-radius: 20px;
            padding: 30px;
            box-shadow: 0 0 30px rgba(0,0,0,0.5);
            width: 800px;
            position: relative;
        }
        
        .machine-title {
            text-align: center;
            color: #FFD700;
            font-size: 24px;
            margin-bottom: 20px;
            text-shadow: 2px 2px 4px #000;
        }
        
        .machine-body {
            background-color: #A67C52;
            border: 10px solid #5D4037;
            border-radius: 10px;
            padding: 20px;
        }
        
        .display-panel {
            background-color: #D2B48C;
            border: 5px solid #5D4037;
            padding: 15px;
            margin-bottom: 20px;
            text-align: right;
            font-size: 28px;
            height: 50px;
            overflow: hidden;
            position: relative;
        }
        
        .display-number {
            position: absolute;
            right: 15px;
            font-family: 'Courier New', monospace;
        }
        
        .levers-container {
            display: flex;
            justify-content: space-between;
            margin-bottom: 20px;
        }
        
        .digit-levers {
            display: flex;
            gap: 15px;
        }
        
        .lever {
            width: 30px;
            height: 100px;
            background: linear-gradient(to right, #C0C0C0, #E0E0E0, #C0C0C0);
            border: 3px solid #333;
            border-radius: 5px;
            cursor: pointer;
            position: relative;
            transition: transform 0.3s;
            transform-origin: bottom center;
        }
        
        .lever:hover {
            background: linear-gradient(to right, #A0A0A0, #C0C0C0, #A0A0A0);
        }
        
        .lever:active {
            transform: rotate(-15deg);
        }
        
        .lever-label {
            position: absolute;
            bottom: -25px;
            left: 0;
            right: 0;
            text-align: center;
            font-weight: bold;
            color: #000;
        }
        
        .operation-levers {
            display: flex;
            flex-direction: column;
            gap: 10px;
        }
        
        .operation-lever {
            width: 80px;
            height: 40px;
            background: linear-gradient(to bottom, #C0C0C0, #E0E0E0, #C0C0C0);
            border: 3px solid #333;
            border-radius: 5px;
            cursor: pointer;
            display: flex;
            justify-content: center;
            align-items: center;
            font-weight: bold;
        }
        
        .operation-lever:hover {
            background: linear-gradient(to bottom, #A0A0A0, #C0C0C0, #A0A0A0);
        }
        
        .operation-lever:active {
            transform: translateY(3px);
        }
        
        .result-lever {
            width: 120px;
            height: 50px;
            background: linear-gradient(to right, #FF8C00, #FFA500, #FF8C00);
            border: 3px solid #8B0000;
            border-radius: 5px;
            cursor: pointer;
            display: flex;
            justify-content: center;
            align-items: center;
            font-weight: bold;
            margin: 0 auto;
        }
        
        .result-lever:hover {
            background: linear-gradient(to right, #E07C00, #FF9500, #E07C00);
        }
        
        .result-lever:active {
            transform: translateY(5px);
        }
        
        .history-panel {
            background-color: #D2B48C;
            border: 5px solid #5D4037;
            padding: 10px;
            margin-top: 20px;
            height: 100px;
            overflow-y: auto;
            font-family: 'Courier New', monospace;
        }
        
        .history-entry {
            margin-bottom: 5px;
            border-bottom: 1px dashed #8B4513;
            padding-bottom: 3px;
        }
        
        .machine-footer {
            text-align: center;
            color: #FFD700;
            margin-top: 15px;
            font-style: italic;
        }
    </style>
</head>
<body>
    <div class="machine-container">
        <div class="machine-title">АРИФМОМЕТРЪ СЛОНИМСКАГО (1844)</div>
        
        <div class="machine-body">
            <div class="display-panel">
                <div class="display-number" id="display">0</div>
            </div>
            
            <div class="levers-container">
                <div class="digit-levers">
                    <div class="lever" onclick="moveLever(7)" data-digit="7">
                        <div class="lever-label">7</div>
                    </div>
                    <div class="lever" onclick="moveLever(8)" data-digit="8">
                        <div class="lever-label">8</div>
                    </div>
                    <div class="lever" onclick="moveLever(9)" data-digit="9">
                        <div class="lever-label">9</div>
                    </div>
                    <div class="lever" onclick="moveLever(4)" data-digit="4">
                        <div class="lever-label">4</div>
                    </div>
                    <div class="lever" onclick="moveLever(5)" data-digit="5">
                        <div class="lever-label">5</div>
                    </div>
                    <div class="lever" onclick="moveLever(6)" data-digit="6">
                        <div class="lever-label">6</div>
                    </div>
                    <div class="lever" onclick="moveLever(1)" data-digit="1">
                        <div class="lever-label">1</div>
                    </div>
                    <div class="lever" onclick="moveLever(2)" data-digit="2">
                        <div class="lever-label">2</div>
                    </div>
                    <div class="lever" onclick="moveLever(3)" data-digit="3">
                        <div class="lever-label">3</div>
                    </div>
                    <div class="lever" onclick="moveLever(0)" data-digit="0">
                        <div class="lever-label">0</div>
                    </div>
                </div>
                
                <div class="operation-levers">
                    <div class="operation-lever" onclick="setOperation('+')">Сложение</div>
                    <div class="operation-lever" onclick="setOperation('-')">Вычитание</div>
                    <div class="operation-lever" onclick="setOperation('*')">Умножение</div>
                    <div class="operation-lever" onclick="setOperation('/')">Деление</div>
                    <div class="operation-lever" onclick="clearMachine()">Сброс</div>
                </div>
            </div>
            
            <div class="result-lever" onclick="calculate()">Получить результат</div>
            
            <div class="history-panel" id="history"></div>
        </div>
        
        <div class="machine-footer">Изобретено Х.З. Слонимским в 1844 году</div>
    </div>

    <script>
        // Состояние машины
        const machineState = {
            currentValue: 0,
            storedValue: null,
            operation: null,
            isNewNumber: true,
            history: []
        };

        // Элементы интерфейса
        const display = document.getElementById('display');
        const historyElement = document.getElementById('history');

        // Анимация рычагов
        function animateLever(leverElement) {
            leverElement.style.transform = 'rotate(-15deg)';
            setTimeout(() => {
                leverElement.style.transform = 'rotate(0)';
            }, 300);
        }

        // Обработка движения рычага
        function moveLever(digit) {
            const lever = document.querySelector(`.lever[data-digit="${digit}"]`);
            animateLever(lever);
            
            if (machineState.isNewNumber) {
                machineState.currentValue = digit;
                machineState.isNewNumber = false;
            } else {
                machineState.currentValue = machineState.currentValue * 10 + digit;
            }
            
            updateDisplay();
        }

        // Установка операции
        function setOperation(op) {
            if (machineState.operation && !machineState.isNewNumber) {
                calculate();
            }
            
            machineState.storedValue = machineState.currentValue;
            machineState.operation = op;
            machineState.isNewNumber = true;
            
            addHistory(`${machineState.storedValue} ${op}`);
        }

        // Вычисление результата
        function calculate() {
            if (!machineState.operation || machineState.isNewNumber) return;
            
            let result;
            const a = machineState.storedValue;
            const b = machineState.currentValue;
            
            switch (machineState.operation) {
                case '+':
                    result = a + b;
                    break;
                case '-':
                    result = a - b;
                    break;
                case '*':
                    // Оригинальный метод умножения Слонимского
                    result = slonimskyMultiplication(a, b);
                    break;
                case '/':
                    result = a / b;
                    break;
                default:
                    return;
            }
            
            machineState.currentValue = result;
            machineState.operation = null;
            machineState.isNewNumber = true;
            
            addHistory(`= ${result}`);
            updateDisplay();
            
            // Анимация рычага результата
            const resultLever = document.querySelector('.result-lever');
            resultLever.style.transform = 'translateY(5px)';
            setTimeout(() => {
                resultLever.style.transform = 'translateY(0)';
            }, 200);
        }

        // Оригинальный алгоритм умножения Слонимского
        function slonimskyMultiplication(a, b) {
            // В оригинале использовались специальные таблицы умножения
            // и механическое сложение частичных произведений
            
            // Для простоты реализуем через последовательное сложение
            // как это делала механическая версия
            let result = 0;
            const isNegative = (a < 0) ^ (b < 0);
            a = Math.abs(a);
            b = Math.abs(b);
            
            for (let i = 0; i < b; i++) {
                result += a;
            }
            
            return isNegative ? -result : result;
        }

        // Сброс машины
        function clearMachine() {
            machineState.currentValue = 0;
            machineState.storedValue = null;
            machineState.operation = null;
            machineState.isNewNumber = true;
            updateDisplay();
            addHistory("--- Машина сброшена ---");
        }

        // Обновление дисплея
        function updateDisplay() {
            display.textContent = machineState.currentValue;
        }

        // Добавление записи в историю
        function addHistory(entry) {
            machineState.history.push(entry);
            if (machineState.history.length > 5) {
                machineState.history.shift();
            }
            
            historyElement.innerHTML = machineState.history
                .map(item => `<div class="history-entry">${item}</div>`)
                .join('');
            historyElement.scrollTop = historyElement.scrollHeight;
        }

        // Инициализация
        updateDisplay();
        addHistory("Машина готова к работе");
    </script>
</body>
</html>

Простите, но это всё-таки не арифмометр, а механизированная таблица.

Да, конечно. То так разместить более 3000 цифр и букв, что практически автоматически получаются 8 произведенией, как это сделал Слонимский, -- надо суметь! Я знаю, что один человек (не в России) сделал реконструкцию машины. С механизмами смещения цилиндров и др. Но без верхней панели с окошками. Красиво!

Модель я планирую опубликовать (вместе со статьёй о машине) на сайте Виртуального компьютерного музея (computer-museum.ru) и на одном очень солидном зарубежном сайте.

Спасибо за все. Буду разбираться.

Общая схема модели здесь:

https://drive.google.com/file/d/1DMrecUT3wB2a4rxLL3n-MkrNYh2CElFS/view?usp=sharing

Элементы модели

·         Двумерный массив win окон ввода, 11 строк, 8 столбцов

·         Двумерный массив dig цифр, 56 строк, 40 столбцов

·         Двумерный массив point указателей, 14 строк, 40 столбцов; элементы 2-символьные

·         Одномерный массив row1 ряда 1,  40 элементов; элементы 2-символьные

·         Массив горизонтальных ScrollBox 8 элементов:

- ScrollBox 0: min = 0, max = 3

 - ScrollBox 7: min = 0, max = 9

- остальные, min = 0, max = 39

·         Массив вертикальных ScrollBox 7 элементов, min = 1, max = 7

 

Значения в массивах dig цифр, point указателей, row1 ряда 1 известны (заполню я)

 

Начальная ситуация

Значения в массиве окон;

- первые 56 строк – 0

- последняя строка – a0, a1, a2, a3, a4, a5, a6, a7, a8, a9

- остальные 14 строк – a7

 

Связи элементов

Значения во всех окнах берутся из трех массивов (dig цифр, point указателей, row1 ряда 1),  и зависят от положения всех ScrollBox:

·         при перемещении горизонтальных ScrollBox 1, 2, …, 6 меняются значения в соответствующем столбце массива окон по общему правилу

·         при перемещении горизонтального ScrollBox 0 меняются значения в первом столбце массива окон по отдельному правилу

·         при перемещении горизонтального ScrollBox 7 меняются значения в последнем столбце массива окон по отдельному правилу

·         при перемещении всех вертикальных ScrollBox меняются значения в соответствующем столбце массива окон по общему правилу

ScrollBox 6 – в столбце 6 окон

ScrollBox 5 – в столбце 5

ScrollBox 4 – в столбце 4

ScrollBox 3 – в столбце 3

ScrollBox 2 – в столбце 2

ScrollBox 1 – в столбце 1

ScrollBox 0 – в столбце 0

Ну вам достаточно более ли менее адекватную модель за основу взять. И попросить написать нужные методы и сделать нужный набор параметров для управления.

Например реальный интерфейс наверное будет быстрее руками нарисовать, но под него все параметры расчитать можно.

html удобно что вы в браузере можете сразу все посмотреть и по расчитывать.

Спасибо. Возникли 2 принципиальных вопроса.

  1. Можно ли вместо нескольких текстовых полей (для вывода цифр) использовать массив полей?

  2. Возможно ли использование элемента "полоса прокрутки" не для скроллинга страниц, а для выбора (изменения) значений из некоторого диапазона (как, например, в регуляторах уровня громкости)?/

    Как я писал, интерфейс модели машины - 88 текстовых полей и элементы для изменения/задания значений в них (лучше полосы прокрутки, хуже - кнопки > <).

    Процедура обработки события этих элементов будет менять содержимой текстовых окон.

    И это - вся модель (кроме истории и хэлпа).

Статья слишком неполная. Она не содержит никакой информации по машине, которые не были бы по другим ссылкам.

По факту - засоряет выдачу гугла.

Моя задача была - найти Вас или такого, как Вы.

А всё новое я написал на сайте Стефана Вайса (самый крупный специалист по ручным и механическим вычислительным устройствам, он результаты оценил и опубликовал) и напишу на сайте Виртуального компьютерного музея (где уже есть ряд моих публикаций)

Ага. А в выдаче гугла теперь эта статья в начале. А Стефана Вайса (кем бы он ни был) гугл в рунете не кажет.

Sign up to leave a comment.

Articles