Skip to content

Commit 16f7adf

Browse files
committed
feat: add day 02 🎅
1 parent 75b0bce commit 16f7adf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+8750
-1
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[![Linkedin](https://img.shields.io/badge/LinkedIn-0077B5?style=for-the-badge&logo=linkedin&logoColor=white)](https://www.linkedin.com/company/advent-of-craft)
44
[![Youtube channel](https://camo.githubusercontent.com/94b947e758f767a15576edfb06cc06075d6b62ef7a8946db69c5ce4a2ee830f7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f596f75547562652d4646303030303f7374796c653d666f722d7468652d6261646765266c6f676f3d796f7574756265266c6f676f436f6c6f723d7768697465)](https://www.youtube.com/@AdventOfCraft)
55

6-
[![License](https://img.shields.io/github/license/advent-of-craft/2024.svg)](https://github.com/advent-of-craft/2024/blob/main/LICENSE) [![Days](https://img.shields.io/badge/%F0%9F%8E%85%20aoc%202024-day%2001-green)](https://github.com/advent-of-craft/2024)
6+
[![License](https://img.shields.io/github/license/advent-of-craft/2024.svg)](https://github.com/advent-of-craft/2024/blob/main/LICENSE) [![Days](https://img.shields.io/badge/%F0%9F%8E%85%20aoc%202024-day%2002-green)](https://github.com/advent-of-craft/2024)
77

88
Join us on [`Discord`](https://discord.gg/E5Z9s9UKTS) and [`Linkedin`](https://www.linkedin.com/company/advent-of-craft) to follow the initiative.
99

@@ -68,6 +68,7 @@ In this story, you have been working as a new consultant at `North Star Solution
6868
## Challenges
6969
- [Day 0: An encrypted email...](docs/day00/challenge.md)
7070
- [Day 1: Too many parameters...](docs/day01/challenge.md)
71+
- [Day 2: Extend the program.](docs/day02/challenge.md)
7172

7273
### Solutions
7374
- [Day 0: An encrypted email...](docs/day00/solution/step-by-step.md)

docs/day02/challenge.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
## Day 2: Extend the program.
2+
3+
On the second day, it's apparently game day! 🎯
4+
A special horn startled you at breakfast and Teo sent you a note that they are starting the production of toys. 🎁📦
5+
6+
Santa and the elves have a tradition and love to play together at `FizzBuzz` during production throughout the day.
7+
8+
They find it a little bit too easy and would like to extend the rules of the game like this:
9+
10+
- Multiples of 7 are `Whizz`
11+
- Multiples of 11 are `Bang`
12+
13+
They would like to be able to configure the game from the outside as well. 🎮
14+
15+
✅🚀 **Challenge: Make the game configurable and add new cases.** 🚀✅
16+
17+
- <u>💡HINT:</u> how can the rules be outside of the class?
18+
19+
![snippet of the day](snippet.webp)
20+
21+
### Proposed Solution
22+
[![Proposed Solution Guide](../../img/proposed-solution.webp)](solution/step-by-step.md)

docs/day02/snippet.webp

82.6 KB
Loading

exercise/C#/day02/FizzBuzz.sln

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 25.0.1700.0
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Games", "Games\Games.csproj", "{0C68A0B9-2D59-4DBC-A101-ADCA4986717E}"
7+
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Games.Tests", "Games.Tests\Games.Tests.csproj", "{A96BFF3E-F3C9-49DA-8933-F3D885F2C544}"
9+
EndProject
10+
Global
11+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
12+
Debug|Any CPU = Debug|Any CPU
13+
Release|Any CPU = Release|Any CPU
14+
EndGlobalSection
15+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
16+
{0C68A0B9-2D59-4DBC-A101-ADCA4986717E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17+
{0C68A0B9-2D59-4DBC-A101-ADCA4986717E}.Debug|Any CPU.Build.0 = Debug|Any CPU
18+
{0C68A0B9-2D59-4DBC-A101-ADCA4986717E}.Release|Any CPU.ActiveCfg = Release|Any CPU
19+
{0C68A0B9-2D59-4DBC-A101-ADCA4986717E}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{A96BFF3E-F3C9-49DA-8933-F3D885F2C544}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{A96BFF3E-F3C9-49DA-8933-F3D885F2C544}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{A96BFF3E-F3C9-49DA-8933-F3D885F2C544}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{A96BFF3E-F3C9-49DA-8933-F3D885F2C544}.Release|Any CPU.Build.0 = Release|Any CPU
24+
EndGlobalSection
25+
GlobalSection(SolutionProperties) = preSolution
26+
HideSolutionNode = FALSE
27+
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {7D9C35C9-81E4-4786-9E2C-F6E177082AAB}
30+
EndGlobalSection
31+
EndGlobal
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using FluentAssertions.LanguageExt;
2+
using FsCheck;
3+
using FsCheck.Xunit;
4+
using Xunit;
5+
6+
namespace Games.Tests
7+
{
8+
public class FizzBuzzTests
9+
{
10+
private static readonly string[] FizzBuzzStrings = ["Fizz", "Buzz", "FizzBuzz"];
11+
12+
[Theory]
13+
[InlineData(1, "1")]
14+
[InlineData(67, "67")]
15+
[InlineData(82, "82")]
16+
[InlineData(3, "Fizz")]
17+
[InlineData(66, "Fizz")]
18+
[InlineData(99, "Fizz")]
19+
[InlineData(5, "Buzz")]
20+
[InlineData(50, "Buzz")]
21+
[InlineData(85, "Buzz")]
22+
[InlineData(15, "FizzBuzz")]
23+
[InlineData(30, "FizzBuzz")]
24+
[InlineData(45, "FizzBuzz")]
25+
public void Returns_Number_Representation(int input, string expectedResult)
26+
=> Games.FizzBuzz.Convert(input)
27+
.Should()
28+
.BeSome(expectedResult);
29+
30+
[Property]
31+
public Property Parse_Return_Valid_String_For_Numbers_Between_1_And_100()
32+
=> Prop.ForAll(
33+
ValidInput(),
34+
IsConvertValid
35+
);
36+
37+
private static Arbitrary<int> ValidInput()
38+
=> Gen.Choose(FizzBuzz.Min, FizzBuzz.Max).ToArbitrary();
39+
40+
private static bool IsConvertValid(int x)
41+
=> FizzBuzz.Convert(x).Exists(s => ValidStringsFor(x).Contains(s));
42+
43+
private static IEnumerable<string> ValidStringsFor(int x)
44+
=> FizzBuzzStrings.Append(x.ToString());
45+
46+
[Property]
47+
public Property ParseFailForNumbersOutOfRange()
48+
=> Prop.ForAll(
49+
InvalidInput(),
50+
x => FizzBuzz.Convert(x).IsNone
51+
);
52+
53+
private static Arbitrary<int> InvalidInput()
54+
=> Gen.Choose(-10_000, 10_000)
55+
.ToArbitrary()
56+
.Filter(x => x is < FizzBuzz.Min or > FizzBuzz.Max);
57+
}
58+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
8+
<IsPackable>false</IsPackable>
9+
<IsTestProject>true</IsTestProject>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="FluentAssertions" Version="6.12.1" />
14+
<PackageReference Include="FluentAssertions.LanguageExt" Version="0.5.0"/>
15+
<PackageReference Include="FsCheck.Xunit" Version="2.16.6"/>
16+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
17+
<PackageReference Include="xunit" Version="2.9.2" />
18+
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
19+
<PrivateAssets>all</PrivateAssets>
20+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
21+
</PackageReference>
22+
</ItemGroup>
23+
24+
<ItemGroup>
25+
<ProjectReference Include="..\Games\Games.csproj" />
26+
</ItemGroup>
27+
28+
</Project>
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using LanguageExt;
2+
3+
namespace Games
4+
{
5+
public static class FizzBuzz
6+
{
7+
public const int Min = 1;
8+
public const int Max = 100;
9+
10+
private static readonly Map<int, string> Mapping =
11+
Map.create(
12+
(15, "FizzBuzz"),
13+
(3, "Fizz"),
14+
(5, "Buzz")
15+
);
16+
17+
public static Option<string> Convert(int input)
18+
=> IsOutOfRange(input)
19+
? Option<string>.None
20+
: ConvertSafely(input);
21+
22+
private static string ConvertSafely(int input)
23+
=> Mapping
24+
.Find(p => Is(p.Key, input))
25+
.Map(kvp => kvp.Value)
26+
.FirstOrDefault(input.ToString());
27+
28+
private static bool Is(int divisor, int input) => input % divisor == 0;
29+
30+
private static bool IsOutOfRange(int input) => input is < Min or > Max;
31+
}
32+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<PackageReference Include="FsCheck" Version="2.16.6"/>
11+
<PackageReference Include="LanguageExt.Core" Version="4.4.9" />
12+
</ItemGroup>
13+
14+
</Project>

exercise/java/day02/pom.xml

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>org.advent-of-craft</groupId>
8+
<artifactId>fizzbuzz</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
13+
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
14+
<junit.version>5.10.3</junit.version>
15+
<assertj.version>3.25.3</assertj.version>
16+
<maven.compiler.version>3.12.1</maven.compiler.version>
17+
<maven.surefire.version>3.2.2</maven.surefire.version>
18+
<vavr.version>0.10.4</vavr.version>
19+
</properties>
20+
21+
<dependencies>
22+
<dependency>
23+
<groupId>org.junit.jupiter</groupId>
24+
<artifactId>junit-jupiter-api</artifactId>
25+
<version>${junit.version}</version>
26+
<scope>test</scope>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.junit.jupiter</groupId>
30+
<artifactId>junit-jupiter-params</artifactId>
31+
<version>${junit.version}</version>
32+
<scope>test</scope>
33+
</dependency>
34+
<dependency>
35+
<groupId>org.assertj</groupId>
36+
<artifactId>assertj-core</artifactId>
37+
<version>${assertj.version}</version>
38+
<scope>test</scope>
39+
</dependency>
40+
<dependency>
41+
<groupId>io.vavr</groupId>
42+
<artifactId>vavr</artifactId>
43+
<version>${vavr.version}</version>
44+
</dependency>
45+
<dependency>
46+
<groupId>io.vavr</groupId>
47+
<artifactId>vavr-test</artifactId>
48+
<version>${vavr.version}</version>
49+
<scope>test</scope>
50+
</dependency>
51+
</dependencies>
52+
53+
<build>
54+
<plugins>
55+
<plugin>
56+
<groupId>org.apache.maven.plugins</groupId>
57+
<artifactId>maven-compiler-plugin</artifactId>
58+
<version>${maven.compiler.version}</version>
59+
<configuration>
60+
<source>21</source>
61+
<target>21</target>
62+
</configuration>
63+
</plugin>
64+
<plugin>
65+
<groupId>org.apache.maven.plugins</groupId>
66+
<artifactId>maven-surefire-plugin</artifactId>
67+
<version>${maven.surefire.version}</version>
68+
</plugin>
69+
</plugins>
70+
</build>
71+
</project>
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package games;
2+
3+
import io.vavr.collection.LinkedHashMap;
4+
import io.vavr.collection.Map;
5+
import io.vavr.control.Option;
6+
7+
import static io.vavr.control.Option.none;
8+
import static io.vavr.control.Option.some;
9+
10+
public class FizzBuzz {
11+
public static final int MIN = 1;
12+
public static final int MAX = 100;
13+
private static final Map<Integer, String> mapping = LinkedHashMap.of(
14+
15, "FizzBuzz",
15+
3, "Fizz",
16+
5, "Buzz"
17+
);
18+
19+
public static Option<String> convert(int input) {
20+
return isOutOfRange(input)
21+
? none()
22+
: some(convertSafely(input));
23+
}
24+
25+
private static String convertSafely(Integer input) {
26+
return mapping
27+
.find(p -> is(p._1, input))
28+
.map(p -> p._2)
29+
.getOrElse(input.toString());
30+
}
31+
32+
private static boolean is(Integer divisor, Integer input) {
33+
return input % divisor == 0;
34+
}
35+
36+
private static boolean isOutOfRange(Integer input) {
37+
return input < MIN || input > MAX;
38+
}
39+
}

0 commit comments

Comments
 (0)