Little boar
Хорошего дня!

Telegram iconПрисоединяйся к нашему каналу

маленькие этюды

Короткие заметки о JavaScript и маленькие программки.

  • #Доказательство обмена через XOR

    20 сентября 2025

    Строгое доказательство XOR‑обмена

    В прошлой заметке мы показали XOR‑обмен на примере и таблице. Демонстрация — это не доказательство. Ниже — краткое строгое объяснение, почему XOR‑обмен работает.

    Думайте о a ^ b как о переключении (инвертировании) битов a в тех позициях, где у b стоят 1. Дважды инвертируем — получаем исходное: a ^ b ^ b = a.

    // Пусть исходные значения — a0 и b0
    let a = a0, b = b0
    a = a ^ b      // a = a0 ^ b0,        b = b0
    b = a ^ b      // a = a0 ^ b0,        b = b0 ^ (a0 ^ b0) = a0
    a = a ^ b      // a = a0 ^ b0 ^ a0 = b0, b = a0
    

    Результат общий: значения меняются местами без временной переменной для любых целых a0 и b0.

    • XOR переключает биты: a ^ b ^ b = a
    • Пошаговое доказательство для a0, b0
    • Обмен без временной переменной
  • #Операция XOR

    20 сентября 2025

    Иллюстрация операции XOR

    В одной из заметок мы использовали оператор XOR для обмена значениями. После короткого введения в двоичную систему разберём XOR подробнее.

    У операции несколько обозначений: ⊕, ^, xor. На одиночных битах она ведёт себя как «сумма по модулю 2»: 0, если входы равны, и 1, если различны. См. Википедию.

    Побитовый XOR — это применение XOR к соответствующим битам двух двоичных чисел. Пример: 5 ^ 3. В двоичном виде: 101 ^ 011. По столбцам: 1^0=1, 0^1=1, 1^1=0110 (то есть 6). Попробуйте: console.log(5 ^ 3).

    01234567
    001234567
    110325476
    223016745
    332107654
    445670123
    554761032
    667452301
    776543210

    Проверим классический алгоритм обмена через XOR по этой таблице. Пусть a = 5, b = 4. Проследим значения после присваиваний:

    a = a ^ b  // a = 5 ^ 4 = 1, b = 4
    b = a ^ b  // a = 1, b = 1 ^ 4 = 5
    a = a ^ b  // a = 1 ^ 5 = 4, b = 5

    Видно, что алгоритм работает: значения обменялись без временной переменной.

    • Побитовая XOR объединяет два числа в третье
    • Полезное тождество: a ^ b ^ a = b
    • Обозначения: ⊕, ^, xor; «сумма по модулю 2»
    • Ассоциативность, коммутативность, самоуничтожение
    • Википедия: XOR
  • #Двоичное представление числа

    15 сентября 2025

    Иллюстрация двоичного представления

    В одной из предыдущих заметок мы разбирали решение задачи «обменять два значения тремя переменными» с использованием оператора XOR. Здесь сделаем шаг назад и объясним, что происходит. Подробности о позиционной системе счисления по основанию 2 см. в Википедии. Главное:

    • любое целое число можно записать последовательностью 0 и 1
    • можно переводить двоичное представление в десятичное и обратно

    Чтобы перевести двоичное число в десятичное, суммируем биты с весами (справа налево): 1, 2, 4, 8, 16, …. Примеры: 101 = 1×4 + 0×2 + 1×1 = 5; 011 = 0×4 + 1×2 + 1×1 = 3.

    Для трёхбитных чисел: 000 → 0
    001 → 1
    010 → 2
    011 → 3
    100 → 4
    101 → 5
    110 → 6
    111 → 7. Чтобы перевести из десятичного в двоичное, найдите число в правом столбце и возьмите соответствующую запись слева.

  • #Симулятор обмена трёх переменных

    5 сентября 2025

    журавли демонстрируют обмен трёх переменных

    В прошлых постах мы обсуждали задачу обмена значениями двух переменных. Здесь представляем симулятор для трёх переменных. Три круга обозначают переменные, их цвета — значения. Шесть кнопок покрывают присваивания a=b, b=a, b=t, t=b, a=t и t=a. Нажмите кнопку, и присваивание произойдёт сразу.

    Мы использовали React для создания приложения и Vite для сборки. Было несколько интересных моментов, о которых расскажем позже. Начнём с задачи: как расположить три круга в вершинах равностороннего треугольника?

    Есть несколько подходов:

    • Сетка с фиксированными ячейками — плюс: просто; минус: неочевидно и, скорее всего, приблизительно
    • Canvas — плюс: точные координаты; минус: элементы не кликабельны, холст растровый
    • SVG — плюс: координаты, кликабельные элементы, лаконичный код
    Мы выбрали SVG. Посмотреть код можно на GitHub. На сегодня всё, позже расскажем подробнее об этой технологии.

    • React-симулятор обмена трёх переменных
    • Ссылка для игры
    • SVG для выравнивания кругов
  • #Операторы

    29 августа 2025

    операторы, нарисованные на стене

    Чтобы решать задачи реального мира, нужно выполнять операции с числами. В JS используются "*" для умножения, "/" для деления и "+", "-" для сложения и вычитания. Откройте консоль браузера и введите выражения 2*2, 5-3, 8/4, 6*6. В C++ и Python есть хитрые правила для дробного деления. В JS результат — число с плавающей точкой. Чтобы округлить его, примените функции Math.ceil или Math.floor.

    Чтобы писать сложные программы, принимающие нетривиальные решения, объединяйте простые логические высказывания в более сложные конструкции. Например, если мы хотим определить, что x слишком мал или слишком велик, нужно объединить выражение (x < 4) с (x > 7). Каждое из них имеет булев тип. Чтобы объединить простые булевы выражения в сложное, используем логические операторы: "||" — или, "&&" — и, "!" — не. Таким образом, выражение записывается как (x < 4) || (x > 7).

    Если нужно упаковать данные в переменную и работать на уровне битов, пригодятся побитовые операторы "|", "&", "^", "~". Это достаточно продвинутая техника, которую не используют каждый день, но иногда она может выручить.

    • арифметические операторы: + - * / %
    • логические операторы: || && !
    • побитовые операторы: | & ^ ~
  • #Обмен значениями

    22 августа 2025

    обмен значениями двух переменных в JavaScript

    До сих пор мы только присваивали значения переменным, и казалось, что ничего интересного сделать нельзя. Но есть известная задача: как обменять значения двух переменных? Это важная часть сортировочных алгоритмов. Попробуйте подумать. У вас есть две переменные:

    let a = 5, b = 8;
    ...
    console.log("a=", a, "b=", b);

    Ваша задача — вставить код вместо ..., чтобы вывод был: a=8, b=5. Разумеется, решение должно быть универсальным и использовать присваивания между переменными. Учтите, что выражения a = b или b = a сразу портят игру: одно из значений теряется. Избежать этой ловушки можно, введя третью переменную. Попробуйте написать свою программу и протестировать её в консоли браузера.

    Получившийся код — известная функция «swap», которую можно встретить в библиотеках. Более сложная и менее известная задача — обменять значения без введения третьей переменной. Здесь можно подумать о других операциях, кроме чистого присваивания.

    Если застряли, загляните на наш GitHub: three, minus и xor. Также можно поиграть в наш симулятор обмена «ref».

    • swap(a, b) переносит значение из a в b и из b в a
    • Обычный подход — использовать три переменные
    • Хитрость — достаточно двух переменных
  • #Хойстинг

    17 августа 2025

    три мушкетёра демонстрируют хойстинг

    В языках вроде C++, Java и Go нельзя использовать переменную до её объявления. JavaScript дважды просматривает файл, сначала обрабатывая объявления.

    Затем выполняется программа, и объявления как бы поднимаются наверх. var-программа может вывести undefined, а «временная мёртвая зона» заставляет let и const выбросить ошибку.

    • Хойстинг поднимает объявления в начало области
    • var доступна до объявления (undefined)
    • let и const недоступны до объявления
    • TDZ обеспечивает это поведение
  • #Let, var и const

    15 августа 2025

    три мушкетёра, представляющие let, const и var

    Ключевые слова var, let и const позволяют создать новую переменную и задать ей начальное значение. var — старая конструкция, сейчас она устарела. Чтобы создать переменную с неизменяемым значением, используйте const. Для переменной, значение которой будет меняться, используйте let.

    Важно понимать, является ли ваше значение примитивом или объектом. const a = 5 полностью запрещает любые изменения, потому что 5 — примитивный тип, и утверждение «значение 5 хранится в переменной a» остаётся верным. А const b = [5] запрещает писать b = [6], но позволяет менять элементы массива, например b[0] = 777. Это происходит потому, что значение b — ссылка на массив; мы читаем эту ссылку из переменной и затем обращаемся к массиву по индексу.

    • var – старый, устаревший
    • let, const – современный
    • let: можно изменять значение
    • const: нельзя присваивать новое значение
    • const + примитив = изменить ничего нельзя
    • const + объект = новый объект нельзя, существующий менять можно
  • #Типы: примитив, объект

    8 июля 2025

    примитивные и ссылочные типы в JavaScript

    Память компьютера состоит из нулей и единиц. Чтобы выполнять вычисления, рисовать картинки и отправлять сообщения, мы должны придать им смысл. Бит — это 0 или 1. Восемь бит — байт. Группы байтов могут хранить символы, числа, значения «истина/ложь». Тип говорит, какой смысл мы вкладываем в набор битов.

    В JavaScript есть примитивные типы: Number, String, Boolean, Undefined, Null. Когда мы работаем с ними, можно сказать «значение находится в переменной», и результаты операций предсказуемы. «a=b» читаем как «берём значение из b и кладём его копию в a».

    Есть и ссылочные типы: Object, Array, Function. В этом случае переменная содержит ссылку на объект где-то в памяти компьютера. «a=b» означает «теперь a ссылается на тот же объект, что и b», поэтому изменения через b затрагивают значение a.

    • Тип определяет, как интерпретировать значения в памяти.
    • Примитивные типы: Number, String, Boolean, Undefined, Null — значение хранится в переменной.
    • Ссылочные типы: Object, Array, Function — в переменной хранится ссылка.
    let a = 5;
    let b = a;
    b = 8;
    console.log(a,b)
    // 5, 8
    
    let a = [5];
    let b = a;
    b[0] = 8;
    console.log(a, b)
    // [8], [8]