Определить что элементы одной коллекции являются квадратными корнями другой

Подскажите можно-ли написать более оптимальный алгоритм. Задача звучит так:

Нужно проверить что все в коллекции numbers являются квадратными корнями чисел в коллекции squares. Коллекции отсортированы по возрастанию и не имеют отрицательных значений.

update: если коллекции разной длины то считаем это как false

Примеры входных данных и ответы:
IN: {1, 2}, {1, 4} OUT: TRUE

IN: {1, 3, 5}, {1, 9, 25, 25} OUT: FALSE

Сигнатура функции:

bool TestForSquares(IEnumerable<int> numbers, IEnumerable<int> squares)

Моё решение:

public static bool TestForSquares(IEnumerable<int> numbers, IEnumerable<int> squares) {
    var isFirstIteration = true;
    var numbersEnumerator = numbers.GetEnumerator();
    var squaresEnumerator = squares.GetEnumerator();

    while (true) {
        bool numberHasNext = numbersEnumerator.MoveNext();
        bool squareHasNext = squaresEnumerator.MoveNext();

        if(numberHasNext != squareHasNext) {
            // случай когда две коллекции имеют разный размер

            return false;
        }

        if(!numberHasNext && !squareHasNext) {

            if (isFirstIteration) {
                // случай когда две коллекции пусты
                return false;
            }

            break;
        }

        var testData = numbersEnumerator.Current * numbersEnumerator.Current;
        if(testData != squaresEnumerator.Current) {
            return false;
        }

        isFirstIteration = false;
    }

    return true;
}

p.s.

Так же интересует решение с той же оптимальностью но не такое многословное.


Ответы (2 шт):

Автор решения: TryBetter

Может быть можно возвести в квадрат все элементы одного списка, а затем проверить, содержит ли один список все элементы второго, используя метод Intersect: https://stackoverflow.com/questions/3274541/check-if-one-ienumerable-contains-all-elements-of-another-ienumerable ?

→ Ссылка
Автор решения: CrazyElf

В C# сейчас есть аналог питоновского Zip, так что можно коротко и просто проверять примерно так:

coll1.Zip(coll2).All(x => x.First * x.First == x.Second)

Но проверку на совпадение длины коллекций надо делать дополнительно. А вот делать эту проверку до или после сравнения элементов коллекций - это зависит от природы коллекций. Если это готовые массивы или там списки, то можно проверить длину заранее, так будет быстрее всего работать. А если это потоковые данные, и особенно если их вообще нельзя перебирать второй раз, то тут решение с Zip вообще не подойдёт, наверное.

→ Ссылка