Project Euler: Level 1

Warm up lesson before going into deep..

Problem #1:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

 

C: main.c
#include "test_sum_of_multiplies_impl.h"

int getSumOfMultiplies(const int N)
{
  int ret = 0;
  if (0 == N)
    return ret;
  int i = 1;
  for (; i < N; i++)
    ret += ((i % 3 == 0) || (i % 5 == 0)) ? i : 0;
  return ret;
}

void main()
{
  test_getSumOfMultiplies(-1, &getSumOfMultiplies);
  test_getSumOfMultiplies(0, &getSumOfMultiplies);
  test_getSumOfMultiplies(1, &getSumOfMultiplies);
  test_getSumOfMultiplies(2, &getSumOfMultiplies);
  test_getSumOfMultiplies(3, &getSumOfMultiplies);
  test_getSumOfMultiplies(4, &getSumOfMultiplies);
}
test_sum_of_multiplies_impl.h
#ifndef TEST_SUM_OF_MULTIPLIES_IMPL_H
#define TEST_SUM_OF_MULTIPLIES_IMPL_H

#include 
#include 

#define PASS          "PASSED"
#define FAIL          "FAILED"
#define MAX_FUNC_NAME 254

char* test_func_name[MAX_FUNC_NAME];
int(*test_func)(int) = NULL;

int test_zero()
{
  strcpy_s(test_func_name, (MAX_FUNC_NAME * sizeof(char)), __FUNCTION__);
  return (test_func(0) == 0) ? 1 : 0;
}
int test_below_10()
{
  strcpy_s(test_func_name, (MAX_FUNC_NAME * sizeof(char)), __FUNCTION__);
  return (test_func(10) == 23) ? 1 : 0;
}
int test_below_1000()
{
  strcpy_s(test_func_name, (MAX_FUNC_NAME * sizeof(char)), __FUNCTION__);
  return (test_func(1000) == 233168) ? 1 : 0;
}
int test_below_1001()
{
  strcpy_s(test_func_name, (MAX_FUNC_NAME * sizeof(char)), __FUNCTION__);
  return (test_func(1001) == 234168) ? 1 : 0;
}

// Test 'getSumOfMultiplies' function for specific value
//[in] testType:
//     0 - zero
//     1 - ten
//     2 - thousand
//     3 - thousand and one
//[in] testFunc:
//     Function to be tested:
//     int testFunc ( int maxValue )
void test_getSumOfMultiplies(const int testType, const void* testFunc)
{
  int res = 0;
  test_func_name[0] = 0;
  test_func = testFunc;
  printf("running test:      \t\t");
  switch (testType)
  {
  case 0:
    res = test_zero();
    printf("%s\n", test_func_name);
    break;
  case 1:
    res = test_below_10();
    printf("%s\n", test_func_name);
    break;
  case 2:
    res = test_below_1000();
    printf("%s\n", test_func_name);
    break;
  case 3:
    res = test_below_1001();
    printf("%s\n", test_func_name);
    break;
  default:
    printf("error: invalid test type '%d'\n\n", testType);
    return;
  }
  if (1 == res)
    printf("result: \t\t\t%s\n\n", PASS);
  else
    printf("result: \t\t\t%s\n\n", FAIL);
}
#endif // !TEST_SUM_OF_MULTIPLIES_IMPL_H
C++: main.cpp
#include "unittest.hpp"

int getSumOfMultiplies(const int N)
{
  int ret = 0;
  if (0 == N)
    return ret;
  for (int i = 0; i < N; i++)
    ret += ((i % 3 == 0) || (i % 5 == 0)) ? i : 0;
  return ret;
}

int main()
{
  UnitTest ut(getSumOfMultiplies);
  ut.run(-1);
  ut.run(0);
  ut.run(1);
  ut.run(2);
  ut.run(3);
  ut.run(4);
}
unittest.hpp
#ifndef UNITTEST_HPP
#define UNITTEST_HPP

