Avatar of shmibs

shmibs's solution

to Sum Of Multiples in the C Track

Published at Jul 13 2018 · 1 comment
Instructions
Test suite
Solution

Note:

This solution was written on an old version of Exercism. The tests below might not correspond to the solution code, and the exercise may have changed since this code was written.

Given a number, find the sum of all the unique multiples of particular numbers up to but not including that number.

If we list all the natural numbers below 20 that are multiples of 3 or 5, we get 3, 5, 6, 9, 10, 12, 15, and 18.

The sum of these multiples is 78.

Getting Started

Make sure you have read the C page on the Exercism site. This covers the basic information on setting up the development environment expected by the exercises.

Passing the Tests

Get the first test compiling, linking and passing by following the three rules of test-driven development.

The included makefile can be used to create and run the tests using the test task.

make test

Create just the functions you need to satisfy any compiler errors and get the test to fail. Then write just enough code to get the test to pass. Once you've done that, move onto the next test.

As you progress through the tests, take the time to refactor your implementation for readability and expressiveness and then go on to the next test.

Try to use standard C99 facilities in preference to writing your own low-level algorithms or facilities by hand.

Source

A variation on Problem 1 at Project Euler http://projecteuler.net/problem=1

Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

test_sum_of_multiples.c

#include "vendor/unity.h"
#include "../src/sum_of_multiples.h"

#define NUM_OF_ELEMENTS(a)    (sizeof(a) / sizeof(a[0]))

void setUp(void)
{
}

void tearDown(void)
{
}

void test_sum_of_multiples_of_3_and_5_up_to_1(void)
{
   const unsigned int multiples[] = { 3, 5 };
   TEST_ASSERT_EQUAL(0,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      1));
}

void test_sum_of_multiples_of_3_and_5_up_to_4(void)
{
   TEST_IGNORE();               // delete this line to run test
   const unsigned int multiples[] = { 3, 5 };
   TEST_ASSERT_EQUAL(3,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      4));
}

void test_sum_of_multiples_of_3_and_5_up_to_10(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 3, 5 };
   TEST_ASSERT_EQUAL(23,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      10));
}

void test_sum_of_multiples_of_3_and_5_up_to_100(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 3, 5 };
   TEST_ASSERT_EQUAL(2318,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      100));
}

void test_sum_of_multiples_of_3_and_5_up_to_1000(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 3, 5 };
   TEST_ASSERT_EQUAL(233168,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      1000));
}

void test_sum_of_multiples_of_7_13_and_17_up_to_20(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 7, 13, 17 };
   TEST_ASSERT_EQUAL(51,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      20));
}

void test_sum_of_multiples_of_4_and_6_up_to_15(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 4, 6 };
   TEST_ASSERT_EQUAL(30,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      15));
}

void test_sum_of_multiples_of_5_6_and_8_up_to_150(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 5, 6, 8 };
   TEST_ASSERT_EQUAL(4419,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      150));
}

void test_sum_of_multiples_of_5_and_25_up_to_51(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 5, 25 };
   TEST_ASSERT_EQUAL(275,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      51));
}

void test_sum_of_multiples_of_43_and_47_up_to_10000(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 43, 47 };
   TEST_ASSERT_EQUAL(2203160,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      10000));
}

void test_sum_of_multiples_of_1_up_to_100(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 1 };
   TEST_ASSERT_EQUAL(4950,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      100));
}

void test_sum_of_multiples_of_0_up_to_100(void)
{
   TEST_IGNORE();
   const unsigned int multiples[] = { 0 };
   TEST_ASSERT_EQUAL(0,
                     sum_of_multiples(multiples, NUM_OF_ELEMENTS(multiples),
                                      100));
}

void test_no_multiples_given(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL(0, sum_of_multiples(NULL, 0, 10000));
}

void test_null_ptr_multiple(void)
{
   TEST_IGNORE();
   TEST_ASSERT_EQUAL(0, sum_of_multiples(NULL, 3, 10000));
}

int main(void)
{
   UnityBegin("test/test_sum_of_multiples.c");

   RUN_TEST(test_sum_of_multiples_of_3_and_5_up_to_1);
   RUN_TEST(test_sum_of_multiples_of_3_and_5_up_to_4);
   RUN_TEST(test_sum_of_multiples_of_3_and_5_up_to_10);
   RUN_TEST(test_sum_of_multiples_of_3_and_5_up_to_100);
   RUN_TEST(test_sum_of_multiples_of_3_and_5_up_to_1000);
   RUN_TEST(test_sum_of_multiples_of_7_13_and_17_up_to_20);
   RUN_TEST(test_sum_of_multiples_of_4_and_6_up_to_15);
   RUN_TEST(test_sum_of_multiples_of_5_6_and_8_up_to_150);
   RUN_TEST(test_sum_of_multiples_of_5_and_25_up_to_51);
   RUN_TEST(test_sum_of_multiples_of_43_and_47_up_to_10000);
   RUN_TEST(test_sum_of_multiples_of_1_up_to_100);
   RUN_TEST(test_sum_of_multiples_of_0_up_to_100);
   RUN_TEST(test_no_multiples_given);
   RUN_TEST(test_null_ptr_multiple);

   UnityEnd();
   return 0;
}

src/sum_of_multiples.c

#include "sum_of_multiples.h"

#include <stdbool.h>

static bool is_mult(const unsigned *a, unsigned count, unsigned n)
{
	unsigned i;

	for(i = 0; i < count; i++) {
		if( !(n % a[i]) )
			return true;
	}

	return false;
}

unsigned sum_of_multiples(const unsigned *a, unsigned count, unsigned max)
{
	unsigned i, sum = 0;

	for(i = 1; i < max; i++)
		sum += is_mult(a, count, i) ? i : 0;

	return sum;
}

src/sum_of_multiples.h

#ifndef SUM_OF_MULTIPLES_H
#define SUM_OF_MULTIPLES_H

unsigned sum_of_multiples(const unsigned *mults, unsigned count, unsigned max);

#endif

Community comments

Find this solution interesting? Ask the author a question to learn more.
Avatar of shmibs

jus formatting clarity; no semantic changes

What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

  • What compromises have been made?
  • Are there new concepts here that you could read more about to improve your understanding?