mirror of
https://codeberg.org/andyscott/exercism.git
synced 2024-12-21 22:33:11 -05:00
C++: completed Hello World, Lasagna, Space Age, and Last Will
This commit is contained in:
parent
483052f0f1
commit
88b3c48a36
40 changed files with 73142 additions and 0 deletions
28
cpp/hello-world/.exercism/config.json
Normal file
28
cpp/hello-world/.exercism/config.json
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"authors": [
|
||||
"samsondstl"
|
||||
],
|
||||
"contributors": [
|
||||
"elyashiv",
|
||||
"jackhughesweb",
|
||||
"KevinWMatthews",
|
||||
"patricksjackson",
|
||||
"sturzl"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"hello_world.cpp",
|
||||
"hello_world.h"
|
||||
],
|
||||
"test": [
|
||||
"hello_world_test.cpp"
|
||||
],
|
||||
"example": [
|
||||
".meta/example.cpp",
|
||||
".meta/example.h"
|
||||
]
|
||||
},
|
||||
"blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".",
|
||||
"source": "This is an exercise to introduce users to using Exercism",
|
||||
"source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program"
|
||||
}
|
1
cpp/hello-world/.exercism/metadata.json
Normal file
1
cpp/hello-world/.exercism/metadata.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"track":"cpp","exercise":"hello-world","id":"9e78de5e578544c2bf9fbea37ecd4f73","url":"https://exercism.org/tracks/cpp/exercises/hello-world","handle":"Chomp1295","is_requester":true,"auto_approve":false}
|
64
cpp/hello-world/CMakeLists.txt
Normal file
64
cpp/hello-world/CMakeLists.txt
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Get the exercise name from the current directory
|
||||
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
|
||||
# Basic CMake project
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
# Name the project after the exercise
|
||||
project(${exercise} CXX)
|
||||
|
||||
# Get a source filename from the exercise name by replacing -'s with _'s
|
||||
string(REPLACE "-" "_" file ${exercise})
|
||||
|
||||
# Implementation could be only a header
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp)
|
||||
set(exercise_cpp ${file}.cpp)
|
||||
else()
|
||||
set(exercise_cpp "")
|
||||
endif()
|
||||
|
||||
# Use the common Catch library?
|
||||
if(EXERCISM_COMMON_CATCH)
|
||||
# For Exercism track development only
|
||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $<TARGET_OBJECTS:catchlib>)
|
||||
elseif(EXERCISM_TEST_SUITE)
|
||||
# The Exercism test suite is being run, the Docker image already
|
||||
# includes a pre-built version of Catch.
|
||||
find_package(Catch2 REQUIRED)
|
||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h)
|
||||
target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain)
|
||||
# When Catch is installed system wide we need to include a different
|
||||
# header, we need this define to use the correct one.
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE)
|
||||
else()
|
||||
# Build executable from sources and headers
|
||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp)
|
||||
endif()
|
||||
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED OFF
|
||||
CXX_EXTENSIONS OFF
|
||||
)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Configure to run all the tests?
|
||||
if(${EXERCISM_RUN_ALL_TESTS})
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS)
|
||||
endif()
|
||||
|
||||
# Tell MSVC not to warn us about unchecked iterators in debug builds
|
||||
if(${MSVC})
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Run the tests on every build
|
||||
add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise})
|
61
cpp/hello-world/HELP.md
Normal file
61
cpp/hello-world/HELP.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
Running the tests involves running `cmake -G` and then using the build command appropriate for your platform.
|
||||
Detailed instructions on how to do this can be found on the [Running the Tests][cpp-tests-instructions] page for C++ on exercism.org.
|
||||
|
||||
## Passing the Tests
|
||||
|
||||
When you start a new exercise locally, the files are configured so that only the first test is performed.
|
||||
Get that first test compiling, linking and passing by following the [three rules of test-driven development][three-laws-of-tdd].
|
||||
Create just enough structure by declaring namespaces, functions, classes, etc., 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, uncomment the next test by moving the line `if defined(EXERCISM_RUN_ALL_TESTS)` past the next test.
|
||||
|
||||
See the example below from the Bob exercise (file `bob_test.cpp`, line 15):
|
||||
|
||||
```diff
|
||||
-#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
TEST_CASE("shouting")
|
||||
{
|
||||
REQUIRE("Whoa, chill out!" == bob::hey("WATCH OUT!"));
|
||||
}
|
||||
+#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
```
|
||||
|
||||
Moving this line past the next test may result in compile errors as new constructs may be invoked that you haven't yet declared or defined.
|
||||
Again, fix the compile errors minimally to get a failing test, then change the code minimally to pass the test, refactor your implementation for readability and expressiveness and then go on to the next test.
|
||||
|
||||
Try to use standard C++17 facilities in preference to writing your own low-level algorithms or facilities by hand.
|
||||
|
||||
[cpp-tests-instructions]: https://exercism.org/docs/tracks/cpp/tests
|
||||
[three-laws-of-tdd]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit hello_world.cpp hello_world.h` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [C++ track's documentation](https://exercism.org/docs/tracks/cpp)
|
||||
- The [C++ track's programming category on the forum](https://forum.exercism.org/c/programming/cpp)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
To get help if you're having trouble, you can use one of the following resources:
|
||||
|
||||
- [`c++-faq` tag on StackOverflow](https://stackoverflow.com/tags/c%2b%2b-faq/info)
|
||||
- [C++ FAQ from isocpp.com](https://isocpp.org/faq)
|
||||
- [CppReference](http://en.cppreference.com/) is a wiki reference to the C++ language and standard library
|
||||
- [C traps and pitfalls](http://www.slideshare.net/LegalizeAdulthood/c-traps-and-pitfalls-for-c-programmers) is useful if you are new to C++, but have programmed in C
|
39
cpp/hello-world/README.md
Normal file
39
cpp/hello-world/README.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Hello World
|
||||
|
||||
Welcome to Hello World on Exercism's C++ Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
|
||||
## Instructions
|
||||
|
||||
The classical introductory exercise.
|
||||
Just say "Hello, World!".
|
||||
|
||||
["Hello, World!"][hello-world] is the traditional first program for beginning programming in a new language or environment.
|
||||
|
||||
The objectives are simple:
|
||||
|
||||
- Modify the provided code so that it produces the string "Hello, World!".
|
||||
- Run the test suite and make sure that it succeeds.
|
||||
- Submit your solution and check it at the website.
|
||||
|
||||
If everything goes well, you will be ready to fetch your first real exercise.
|
||||
|
||||
[hello-world]: https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @samsondstl
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @elyashiv
|
||||
- @jackhughesweb
|
||||
- @KevinWMatthews
|
||||
- @patricksjackson
|
||||
- @sturzl
|
||||
|
||||
### Based on
|
||||
|
||||
This is an exercise to introduce users to using Exercism - https://en.wikipedia.org/wiki/%22Hello,_world!%22_program
|
9
cpp/hello-world/hello_world.cpp
Normal file
9
cpp/hello-world/hello_world.cpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include "hello_world.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace hello_world {
|
||||
|
||||
string hello() { return "Hello, World!"; }
|
||||
|
||||
} // namespace hello_world
|
22
cpp/hello-world/hello_world.h
Normal file
22
cpp/hello-world/hello_world.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
// This is an include guard.
|
||||
// You could alternatively use '#pragma once'
|
||||
// See https://en.wikipedia.org/wiki/Include_guard
|
||||
#if !defined(HELLO_WORLD_H)
|
||||
#define HELLO_WORLD_H
|
||||
|
||||
// Include the string header so that we have access to 'std::string'
|
||||
#include <string>
|
||||
|
||||
// Declare a namespace for the function(s) we are exporting.
|
||||
// https://en.cppreference.com/w/cpp/language/namespace
|
||||
namespace hello_world {
|
||||
|
||||
// Declare the 'hello()' function, which takes no arguments and returns a
|
||||
// 'std::string'. The function itself is defined in the hello_world.cpp source
|
||||
// file. Because it is inside of the 'hello_world' namespace, it's full name is
|
||||
// 'hello_world::hello()'.
|
||||
std::string hello();
|
||||
|
||||
} // namespace hello_world
|
||||
|
||||
#endif
|
16
cpp/hello-world/hello_world_test.cpp
Normal file
16
cpp/hello-world/hello_world_test.cpp
Normal file
|
@ -0,0 +1,16 @@
|
|||
// Include the header file with the definitions of the functions you create.
|
||||
#include "hello_world.h"
|
||||
|
||||
// Include the test framework.
|
||||
#ifdef EXERCISM_TEST_SUITE
|
||||
#include <catch2/catch.hpp>
|
||||
#else
|
||||
#include "test/catch.hpp"
|
||||
#endif
|
||||
|
||||
// Declares a single test.
|
||||
TEST_CASE("test_hello")
|
||||
{
|
||||
// Check if your function returns "Hello, World!".
|
||||
REQUIRE(hello_world::hello() == "Hello, World!");
|
||||
}
|
17937
cpp/hello-world/test/catch.hpp
Normal file
17937
cpp/hello-world/test/catch.hpp
Normal file
File diff suppressed because it is too large
Load diff
2
cpp/hello-world/test/tests-main.cpp
Normal file
2
cpp/hello-world/test/tests-main.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
18
cpp/lasagna/.exercism/config.json
Normal file
18
cpp/lasagna/.exercism/config.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"authors": [
|
||||
"vaeng"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"lasagna.cpp"
|
||||
],
|
||||
"test": [
|
||||
"lasagna_test.cpp"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/exemplar.cpp"
|
||||
]
|
||||
},
|
||||
"icon": "lasagna",
|
||||
"blurb": "Learn the basics of C++ by cooking lasagna"
|
||||
}
|
1
cpp/lasagna/.exercism/metadata.json
Normal file
1
cpp/lasagna/.exercism/metadata.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"track":"cpp","exercise":"lasagna","id":"ab4ffc7e34e84e69b41def6abe48f99f","url":"https://exercism.org/tracks/cpp/exercises/lasagna","handle":"Chomp1295","is_requester":true,"auto_approve":false}
|
66
cpp/lasagna/CMakeLists.txt
Normal file
66
cpp/lasagna/CMakeLists.txt
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Basic CMake project
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
# Get the exercise name from the current directory
|
||||
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
|
||||
# Name the project after the exercise
|
||||
project(${exercise} CXX)
|
||||
|
||||
# Get a source filename from the exercise name by replacing -'s with _'s
|
||||
string(REPLACE "-" "_" file ${exercise})
|
||||
|
||||
# Implementation could be only a header
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp)
|
||||
set(exercise_cpp ${file}.cpp)
|
||||
else()
|
||||
set(exercise_cpp "")
|
||||
endif()
|
||||
|
||||
# Use the common Catch library?
|
||||
if(EXERCISM_COMMON_CATCH)
|
||||
# For Exercism track development only
|
||||
add_executable(${exercise} ${file}_test.cpp $<TARGET_OBJECTS:catchlib>)
|
||||
elseif(EXERCISM_TEST_SUITE)
|
||||
# The Exercism test suite is being run, the Docker image already
|
||||
# includes a pre-built version of Catch.
|
||||
find_package(Catch2 REQUIRED)
|
||||
add_executable(${exercise} ${file}_test.cpp)
|
||||
target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain)
|
||||
# When Catch is installed system wide we need to include a different
|
||||
# header, we need this define to use the correct one.
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE)
|
||||
else()
|
||||
# Build executable from sources and headers
|
||||
add_executable(${exercise} ${file}_test.cpp test/tests-main.cpp)
|
||||
endif()
|
||||
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED OFF
|
||||
CXX_EXTENSIONS OFF
|
||||
)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
# added "-Wno-unused-parameter" to remove compiler warnings
|
||||
# should make it easier for students to run their first real code
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror -Wno-unused-parameter"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Configure to run all the tests?
|
||||
if(${EXERCISM_RUN_ALL_TESTS})
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS)
|
||||
endif()
|
||||
|
||||
# Tell MSVC not to warn us about unchecked iterators in debug builds
|
||||
if(${MSVC})
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Run the tests on every build
|
||||
add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise})
|
61
cpp/lasagna/HELP.md
Normal file
61
cpp/lasagna/HELP.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
Running the tests involves running `cmake -G` and then using the build command appropriate for your platform.
|
||||
Detailed instructions on how to do this can be found on the [Running the Tests][cpp-tests-instructions] page for C++ on exercism.org.
|
||||
|
||||
## Passing the Tests
|
||||
|
||||
When you start a new exercise locally, the files are configured so that only the first test is performed.
|
||||
Get that first test compiling, linking and passing by following the [three rules of test-driven development][three-laws-of-tdd].
|
||||
Create just enough structure by declaring namespaces, functions, classes, etc., 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, uncomment the next test by moving the line `if defined(EXERCISM_RUN_ALL_TESTS)` past the next test.
|
||||
|
||||
See the example below from the Bob exercise (file `bob_test.cpp`, line 15):
|
||||
|
||||
```diff
|
||||
-#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
TEST_CASE("shouting")
|
||||
{
|
||||
REQUIRE("Whoa, chill out!" == bob::hey("WATCH OUT!"));
|
||||
}
|
||||
+#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
```
|
||||
|
||||
Moving this line past the next test may result in compile errors as new constructs may be invoked that you haven't yet declared or defined.
|
||||
Again, fix the compile errors minimally to get a failing test, then change the code minimally to pass the test, refactor your implementation for readability and expressiveness and then go on to the next test.
|
||||
|
||||
Try to use standard C++17 facilities in preference to writing your own low-level algorithms or facilities by hand.
|
||||
|
||||
[cpp-tests-instructions]: https://exercism.org/docs/tracks/cpp/tests
|
||||
[three-laws-of-tdd]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit lasagna.cpp` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [C++ track's documentation](https://exercism.org/docs/tracks/cpp)
|
||||
- The [C++ track's programming category on the forum](https://forum.exercism.org/c/programming/cpp)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
To get help if you're having trouble, you can use one of the following resources:
|
||||
|
||||
- [`c++-faq` tag on StackOverflow](https://stackoverflow.com/tags/c%2b%2b-faq/info)
|
||||
- [C++ FAQ from isocpp.com](https://isocpp.org/faq)
|
||||
- [CppReference](http://en.cppreference.com/) is a wiki reference to the C++ language and standard library
|
||||
- [C traps and pitfalls](http://www.slideshare.net/LegalizeAdulthood/c-traps-and-pitfalls-for-c-programmers) is useful if you are new to C++, but have programmed in C
|
24
cpp/lasagna/HINTS.md
Normal file
24
cpp/lasagna/HINTS.md
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- Don't forget the `;` after each statement.
|
||||
- You can define an integer with `int myInteger = 44;`.
|
||||
|
||||
## 1. Get the baking time.
|
||||
|
||||
- The instructions have information on the time for the recipe.
|
||||
- A function can return a value in the form of `return 2;`
|
||||
|
||||
## 2. Get the preparation time.
|
||||
|
||||
- You can access the number of layers by using the respective parameter.
|
||||
- You can do calculations when you define an integer: `int myInteger = 3 + myOtherInteger;`
|
||||
|
||||
## 3. Calculate the time left in the oven
|
||||
|
||||
- You can call other functions and use the returned value like variables: `return 22 * myOtherCalculation();`
|
||||
|
||||
## 4. Calculate the total time spent on the lasagna
|
||||
|
||||
- The output should combine the time for the preparation and the time the lasagna has already been in the oven.
|
173
cpp/lasagna/README.md
Normal file
173
cpp/lasagna/README.md
Normal file
|
@ -0,0 +1,173 @@
|
|||
# Lasagna
|
||||
|
||||
Welcome to Lasagna on Exercism's C++ Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
|
||||
|
||||
## Introduction
|
||||
|
||||
## Basics
|
||||
|
||||
To set off the C++ journey we are starting with variables, function calls, and comments.
|
||||
|
||||
### Comments
|
||||
|
||||
Comments come in two flavors: single- and multi-line.
|
||||
Everything that comes after `//` on the same line is ignored by the compiler.
|
||||
Multi-line comments are also known as C-style comments.
|
||||
They are surrounded by `/*` and `*/`.
|
||||
Anything that comes between these will be ignored as well.
|
||||
|
||||
### Variables
|
||||
|
||||
C++ is a typed language.
|
||||
All types need to be known at compile time, and you generally need to state them explicitly.
|
||||
A variable's type cannot change.
|
||||
An integer variable with the name `years` can be declared like this:
|
||||
|
||||
```cpp
|
||||
int years;
|
||||
```
|
||||
|
||||
It is good practice to initialize variables upon declaration.
|
||||
C++ offers different mechanisms to do so.
|
||||
The version with the curly braces is more in line with modern C++, but the equal-sign version is also very common.
|
||||
|
||||
```cpp
|
||||
int tomatoes{80};
|
||||
int potatoes = 40;
|
||||
```
|
||||
|
||||
~~~~exercism/caution
|
||||
C++ does allow using uninitialized variables.
|
||||
Until the variable is deliberately set, it is undefined and might contain anything.
|
||||
To avoid used-before-set errors and undefined behavior it is advisable to **always initialize**.
|
||||
Undefined behavior can crash your program at the worst possible moment, while it was running fine previously.
|
||||
It cannot be stressed enough: avoid undefined behavior at all cost.
|
||||
~~~~
|
||||
|
||||
### Arithmetic Operations
|
||||
|
||||
Arithmetic operators like `*`, `+`, or `-` can be part of an expression like `3 * 2` or `tomatoes + potatoes`.
|
||||
|
||||
### Updating Variables
|
||||
|
||||
You can reassign variables, as long as they keep their type:
|
||||
|
||||
```cpp
|
||||
tomatoes = tomatoes - 5; // tomatoes is now 75
|
||||
potatoes = (32 * 2) + 11; // potatoes is now 75 as well
|
||||
```
|
||||
|
||||
### Functions
|
||||
|
||||
Functions have a name, a return type and a (possibly empty) parameter list.
|
||||
An example of a function named `always_fortyseven` that would always return 47 would look like this:
|
||||
|
||||
```cpp
|
||||
int always_fortyseven() {
|
||||
return 47;
|
||||
}
|
||||
```
|
||||
|
||||
Here is `vip_fee`, which has one parameter:
|
||||
|
||||
```cpp
|
||||
int vip_fee(int standard_fee) {
|
||||
/*
|
||||
vip_fee calculates the vip fee based on the standard_fee.
|
||||
*/
|
||||
int vip_multi{3};
|
||||
return standard_fee * vip_multi;
|
||||
}
|
||||
```
|
||||
|
||||
Or `total_fee`, a function with three parameters and a call to another function.
|
||||
|
||||
```cpp
|
||||
int total_fee(int vips, int adults, int kids) {
|
||||
/*
|
||||
total_fee calculates the total price for a group of VIP and adult guests with kids.
|
||||
Kids get a flat discount on the standard fee.
|
||||
VIP guest fees are calculated by calling vip_fee.
|
||||
*/
|
||||
int standard_fee{30};
|
||||
int kids_discount{15};
|
||||
|
||||
int kids_total_fee = kids * (standard_fee - kids_discount);
|
||||
int vips_total_fee = vips * vip_fee(standard_fee);
|
||||
int adult_total_fee = adults * standard_fee;
|
||||
|
||||
return vips_total_fee + adult_total_fee + kids_total_fee;
|
||||
}
|
||||
```
|
||||
|
||||
Functions in C++ do not return the value of the last statement like in some other languages.
|
||||
The `return` keyword is required for the code to compile.
|
||||
|
||||
### Whitespace
|
||||
|
||||
Whitespace is used for formatting source code and includes spaces, tabs, or newlines.
|
||||
As the compiler ignores unnecessary whitespace, you can use it to structure your code.
|
||||
Smart use of whitespace can improve the readability of your code.
|
||||
There are different formatting standards, but these are all conventional and not enforced by the compiler.
|
||||
|
||||
```cpp
|
||||
// Formatting makes it easier to find bugs
|
||||
|
||||
int eggs_yolks = 3;
|
||||
int yeast = 15;
|
||||
|
||||
int flour=500;int sugar=200;// compact, but difficult to read
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
Lucian's girlfriend is on her way home and he hasn't cooked their anniversary dinner!
|
||||
|
||||
In this exercise, you're going to write some code to help Lucian cook an exquisite lasagna from his favorite cookbook.
|
||||
|
||||
You have four tasks, all related to the time spent cooking the lasagna.
|
||||
|
||||
## 1. Define the expected oven time in minutes
|
||||
|
||||
Define the `ovenTime()` function that does not take any arguments and returns how many minutes the lasagna should be in the oven.
|
||||
According to the cookbook, the expected oven time is 40 minutes:
|
||||
|
||||
```cpp
|
||||
ovenTime();
|
||||
// => 40
|
||||
```
|
||||
|
||||
## 2. Calculate the remaining oven time in minutes
|
||||
|
||||
Define the `remainingOvenTime(int actualMinutesInOven)` function that takes the actual minutes the lasagna has been in the oven as an argument and returns how many minutes the lasagna still has to remain in the oven, based on the expected oven time in minutes from the previous task.
|
||||
|
||||
```cpp
|
||||
remainingOvenTime(30);
|
||||
// => 10
|
||||
```
|
||||
|
||||
## 3. Calculate the preparation time in minutes
|
||||
|
||||
Define the `preparationTime(int numberOfLayers)` function that takes the number of layers you added to the lasagna as an argument and returns how many minutes you spent preparing the lasagna, assuming each layer takes you 2 minutes to prepare.
|
||||
|
||||
```cpp
|
||||
preparationTime(2);
|
||||
// => 4
|
||||
```
|
||||
|
||||
## 4. Calculate the elapsed time in minutes
|
||||
|
||||
Define the `elapsedTime(int numberOfLayers, int actualMinutesInOven)` function that takes two arguments: the first argument is the number of layers you added to the lasagna, and the second argument is the number of minutes the lasagna has been in the oven. The function should return how many minutes you've worked on cooking the lasagna, which is the sum of the preparation time in minutes, and the time in minutes the lasagna has spent in the oven at the moment.
|
||||
|
||||
```cpp
|
||||
elapsedTime(3, 20);
|
||||
// => 26
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @vaeng
|
21
cpp/lasagna/lasagna.cpp
Normal file
21
cpp/lasagna/lasagna.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
// ovenTime returns the amount in minutes that the lasagna should stay in the
|
||||
// oven.
|
||||
int ovenTime() { return 40; }
|
||||
|
||||
/* remainingOvenTime returns the remaining
|
||||
minutes based on the actual minutes already in the oven.
|
||||
*/
|
||||
int remainingOvenTime(int actualMinutesInOven) {
|
||||
return ovenTime() - actualMinutesInOven;
|
||||
}
|
||||
|
||||
/* preparationTime returns an estimate of the preparation time based on the
|
||||
number of layers and the necessary time per layer.
|
||||
*/
|
||||
int preparationTime(int numberOfLayers) { return numberOfLayers * 2; }
|
||||
|
||||
// elapsedTime calculates the total time spent to create and bake the lasagna so
|
||||
// far.
|
||||
int elapsedTime(int numberOfLayers, int actualMinutesInOven) {
|
||||
return preparationTime(numberOfLayers) + actualMinutesInOven;
|
||||
}
|
75
cpp/lasagna/lasagna_test.cpp
Normal file
75
cpp/lasagna/lasagna_test.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "lasagna.cpp"
|
||||
#ifdef EXERCISM_TEST_SUITE
|
||||
#include <catch2/catch.hpp>
|
||||
#else
|
||||
#include "test/catch.hpp"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
TEST_CASE("Preparation time correct", "[task_1]") {
|
||||
int actual = 40;
|
||||
int expected = ovenTime();
|
||||
|
||||
REQUIRE(expected == actual);
|
||||
}
|
||||
|
||||
TEST_CASE("Fresh in the oven", "[task_2]") {
|
||||
int timeSpendInOven = 0;
|
||||
int neededBakeTime = 40;
|
||||
int actual = remainingOvenTime(timeSpendInOven);
|
||||
int expected{neededBakeTime - timeSpendInOven};
|
||||
|
||||
REQUIRE(expected == actual);
|
||||
}
|
||||
|
||||
TEST_CASE("Halfway done", "[task_2]") {
|
||||
int timeSpendInOven = 20;
|
||||
int neededBakeTime = 40;
|
||||
int actual = remainingOvenTime(timeSpendInOven);
|
||||
int expected{neededBakeTime - timeSpendInOven};
|
||||
|
||||
REQUIRE(expected == actual);
|
||||
}
|
||||
|
||||
TEST_CASE("Correct for six layers", "[task_3]") {
|
||||
int timePerLayer = 2;
|
||||
int layers = 6;
|
||||
int actual = preparationTime(layers);
|
||||
int expected{timePerLayer * layers};
|
||||
|
||||
REQUIRE(expected == actual);
|
||||
}
|
||||
|
||||
TEST_CASE("Correct for 11 layers", "[task_3]") {
|
||||
int timePerLayer = 2;
|
||||
int layers = 11;
|
||||
int actual = preparationTime(layers);
|
||||
int expected{timePerLayer * layers};
|
||||
|
||||
REQUIRE(expected == actual);
|
||||
}
|
||||
|
||||
TEST_CASE("Fresh in the oven, 12 layers!", "[task_4]") {
|
||||
int timeSpendInOven = 0;
|
||||
int timePerLayer = 2;
|
||||
int layers = 12;
|
||||
int actual = elapsedTime(layers, timeSpendInOven);
|
||||
int expected{timePerLayer * layers + timeSpendInOven};
|
||||
|
||||
REQUIRE(expected == actual);
|
||||
}
|
||||
|
||||
TEST_CASE("One minute left, 5 layers!", "[task_4]") {
|
||||
int timeSpendInOven = 39;
|
||||
int timePerLayer = 2;
|
||||
int layers = 5;
|
||||
int actual = elapsedTime(layers, timeSpendInOven);
|
||||
int expected{timePerLayer * layers + timeSpendInOven};
|
||||
|
||||
REQUIRE(expected == actual);
|
||||
}
|
||||
|
||||
#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
|
||||
#endif
|
17937
cpp/lasagna/test/catch.hpp
Normal file
17937
cpp/lasagna/test/catch.hpp
Normal file
File diff suppressed because it is too large
Load diff
2
cpp/lasagna/test/tests-main.cpp
Normal file
2
cpp/lasagna/test/tests-main.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
17
cpp/last-will/.exercism/config.json
Normal file
17
cpp/last-will/.exercism/config.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"authors": [
|
||||
"vaeng"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"last_will.cpp"
|
||||
],
|
||||
"test": [
|
||||
"last_will_test.cpp"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/exemplar.cpp"
|
||||
]
|
||||
},
|
||||
"blurb": "Learn about namespaces by executing an estate."
|
||||
}
|
1
cpp/last-will/.exercism/metadata.json
Normal file
1
cpp/last-will/.exercism/metadata.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"track":"cpp","exercise":"last-will","id":"f8193219ae494bd5a2e0b56388151289","url":"https://exercism.org/tracks/cpp/exercises/last-will","handle":"Chomp1295","is_requester":true,"auto_approve":false}
|
66
cpp/last-will/CMakeLists.txt
Normal file
66
cpp/last-will/CMakeLists.txt
Normal file
|
@ -0,0 +1,66 @@
|
|||
# Basic CMake project
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
# Get the exercise name from the current directory
|
||||
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
|
||||
# Name the project after the exercise
|
||||
project(${exercise} CXX)
|
||||
|
||||
# Get a source filename from the exercise name by replacing -'s with _'s
|
||||
string(REPLACE "-" "_" file ${exercise})
|
||||
|
||||
# Implementation could be only a header
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp)
|
||||
set(exercise_cpp ${file}.cpp)
|
||||
else()
|
||||
set(exercise_cpp "")
|
||||
endif()
|
||||
|
||||
# Use the common Catch library?
|
||||
if(EXERCISM_COMMON_CATCH)
|
||||
# For Exercism track development only
|
||||
add_executable(${exercise} ${file}_test.cpp $<TARGET_OBJECTS:catchlib>)
|
||||
elseif(EXERCISM_TEST_SUITE)
|
||||
# The Exercism test suite is being run, the Docker image already
|
||||
# includes a pre-built version of Catch.
|
||||
find_package(Catch2 REQUIRED)
|
||||
add_executable(${exercise} ${file}_test.cpp)
|
||||
target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain)
|
||||
# When Catch is installed system wide we need to include a different
|
||||
# header, we need this define to use the correct one.
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE)
|
||||
else()
|
||||
# Build executable from sources and headers
|
||||
add_executable(${exercise} ${file}_test.cpp test/tests-main.cpp)
|
||||
endif()
|
||||
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED OFF
|
||||
CXX_EXTENSIONS OFF
|
||||
)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
# added "-Wno-unused-parameter" to remove compiler warnings
|
||||
# should make it easier for students to run their first real code
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror -Wno-unused-parameter"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Configure to run all the tests?
|
||||
if(${EXERCISM_RUN_ALL_TESTS})
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS)
|
||||
endif()
|
||||
|
||||
# Tell MSVC not to warn us about unchecked iterators in debug builds
|
||||
if(${MSVC})
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Run the tests on every build
|
||||
add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise})
|
61
cpp/last-will/HELP.md
Normal file
61
cpp/last-will/HELP.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
Running the tests involves running `cmake -G` and then using the build command appropriate for your platform.
|
||||
Detailed instructions on how to do this can be found on the [Running the Tests][cpp-tests-instructions] page for C++ on exercism.org.
|
||||
|
||||
## Passing the Tests
|
||||
|
||||
When you start a new exercise locally, the files are configured so that only the first test is performed.
|
||||
Get that first test compiling, linking and passing by following the [three rules of test-driven development][three-laws-of-tdd].
|
||||
Create just enough structure by declaring namespaces, functions, classes, etc., 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, uncomment the next test by moving the line `if defined(EXERCISM_RUN_ALL_TESTS)` past the next test.
|
||||
|
||||
See the example below from the Bob exercise (file `bob_test.cpp`, line 15):
|
||||
|
||||
```diff
|
||||
-#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
TEST_CASE("shouting")
|
||||
{
|
||||
REQUIRE("Whoa, chill out!" == bob::hey("WATCH OUT!"));
|
||||
}
|
||||
+#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
```
|
||||
|
||||
Moving this line past the next test may result in compile errors as new constructs may be invoked that you haven't yet declared or defined.
|
||||
Again, fix the compile errors minimally to get a failing test, then change the code minimally to pass the test, refactor your implementation for readability and expressiveness and then go on to the next test.
|
||||
|
||||
Try to use standard C++17 facilities in preference to writing your own low-level algorithms or facilities by hand.
|
||||
|
||||
[cpp-tests-instructions]: https://exercism.org/docs/tracks/cpp/tests
|
||||
[three-laws-of-tdd]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit last_will.cpp` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [C++ track's documentation](https://exercism.org/docs/tracks/cpp)
|
||||
- The [C++ track's programming category on the forum](https://forum.exercism.org/c/programming/cpp)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
To get help if you're having trouble, you can use one of the following resources:
|
||||
|
||||
- [`c++-faq` tag on StackOverflow](https://stackoverflow.com/tags/c%2b%2b-faq/info)
|
||||
- [C++ FAQ from isocpp.com](https://isocpp.org/faq)
|
||||
- [CppReference](http://en.cppreference.com/) is a wiki reference to the C++ language and standard library
|
||||
- [C traps and pitfalls](http://www.slideshare.net/LegalizeAdulthood/c-traps-and-pitfalls-for-c-programmers) is useful if you are new to C++, but have programmed in C
|
20
cpp/last-will/HINTS.md
Normal file
20
cpp/last-will/HINTS.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- Do not change the code in the families' namespaces.
|
||||
- Do not copy the values into your code, call the functions.
|
||||
|
||||
## 1. Take your seat in front of the families and lay out your papers
|
||||
|
||||
- The namespace has to be called `estate_executor` for the tests to work.
|
||||
|
||||
## 2. Find the secret account number
|
||||
|
||||
Each `bank_number_part` has to be called with the `secret_modifier` from the parameter list.
|
||||
|
||||
## 3. Last step: Enter the secret code
|
||||
|
||||
- You can call functions from nested namespaces like this `outer_namespace::inner_namespac::my_function`.
|
||||
|
||||
- Take care to add the blue and the red fragments separately before multiplicating both parts.
|
83
cpp/last-will/README.md
Normal file
83
cpp/last-will/README.md
Normal file
|
@ -0,0 +1,83 @@
|
|||
# Last Will
|
||||
|
||||
Welcome to Last Will on Exercism's C++ Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
If you get stuck on the exercise, check out `HINTS.md`, but try and solve it without using those first :)
|
||||
|
||||
## Introduction
|
||||
|
||||
## Namespaces
|
||||
|
||||
An important method for code organization are namespaces.
|
||||
Two functions might have a naming collision, which can be resolved by putting them in different namespaces.
|
||||
Namespaces can be nested, which might help to structure big code bases.
|
||||
Access to the namespaces is done via the scope-resolution operator `::`.
|
||||
|
||||
The example below shows the use of two different `foo` functions.
|
||||
They are used together by prefixing their respective namespaces.
|
||||
|
||||
```cpp
|
||||
namespace my_ns {
|
||||
int foo() {
|
||||
return 44;
|
||||
}
|
||||
namespace my_inner_ns {
|
||||
int baz() {
|
||||
return 90;
|
||||
}
|
||||
}
|
||||
}
|
||||
namespace my_other_ns {
|
||||
int foo() {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
int myresult{my_ns::foo() + my_other_ns::foo() * my_ns::my_inner_ns::baz()};
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
You work for a prestigious law firm that is specialized in handling unique testament requests.
|
||||
|
||||
In this exercise, you are going to open a mysterious vault.
|
||||
You are the executor of the estate and will assemble the long-kept secret codes of three families to get an account number and the matching code.
|
||||
|
||||
To prevent any family from opening the vault alone, it can only be opened by combining their knowledge with a secret modifier that you know from the last will.
|
||||
|
||||
You have three tasks, all related to helping the families to open the vault.
|
||||
|
||||
## 1. Take your seat in front of the families and lay out your papers
|
||||
|
||||
Define a namespace called `estate_executor`.
|
||||
The code from the next tasks should be defined in the body of the `estate_executor` namespace.
|
||||
|
||||
```cpp
|
||||
namespace some_name {
|
||||
// The space between the curly brackets
|
||||
// is called body of the namespace.
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Find the secret account number
|
||||
|
||||
This is your big moment.
|
||||
Only you have the secret modifier key to reveal the secret account number.
|
||||
|
||||
Define the `assemble_account_number(int secret_modifier)` function that takes the secret modifier as an argument and returns the assembled account number as an `int`.
|
||||
|
||||
To get the correct number, you have to sum up the `bank_number_part` from each of the three families.
|
||||
|
||||
## 3. Last step: Enter the secret code
|
||||
|
||||
The instructions in the testament ask you to add all the blue and then all the red fragments.
|
||||
The resulting code is obtained by multiplying both sums.
|
||||
|
||||
Define the `assemble_code()` function that returns the resulting code by combining the fragments from the three families to a single `integer`.
|
||||
The function does not have any arguments and relies solely on the information in the relevant namespaces from the families.
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @vaeng
|
65
cpp/last-will/last_will.cpp
Normal file
65
cpp/last-will/last_will.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Enter your code below the lines of the families' information
|
||||
|
||||
// Secret knowledge of the Zhang family:
|
||||
namespace zhang {
|
||||
int bank_number_part(int secret_modifier) {
|
||||
int zhang_part{8'541};
|
||||
return (zhang_part * secret_modifier) % 10000;
|
||||
}
|
||||
namespace red {
|
||||
int code_fragment() { return 512; }
|
||||
} // namespace red
|
||||
namespace blue {
|
||||
int code_fragment() { return 677; }
|
||||
} // namespace blue
|
||||
} // namespace zhang
|
||||
|
||||
// Secret knowledge of the Khan family:
|
||||
namespace khan {
|
||||
int bank_number_part(int secret_modifier) {
|
||||
int khan_part{4'142};
|
||||
return (khan_part * secret_modifier) % 10000;
|
||||
}
|
||||
namespace red {
|
||||
int code_fragment() { return 148; }
|
||||
} // namespace red
|
||||
namespace blue {
|
||||
int code_fragment() { return 875; }
|
||||
} // namespace blue
|
||||
} // namespace khan
|
||||
|
||||
// Secret knowledge of the Garcia family:
|
||||
namespace garcia {
|
||||
int bank_number_part(int secret_modifier) {
|
||||
int garcia_part{4'023};
|
||||
return (garcia_part * secret_modifier) % 10000;
|
||||
}
|
||||
namespace red {
|
||||
int code_fragment() { return 118; }
|
||||
} // namespace red
|
||||
namespace blue {
|
||||
int code_fragment() { return 923; }
|
||||
} // namespace blue
|
||||
} // namespace garcia
|
||||
|
||||
// Enter your code below
|
||||
|
||||
namespace estate_executor {
|
||||
|
||||
int assemble_account_number(int secret_modifier) {
|
||||
return zhang::bank_number_part(secret_modifier) +
|
||||
khan::bank_number_part(secret_modifier) +
|
||||
garcia::bank_number_part(secret_modifier);
|
||||
}
|
||||
|
||||
int assemble_code() {
|
||||
|
||||
int red = zhang::red::code_fragment() + khan::red::code_fragment() +
|
||||
garcia::red::code_fragment();
|
||||
|
||||
int blue = zhang::blue::code_fragment() + khan::blue::code_fragment() +
|
||||
garcia::blue::code_fragment();
|
||||
|
||||
return red * blue;
|
||||
}
|
||||
} // namespace estate_executor
|
65
cpp/last-will/last_will_test.cpp
Normal file
65
cpp/last-will/last_will_test.cpp
Normal file
|
@ -0,0 +1,65 @@
|
|||
// Trick to let the code compile, even if the function has not been implemented:
|
||||
namespace estate_executor {
|
||||
int assemble_account_number(int) __attribute__((weak));
|
||||
int assemble_code() __attribute__((weak));
|
||||
} // namespace estate_executor
|
||||
|
||||
#include "last_will.cpp"
|
||||
#ifdef EXERCISM_TEST_SUITE
|
||||
#include <catch2/catch.hpp>
|
||||
#else
|
||||
#include "test/catch.hpp"
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
TEST_CASE("Family secrets have not been altered", "[task_1]") {
|
||||
// We cannot test the existence of a namespace in the compiled
|
||||
// Code.
|
||||
// This test merely checks if the numbers in the file have
|
||||
// been changed. They have to be correct for the test to work.
|
||||
|
||||
REQUIRE(zhang::bank_number_part(1) == 8541);
|
||||
REQUIRE(zhang::bank_number_part(3) == 8541 * 3 % 10'000);
|
||||
REQUIRE(khan::bank_number_part(1) == 4142);
|
||||
REQUIRE(khan::bank_number_part(3) == 4142 * 3 % 10'000);
|
||||
REQUIRE(garcia::bank_number_part(1) == 4023);
|
||||
REQUIRE(garcia::bank_number_part(3) == 4023 * 3 % 10'000);
|
||||
|
||||
REQUIRE(zhang::red::code_fragment() == 512);
|
||||
REQUIRE(khan::red::code_fragment() == 148);
|
||||
REQUIRE(garcia::red::code_fragment() == 118);
|
||||
|
||||
REQUIRE(zhang::blue::code_fragment() == 677);
|
||||
REQUIRE(khan::blue::code_fragment() == 875);
|
||||
REQUIRE(garcia::blue::code_fragment() == 923);
|
||||
}
|
||||
|
||||
TEST_CASE("Account number assembly function exists in correct namespace",
|
||||
"[task_2]") {
|
||||
REQUIRE_NOTHROW(estate_executor::assemble_account_number(0));
|
||||
}
|
||||
|
||||
TEST_CASE("Account number assembly works correctly", "[task_2]") {
|
||||
int account_with_secret_1{16706};
|
||||
int account_with_secret_23{14238};
|
||||
|
||||
REQUIRE(estate_executor::assemble_account_number(1) == account_with_secret_1);
|
||||
REQUIRE(estate_executor::assemble_account_number(23) ==
|
||||
account_with_secret_23);
|
||||
}
|
||||
|
||||
TEST_CASE("Code fragment number assembly function exists in correct namespace",
|
||||
"[task_3]") {
|
||||
REQUIRE_NOTHROW(estate_executor::assemble_code());
|
||||
}
|
||||
|
||||
TEST_CASE("Code fragments fit correctly", "[task_3]") {
|
||||
int final_code{1925550};
|
||||
|
||||
REQUIRE(estate_executor::assemble_code() == final_code);
|
||||
}
|
||||
|
||||
#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
|
||||
#endif
|
17937
cpp/last-will/test/catch.hpp
Normal file
17937
cpp/last-will/test/catch.hpp
Normal file
File diff suppressed because it is too large
Load diff
2
cpp/last-will/test/tests-main.cpp
Normal file
2
cpp/last-will/test/tests-main.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
30
cpp/space-age/.exercism/config.json
Normal file
30
cpp/space-age/.exercism/config.json
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"authors": [
|
||||
"LegalizeAdulthood"
|
||||
],
|
||||
"contributors": [
|
||||
"cyborgsphinx",
|
||||
"elyashiv",
|
||||
"HenryRLee",
|
||||
"jackhughesweb",
|
||||
"KevinWMatthews",
|
||||
"kytrinyx",
|
||||
"patricksjackson"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"space_age.cpp",
|
||||
"space_age.h"
|
||||
],
|
||||
"test": [
|
||||
"space_age_test.cpp"
|
||||
],
|
||||
"example": [
|
||||
".meta/example.cpp",
|
||||
".meta/example.h"
|
||||
]
|
||||
},
|
||||
"blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.",
|
||||
"source": "Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial.",
|
||||
"source_url": "https://pine.fm/LearnToProgram/?Chapter=01"
|
||||
}
|
1
cpp/space-age/.exercism/metadata.json
Normal file
1
cpp/space-age/.exercism/metadata.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"track":"cpp","exercise":"space-age","id":"9d419e83cce74e1e8248321cd1d8aff1","url":"https://exercism.org/tracks/cpp/exercises/space-age","handle":"Chomp1295","is_requester":true,"auto_approve":false}
|
64
cpp/space-age/CMakeLists.txt
Normal file
64
cpp/space-age/CMakeLists.txt
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Get the exercise name from the current directory
|
||||
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
||||
|
||||
# Basic CMake project
|
||||
cmake_minimum_required(VERSION 3.5.1)
|
||||
|
||||
# Name the project after the exercise
|
||||
project(${exercise} CXX)
|
||||
|
||||
# Get a source filename from the exercise name by replacing -'s with _'s
|
||||
string(REPLACE "-" "_" file ${exercise})
|
||||
|
||||
# Implementation could be only a header
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp)
|
||||
set(exercise_cpp ${file}.cpp)
|
||||
else()
|
||||
set(exercise_cpp "")
|
||||
endif()
|
||||
|
||||
# Use the common Catch library?
|
||||
if(EXERCISM_COMMON_CATCH)
|
||||
# For Exercism track development only
|
||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $<TARGET_OBJECTS:catchlib>)
|
||||
elseif(EXERCISM_TEST_SUITE)
|
||||
# The Exercism test suite is being run, the Docker image already
|
||||
# includes a pre-built version of Catch.
|
||||
find_package(Catch2 REQUIRED)
|
||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h)
|
||||
target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain)
|
||||
# When Catch is installed system wide we need to include a different
|
||||
# header, we need this define to use the correct one.
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE)
|
||||
else()
|
||||
# Build executable from sources and headers
|
||||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp)
|
||||
endif()
|
||||
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED OFF
|
||||
CXX_EXTENSIONS OFF
|
||||
)
|
||||
|
||||
set(CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror"
|
||||
)
|
||||
endif()
|
||||
|
||||
# Configure to run all the tests?
|
||||
if(${EXERCISM_RUN_ALL_TESTS})
|
||||
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS)
|
||||
endif()
|
||||
|
||||
# Tell MSVC not to warn us about unchecked iterators in debug builds
|
||||
if(${MSVC})
|
||||
set_target_properties(${exercise} PROPERTIES
|
||||
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
# Run the tests on every build
|
||||
add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise})
|
61
cpp/space-age/HELP.md
Normal file
61
cpp/space-age/HELP.md
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
Running the tests involves running `cmake -G` and then using the build command appropriate for your platform.
|
||||
Detailed instructions on how to do this can be found on the [Running the Tests][cpp-tests-instructions] page for C++ on exercism.org.
|
||||
|
||||
## Passing the Tests
|
||||
|
||||
When you start a new exercise locally, the files are configured so that only the first test is performed.
|
||||
Get that first test compiling, linking and passing by following the [three rules of test-driven development][three-laws-of-tdd].
|
||||
Create just enough structure by declaring namespaces, functions, classes, etc., 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, uncomment the next test by moving the line `if defined(EXERCISM_RUN_ALL_TESTS)` past the next test.
|
||||
|
||||
See the example below from the Bob exercise (file `bob_test.cpp`, line 15):
|
||||
|
||||
```diff
|
||||
-#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
TEST_CASE("shouting")
|
||||
{
|
||||
REQUIRE("Whoa, chill out!" == bob::hey("WATCH OUT!"));
|
||||
}
|
||||
+#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
```
|
||||
|
||||
Moving this line past the next test may result in compile errors as new constructs may be invoked that you haven't yet declared or defined.
|
||||
Again, fix the compile errors minimally to get a failing test, then change the code minimally to pass the test, refactor your implementation for readability and expressiveness and then go on to the next test.
|
||||
|
||||
Try to use standard C++17 facilities in preference to writing your own low-level algorithms or facilities by hand.
|
||||
|
||||
[cpp-tests-instructions]: https://exercism.org/docs/tracks/cpp/tests
|
||||
[three-laws-of-tdd]: http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit space_age.cpp space_age.h` command.
|
||||
This command will upload your solution to the Exercism website and print the solution page's URL.
|
||||
|
||||
It's possible to submit an incomplete solution which allows you to:
|
||||
|
||||
- See how others have completed the exercise
|
||||
- Request help from a mentor
|
||||
|
||||
## Need to get help?
|
||||
|
||||
If you'd like help solving the exercise, check the following pages:
|
||||
|
||||
- The [C++ track's documentation](https://exercism.org/docs/tracks/cpp)
|
||||
- The [C++ track's programming category on the forum](https://forum.exercism.org/c/programming/cpp)
|
||||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5)
|
||||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
|
||||
|
||||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
|
||||
|
||||
To get help if you're having trouble, you can use one of the following resources:
|
||||
|
||||
- [`c++-faq` tag on StackOverflow](https://stackoverflow.com/tags/c%2b%2b-faq/info)
|
||||
- [C++ FAQ from isocpp.com](https://isocpp.org/faq)
|
||||
- [CppReference](http://en.cppreference.com/) is a wiki reference to the C++ language and standard library
|
||||
- [C traps and pitfalls](http://www.slideshare.net/LegalizeAdulthood/c-traps-and-pitfalls-for-c-programmers) is useful if you are new to C++, but have programmed in C
|
50
cpp/space-age/README.md
Normal file
50
cpp/space-age/README.md
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Space Age
|
||||
|
||||
Welcome to Space Age on Exercism's C++ Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
|
||||
## Instructions
|
||||
|
||||
Given an age in seconds, calculate how old someone would be on:
|
||||
|
||||
- Mercury: orbital period 0.2408467 Earth years
|
||||
- Venus: orbital period 0.61519726 Earth years
|
||||
- Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds
|
||||
- Mars: orbital period 1.8808158 Earth years
|
||||
- Jupiter: orbital period 11.862615 Earth years
|
||||
- Saturn: orbital period 29.447498 Earth years
|
||||
- Uranus: orbital period 84.016846 Earth years
|
||||
- Neptune: orbital period 164.79132 Earth years
|
||||
|
||||
So if you were told someone were 1,000,000,000 seconds old, you should
|
||||
be able to say that they're 31.69 Earth-years old.
|
||||
|
||||
If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video].
|
||||
|
||||
Note: The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year).
|
||||
The Gregorian calendar has, on average, 365.2425 days.
|
||||
While not entirely accurate, 365.25 is the value used in this exercise.
|
||||
See [Year on Wikipedia][year] for more ways to measure a year.
|
||||
|
||||
[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs
|
||||
[year]: https://en.wikipedia.org/wiki/Year#Summary
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @LegalizeAdulthood
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @cyborgsphinx
|
||||
- @elyashiv
|
||||
- @HenryRLee
|
||||
- @jackhughesweb
|
||||
- @KevinWMatthews
|
||||
- @kytrinyx
|
||||
- @patricksjackson
|
||||
|
||||
### Based on
|
||||
|
||||
Partially inspired by Chapter 1 in Chris Pine's online Learn to Program tutorial. - https://pine.fm/LearnToProgram/?Chapter=01
|
24
cpp/space-age/space_age.cpp
Normal file
24
cpp/space-age/space_age.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "space_age.h"
|
||||
namespace space_age {
|
||||
|
||||
space_age::space_age(unsigned long secs) : seconds_(secs) {}
|
||||
|
||||
unsigned long space_age::seconds() const { return seconds_; }
|
||||
|
||||
float space_age::on_earth() const { return (float)seconds_ / 31557600; }
|
||||
|
||||
float space_age::on_mercury() const { return on_earth() / 0.2408467; }
|
||||
|
||||
float space_age::on_venus() const { return on_earth() / 0.61519726; }
|
||||
|
||||
float space_age::on_mars() const { return on_earth() / 1.8808158; }
|
||||
|
||||
float space_age::on_jupiter() const { return on_earth() / 11.862615; }
|
||||
|
||||
float space_age::on_saturn() const { return on_earth() / 29.447498; }
|
||||
|
||||
float space_age::on_uranus() const { return on_earth() / 84.016846; }
|
||||
|
||||
float space_age::on_neptune() const { return on_earth() / 164.79132; }
|
||||
|
||||
} // namespace space_age
|
24
cpp/space-age/space_age.h
Normal file
24
cpp/space-age/space_age.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#if !defined(SPACE_AGE_H)
|
||||
#define SPACE_AGE_H
|
||||
|
||||
namespace space_age {
|
||||
class space_age {
|
||||
public:
|
||||
space_age(unsigned long secs);
|
||||
|
||||
unsigned long seconds() const;
|
||||
float on_earth() const;
|
||||
float on_mercury() const;
|
||||
float on_venus() const;
|
||||
float on_mars() const;
|
||||
float on_jupiter() const;
|
||||
float on_saturn() const;
|
||||
float on_uranus() const;
|
||||
float on_neptune() const;
|
||||
|
||||
private:
|
||||
unsigned long seconds_;
|
||||
};
|
||||
} // namespace space_age
|
||||
|
||||
#endif // SPACE_AGE_H
|
75
cpp/space-age/space_age_test.cpp
Normal file
75
cpp/space-age/space_age_test.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
#include "space_age.h"
|
||||
#ifdef EXERCISM_TEST_SUITE
|
||||
#include <catch2/catch.hpp>
|
||||
#else
|
||||
#include "test/catch.hpp"
|
||||
#endif
|
||||
|
||||
TEST_CASE("age_in_seconds") {
|
||||
const space_age::space_age age(1000000);
|
||||
|
||||
REQUIRE(age.seconds() == 1000000);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const double accuracy = 0.005;
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_earth_years") {
|
||||
const space_age::space_age age(1000000000);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(31.69, accuracy));
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_mercury_years") {
|
||||
const space_age::space_age age(2134835688);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(67.65, accuracy));
|
||||
REQUIRE_THAT(age.on_mercury(), Catch::Matchers::WithinAbs(280.88, accuracy));
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_venus_years") {
|
||||
const space_age::space_age age(189839836);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(6.02, accuracy));
|
||||
REQUIRE_THAT(age.on_venus(), Catch::Matchers::WithinAbs(9.78, accuracy));
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_mars_years") {
|
||||
const space_age::space_age age(2329871239);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(73.83, accuracy));
|
||||
REQUIRE_THAT(age.on_mars(), Catch::Matchers::WithinAbs(39.25, accuracy));
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_jupiter_years") {
|
||||
const space_age::space_age age(901876382);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(28.58, accuracy));
|
||||
REQUIRE_THAT(age.on_jupiter(), Catch::Matchers::WithinAbs(2.41, accuracy));
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_saturn_years") {
|
||||
const space_age::space_age age(3000000000);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(95.06, accuracy));
|
||||
REQUIRE_THAT(age.on_saturn(), Catch::Matchers::WithinAbs(3.23, accuracy));
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_uranus_years") {
|
||||
const space_age::space_age age(3210123456);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(101.72, accuracy));
|
||||
REQUIRE_THAT(age.on_uranus(), Catch::Matchers::WithinAbs(1.21, accuracy));
|
||||
}
|
||||
|
||||
TEST_CASE("age_in_neptune_year") {
|
||||
const space_age::space_age age(8210123456);
|
||||
|
||||
REQUIRE_THAT(age.on_earth(), Catch::Matchers::WithinAbs(260.16, accuracy));
|
||||
REQUIRE_THAT(age.on_neptune(), Catch::Matchers::WithinAbs(1.58, accuracy));
|
||||
}
|
||||
|
||||
#if defined(EXERCISM_RUN_ALL_TESTS)
|
||||
|
||||
#endif
|
17937
cpp/space-age/test/catch.hpp
Normal file
17937
cpp/space-age/test/catch.hpp
Normal file
File diff suppressed because it is too large
Load diff
2
cpp/space-age/test/tests-main.cpp
Normal file
2
cpp/space-age/test/tests-main.cpp
Normal file
|
@ -0,0 +1,2 @@
|
|||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch.hpp"
|
Loading…
Reference in a new issue