#include 
#include 

class UnitTest
{
public:
  //[in] testFunc:
  //     Function address to be tested:
  //     int testFunc ( int maxValue )
  UnitTest(const void* funcAddr);

  void printResult(const int& testType);

  // Test 'getSumOfMultiplies' function for specific value
  //[in] testType:
  //     0 - zero
  //     1 - ten
  //     2 - thousand
  //     3 - thousand and one
  void run(const int& testType);

private:
  int test_zero();
  int test_below_10();
  int test_below_1000();
  int test_below_1001();

  int(*m_testFunc)(int);
  std::string m_funcName;
};

#endif // !UNITTEST_HPP

unittest.cpp
#include "unittest.hpp"

const std::string& PASS{ "PASS" };
const std::string& FAIL{ "FAIL" };

UnitTest::UnitTest(const void* funcAddr)
{
  m_testFunc = (int(*)(int))funcAddr;
}

void UnitTest::run(const int & testType)
{
  int res = 0;
  std::cout << "running test:      \t\t";
  printResult(testType);
}

void UnitTest::printResult(const int & testType)
{
  int res = 0;
  switch (testType)
  {
  case 0:
    res = test_zero();
    break;
  case 1:
    res = test_below_10();
    break;
  case 2:
    res = test_below_1000();
    break;
  case 3:
    res = test_below_1001();
    break;
  default:
    std::cout << "error: invalid test type '" << testType << "'\n\n";
    return;
  }
  std::cout << m_funcName << std::endl;
  if (1 == res)
    std::cout << "result: \t\t\t" << PASS << "\n\n";
  else
    std::cout << "result: \t\t\t" << FAIL << "\n\n";
}

int UnitTest::test_zero()
{
  m_funcName = __func__;
  return (m_testFunc(0) == 0) ? 1 : 0;
}

int UnitTest::test_below_10()
{
  m_funcName = __func__;
  return (m_testFunc(10) == 23) ? 1 : 0;
}

int UnitTest::test_below_1000()
{
  m_funcName = __func__;
  return (m_testFunc(1000) == 233168) ? 1 : 0;
}

int UnitTest::test_below_1001()
{
  m_funcName = __func__;
  return (m_testFunc(1001) == 234168) ? 1 : 0;
}
Java:

public class TestGetSumOfMultiplies
{
  public static void main(String[] args)
  {
    UnitTest ut = new UnitTest();
    ut.RunTests();
  }
  
  public static int GetSumOfMultiplies(int N)
  {
    int ret = 0;
    if (0 == N)
      return ret;
    for (int i = 0; i < N; i++)
      ret += ((i % 3 == 0) || (i % 5 == 0)) ? i : 0;
    return ret;
  }
}


public class UnitTest
{
  public void RunTests()
  {
    for(int i=0; i<4; i++)
    {
      System.out.print("running test:      \t\t");
      switch (i)
      {
        case 0:
        TestZero();
        System.out.println(funcName);
        System.out.println("result: \t\t\t" + result + "\n"); 
        continue;
        case 1:
        TestBelow10();
        System.out.println(funcName);
        System.out.println("result: \t\t\t" + result + "\n"); 
        continue;
        case 2:
        TestBelow1000();
        System.out.println(funcName);
        System.out.println("result: \t\t\t" + result + "\n"); 
        continue;
        case 3:
        TestBelow1001();
        System.out.println(funcName);
        System.out.println("result: \t\t\t" + result + "\n"); 
        continue;
        default:
        System.out.println("error: invalid test type..");
        break;
      }
    }
  }
  
  private String funcName;
  private String result;                           
  
  private void TestZero()
  {
    funcName = "TestZero";
    result = (TestGetSumOfMultiplies.GetSumOfMultiplies(0) == 0) ? "PASSED" : "FAILED";
  }

