Tribonacci Sequence(6kyu)
codewars地址
Instructions
Well met with Fibonacci bigger brother, AKA Tribonacci.
As the name may already reveal, it works basically like a Fibonacci, but summing the last 3 (instead of 2) numbers of the sequence to generate the next. And, worse part of it, regrettably I won’t get to hear non-native Italian speakers trying to pronounce it ?
So, if we are to start our Tribonacci sequence with [1, 1, 1] as a starting input (AKA signature), we have this sequence:
[1, 1 ,1, 3, 5, 9, 17, 31, …]
But what if we started with [0, 0, 1] as a signature? As starting with [0, 1] instead of [1, 1] basically shifts the common Fibonacci sequence by once place, you may be tempted to think that we would get the same sequence shifted by 2 places, but that is not the case and we would get:
[0, 0, 1, 1, 2, 4, 7, 13, 24, …]
Well, you may have guessed it by now, but to be clear: you need to create a fibonacci function that given a signature array/list, returns the first n elements - signature included of the so seeded sequence.
Signature will always contain 3 numbers; n will always be a non-negative number; if n == 0, then return an empty array (except in C return NULL) and be ready for anything else which is not clearly specified ?
问题描述这么多,其实就是一个点将我们熟知的Tribonacci由后2位求下一数,变为3个数来求值
MySolution:
#include <stdlib.h>
long long *tribonacci(const long long signature[3], size_t n) {
long long *result = malloc(n*sizeof(long long));
if(n==0) return NULL;
else{
for(int i=0; i<3; ++i) result[i] = signature[i];
for(int i=3; i<n; ++i) result[i] = result[i-3]+result[i-2]+result[i-1];
}
return result;
}
我们首先动态分配内存给出目标数组,然后判断给的目标数组大小是否为0,是就返回0,不是先将前3位赋值(这样也方便n<=3情况),然后再按照数学上f[n]=f[n-3]+f[n-2]+f[n-1]对新数组进行填充。
这里用到了size_t,这个和int一样表示整型,但是他是用来计数大小的,sizeof()的结果类型就是size_t
Sample Tests:
#include <criterion/criterion.h>
#include <stdlib.h>
#include <stdio.h>
#define ASSERT_ARR_EQ(expected, submitted, sz) \
if(sz == 0 && submitted != NULL) \
{ free(submitted); submitted = NULL; \
cr_assert(0, "n == 0, should return NULL\n"); } \
for(size_t i=0; i<sz; i++) \
if(submitted[i] != expected[i]) \
cr_assert(0, \
"Incorrect value at index %i: %i should equal %i\n", \
i, submitted[i], expected[i]); \
cr_assert(1);
long long *tribonacci(const long long signature[3], size_t n);
Test(Sample_Tests, should_pass_all_the_tests_provided) {
{
const long long signature[3] = {1, 1, 1};
const size_t n = 10;
const long long expected[10] = {1, 1, 1, 3, 5, 9, 17, 31, 57, 105};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {0, 0, 1};
const size_t n = 10;
const long long expected[10] = {0, 0, 1, 1, 2, 4, 7, 13, 24, 44};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {0, 1, 1};
const size_t n = 10;
const long long expected[10] = {0, 1, 1, 2, 4, 7, 13, 24, 44, 81};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {1, 0, 0};
const size_t n = 10;
const long long expected[10] = {1, 0, 0, 1, 1, 2, 4, 7, 13, 24};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {0, 0, 0};
const size_t n = 10;
const long long expected[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {0, 0, 0};
const size_t n = 10;
const long long expected[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {1, 2, 3};
const size_t n = 10;
const long long expected[10] = {1, 2, 3, 6, 11, 20, 37, 68, 125, 230};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {3, 2, 1};
const size_t n = 10;
const long long expected[10] = {3, 2, 1, 6, 9, 16, 31, 56, 103, 190};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {42, 55, 70};
const size_t n = 1;
const long long expected[1] = {42};
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
free(submitted);
submitted = NULL;
}
{
const long long signature[3] = {300, 200, 100};
const size_t n = 0;
const long long *expected = NULL;
const long long *submitted = tribonacci(signature, n);
ASSERT_ARR_EQ(expected, submitted, n);
}
}
注:因为前面2次写,对于引用的文献,我都是直接把地址放出来,感觉不好,现在开始标明文献