Маленькая, но интересная задача о спирали


#1

Рассмотрим спираль, в которой, начиная с 1 в центре, последовательно расставим числа по часовой стрелке, пока не получится спираль 5 на 5

21 22 23 24 25
20  7  8  9 10
19  6  1  2 11
18  5  4  3 12
17 16 15 14 13

Можно проверить, что сумма всех чисел на диагоналях равна 101.
101 = 21 + 25 + 7 + 9 + 1 + 5 + 3 + 17 + 13
Чему будет равна сумма чисел на диагоналях, для спирали размером 1091 на 1091?
Я решил, но мне интересны алгоритмы других. То есть цифра мне итоговая ни к чему, мне интересно само решение.

Решением считается функция, в которую можно в качестве входного параметра поставить размер спирали по одной стороне (в примере это 1091) и получить в вывод сумму всех чисел на диагоналях.


#2

а ну вот это объясни?


#3

Дописал в первом посте пояснение


#4

Привет! Мое решение такое:

struct Spiral {
    var side: Int!
   
    init(withSide side: Int) {
        self.side = side
    }
    
    lazy var sumOfDiagonalNumbers: Int = {
        var startSquare: Int = 2
        let endSquare: Int = ((self.side - 1) / 2) + 1
        var sum: Int = 1
        
        while(startSquare <= endSquare) {
            let numsInSide = (startSquare * 2) - 1
            let endNum = numsInSide * numsInSide
            
            for i in 0...3 {
                sum += endNum - (numsInSide - 1) * i
            }
            
            startSquare += 1
        }

        return sum
    }()
}

var spiral = Spiral(withSide: 1091)

print(spiral.sumOfDiagonalNumbers)  // 866327641

#5

И оно у вас работает в таком виде?
Я скопировал в плэйграунд и у меня в строке:

let endSquare: Int = ((side - 1) / 2) + 1

требует self.side, а не просто side


#6

Верно, в XCode 9 beta не требует, в XCode 8.x требует. Вообще-то лучше именно с self.


#7

Могу я поинтересоваться - а в связи с чем вы использовали именно структуру? То есть я, например, в своем решении писал банально функцию. Структура более правильна с точки зрения ООП? Или какая то еще причина?


#8

Ну я в контексте задачи увидел некую абстракцию (числовую спираль), но не нашел поведения, присущего классу, например наследования, т.к. она очень специфичная. У спирали есть характеристики, такие как кол-во “витков” и какие-то еще свойства, в том числе вычисляемые. Конечно, если будет, к примеру, спираль из символов, можно выделить какие-либо общие признаки и создать базовый класс Spiral со свойством кол-ва витков, а от него унаследовать NumericSpiral и SymbolSpiral - зависит от Ваших потребностей.