  private void TestBelow10()
  {
    funcName = "TestBelow10";
    result = (TestGetSumOfMultiplies.GetSumOfMultiplies(0) == 0) ? "PASSED" : "FAILED";
  }

  private void TestBelow1000()
  {
    funcName = "TestBelow1000";
    result = (TestGetSumOfMultiplies.GetSumOfMultiplies(0) == 0) ? "PASSED" : "FAILED";
  }

  private void TestBelow1001()
  {
    funcName = "TestBelow1001";
    result = (TestGetSumOfMultiplies.GetSumOfMultiplies(0) == 0) ? "PASSED" : "FAILED";
  }
}

Python:

JavaScript:

Go:

Haskell:

Advertisements

#include “mlpack\core.hpp”

Using mlpack in other applications under Visual Studio 2015


If you want to write your own application and link mlpack against it, you will need to add the include directories of mlpack to your project and add mlpack.lib to the libraries you link against.

Let’s do it accordingly to Once again… guide.

Prerequisites

First of all OpenBLAS libraries should be copied to C:/Windows/System32/ and those are:

~\OpenBLAS.0.2.14.1\lib\native\bin\x64\libgcc_s_seh-1.dll
~\OpenBLAS.0.2.14.1\lib\native\bin\x64\libgfortran-3.dll
~\OpenBLAS.0.2.14.1\lib\native\bin\x64\libopenblas.dll
~\OpenBLAS.0.2.14.1\lib\native\bin\x64\libquadmath-0.dll

or

~/OpenBLAS.0.2.14.1/lib/native/bin/x32/libgcc_s_seh-1.dll
~/OpenBLAS.0.2.14.1/lib/native/bin/x32/libgfortran-3.dll
~/OpenBLAS.0.2.14.1/lib/native/bin/x32/libopenblas.dll
~/OpenBLAS.0.2.14.1/lib/native/bin/x32/libquadmath-0.dll

And also libopenblas.dll.a from:

~/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a

Warning: This is of course optional, but it’s easier later to include each one as Additional Dependency

1. Create New Project

Let’s create new project and paste example code from mlpack tutorials mlpack Input and Output

newProject.png

Warning1: Remember to change Solution Configuration to Debug/Release & Solution Platform to x64/x86 – it’s dependent from how mlpack & armadillo was compiled.

Warning2: Don’t forget to include #include “stdafx.h” & #include <iostream> or just copy this snippet:

#include "stdafx.h"
#include <iostream>

#include "mlpack\core.hpp"

int main(int argc, char** argv)
{
	//pass main's arguments..
	mlpack::CLI::ParseCommandLine(argc, argv);

	//some_timer starts ticking..
	mlpack::Timer::Start("some_timer");

	//some outputs..
	mlpack::Log::Debug << "Compiled with debugging symbols." << std::endl;
	mlpack::Log::Info << "Some test informational output." << std::endl;
	mlpack::Log::Warn << "A warning!" << std::endl;

	//better comment it or..
	//mlpack::Log::Fatal << "Program has crashed." << std::endl;
	mlpack::Log::Warn << "Made it!" << std::endl;

	//some_timer stops..
	mlpack::Timer::Stop("some_timer");

	return 0;
}

2. Compiler Additional Include Directories

Go to Project > Properties > C/C++ > General and add mlpack, armadillo and boost include directories:

~/armadillo-7.400.1/include
~/boost.1.61.0.0/lib/native/include
~/mlpack-2.0.3/build/include

addIncludeDirs.png

3. Compiler Additional Library Directories

Create following folder:

C:/projects/libs

and copy there all files listed below:

