Let's take an integer number, ``` start``` and let's do the iterative process described below:

- we take its digits and raise each of them to a certain power, ```n```, and add all those values up. (result = ```r1```)

- we repeat the same process with the value ```r1``` and so on, ```k``` times.

Let's do it with ```start = 420, n = 3, k = 5```

```
420 ---> 72 (= 4³ + 2³ + 0³) ---> 351 (= 7³ + 2³) ---> 153 ---> 153 ----> 153
```

We can observe that it took ```3``` steps to reach a cyclical pattern ```[153]```(```h = 3```). The length of this cyclical pattern is ```1```, ```patt_len```. The last term of our k operations is 153, ```last_term```

Now, ```start = 420, n = 4, k = 30```

```
420 ---> 272 ---> 2433 ---> 434 ---> 593 ---> 7267 --->
6114 ---> 1554 ---> 1507 ---> 3027 ---> 2498 ---> 10929 --->
13139 ---> 6725 ---> 4338 ---> 4514 ---> 1138 ---> 4179 ---> 9219 ---> 
13139 ---> 6725 ---> 4338 ---> 4514 ---> 1138 ---> 4179 ---> 9219 ---> 
13139 ---> 6725 ---> 4338 ---> 4514 ---> 1138 ---> 4179 ---> 9219......
```

In this example we can observe that the cyclical pattern (```cyc_patt_arr```) is ```[13139, 6725, 4338, 4514, 1138, 4179, 9219]``` with a length of ```7```, (```patt_len = 7```), and it took ```12``` steps (```h = 12```) to reach the cyclical pattern. The last term after doing ```30``` operations is ```1138```

Make the function ```sum_pow_dig_seq()```, that receives the arguments in the order shown below with the corresponding output:
```python
sum_pow_dig_seq(start, n, k) ---> [h, cyc_patt_arr, patt_len, last_term]
```

For our given examples, 
```python
sum_pow_dig_seq(420, 3, 5) == [3, [153], 1, 153]

sum_pow_dig_seq(420, 4, 30) == [12, [13139, 6725, 4338, 4514, 1138, 4179, 9219], 7, 1138]
```

Constraints for tests:
```
500 ≤ start ≤ 8000
2 ≤ n ≤ 9
100 * n ≤ k ≤ 200 * n
```
Do your best!

Source: codewars | Difficulty: EASY
Tags: Data structures

Mathematics

Complete search

Starter code: def sum_pow_dig_seq(start, n, k):
	

Solutions:
def sum_pow_dig_seq(num, exp, k):
	seq = []
	for step in range(k):
		seq.append(num)
		num = sum((int(dig) ** exp for dig in str(num)))
		if num in seq:
			cycle_start = seq.index(num)
			cycle = seq[cycle_start:]
			last_term = cycle[(k - cycle_start) % len(cycle)]
			return [cycle_start, cycle, len(cycle), last_term]
	return [0, [], 0, num]


def sum_pow_dig_seq(start, n, k):
	seq = [start]
	num = start
	for i in range(k):
		num = sum([int(x) ** n for x in str(num)])
		if num in seq:
			loop_starts_from = seq.index(num)
			loop_array = seq[loop_starts_from:]
			tail_size = loop_starts_from
			loop_size = len(loop_array)
			last_term = loop_array[(k - tail_size) % loop_size]
			return [tail_size, loop_array, loop_size, last_term]
		seq.append(num)
	else:
		return [len(seq), [], 0, seq[-1]]


def sum_pow_dig_seq(start, n, k):
	seen = [start]
	for i in range(k):
		r1 = sum(map(lambda x: x ** n, map(int, str(seen[-1]))))
		if r1 in seen:
			h = seen.index(r1)
			cyc_patt_arr = seen[h:]
			patt_len = len(seen) - h
			last_term = cyc_patt_arr[(k - i - 1) % patt_len]
			break
		seen.append(r1)
	return [h, cyc_patt_arr, patt_len, last_term]


def sum_of_digits_pow(n, e):
	return sum([i ** e for i in map(int, str(n))])

def sum_pow_dig_seq(start, e, k):
	h = 0
	(cyc_patt_arr, sums) = ([], [])
	for i in range(1, k + 1):
		start = sum_of_digits_pow(start, e)
		if not cyc_patt_arr and start in sums:
			cyc_patt_arr = [j for j in sums[sums.index(start):]]
			h = sums.index(start) + 1
			return [h, cyc_patt_arr, len(cyc_patt_arr), cyc_patt_arr[(k - i) % len(cyc_patt_arr)]]
		sums.append(start)


def sum_pow_dig_seq(start, n, k):

	def next_(v):
		return sum((int(c) ** n for c in str(v)))
	history = []
	history_set = set()
	x = start
	while True:
		if x in history_set:
			i = history.index(x)
			cyc = history[i:]
			if k < len(history):
				return [i, cyc, len(cyc), history[k]]
			return [i, cyc, len(cyc), cyc[(k - i) % len(cyc)]]
		history.append(x)
		history_set.add(x)
		x = next_(x)


def sum_pow_dig_seq(start, n, k):
	(cycle, l, h, drop) = (set(), [], -1, False)
	for i in range(k):
		start = sum((int(d) ** n for d in str(start)))
		if h != -1 and start in cycle:
			break
		if h == -1 and start in cycle:
			(cycle, h, l) = (set(), i, [])
		cycle.add(start)
		l.append(start)
	return [h - len(l) + 1, l, len(l), l[(k - i - 1) % len(l)]]


def sum_pow_dig_seq(start, n, k):
	x = start
	series = []
	seen_at = {}
	i = 0
	while x not in seen_at:
		series.append(x)
		seen_at[x] = i
		x = sum((int(d) ** n for d in str(x)))
		i += 1
	i_first = seen_at[x]
	cycle_length = i - i_first
	if k >= i:
		k = i_first + (k - i_first) % cycle_length
	return [i_first, series[i_first:], cycle_length, series[k]]


def sum_pow_dig_seq(start, n, k):
	r = []
	for i in range(0, k):
		c = 0
		for d in str(start):
			c += int(d) ** n
		r.append(c)
		start = c
	for i in range(0, k):
		if r[i] in r[i + 1:]:
			posE = r.index(r[i], i + 1)
			if posE >= 0:
				if r[i:posE - 1] == r[posE:posE + posE - 1 - i]:
					posS = i
					break
	return [posS + 1, r[posS:posE], posE - posS, start]


def sum_pow_dig_seq(start, n, k):
	li = []
	for _ in range(k):
		r = sum([j ** n for j in map(int, str(start))])
		if r in li:
			reach = n = li.index(r) + 1
			series = li[li.index(r):]
			s_l = len(series)
			while n + s_l <= k:
				n += s_l
			return [reach, series, s_l, series[k - n]]
		li.append(r)
		start = r


def sum_pow_dig_seq(n, e, k):
	path = [n]
	while True:
		n = sum((int(d) ** e for d in str(n)))
		if n in path:
			break
		path.append(n)
	h = path.index(n)
	loop = path[h:]
	return [h, loop, len(loop), loop[(k - h) % len(loop)]]