did some more exercises
This commit is contained in:
parent
b0b200cb0a
commit
4cc4feeb8a
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"blurb": "Learn about error handling by working on a simple calculator.",
|
||||
"contributors": ["valentin-p", "yzAlvin", "sanderploegsma"],
|
||||
"authors": ["archrisV"],
|
||||
"files": {
|
||||
"solution": ["CalculatorConundrum.cs"],
|
||||
"test": ["CalculatorConundrumTests.cs"],
|
||||
"exemplar": [".meta/Exemplar.cs"],
|
||||
"editor": ["SimpleOperation.cs"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"track":"csharp","exercise":"calculator-conundrum","id":"37f38dc680a34174b199b5fc4c693916","url":"https://exercism.org/tracks/csharp/exercises/calculator-conundrum","handle":"benharri","is_requester":true,"auto_approve":false}
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
|
||||
public static class SimpleCalculator
|
||||
{
|
||||
public static string Calculate(int operand1, int operand2, string operation)
|
||||
{
|
||||
int result;
|
||||
try
|
||||
{
|
||||
result = operation switch
|
||||
{
|
||||
"+" => operand1 + operand2,
|
||||
"*" => operand1 * operand2,
|
||||
"/" => operand1 / operand2,
|
||||
"" => throw new ArgumentException(nameof(operation)),
|
||||
null => throw new ArgumentNullException(nameof(operation)),
|
||||
_ => throw new ArgumentOutOfRangeException(operation)
|
||||
};
|
||||
}
|
||||
catch (DivideByZeroException)
|
||||
{
|
||||
return "Division by zero is not allowed.";
|
||||
}
|
||||
|
||||
return $"{operand1} {operation} {operand2} = {result}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
||||
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,80 @@
|
|||
using Xunit;
|
||||
using Exercism.Tests;
|
||||
using System;
|
||||
|
||||
public class CalculatorConundrumTests
|
||||
{
|
||||
//Addition tests
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Addition_with_small_operands()
|
||||
{
|
||||
Assert.Equal("22 + 25 = 47", SimpleCalculator.Calculate(22, 25, "+"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Addition_with_large_operands()
|
||||
{
|
||||
Assert.Equal("378961 + 399635 = 778596", SimpleCalculator.Calculate(378_961, 399_635, "+"));
|
||||
}
|
||||
|
||||
//Multiplication tests
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Multiplication_with_small_operands()
|
||||
{
|
||||
Assert.Equal("3 * 21 = 63", SimpleCalculator.Calculate(3, 21, "*"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Multiplication_with_large_operands()
|
||||
{
|
||||
Assert.Equal("72441 * 2048 = 148359168", SimpleCalculator.Calculate(72_441, 2_048, "*"));
|
||||
}
|
||||
|
||||
//Division tests
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Division_with_small_operands()
|
||||
{
|
||||
Assert.Equal("72 / 9 = 8", SimpleCalculator.Calculate(72, 9, "/"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Division_with_large_operands()
|
||||
{
|
||||
Assert.Equal("1338800 / 83675 = 16", SimpleCalculator.Calculate(1_338_800, 83_675, "/"));
|
||||
}
|
||||
|
||||
// Invalid operator
|
||||
[Fact]
|
||||
[Task(2)]
|
||||
public void Calculate_throws_exception_for_non_valid_operations()
|
||||
{
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => SimpleCalculator.Calculate(1, 2, "**"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(2)]
|
||||
public void Calculate_throws_exception_for_null_as_operation()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => SimpleCalculator.Calculate(1, 2, null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(2)]
|
||||
public void Calculate_throws_exception_for_empty_string_as_operation()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => SimpleCalculator.Calculate(1, 2, ""));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Calculate_throws_exception_for_division_with_0()
|
||||
{
|
||||
Assert.Equal("Division by zero is not allowed.", SimpleCalculator.Calculate(33, 0, "/"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
|
||||
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
|
||||
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
|
||||
|
||||
## Skipped tests
|
||||
|
||||
Initially, only the first test will be enabled.
|
||||
This is to encourage you to solve the exercise one step at a time.
|
||||
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit CalculatorConundrum.cs` 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/csharp)
|
||||
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
|
||||
- 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:
|
||||
|
||||
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
|
||||
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
|
||||
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
|
|
@ -0,0 +1,20 @@
|
|||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- [Exceptions][exceptions]: basic introduction to exceptions.
|
||||
- [Using exceptions][using-exceptions]: how to use exceptions.
|
||||
|
||||
## 2. Handle illegal operations
|
||||
|
||||
- You need to [throw an exception][creating-and-throwing-exceptions] here.
|
||||
|
||||
## 3. Handle errors when dividing by zero
|
||||
|
||||
- You need to [catch an exception][exception-handling] here to handle the [`DivideByZeroException`][divide-by-zero-exception] that is thrown when dividing by zero.
|
||||
|
||||
[exceptions]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/
|
||||
[using-exceptions]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/using-exceptions
|
||||
[exception-handling]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/exception-handling
|
||||
[creating-and-throwing-exceptions]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/exceptions/creating-and-throwing-exceptions
|
||||
[divide-by-zero-exception]: https://docs.microsoft.com/en-us/dotnet/api/system.dividebyzeroexception?view=net-5.0
|
|
@ -0,0 +1,108 @@
|
|||
# Calculator Conundrum
|
||||
|
||||
Welcome to Calculator Conundrum 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
|
||||
|
||||
Exceptions in C# provide a structured, uniform, and type-safe way of handling error conditions that occur during runtime. Proper handling of exceptions and error is important when trying to prevent application crashes.
|
||||
|
||||
In C#, all exceptions have `System.Exception` class as their base type. It contains important properties such as `Message`, which contains a human-readable description of the reason for the exception being thrown.
|
||||
|
||||
To signal that there should be an error in a certain part of the code, a new exception object needs to be created and then thrown, using the `throw` keyword:
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
static int Square(int number)
|
||||
{
|
||||
if (number >= 46341)
|
||||
{
|
||||
throw new ArgumentException($"Argument {number} cannot be higher than 46340 as its' square doesn't fit into int type.");
|
||||
}
|
||||
return number * number;
|
||||
}
|
||||
```
|
||||
|
||||
When an exception gets thrown, the runtime has the task of finding a piece of code that is responsible for handling of that exception. If no appropriate handler is found, the runtime displays the unhandled exception message in addition to stopping the execution of the program.
|
||||
|
||||
To create a handler for an exception, C# uses the try-catch statement, which consists of a `try` block and one or more `catch` clauses. The `try` block should contain and guard code that may result in the exception getting thrown. The `catch` clauses should contain code that handles the behavior of the program after the error has occurred. It is important to note that the order of exceptions matters after the `try` block, as when multiple exceptions are listed, the first matching `catch` clause is executed.
|
||||
|
||||
```csharp
|
||||
try
|
||||
{
|
||||
if (number == 42)
|
||||
{
|
||||
throw new ArgumentException("The number cannot be equal to 42.", "number");
|
||||
}
|
||||
|
||||
if (number < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("number", "The number cannot be negative.");
|
||||
}
|
||||
|
||||
// Process number ...
|
||||
}
|
||||
catch (ArgumentOutOfRangeException e)
|
||||
{
|
||||
Console.WriteLine($"Number is out of range: {e.Message}.");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
Console.WriteLine("Invalid number.");
|
||||
}
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
In this exercise you will be building error handling for a simple integer calculator. To make matters simple, methods for calculating addition, multiplication and division are provided.
|
||||
|
||||
The goal is to have a working calculator that returns a string with the following pattern: `16 + 51 = 67`, when provided with arguments `16`, `51` and `+`.
|
||||
|
||||
```csharp
|
||||
SimpleCalculator.Calculate(16, 51, "+"); // => returns "16 + 51 = 67"
|
||||
|
||||
SimpleCalculator.Calculate(32, 6, "*"); // => returns "32 * 6 = 192"
|
||||
|
||||
SimpleCalculator.Calculate(512, 4, "/"); // => returns "512 / 4 = 128"
|
||||
```
|
||||
|
||||
## 1. Implement the calculator operations
|
||||
|
||||
The main method for implementation in this task will be the (_static_) `SimpleCalculator.Calculate()` method. It takes three arguments. The first two arguments are integer numbers on which an operation is going to be conducted. The third argument is of type string and for this exercise it is necessary to implement the following operations:
|
||||
|
||||
- addition using the `+` string
|
||||
- multiplication using the `*` string
|
||||
- division using the `/` string
|
||||
|
||||
## 2. Handle illegal operations
|
||||
|
||||
Any other operation symbol should throw the `ArgumentOutOfRangeException` exception. If the operation argument is an empty string, then the method should throw the `ArgumentException` exception. When `null` is provided as an operation argument, then the method should throw the `ArgumentNullException` exception.
|
||||
|
||||
```csharp
|
||||
SimpleCalculator.Calculate(100, 10, "-"); // => throws ArgumentOutOfRangeException
|
||||
|
||||
SimpleCalculator.Calculate(8, 2, ""); // => throws ArgumentException
|
||||
|
||||
SimpleCalculator.Calculate(58, 6, null); // => throws ArgumentNullException
|
||||
```
|
||||
|
||||
## 3. Handle errors when dividing by zero
|
||||
|
||||
When attempting to divide by `0`, the calculator should return a string with the content `Division by zero is not allowed.`. Any other exception should not be handled by the `SimpleCalculator.Calculate()` method.
|
||||
|
||||
```csharp
|
||||
SimpleCalculator.Calculate(512, 0, "/"); // => returns "Division by zero is not allowed."
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @archrisV
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @valentin-p
|
||||
- @yzAlvin
|
||||
- @sanderploegsma
|
|
@ -0,0 +1,17 @@
|
|||
public static class SimpleOperation
|
||||
{
|
||||
public static int Division(int operand1, int operand2)
|
||||
{
|
||||
return operand1 / operand2;
|
||||
}
|
||||
|
||||
public static int Multiplication(int operand1, int operand2)
|
||||
{
|
||||
return operand1 * operand2;
|
||||
}
|
||||
|
||||
public static int Addition(int operand1, int operand2)
|
||||
{
|
||||
return operand1 + operand2;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"blurb": "Learn about enums by parsing logs.",
|
||||
"contributors": [
|
||||
"valentin-p",
|
||||
"yzAlvin"
|
||||
],
|
||||
"authors": [
|
||||
"ErikSchierboom"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"LogsLogsLogs.cs"
|
||||
],
|
||||
"test": [
|
||||
"LogsLogsLogsTests.cs"
|
||||
],
|
||||
"exemplar": [
|
||||
".meta/Exemplar.cs"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"track":"csharp","exercise":"logs-logs-logs","id":"a31a4aeebb374c45bd9a809e6d2c6b75","url":"https://exercism.org/tracks/csharp/exercises/logs-logs-logs","handle":"benharri","is_requester":true,"auto_approve":false}
|
|
@ -0,0 +1,39 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
|
||||
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
|
||||
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
|
||||
|
||||
## Skipped tests
|
||||
|
||||
Initially, only the first test will be enabled.
|
||||
This is to encourage you to solve the exercise one step at a time.
|
||||
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit LogsLogsLogs.cs` 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/csharp)
|
||||
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
|
||||
- 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:
|
||||
|
||||
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
|
||||
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
|
||||
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
|
|
@ -0,0 +1,27 @@
|
|||
# Hints
|
||||
|
||||
## General
|
||||
|
||||
- [Tutorial on working with enums][docs.microsoft.com-enumeration-types].
|
||||
|
||||
## 1. Parse log level
|
||||
|
||||
- There is a [method to get a part of a string][docs.microsoft.com_system_string_substring].
|
||||
- You can use a [`switch` statement][docs.microsoft.com_keyword_switch] to elegantly handle the various log levels.
|
||||
|
||||
## 2. Support unknown log level
|
||||
|
||||
- There is a [special switch case][docs.microsoft.com_keyword_switch_default] that can be used to catch unspecified cases.
|
||||
|
||||
## 3. Convert log line to short format
|
||||
|
||||
- One can [assign specific values to enum members][docs.microsoft.com_creating-an-enumeration-type].
|
||||
- Converting an enum to a number can be done through [casting][docs.microsoft.com_enumeration-types-casting] or by using a [format string][docs.microsoft.com_system.enum.tostring].
|
||||
|
||||
[docs.microsoft.com-enumeration-types]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/enumeration-types
|
||||
[docs.microsoft.com_system_string_substring]: https://docs.microsoft.com/en-us/dotnet/api/system.string.substring?view=net-5.0
|
||||
[docs.microsoft.com_keyword_switch]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch
|
||||
[docs.microsoft.com_keyword_switch_default]: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/switch#the-default-case
|
||||
[docs.microsoft.com_enumeration-types-casting]: https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/enumeration-types#code-try-1
|
||||
[docs.microsoft.com_creating-an-enumeration-type]: https://docs.microsoft.com/en-us/dotnet/api/system.enum?view=net-5.0#creating-an-enumeration-type
|
||||
[docs.microsoft.com_system.enum.tostring]: https://docs.microsoft.com/en-us/dotnet/api/system.enum.tostring?view=net-5.0
|
|
@ -0,0 +1,28 @@
|
|||
enum LogLevel
|
||||
{
|
||||
Unknown = 0,
|
||||
Trace = 1,
|
||||
Debug = 2,
|
||||
Info = 4,
|
||||
Warning = 5,
|
||||
Error = 6,
|
||||
Fatal = 42
|
||||
}
|
||||
|
||||
static class LogLine
|
||||
{
|
||||
public static LogLevel ParseLogLevel(string logLine) =>
|
||||
logLine[1..4] switch
|
||||
{
|
||||
"TRC" => LogLevel.Trace,
|
||||
"DBG" => LogLevel.Debug,
|
||||
"INF" => LogLevel.Info,
|
||||
"WRN" => LogLevel.Warning,
|
||||
"ERR" => LogLevel.Error,
|
||||
"FTL" => LogLevel.Fatal,
|
||||
_ => LogLevel.Unknown
|
||||
};
|
||||
|
||||
public static string OutputForShortLog(LogLevel logLevel, string message) =>
|
||||
$"{(int)logLevel}:{message}";
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
||||
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,103 @@
|
|||
using Xunit;
|
||||
using Exercism.Tests;
|
||||
|
||||
public class LogsLogsLogsTests
|
||||
{
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Parse_trace()
|
||||
{
|
||||
Assert.Equal(LogLevel.Trace, LogLine.ParseLogLevel("[TRC]: Line 84 - Console.WriteLine('Hello World');"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Parse_debug()
|
||||
{
|
||||
Assert.Equal(LogLevel.Debug, LogLine.ParseLogLevel("[DBG]: ; expected"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Parse_info()
|
||||
{
|
||||
Assert.Equal(LogLevel.Info, LogLine.ParseLogLevel("[INF]: Timezone changed"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Parse_warning()
|
||||
{
|
||||
Assert.Equal(LogLevel.Warning, LogLine.ParseLogLevel("[WRN]: Timezone not set"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Parse_error()
|
||||
{
|
||||
Assert.Equal(LogLevel.Error, LogLine.ParseLogLevel("[ERR]: Disk full"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(1)]
|
||||
public void Parse_fatal()
|
||||
{
|
||||
Assert.Equal(LogLevel.Fatal, LogLine.ParseLogLevel("[FTL]: Not enough memory"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(2)]
|
||||
public void Parse_unknown()
|
||||
{
|
||||
Assert.Equal(LogLevel.Unknown, LogLine.ParseLogLevel("[XYZ]: Gibberish message.. beep boop.."));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Output_for_short_log_for_trace()
|
||||
{
|
||||
Assert.Equal("1:Line 13 - int myNum = 42;", LogLine.OutputForShortLog(LogLevel.Trace, "Line 13 - int myNum = 42;"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Output_for_short_log_for_debug()
|
||||
{
|
||||
Assert.Equal("2:The name 'LogLevel' does not exist in the current context", LogLine.OutputForShortLog(LogLevel.Debug, "The name 'LogLevel' does not exist in the current context"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Output_for_short_log_for_info()
|
||||
{
|
||||
Assert.Equal("4:File moved", LogLine.OutputForShortLog(LogLevel.Info, "File moved"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Output_for_short_log_for_warning()
|
||||
{
|
||||
Assert.Equal("5:Unsafe password", LogLine.OutputForShortLog(LogLevel.Warning, "Unsafe password"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Output_for_short_log_for_error()
|
||||
{
|
||||
Assert.Equal("6:Stack overflow", LogLine.OutputForShortLog(LogLevel.Error, "Stack overflow"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Output_for_short_log_for_fatal()
|
||||
{
|
||||
Assert.Equal("42:Dumping all files", LogLine.OutputForShortLog(LogLevel.Fatal, "Dumping all files"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[Task(3)]
|
||||
public void Output_for_short_log_for_unknown()
|
||||
{
|
||||
Assert.Equal("0:Something unknown happened", LogLine.OutputForShortLog(LogLevel.Unknown, "Something unknown happened"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
# Logs, Logs, Logs!
|
||||
|
||||
Welcome to Logs, Logs, Logs! 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
|
||||
|
||||
The C# `enum` type represents a fixed set of named constants (an enumeration). Its chief purpose is to provide a type-safe way of interacting with numeric constants, limiting the available values to a pre-defined set. A simple enum can be defined as follows:
|
||||
|
||||
```csharp
|
||||
enum Season
|
||||
{
|
||||
Spring,
|
||||
Summer,
|
||||
Autumn,
|
||||
Winter
|
||||
}
|
||||
```
|
||||
|
||||
If not defined explicitly, enum members will automatically get assigned incrementing integer values, with the first value being zero. It is also possible to assign values explicitly:
|
||||
|
||||
```csharp
|
||||
enum Answer
|
||||
{
|
||||
Maybe = 1,
|
||||
Yes = 3,
|
||||
No = 5
|
||||
}
|
||||
```
|
||||
|
||||
## Instructions
|
||||
|
||||
In this exercise you'll be processing log-lines.
|
||||
|
||||
Each log line is a string formatted as follows: `"[<LVL>]: <MESSAGE>"`.
|
||||
|
||||
These are the different log levels:
|
||||
|
||||
- `TRC` (trace)
|
||||
- `DBG` (debug)
|
||||
- `INF` (info)
|
||||
- `WRN` (warning)
|
||||
- `ERR` (error)
|
||||
- `FTL` (fatal)
|
||||
|
||||
You have three tasks.
|
||||
|
||||
## 1. Parse log level
|
||||
|
||||
Define a `LogLevel` enum that has six elements corresponding to the above log levels.
|
||||
|
||||
- `Trace`
|
||||
- `Debug`
|
||||
- `Info`
|
||||
- `Warning`
|
||||
- `Error`
|
||||
- `Fatal`
|
||||
|
||||
Next, implement the (_static_) `LogLine.ParseLogLevel()` method to parse the log level of a log line:
|
||||
|
||||
```csharp
|
||||
LogLine.ParseLogLevel("[INF]: File deleted")
|
||||
// => LogLevel.Info
|
||||
```
|
||||
|
||||
## 2. Support unknown log level
|
||||
|
||||
Unfortunately, occasionally some log lines have an unknown log level. To gracefully handle these log lines, add an `Unknown` element to the `LogLevel` enum which should be returned when parsing an unknown log level:
|
||||
|
||||
```csharp
|
||||
LogLine.ParseLogLevel("[XYZ]: Overly specific, out of context message")
|
||||
// => LogLevel.Unknown
|
||||
```
|
||||
|
||||
## 3. Convert log line to short format
|
||||
|
||||
The log level of a log line is quite verbose. To reduce the disk space needed to store the log lines, a short format is developed: `"[<ENCODED_LEVEL>]:<MESSAGE>"`.
|
||||
|
||||
The encoded log level is a simple mapping of a log level to a number:
|
||||
|
||||
- `Unknown` - `0`
|
||||
- `Trace` - `1`
|
||||
- `Debug` - `2`
|
||||
- `Info` - `4`
|
||||
- `Warning` - `5`
|
||||
- `Error` - `6`
|
||||
- `Fatal` - `42`
|
||||
|
||||
Implement the (_static_) `LogLine.OutputForShortLog()` method that can output the shortened log line format:
|
||||
|
||||
```csharp
|
||||
LogLine.OutputForShortLog(LogLevel.Error, "Stack overflow")
|
||||
// => "6:Stack overflow"
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @ErikSchierboom
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @valentin-p
|
||||
- @yzAlvin
|
|
@ -0,0 +1,141 @@
|
|||
###############################
|
||||
# Core EditorConfig Options #
|
||||
###############################
|
||||
|
||||
; This file is for unifying the coding style for different editors and IDEs.
|
||||
; More information at:
|
||||
; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
|
||||
; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
|
||||
[SpiralMatrix.cs]
|
||||
indent_size = 4
|
||||
|
||||
###############################
|
||||
# .NET Coding Conventions #
|
||||
###############################
|
||||
|
||||
# Organize usings
|
||||
dotnet_sort_system_directives_first = true
|
||||
dotnet_separate_import_directive_groups = true
|
||||
|
||||
# this. preferences
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
# Parentheses preferences
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
|
||||
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
|
||||
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
dotnet_style_require_accessibility_modifiers = always:suggestion
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
|
||||
# Expression-level preferences
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
|
||||
###############################
|
||||
# Naming Conventions #
|
||||
###############################
|
||||
|
||||
# Style Definitions
|
||||
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
||||
|
||||
# Use PascalCase for constant fields
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
|
||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||
|
||||
###############################
|
||||
# C# Code Style Rules #
|
||||
###############################
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_for_built_in_types = true:none
|
||||
csharp_style_var_when_type_is_apparent = true:none
|
||||
csharp_style_var_elsewhere = true:none
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_methods = true:suggestion
|
||||
csharp_style_expression_bodied_constructors = true:suggestion
|
||||
csharp_style_expression_bodied_operators = true:suggestion
|
||||
csharp_style_expression_bodied_properties = true:suggestion
|
||||
csharp_style_expression_bodied_indexers = true:suggestion
|
||||
csharp_style_expression_bodied_accessors = true:suggestion
|
||||
|
||||
# Pattern-matching preferences
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
|
||||
# Null-checking preferences
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_prefer_braces = true:none
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
|
||||
###############################
|
||||
# C# Formatting Rules #
|
||||
###############################
|
||||
|
||||
# New line preferences
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = false
|
||||
csharp_new_line_before_members_in_anonymous_types = false
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# Indentation preferences
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_labels = flush_left
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"blurb": " Given the size, return a square matrix of numbers in spiral order.",
|
||||
"authors": [
|
||||
"jpreese"
|
||||
],
|
||||
"contributors": [
|
||||
"ErikSchierboom",
|
||||
"j2jensen",
|
||||
"robkeim",
|
||||
"wolf99"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"SpiralMatrix.cs"
|
||||
],
|
||||
"test": [
|
||||
"SpiralMatrixTests.cs"
|
||||
],
|
||||
"example": [
|
||||
".meta/Example.cs"
|
||||
]
|
||||
},
|
||||
"source": "Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension.",
|
||||
"source_url": "https://www.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/"
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"track":"csharp","exercise":"spiral-matrix","id":"90535426d1be4eca8ea458a472fff41b","url":"https://exercism.org/tracks/csharp/exercises/spiral-matrix","handle":"benharri","is_requester":true,"auto_approve":false}
|
|
@ -0,0 +1,39 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
|
||||
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
|
||||
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
|
||||
|
||||
## Skipped tests
|
||||
|
||||
Initially, only the first test will be enabled.
|
||||
This is to encourage you to solve the exercise one step at a time.
|
||||
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit SpiralMatrix.cs` 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/csharp)
|
||||
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
|
||||
- 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:
|
||||
|
||||
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
|
||||
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
|
||||
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
|
|
@ -0,0 +1,47 @@
|
|||
# Spiral Matrix
|
||||
|
||||
Welcome to Spiral Matrix on Exercism's C# Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
|
||||
## Instructions
|
||||
|
||||
Given the size, return a square matrix of numbers in spiral order.
|
||||
|
||||
The matrix should be filled with natural numbers, starting from 1
|
||||
in the top-left corner, increasing in an inward, clockwise spiral order,
|
||||
like these examples:
|
||||
|
||||
## Examples
|
||||
### Spiral matrix of size 3
|
||||
|
||||
```text
|
||||
1 2 3
|
||||
8 9 4
|
||||
7 6 5
|
||||
```
|
||||
|
||||
### Spiral matrix of size 4
|
||||
|
||||
```text
|
||||
1 2 3 4
|
||||
12 13 14 5
|
||||
11 16 15 6
|
||||
10 9 8 7
|
||||
```
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @jpreese
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @ErikSchierboom
|
||||
- @j2jensen
|
||||
- @robkeim
|
||||
- @wolf99
|
||||
|
||||
### Based on
|
||||
|
||||
Reddit r/dailyprogrammer challenge #320 [Easy] Spiral Ascension. - https://www.reddit.com/r/dailyprogrammer/comments/6i60lr/20170619_challenge_320_easy_spiral_ascension/
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
|
||||
public class SpiralMatrix
|
||||
{
|
||||
public static int[,] GetMatrix(int size)
|
||||
{
|
||||
var m = new int[size, size];
|
||||
int x = 0, y = 0, min = 0, max = size - 1;
|
||||
|
||||
for (var i = 1; i <= size * size; i++)
|
||||
{
|
||||
// fill array with index
|
||||
m[y, x] = i;
|
||||
|
||||
// update coordinates
|
||||
if (y == max && x != min) x--;
|
||||
else if (x == max) y++;
|
||||
else if (y == min) x++;
|
||||
else if (x == min && y != min + 1) y--;
|
||||
else
|
||||
{
|
||||
max--; min++; x++;
|
||||
}
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
||||
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,70 @@
|
|||
using Xunit;
|
||||
|
||||
public class SpiralMatrixTests
|
||||
{
|
||||
[Fact]
|
||||
public void Empty_spiral()
|
||||
{
|
||||
Assert.Empty(SpiralMatrix.GetMatrix(0));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove this Skip property to run this test")]
|
||||
public void Trivial_spiral()
|
||||
{
|
||||
var expected = new[,]
|
||||
{
|
||||
{ 1 }
|
||||
};
|
||||
Assert.Equal(expected, SpiralMatrix.GetMatrix(1));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove this Skip property to run this test")]
|
||||
public void Spiral_of_size_2()
|
||||
{
|
||||
var expected = new[,]
|
||||
{
|
||||
{ 1, 2 },
|
||||
{ 4, 3 }
|
||||
};
|
||||
Assert.Equal(expected, SpiralMatrix.GetMatrix(2));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove this Skip property to run this test")]
|
||||
public void Spiral_of_size_3()
|
||||
{
|
||||
var expected = new[,]
|
||||
{
|
||||
{ 1, 2, 3 },
|
||||
{ 8, 9, 4 },
|
||||
{ 7, 6, 5 }
|
||||
};
|
||||
Assert.Equal(expected, SpiralMatrix.GetMatrix(3));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove this Skip property to run this test")]
|
||||
public void Spiral_of_size_4()
|
||||
{
|
||||
var expected = new[,]
|
||||
{
|
||||
{ 1, 2, 3, 4 },
|
||||
{ 12, 13, 14, 5 },
|
||||
{ 11, 16, 15, 6 },
|
||||
{ 10, 9, 8, 7 }
|
||||
};
|
||||
Assert.Equal(expected, SpiralMatrix.GetMatrix(4));
|
||||
}
|
||||
|
||||
[Fact(Skip = "Remove this Skip property to run this test")]
|
||||
public void Spiral_of_size_5()
|
||||
{
|
||||
var expected = new[,]
|
||||
{
|
||||
{ 1, 2, 3, 4, 5 },
|
||||
{ 16, 17, 18, 19, 6 },
|
||||
{ 15, 24, 25, 20, 7 },
|
||||
{ 14, 23, 22, 21, 8 },
|
||||
{ 13, 12, 11, 10, 9 }
|
||||
};
|
||||
Assert.Equal(expected, SpiralMatrix.GetMatrix(5));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
###############################
|
||||
# Core EditorConfig Options #
|
||||
###############################
|
||||
|
||||
; This file is for unifying the coding style for different editors and IDEs.
|
||||
; More information at:
|
||||
; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
|
||||
; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017
|
||||
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
|
||||
[Tournament.cs]
|
||||
indent_size = 4
|
||||
|
||||
###############################
|
||||
# .NET Coding Conventions #
|
||||
###############################
|
||||
|
||||
# Organize usings
|
||||
dotnet_sort_system_directives_first = true
|
||||
dotnet_separate_import_directive_groups = true
|
||||
|
||||
# this. preferences
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
|
||||
dotnet_style_predefined_type_for_member_access = true:suggestion
|
||||
|
||||
# Parentheses preferences
|
||||
dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
|
||||
dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
|
||||
dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
|
||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
dotnet_style_require_accessibility_modifiers = always:suggestion
|
||||
dotnet_style_readonly_field = true:suggestion
|
||||
|
||||
# Expression-level preferences
|
||||
dotnet_style_object_initializer = true:suggestion
|
||||
dotnet_style_collection_initializer = true:suggestion
|
||||
dotnet_style_explicit_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion
|
||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
|
||||
dotnet_style_prefer_auto_properties = true:suggestion
|
||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
|
||||
dotnet_style_prefer_conditional_expression_over_return = true:suggestion
|
||||
dotnet_style_coalesce_expression = true:suggestion
|
||||
dotnet_style_null_propagation = true:suggestion
|
||||
|
||||
###############################
|
||||
# Naming Conventions #
|
||||
###############################
|
||||
|
||||
# Style Definitions
|
||||
dotnet_naming_style.pascal_case_style.capitalization = pascal_case
|
||||
|
||||
# Use PascalCase for constant fields
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
|
||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
|
||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field
|
||||
dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
|
||||
dotnet_naming_symbols.constant_fields.required_modifiers = const
|
||||
|
||||
###############################
|
||||
# C# Code Style Rules #
|
||||
###############################
|
||||
|
||||
# var preferences
|
||||
csharp_style_var_for_built_in_types = true:none
|
||||
csharp_style_var_when_type_is_apparent = true:none
|
||||
csharp_style_var_elsewhere = true:none
|
||||
|
||||
# Expression-bodied members
|
||||
csharp_style_expression_bodied_methods = true:suggestion
|
||||
csharp_style_expression_bodied_constructors = true:suggestion
|
||||
csharp_style_expression_bodied_operators = true:suggestion
|
||||
csharp_style_expression_bodied_properties = true:suggestion
|
||||
csharp_style_expression_bodied_indexers = true:suggestion
|
||||
csharp_style_expression_bodied_accessors = true:suggestion
|
||||
|
||||
# Pattern-matching preferences
|
||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
|
||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
|
||||
|
||||
# Null-checking preferences
|
||||
csharp_style_throw_expression = true:suggestion
|
||||
csharp_style_conditional_delegate_call = true:suggestion
|
||||
|
||||
# Modifier preferences
|
||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
|
||||
|
||||
# Expression-level preferences
|
||||
csharp_prefer_braces = true:none
|
||||
csharp_prefer_simple_default_expression = true:suggestion
|
||||
csharp_style_deconstructed_variable_declaration = true:suggestion
|
||||
csharp_style_pattern_local_over_anonymous_function = true:suggestion
|
||||
csharp_style_inlined_variable_declaration = true:suggestion
|
||||
|
||||
###############################
|
||||
# C# Formatting Rules #
|
||||
###############################
|
||||
|
||||
# New line preferences
|
||||
csharp_new_line_before_open_brace = all
|
||||
csharp_new_line_before_else = true
|
||||
csharp_new_line_before_catch = true
|
||||
csharp_new_line_before_finally = true
|
||||
csharp_new_line_before_members_in_object_initializers = false
|
||||
csharp_new_line_before_members_in_anonymous_types = false
|
||||
csharp_new_line_between_query_expression_clauses = true
|
||||
|
||||
# Indentation preferences
|
||||
csharp_indent_case_contents = true
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_labels = flush_left
|
||||
|
||||
# Space preferences
|
||||
csharp_space_after_cast = false
|
||||
csharp_space_after_keywords_in_control_flow_statements = true
|
||||
csharp_space_between_method_declaration_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_parameter_list_parentheses = false
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_space_around_binary_operators = before_and_after
|
||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
|
||||
csharp_space_between_method_call_name_and_opening_parenthesis = false
|
||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false
|
||||
|
||||
# Wrapping preferences
|
||||
csharp_preserve_single_line_blocks = true
|
||||
csharp_preserve_single_line_statements = true
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"blurb": "Tally the results of a small football competition.",
|
||||
"authors": [
|
||||
"pminten"
|
||||
],
|
||||
"contributors": [
|
||||
"bressain",
|
||||
"ErikSchierboom",
|
||||
"GKotfis",
|
||||
"j2jensen",
|
||||
"jwood803",
|
||||
"robkeim",
|
||||
"wolf99"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"Tournament.cs"
|
||||
],
|
||||
"test": [
|
||||
"TournamentTests.cs"
|
||||
],
|
||||
"example": [
|
||||
".meta/Example.cs"
|
||||
]
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"track":"csharp","exercise":"tournament","id":"560de2cadb8346d19088a013bcabbe0f","url":"https://exercism.org/tracks/csharp/exercises/tournament","handle":"benharri","is_requester":true,"auto_approve":false}
|
|
@ -0,0 +1,39 @@
|
|||
# Help
|
||||
|
||||
## Running the tests
|
||||
|
||||
You can run the tests by opening a command prompt in the exercise's directory, and then running the [`dotnet test` command](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-test)
|
||||
Alternatively, most IDE's have built-in support for running tests, including [Visual Studio](https://docs.microsoft.com/en-us/visualstudio/test/run-unit-tests-with-test-explorer), [Rider](https://www.jetbrains.com/help/rider/Unit_Testing_in_Solution.html) and [Visual Studio code](https://github.com/OmniSharp/omnisharp-vscode/wiki/How-to-run-and-debug-unit-tests).
|
||||
See the [tests page](https://exercism.io/tracks/csharp/tests) for more information.
|
||||
|
||||
## Skipped tests
|
||||
|
||||
Initially, only the first test will be enabled.
|
||||
This is to encourage you to solve the exercise one step at a time.
|
||||
Once you get the first test passing, remove the `Skip` property from the next test and work on getting that test passing.
|
||||
|
||||
## Submitting your solution
|
||||
|
||||
You can submit your solution using the `exercism submit Tournament.cs` 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/csharp)
|
||||
- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
|
||||
- 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:
|
||||
|
||||
- [Gitter](https://gitter.im/exercism/xcsharp) is Exercism C# track's Gitter room; go here to get support and ask questions related to the C# track.
|
||||
- [/r/csharp](https://www.reddit.com/r/csharp) is the C# subreddit.
|
||||
- [StackOverflow](http://stackoverflow.com/questions/tagged/c%23) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions.
|
|
@ -0,0 +1,84 @@
|
|||
# Tournament
|
||||
|
||||
Welcome to Tournament on Exercism's C# Track.
|
||||
If you need help running the tests or submitting your code, check out `HELP.md`.
|
||||
|
||||
## Instructions
|
||||
|
||||
Tally the results of a small football competition.
|
||||
|
||||
Based on an input file containing which team played against which and what the
|
||||
outcome was, create a file with a table like this:
|
||||
|
||||
```text
|
||||
Team | MP | W | D | L | P
|
||||
Devastating Donkeys | 3 | 2 | 1 | 0 | 7
|
||||
Allegoric Alaskans | 3 | 2 | 0 | 1 | 6
|
||||
Blithering Badgers | 3 | 1 | 0 | 2 | 3
|
||||
Courageous Californians | 3 | 0 | 1 | 2 | 1
|
||||
```
|
||||
|
||||
What do those abbreviations mean?
|
||||
|
||||
- MP: Matches Played
|
||||
- W: Matches Won
|
||||
- D: Matches Drawn (Tied)
|
||||
- L: Matches Lost
|
||||
- P: Points
|
||||
|
||||
A win earns a team 3 points. A draw earns 1. A loss earns 0.
|
||||
|
||||
The outcome should be ordered by points, descending. In case of a tie, teams are ordered alphabetically.
|
||||
|
||||
## Input
|
||||
|
||||
Your tallying program will receive input that looks like:
|
||||
|
||||
```text
|
||||
Allegoric Alaskans;Blithering Badgers;win
|
||||
Devastating Donkeys;Courageous Californians;draw
|
||||
Devastating Donkeys;Allegoric Alaskans;win
|
||||
Courageous Californians;Blithering Badgers;loss
|
||||
Blithering Badgers;Devastating Donkeys;loss
|
||||
Allegoric Alaskans;Courageous Californians;win
|
||||
```
|
||||
|
||||
The result of the match refers to the first team listed. So this line:
|
||||
|
||||
```text
|
||||
Allegoric Alaskans;Blithering Badgers;win
|
||||
```
|
||||
|
||||
means that the Allegoric Alaskans beat the Blithering Badgers.
|
||||
|
||||
This line:
|
||||
|
||||
```text
|
||||
Courageous Californians;Blithering Badgers;loss
|
||||
```
|
||||
|
||||
means that the Blithering Badgers beat the Courageous Californians.
|
||||
|
||||
And this line:
|
||||
|
||||
```text
|
||||
Devastating Donkeys;Courageous Californians;draw
|
||||
```
|
||||
|
||||
means that the Devastating Donkeys and Courageous Californians tied.
|
||||
|
||||
## Source
|
||||
|
||||
### Created by
|
||||
|
||||
- @pminten
|
||||
|
||||
### Contributed to by
|
||||
|
||||
- @bressain
|
||||
- @ErikSchierboom
|
||||
- @GKotfis
|
||||
- @j2jensen
|
||||
- @jwood803
|
||||
- @robkeim
|
||||
- @wolf99
|
|
@ -0,0 +1,59 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
public static class Tournament
|
||||
{
|
||||
public static void Tally(Stream inStream, Stream outStream)
|
||||
{
|
||||
var teams = new Dictionary<string, Team>();
|
||||
using var reader = new StreamReader(inStream);
|
||||
using var writer = new StreamWriter(outStream);
|
||||
|
||||
while (reader.Peek() != -1)
|
||||
{
|
||||
var split = reader.ReadLine().Split(';');
|
||||
var team1 = teams.ContainsKey(split[0]) ? teams[split[0]] : new Team { Name = split[0] };
|
||||
var team2 = teams.ContainsKey(split[1]) ? teams[split[1]] : new Team { Name = split[1] };
|
||||
|
||||
switch (split[2])
|
||||
{
|
||||
case "win":
|
||||
team1.Points += 3;
|
||||
team1.Won++;
|
||||
team2.Lost++;
|
||||
break;
|
||||
case "loss":
|
||||
team2.Points += 3;
|
||||
team1.Lost++;
|
||||
team2.Won++;
|
||||
break;
|
||||
case "draw":
|
||||
team1.Points++;
|
||||
team2.Points++;
|
||||
team1.Drawn++;
|
||||
team2.Drawn++;
|
||||
break;
|
||||
}
|
||||
|
||||
teams[split[0]] = team1;
|
||||
teams[split[1]] = team2;
|
||||
}
|
||||
|
||||
var output = new List<string>(teams.Count + 1) { "Team | MP | W | D | L | P" };
|
||||
output.AddRange(teams.Values.OrderByDescending(t => t.Points).ThenBy(t => t.Name).Select(t => t.PrintRow()));
|
||||
writer.Write(string.Join('\n', output));
|
||||
}
|
||||
}
|
||||
|
||||
public class Team
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Played => Won + Drawn + Lost;
|
||||
public int Won { get; set; }
|
||||
public int Drawn { get; set; }
|
||||
public int Lost { get; set; }
|
||||
public int Points { get; set; }
|
||||
public string PrintRow() =>
|
||||
$"{Name,-30} | {Played,2} | {Won,2} | {Drawn,2} | {Lost,2} | {Points,2}";
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
|
||||
<PackageReference Include="Exercism.Tests" Version="0.1.0-beta1" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,166 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Xunit;
|
||||
|
||||
public class TournamentTests
|
||||
{
|
||||
[Fact]
|
||||
public void Just_the_header_if_no_input()
|
||||
{
|
||||
var rows = "";
|
||||
var expected = "Team | MP | W | D | L | P";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_win_is_three_points_a_loss_is_zero_points()
|
||||
{
|
||||
var rows = "Allegoric Alaskans;Blithering Badgers;win";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 1 | 1 | 0 | 0 | 3\n" +
|
||||
"Blithering Badgers | 1 | 0 | 0 | 1 | 0";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_win_can_also_be_expressed_as_a_loss()
|
||||
{
|
||||
var rows = "Blithering Badgers;Allegoric Alaskans;loss";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 1 | 1 | 0 | 0 | 3\n" +
|
||||
"Blithering Badgers | 1 | 0 | 0 | 1 | 0";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_different_team_can_win()
|
||||
{
|
||||
var rows = "Blithering Badgers;Allegoric Alaskans;win";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Blithering Badgers | 1 | 1 | 0 | 0 | 3\n" +
|
||||
"Allegoric Alaskans | 1 | 0 | 0 | 1 | 0";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void A_draw_is_one_point_each()
|
||||
{
|
||||
var rows = "Allegoric Alaskans;Blithering Badgers;draw";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 1 | 0 | 1 | 0 | 1\n" +
|
||||
"Blithering Badgers | 1 | 0 | 1 | 0 | 1";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void There_can_be_more_than_one_match()
|
||||
{
|
||||
var rows =
|
||||
"Allegoric Alaskans;Blithering Badgers;win\n" +
|
||||
"Allegoric Alaskans;Blithering Badgers;win";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 2 | 2 | 0 | 0 | 6\n" +
|
||||
"Blithering Badgers | 2 | 0 | 0 | 2 | 0";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void There_can_be_more_than_one_winner()
|
||||
{
|
||||
var rows =
|
||||
"Allegoric Alaskans;Blithering Badgers;loss\n" +
|
||||
"Allegoric Alaskans;Blithering Badgers;win";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 2 | 1 | 0 | 1 | 3\n" +
|
||||
"Blithering Badgers | 2 | 1 | 0 | 1 | 3";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void There_can_be_more_than_two_teams()
|
||||
{
|
||||
var rows =
|
||||
"Allegoric Alaskans;Blithering Badgers;win\n" +
|
||||
"Blithering Badgers;Courageous Californians;win\n" +
|
||||
"Courageous Californians;Allegoric Alaskans;loss";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 2 | 2 | 0 | 0 | 6\n" +
|
||||
"Blithering Badgers | 2 | 1 | 0 | 1 | 3\n" +
|
||||
"Courageous Californians | 2 | 0 | 0 | 2 | 0";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Typical_input()
|
||||
{
|
||||
var rows =
|
||||
"Allegoric Alaskans;Blithering Badgers;win\n" +
|
||||
"Devastating Donkeys;Courageous Californians;draw\n" +
|
||||
"Devastating Donkeys;Allegoric Alaskans;win\n" +
|
||||
"Courageous Californians;Blithering Badgers;loss\n" +
|
||||
"Blithering Badgers;Devastating Donkeys;loss\n" +
|
||||
"Allegoric Alaskans;Courageous Californians;win";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Devastating Donkeys | 3 | 2 | 1 | 0 | 7\n" +
|
||||
"Allegoric Alaskans | 3 | 2 | 0 | 1 | 6\n" +
|
||||
"Blithering Badgers | 3 | 1 | 0 | 2 | 3\n" +
|
||||
"Courageous Californians | 3 | 0 | 1 | 2 | 1";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Incomplete_competition_not_all_pairs_have_played_()
|
||||
{
|
||||
var rows =
|
||||
"Allegoric Alaskans;Blithering Badgers;loss\n" +
|
||||
"Devastating Donkeys;Allegoric Alaskans;loss\n" +
|
||||
"Courageous Californians;Blithering Badgers;draw\n" +
|
||||
"Allegoric Alaskans;Courageous Californians;win";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 3 | 2 | 0 | 1 | 6\n" +
|
||||
"Blithering Badgers | 2 | 1 | 1 | 0 | 4\n" +
|
||||
"Courageous Californians | 2 | 0 | 1 | 1 | 1\n" +
|
||||
"Devastating Donkeys | 1 | 0 | 0 | 1 | 0";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Ties_broken_alphabetically()
|
||||
{
|
||||
var rows =
|
||||
"Courageous Californians;Devastating Donkeys;win\n" +
|
||||
"Allegoric Alaskans;Blithering Badgers;win\n" +
|
||||
"Devastating Donkeys;Allegoric Alaskans;loss\n" +
|
||||
"Courageous Californians;Blithering Badgers;win\n" +
|
||||
"Blithering Badgers;Devastating Donkeys;draw\n" +
|
||||
"Allegoric Alaskans;Courageous Californians;draw";
|
||||
var expected =
|
||||
"Team | MP | W | D | L | P\n" +
|
||||
"Allegoric Alaskans | 3 | 2 | 1 | 0 | 7\n" +
|
||||
"Courageous Californians | 3 | 2 | 1 | 0 | 7\n" +
|
||||
"Blithering Badgers | 3 | 0 | 1 | 2 | 1\n" +
|
||||
"Devastating Donkeys | 3 | 0 | 1 | 2 | 1";
|
||||
Assert.Equal(expected, RunTally(rows));
|
||||
}
|
||||
|
||||
private string RunTally(string input)
|
||||
{
|
||||
var encoding = new UTF8Encoding();
|
||||
using (var inStream = new MemoryStream(encoding.GetBytes(input)))
|
||||
using (var outStream = new MemoryStream())
|
||||
{
|
||||
Tournament.Tally(inStream, outStream);
|
||||
return encoding.GetString(outStream.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue