#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N_SIZE 2
typedef size_t max_num;
max_num func(max_num n, max_num **base);
max_num **mem_init(max_num size);
void print_matrix(max_num **arr, max_num size)
{
max_num i =-1, j = -1;
while (++i < size)
{
j = -1;
while (++j < size)
printf("%zu ", arr[i][j]);
printf("\n");
}
printf("\n");
}
void ft_memset(max_num **arr, max_num size)
{
max_num i = -1, j = -1;
while (++i < size)
{
j = -1;
while (++j < size)
arr[i][j] = 0;
}
}
int main(int ac, char *av[])
{
max_num base[N_SIZE][N_SIZE] = {{1, 1}, {1, 0}};
max_num **base_a = mem_init(N_SIZE);
max_num arg = 0;
max_num i =0, j = 0;
while (i < N_SIZE)
{
j = 0;
while (j < N_SIZE)
{
base_a[i][j] = base[i][j];
j++;
}
i++;
}
arg = atoi(av[1]); // n을 받음
printf("%zu\n", func(arg - 1, base_a)); // n-1을 계산.
}
max_num **mem_init(max_num size)
{
max_num **arr = (max_num **)malloc(sizeof(max_num *) * size);
max_num i = 0;
while (i < size)
{
arr[i] = (max_num *)malloc(sizeof(max_num) * size);
i++;
}
return (arr);
}
void mem_free(max_num size, max_num **arr)
{
max_num i = 0;
while (i < size)
{
free(arr[i]);
i++;
}
free(arr);
}
// 행렬곱 계산.
max_num **matrix_mutiply(max_num **src1, max_num **srcN_SIZE)
{
max_num i = -1, j = -1, k = -1;
max_num **arr = mem_init(N_SIZE);
while (++i < N_SIZE)
{
j = -1;
while (++j < N_SIZE)
{
k = -1;
while (++k < N_SIZE)
{
arr[i][j] += src1[i][k] * srcN_SIZE[k][j];
}
}
}
return (arr);
}
void mem_cpy(max_num **dst, max_num **src, max_num size)
{
max_num i = 0, j = 0;
while (i < size)
{
j = 0;
while (j < size)
{
dst[i][j] = src[i][j];
j++;
}
i++;
}
}
max_num func(max_num n, max_num **base)
{
max_num **temp;
max_num **odd_base = mem_init(N_SIZE);
max_num i = 0;
ft_memset(odd_base, N_SIZE);
//Identity matrix.
while (i < N_SIZE)
{
odd_base[i][i] = 1;
i++;
}
// 홀수면 단위벡터와 베이스를 곱함.
while (n > 1)
{
if (n % 2 == 1)
{
temp = matrix_mutiply(base, odd_base);
mem_cpy(odd_base, temp, N_SIZE);
mem_free(N_SIZE, temp);
n -= 1;
printf("odd_base\n");
print_matrix(odd_base, N_SIZE);
}
else
{
printf("n:%zu\n", n);
temp = matrix_mutiply(base, base);
mem_cpy(base, temp, N_SIZE);
print_matrix(base, N_SIZE);
mem_free(N_SIZE, temp);
n /= 2;
}
}
temp = matrix_mutiply(odd_base, base);
mem_cpy(base, temp, N_SIZE);
mem_free(N_SIZE, temp);
print_matrix(base, N_SIZE);
return (base[1][0] + base[1][1]);
}