/*
 * Copyright 2019 <NAME>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this project except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.lillicoder.projecteuler

import kotlin.math.ceil
import kotlin.math.sqrt

/**
 * Project Euler - Problem #12
 *
 * Highly divisible triangular number
 *
 * Problem 12
 *
 * The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:
 *
 * 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
 *
 * Let us list the factors of the first seven triangle numbers:
 *
 * 1: 1
 * 3: 1,3
 * 6: 1,2,3,6
 * 10: 1,2,5,10
 * 15: 1,3,5,15
 * 21: 1,3,7,21
 * 28: 1,2,4,7,14,28
 *
 * We can see that 28 is the first triangle number to have over five divisors.
 *
 * What is the value of the first triangle number to have over five hundred divisors?
 */

fun main() {
    val divisorCount = 500
    val triangleNumber = Problem12().withDivisorCount(divisorCount)
    println("The triangle number with more than $divisorCount divisors is: $triangleNumber")
}

class Problem12 {

    fun withDivisorCount(count: Int): Long {
        var current = 0L
        var iteration = 1

        var didFind = false
        while (!didFind) {
            current = nextTriangleNumber(current, iteration)
            val divisors = divisors(current)
            if (divisors.size > count) didFind = true

            println("[debug] Triangle number: $current, divisorCount: ${divisors.size}, divisors: $divisors")
            iteration++
        }

        return current
    }

    private fun divisors(number: Long): List<Long> {
        val divisors = mutableListOf(number)
        val half = number / 2
        for (divisor in 1..half) {
            if (number % divisor == 0.toLong()) divisors.add(divisor)
        }

        return divisors
    }

    private fun nextTriangleNumber(lastTriangleNumber: Long, iteration: Int): Long {
        return lastTriangleNumber + iteration;
    }

}