Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   объясните условие задачи (https://javascript.ru/forum/misc/82565-obyasnite-uslovie-zadachi.html)

vurdalak21 26.05.2021 12:38

объясните условие задачи
 
Alice and Bob take turns playing a game, with Alice starting first.

There are n stones in a pile. On each player's turn, they can remove a stone from the pile and receive points based on the stone's value. Alice and Bob may value the stones differently.

You are given two integer arrays of length n, aliceValues and bobValues. Each aliceValues[i] and bobValues[i] represents how Alice and Bob, respectively, value the ith stone.

The winner is the person with the most points after all the stones are chosen. If both players have the same amount of points, the game results in a draw. Both players will play optimally. Both players know the other's values.

Determine the result of the game, and:

If Alice wins, return 1.
If Bob wins, return -1.
If the game results in a draw, return 0.


Example 1:

Input: aliceValues = [1,3], bobValues = [2,1]
Output: 1
Explanation:
If Alice takes stone 1 (0-indexed) first, Alice will receive 3 points.
Bob can only choose stone 0, and will only receive 2 points.
Alice wins.
Example 2:

Input: aliceValues = [1,2], bobValues = [3,1]
Output: 0
Explanation:
If Alice takes stone 0, and Bob takes stone 1, they will both have 1 point.
Draw.
Example 3:

Input: aliceValues = [2,4,3], bobValues = [1,6,7]
Output: -1
Explanation:
Regardless of how Alice plays, Bob will be able to have more points than Alice.
For example, if Alice takes stone 1, Bob can take stone 2, and Alice takes stone 0, Alice will have 6 points to Bob's 7.
Bob wins.

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

Alexandroppolus 26.05.2021 13:43

Число в массиве означает, сколько очков i-й камень приносит игроку.
Суть второго примера: если бы Алиса пожадничала и взяла камень [1], получив 2 очка, то Боб забрал бы камень [0] и 3 очка, с выигрышем.
Потому Алиса берет камень [0] "назло Бобу", теряя очки, но Боб при этом теряет больше.

vurdalak21 26.05.2021 15:51

Alexandroppolus,
спасибо за объяснение. смог сделать только в императивном подходе, теперь хочу сделать в декларативном подходе(функциональное программирование), какими методами можно воспользоваться для решения данной задачи?

let stoneGameVI = function (aliceValues, bobValues) {
    let winAlice = 0;
    let winBob = 0;
    let arr = [];
    for (let i = 0; i < aliceValues.length; i++) {
        arr.push([aliceValues[i] + bobValues[i], aliceValues[i], bobValues[i]]);

    }
    arr.sort((a, b) => b[0] - a[0]);
    for (let i = 0; i < aliceValues.length; i += 2) {
        winAlice += arr[i][1]
        if (arr[i + 1] !== undefined) {
            winBob += arr[i + 1][2]
        }
    }

    if (winAlice > winBob) return 1
    if (winAlice === winBob) return 0
    if (winAlice < winBob) return -1
};

prototip 26.05.2021 21:27

Пример для последних трех строк:

if (winAlice > winBob) return 1
    if (winAlice === winBob) return 0
    if (winAlice < winBob) return -1
//… станет…

function getResult(scoreA, scoreB){
    return scoreA > scoreB ? 1 : scoreA < scoreB ? -1 : 0
}

let stoneGameVI = function (aliceValues, bobValues) {

    ....

    return getResult(winAlice, winBob)
}

Затем сделайте что-нибудь подобное для обоих циклов, и ваша основная функция будет довольно чистой.

prototip 26.05.2021 21:37

С первым циклом будет так:
const arr = aliceValues.map( (e, i) => [e + bobValues[I], e, bobValues[I]);

Ваш второй for цикл немного сложнее. Его придется преобразовать с помощью map / filter / reduce.
Я слабо решаю такие задачки, помог чем смог)

ksa 27.05.2021 10:28

Цитата:

Сообщение от prototip
map / filter

Недавно тут разбирали быстродействие разных подходов...
Так "обычный" цикл уделал все остальные варианты. ;)

vurdalak21 27.05.2021 11:03

Ребята, фигня получается, помогите пожалуйста

function getResult(scoreA, scoreB){
    return scoreA > scoreB ? 1 : scoreA < scoreB ? -1 : 0
}

const stoneGameVI = function (aliceValues, bobValues) {

    return getResult(winAlice, winBob)
}
                                        
const arr = function(aliceValues) {
    return aliceValues.map( (e, i) => [e + bobValues[1], e, bobValues[1] ])
}

const subtract = (a, b) => b[0] - a[0];
const getAmount = (e, i) => [e + aliceValues[1], e, aliceValues[1] ];
const sumAmount = (currentTotalAmount, order) => currentTotalAmount + order[1];

const winAlice = function(aliceValues) {
return aliceValues
    .filter(subtract)
    .map(getAmount)
    .reduce(sumAmount, 0);
}
    const sumbob = (currentTotalAmount, order) => currentTotalAmount + order[2];

const bobValues = function(bobValues) {
    return bobValues
    .reduce(sumbob, 0);
};

Alexandroppolus 27.05.2021 12:33

Цитата:

Сообщение от ksa (Сообщение 537198)
Недавно тут разбирали быстродействие разных подходов...
Так "обычный" цикл уделал все остальные варианты. ;)

само собой, вызов функции не бесплатный (во всяких там forEach - на каждой итерации). На хабре статья недавно была, так вот, функция вообще без параметров и локальных переменных отжирает порядка 80 байт на стеке, там чисто служебная инфа. Если какой-либо "полезной нагрузки" внутри функции нет, то эти "копейки" будут вполне ощутимы.

потому если надо упороться в скорость, забывают про всякие ФП-шные красивости и используют старый добрый.


Часовой пояс GMT +3, время: 20:37.