• Как найти все комбинации, из которых можно составить n?

    #include <iostream>
    #include <vector>
    
    std::vector<int> arr = { 100, 50, 25, 10, 5, 1 };
    int n = 100;
    int matches = 0;
    
    void calc( int val, unsigned int offs ) {
      if( val == n ) {
        matches++;
        return;
      } else if( val > n ) {
        return;
      }
      for( unsigned int i = offs; i < arr.size(); ++i ) {
        calc( val + arr[i], i );
      }
    }
    
    int main( int argc, char** argv ) {
      calc( 0, 0 );
      std::cout << matches << std::endl;
      return( EXIT_SUCCESS );
    }
    Ответ написан
    Комментировать
  • Как различить бинарный и унарный операторы когда они используются вместе?

    @Interface
    Если возникает необходимость посмотреть как интерпритируется тот или иной синтаксис - может быть полезно посмотреть на AST. Сделать это можно, например, тут https://astexplorer.net/

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

    Если вы вдруг забыли приоритеты операций (yield vs. ternary например) - это может быть полезно
    Ответ написан
    Комментировать
  • Как можно оптимизировать код для проверки числа на простоту?

    usdglander
    @usdglander
    Yipee-ki-yay
    Я так понимаю, что нужно не нахождение простых чисел, а эффективная проверка числа на простоту. Ваше решение представляет собой классическое решение "в лоб", которое, разумеется работает и даёт стопроцентно точный результат. Однако, помимо простого перебора всех чисел от 2 до sqrt(n) есть и более эффективные алгоритмы. На ум быстро приходит два метода оптимизации:

    1. Если не нужна прям гарантия простоты, то можно воспользоваться тестом Рабина-Миллера. Есть ряд чисел, которые не являются простыми, но проходят этот тест. Про них можно почитать и добавить в дополнительное условие.

    2. Можно использовать свойство составных чисел, что они не только не делятся на числа из диапазона 2 .. sqrt(n), но так же не делятся ни на одно из простых чисел меньше sqrt(n). Если после отработки функции isPrime сохранять переданное число в массив, если оно оказалось простым, то можно организовывать цикл не по диапазону 2 .. sqrt(n), а по массиву уже известных простых чисел.
    Ответ написан
    Комментировать
  • Область видимости и iife?

    Vlad_IT
    @Vlad_IT Куратор тега JavaScript
    Front-end разработчик
    Смотрите
    var obj = {
      test() {
        console.log(this);
      }
    }(obj.test)()

    На что это похоже?
    А вот так?
    var obj = {
      test() {
        console.log(this);
      }
    }();

    На попытку вызвать функцию с выражения, и передать в нее obj.test, хотя obj еще не существует.
    Вот так еще нагляднее
    var obj = ({
      test() {
        console.log(this);
      }
    }(obj.test)());

    т.е. присваивание всего этого в obj идет в последнюю очередь, а до этого, мы пытаемся использовать obj, но он еще не существует. Хотя даже если вы вместо obj.test поставите другую переменную, или например число, то будет ошибка
    Uncaught TypeError: {(intermediate value)} is not a function
    т.е. вы пытаетесь выполнить конструкцию вида
    ({a: 10}())
    И все из-за того, что вы забыли точку с запятой
    var obj = {
      test() {
        console.log(this);
      }
    };
    
    (obj.test)()
    Ответ написан
    5 комментариев
  • Алгоритм нахождения победителя (крестики нолики)?

    BuriK666
    @BuriK666
    Компьютерный псих
    function checkWinner(arr) {
        function Eq(a, b, c) {
            return a != 0 && a == b && a == c;
        }
        for (let i = 0; i < 3; i++) {
            // check rows
            if (Eq(arr[0][i], arr[1][i], arr[2][i])) {
                return arr[0][i]
            }
    
            // check cols
            if (Eq(arr[i][0], arr[i][1], arr[i][2])) {
                return arr[i][0]
            }
        }
    
        // check diagonal
        if (Eq(arr[0][0], arr[1][1], arr[2][2])) {
            return arr[0][0]
        }
    
        if (Eq(arr[0][2], arr[1][1], arr[2][1])) {
            return arr[0][2]
        }
    
        return 0
    }


    OFFTOP: шутка на тему tic-tac-toe https://github.com/asweigart/my_first_tic_tac_toe
    Ответ написан
    1 комментарий
  • Порядок в деструктурирующем присваивании?

    potapchino
    @potapchino
    var arr = [1,2,3,4,5,6,7,8]
    var i = 3
    var j = 4
    
    console.log(arr); // [1,2,3,4,5,6,7,8]
    [arr[i], arr[j]] = [arr[j++], arr[i--]];
    console.log(arr); // [1,2,5,4,5,4,7,8]
    
    // #1
    // arr[j++]
    // j++  вернет 4
    // arr[4] вернет 5
    // [arr[i], arr[j]] = [5, arr[i--]]
    
    // #2
    // arr[i--]
    // i--  вернет 3
    // arr[3] вернет 4
    // [arr[i], arr[j]] = [5, 4]
    
    // #3
    // arr[i]
    // i вернет 2
    // [arr[2], arr[j]] = [5, 4]
    
    // #4
    // arr[j]
    // j вернет 5
    // [arr[2], arr[5]] = [5, 4]
    
    // #5
    // выполняем деструктуризацию
    
    // #5.1
    // console.log(arr[2]); // 3
    // arr[2] = 5
    // console.log(arr[2]); // 5
    
    // #5.2
    // console.log(arr[5]); // 6
    // arr[5] = 4
    // console.log(arr[5]); // 4
    
    // #6
    // в результате деструктуризации изменили исходный массив:
    // [ 1, 2, 5, 4, 5, 4, 7, 8 ]
    Ответ написан
    Комментировать
  • Как найти внутренний квадрат в квадрате?

    0xD34F
    @0xD34F Куратор тега JavaScript
    При известных размерах поля можно вычислить координаты элемента на основе его индекса:

    строка = floor(индекс / количество столбцов)
    столбец = индекс % количество столбцов

    Ну а при клике надо взять все элементы, чьи координаты отличаются от координат кликнутого элемента не более чем на какое-то определённое значение (в данном случае 2 - т.к. сторона квадрата 5, floor(5 / 2)).

    Заценить живьём.
    Ответ написан
    1 комментарий
  • Переопределение функции после выполнения?

    meltmestnt
    @meltmestnt
    У верблюда два горба, потому что жизнь - борьба
    Во втором случае методу foo объекта obj присваивается
    function () {
      console.log('Hello!');
      foo = function () {
        console.log('Bye!');
      };
    }
    . При вызове метода foo у объекта obj выполняетя console.log("Hello"), затем сама функция foo ( Не метод объекта! ) меняется на
    function () {
        console.log('Bye!');
      };
    Ответ написан
    Комментировать
  • Переопределение функции после выполнения?

    0xD34F
    @0xD34F Куратор тега JavaScript
    Но если на функцию ссылается объект...

    Ну так это совсем другая ссылка, не та, что вы используете при переопределении.

    Указывайте контекст при переопределении, т.е., замените

    foo = function () {

    на

    this.foo = function () {
    Ответ написан
    Комментировать
  • Лучший способ хранить координаты в JS?

    alexey-m-ukolov
    @alexey-m-ukolov Куратор тега JavaScript
    Первый лучше с точки зрения написания кода - легче читать, понятнее структура данных.

    Второй - с точки зрения потребления ресурсов и скорости работы (массив целых чисел особенно хорошо оптимизируется движками js).

    Если у вас не тысячи точек, имеет смысл остановиться на первом варианте.

    P.S. Написал и задумался - а действительно ли второй вариант оптимальнее? Ведь это не массив интеджеров, а массив массивов и он может быть вполне равнозначен массиву объектов из первого варианта.
    Ответ написан
    2 комментария
  • Правильно ли я понимаю замыкание в JS?

    rockon404
    @rockon404
    Frontend Developer
    Нет, у тебя в примере в переменную d записывается 2 и все.
    Там нет замыкания.
    И понимаешь ты все не верно.
    Твой пример похож на задачу по замыканиям, которую надо решить.

    Вот если переписать так:
    function a() {
        var c = 2;
    
        function b() { 
          return c++;
        };
    
        return b;
    }
    
    var d = a();
    
    alert(d()); // 2
    alert(d()); // 3

    то d будет присвоенна функция:
    function b() { 
      return c++;
    };

    а значение с будет браться из скоупа в котором функция была создана и перезаписывается с каждым вызовом d.
    Скоуп будет существовать пока есть ссылка на функцию, то есть пока мы не присвоим d другое значение.
    Это и есть замыкание.

    Значение c было определенно в функции a в момент вызова. Следом мы возвращаем из функции a функцию b. Функция b использует переменную c из скоупа созданного в момент вызова функции a и, как я писал выше, пока будет существовать ссылка на функцию b скоуп будет существовать, потому что функция b использует a и может быть вызвана.
    А с каждым вызовом a мы создаем новый скоуп, и если возвращать каждый результат вызова a в переменную, каждый раз мы будем получать новое замыкание:
    function a() {
        var c = 2;
    
        function b() { 
          return c++;
        };
    
        return b;
    }
    
    var d = a();
    var e = a();
    
    alert(d()); // 2
    alert(d()); // 3
    
    alert(e()); // 2
    
    alert(d()); // 4
    alert(d()); // 5
    
    alert(e()); // 3

    Надеюсь так понятней.
    Ответ написан
    1 комментарий
  • Как написать функцию, тело которой будет содержать по одному символу на строку?

    0xD34F
    @0xD34F Куратор тега JavaScript
    ну, например
    const foo = () =>
    (
    0
    +
    {
    }
    )
    [
    7
    ]
    +
    (
    0
    +
    {
    }
    )
    [
    2
    ]
    +
    (
    !
    1
    +
    `
    `
    )
    [
    3
    ]
    +
    (
    0
    +
    {
    }
    )
    [
    7
    ]
    +
    (
    !
    1
    +
    `
    `
    )
    [
    4
    ]
    +
    (
    !
    0
    +
    `
    `
    )
    [
    1
    ]

    Конечно, можно и чуть проще - любой символ можно получить с помощью конструкции вида

    `
    X
    `
    [
    1
    ]

    Ответ написан
    6 комментариев
  • Как, имея число, получить близжайшее большее число, состоящее из тех же цифр?

    sergiks
    @sergiks Куратор тега Алгоритмы
    ♬♬
    Upd. Алгоритм ниже неверный, т.к. не работает в случае, когда необходимо переставить сразу несколько цифр.

    Рассматриваем пары неодинаковых цифр в числе.
    Взаимной их перестановкой можно увеличить число только когда левая цифра меньше правой. 23 -> 32
    Размер увеличения тем меньше, чем правее обе цифры. Они могут идти и не подряд, а, скажем, через одну.

    Коэффициент, который требуется минимизировать – это десятичное число из нулей с единицами в этих позициях. Скажем, лучше поменять позиции 2 и 3, чем 4 и 1, т.к. 110 < 1001 Т.е. при переборе позиций меньше всего хотим двигать левую позицию, пока не переберем все варианты правой:
    Варианты для 4
    0011
    0101
    0110
    1001
    1010
    1100

    Отсюда алгоритм.
    1. справа налево перебираем пары цифр пока не найдётся первая пара, где
      левая меньше правой
    2. меняем их местами.

    Всё.
    Ответ написан
    9 комментариев
  • Как упростить подсчёт нажатий кнопок?

    0xD34F
    @0xD34F Куратор тега JavaScript
    А зачем двигаться "пошагово"? Известны же координаты кнопок - можно вычитать одни из других, и сразу получать количество шагов:

    const keyboard = [
      'abcde123',
      'fghij456',
      'klmno789',
      'pqrst.@0',
      'uvwxyz_/',
    ].reduce((acc, [...row], iRow) => {
      row.forEach((key, iCol) => acc[key] = [ iRow, iCol ]);
      return acc;
    }, {});
    
    function tvRemote(word) {
      let steps = word.length;
      let prev = [ 0, 0 ];
    
      for (const n of word) {
        const curr = keyboard[n];
        steps += Math.abs(prev[0] - curr[0]) + Math.abs(prev[1] - curr[1]);
        prev = curr;
      }
    
      return steps;
    }
    Ответ написан
    2 комментария
  • Как оптимизировать этот JS код?

    Ni55aN
    @Ni55aN
    Алгоритм следующий: для каждого элемента массива вычислять сумму с каждым из предыдущих элементов до тех пор, пока сумма не будет равна указанной. Таким образом ответ будет получен ранее, чем за NxN, так как нужно получить только первую пару (зависит от того, как близко к началу расположены эти элементы)

    function sum_pairs(arr, sum){
     for(var i=1; i<arr.length;i++){
       for(var n=0;n<i;n++){
    		if(arr[n]+arr[i]===sum) return [arr[n], arr[i]];
        }
     }
    }


    Тест быстродействия:

    var a = [...new Array(10000).fill(0).map(_ => Math.round(Math.random()*8)), 14, 16];
    var a1 = a.slice();
    var a2 = a.slice();
    
    console.time('1');
    console.log(sum_pairs1(a1,30))
    console.timeEnd('1');
    
    console.time('2');
    console.log(sum_pairs2(a2,30))
    console.timeEnd('2');


    В моем случае результаты следующие:
    функция из вопроса отработала за 350 мс
    функция из текущего ответа - 110 мс

    К тому же, было специально добавлено два числа в конец массива и сумму равную 30, чтобы sum_pairs2 проделал максимально возможное количество итераций. И еще, sum_pairs1, она же функция из вопроса, мутируем массив, что нехорошо
    Ответ написан
  • Как оптимизировать этот JS код?

    byte916
    @byte916
    Вот это
    for (var i = 0; i < ints.length; i++) {
          if (i <= ind) continue;

    Следует записать так
    for (var i = ind+1; i < ints.length; i++) {
    Этим вы сразу уберете миллионы итераций на больших массивах

    Если таких пар несколько, то возвращается та пара у которой индекс второго числа меньше

    После нахождения первой пары нужно проверить все пары до второго числа пары. После нахождения каждой следующей пары у которой индекс второго числа меньше, нужно смещать верхнюю границу поиска. Так вы избавитесь от массива куда засовываете результат. и значительно увеличите скорость работы.
    Ответ написан
  • Как сравнить все соседние числа в массиве?

    Stalker_RED
    @Stalker_RED
    function foo(data) {
    	return data.reduce((acc, x) => {
        if (acc[acc.length-1]+x !== 0) acc.push(x)
        else acc.pop()
        return acc
      }, [])
    }
    jsfiddle.net/ztfu2a9v
    Ответ написан
    1 комментарий
  • Как сравнить все соседние числа в массиве?

    Ni55aN
    @Ni55aN
    var arr = [1, -1, -1, -2, 2, 1, 2];
    var r = [];
    for(var i=0;i<arr.length;i++){
       if(i== arr.length-1 || arr[i]+arr[i+1]!==0)
          r.push(arr[i]);
       else
          i++;
    }
    Ответ написан
    Комментировать
  • Как сложить часть чисел в массиве?

    rockon404
    @rockon404
    Frontend Developer
    const result = arr.slice(index).reduce((acc, el) => acc + el);

    Массивы индексируются с нуля. В вашем случае, надо прибавлять к позиции 1.
    Ответ написан
    Комментировать
  • Как сложить часть чисел в массиве?

    Vlad_IT
    @Vlad_IT Куратор тега JavaScript
    Front-end разработчик
    arr.slice(ind+1).reduce((val, sum) => sum + val)
    Ответ написан
    Комментировать