ゼロから始めるcodewars kata yield とフィボナッチ数列

codewars kataではプログラミングと実用英語が同時に学べます。
githubアカウントがあれば30秒で始められます
興味が沸いたら今すぐここから始めよう

ちなみにpython以外でも多くの言語でチャレンジ出来ます


# Q1.https://www.codewars.com/kata/54d512e62a5e54c96200019e/train/python

```
Given a positive number n > 1 find the prime factor decomposition of n. The result will be a string with the following form :

 "(p1**n1)(p2**n2)...(pk**nk)"
with the p(i) in increasing order and n(i) empty if n(i) is 1.

Example: n = 86240 should return "(2**5)(5)(7**2)(11)"
```
正の整数nを与えられたときそれを構成する素数を返せ

my A.

```python

def primeFactors(b ):

    ps = []
    ns = []
    i = 1
    while  not b==1:
        i += 1
        j = 0
        while not b % i:
            b = b / (i)
            j += 1
        if not j == 0:        
            ps.append(i)
            ns.append(j)
            
    return ''.join([ '({})'.format(p) if  n == 1 else '({}**{})'.format(p,n) for p,n in zip(ps,ns)])
   
```
3000ms

はじめてのattempt成功

```python

def primeFactors(b ):

    k = 100000000000000
    ps = []
    ns = []
    
    for i in range(2,k):
        mod = 0    
        j = 0
        if b ==1:
            break
        while mod == 0:
            div,mod = divmod(b,i)
            if mod == 0:
                b = b / (i)
                j += 1
        if not j == 0:        
            ps.append(i)
            ns.append(j)
            
    return ''.join([ '({})'.format(p) if  n == 1 else '({}**{})'.format(p,n) for p,n in zip(ps,ns)])
```
5500ms


Best Answer

```python

def primeFactors(n):
    ret = ''
    for i in range(2, n + 1):
        num = 0
        while(n % i == 0):
            num += 1
            n /= i
        if num > 0:
            ret += '({}{})'.format(i, '**%d' % num if num > 1 else '')
        if n == 1:
            return ret
```
3000ms
私のが結果をリストで保存→文字列に対し
こっちは初めから文字列
実行時間はほぼ変わらないけどどっちがいいんだろう

# Q2.https://www.codewars.com/kata/559a28007caad2ac4e000083/solutions/python

```
The drawing shows 6 squares the sides of which have a length of 1, 1, 2, 3, 5, 8. It's easy to see that the sum of the perimeters of these squares is : 4 * (1 + 1 + 2 + 3 + 5 + 8) = 4 * 20 = 80

Could you give the sum of the perimeters of all the squares in a rectangle when there are n + 1 squares disposed in the same manner as in the drawing:
```
フィボナッチ数列の和の4倍を求めよ


my A.https://www.codewars.com/kata/559a28007caad2ac4e000083/train/python

```python

def perimeter(n):
    # your code
    fibo = [1,1]
    for i in range(n-1):
        fibo.append(fibo[-1] + fibo[-2] )
    return sum(fibo)*4
```

best A1.

```python
def fib(n):
    a, b = 0, 1

    for i in range(n+1):
        if i == 0:
            yield b 
        else:
            a, b = b, a+b
            yield b
        

def perimeter(n):
    return sum(fib(n)) * 4
```
yieldは、関数を一時的に実行停止させることが出来る機能を持つ文で、
returnではなくyieldを使う事でリストなどに格納せず要素を1つずつ返すことが出来る
どういう事かというと

```python
length = 5
generator  =fib(length)
for i in range(length):
    print(next(generator),end=', ')
```
out

```
1, 1, 2, 3, 5, 
```
このように関数内のforループを途中で止めて値を返すことが出来る。
このsumを取っている様だ。
詳しくは[解説サイト](https://www.sejuku.net/blog/23716)などで

best A2.

```python

def perimeter(n):
    a, b = 1, 2
    while n:
        a, b, n = b, a + b, n - 1
    return 4 * (b - 1)
```
これはどういう事かというとこの式を使っているようです

$$\sum a_n = a_{n+2} - a_{1} $$
導出してみます
もっとも使う式は$$a_{k}=a_{k-1}+a_{k-2}$$だけですが…
$$a_{n+2}$$をもとに考えていきます。
$$a_{n+2} = a_{n+1} + a_{n}$$
$$a_{n+2} = (a_{n} + a_{n-1}) + a_{n}$$
$$a_{n+2} =  a_{n} + 2a_{n-1} + a_{n-2}$$
以降係数が2となる項を、係数が1になるように展開していくと
$$a_{n+2} =  a_{n} + a_{n-1} + 2a_{n-2}+ a_{n-3}$$
$$…$$

$$a_{n+2} =  a_{n} + a_{n-1} + a_{n-2}+…+a_{3}+2a_{1} + a_{0}$$
となり移行して
$$a_{n+2} - a_{1} = \sum a_n $$
となります。