mlpack.lib/dll (depends on how mlpack and armadillo target was compiled)
armadillo.lib/dll (same as above)
~/boost_math_c99-vc140.1.60.0.0/lib/native/address-model-64/lib/*
~/boost_program_options-vc140.1.60.0.0/lib/native/address-model-64/lib/*
~/boost_unit_test_framework-vc140.1.60.0.0/lib/native/address-model-64/lib/*
~/boost_serialization-vc140.1.60.0.0/lib/native/address-model-64/lib/*
~/boost_random-vc140.1.60.0.0/lib/native/address-model-64/lib/*

* - whole folder

Go to Project > Properties > Linker > General and add C:/projects/libs

libs.png

4. Linker Additional Dependencies

Go to Project > Properties > Linker > Input and add C:/libraries/mlpack.lib

inputLibs.png

Warning: Additional Dependencies (mlpack.lib or mlpack.dll) should point to the same .lib/.dll from Additional Library Directories (C:/libraries/mlpack.lib or C:/libraries/mlpack.dll)

5. Compile & Run

Output should be:

[WARN ] A warning!
[WARN ] Made it!
Press any key to continue . . .

out1

or in verbose mode with -v as input argument for application:

[INFO ] Some test informational output.
[WARN ] A warning!
[WARN ] Made it!
[INFO ]
[INFO ] Execution parameters:
[INFO ]   help: false
[INFO ]   info: ""
[INFO ]   verbose: true
[INFO ]   version: false
[INFO ]
[INFO ] Program timers:
[INFO ]   some_timer: 0.002928s
[INFO ]   total_time: 0.004584s
Press any key to continue . . .

M90nI

This can be done by going to Project > Properties > Debugging and setting Command Arguments: -v

verb.png


TODO:

  • Prepare weekly challenge
  • Maximize Japanese lessons
  • Finish story with mlpack::backtrace under Windows

Once again…

Yup, once again I’m installing Windows.

There are some people who sometimes are tempted to go for shopping or have some fun at the club, but me… I like from time to time to change the operating system [wat?]. I get the impression then that my computer has been cleared from all of the errors and failures which I did with his previous incarnation.

Okay, seriously, I wanted to finally compile MLPACK under Windows. According to the keonkim's guidelines, it went like clockwork.

========== Build: 40 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

In case I forgot how it was doing:

    1. Configurate MLPACK in Visual Studio 2015 Community:
      • create new project: File > New > Project from Existing Code
      • install dependencies: Tools > NuGet Package Manager > Manage NuGet Packages for Solution > Browse
        • OpenBLAS.0.2.14.1
        • boost.1.61.0
        • boost_unit_test_framework-vc140.1.61.0
        • boost_program_options-vc140.1.61.0
        • boost_random-vc140.1.61.0
        • boost_serialization-vc140.1.61.0
        • boost_math_c99-vc11.0
    2. Build latest stable Armadillo
cmake -G "Visual Studio 14 2015 Win64"- BLAS_LIBRARY:FILEPATH="C:/projects/mlpack-2.0.3/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DLAPACK_LIBRARY:FILEPATH="C:/projects/mlpack-2.0.3/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DCMAKE_PREFIX:FILEPATH="C:/projects/armadillo" -DBUILD_SHARED_LIBS=OFF ..

 3. Build latest stable MLPACK

cmake -G "Visual Studio 14 2015 Win64" -DBLAS_LIBRARY:FILEPATH="C:/projects/mlpack-2.0.3/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DLAPACK_LIBRARY:FILEPATH="C:/projects/mlpack-2.0.3/packages/OpenBLAS.0.2.14.1/lib/native/lib/x64/libopenblas.dll.a" -DARMADILLO_INCLUDE_DIR="C:/projects/armadillo-7.400.1/include" -DARMADILLO_LIBRARY:FILEPATH="C:/projects/armadillo-7.400.1/build/Debug/armadillo.lib" -DBOOST_INCLUDEDIR:PATH="C:/projects/mlpack-2.0.3/packages/boost.1.61.0.0/lib/native/include" -DBOOST_LIBRARYDIR:PATH="C:/projects/mlpack-2.0.3/packages/boost_libs" -DDEBUG=ON -DPROFILE=OFF ..