Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.

New Challenge: Robot gravity #2

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
|Challenge|Challenge Date|Contributor(s)|Source|
|:-|:-|:-|:-|
|[Wire Ends](src/Wire%20Ends)| |[@zacharypatten](https://github.com/ZacharyPatten)|_original_|
|[Robot Gravity](src/Robot%20Gravity)| |[@zacharypatten](https://github.com/ZacharyPatten)|_original_|

Contributions are welcome. :)

Expand Down
6 changes: 6 additions & 0 deletions challenges.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wire Ends", "src\Wire Ends\Wire Ends.csproj", "{5468530B-AA66-4594-A126-4884664BE91D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Robot Gravity", "src\Robot Gravity\Robot Gravity.csproj", "{98FAB7D8-0C64-43B0-B03C-9CF08BED9089}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -15,6 +17,10 @@ Global
{5468530B-AA66-4594-A126-4884664BE91D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5468530B-AA66-4594-A126-4884664BE91D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5468530B-AA66-4594-A126-4884664BE91D}.Release|Any CPU.Build.0 = Release|Any CPU
{98FAB7D8-0C64-43B0-B03C-9CF08BED9089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98FAB7D8-0C64-43B0-B03C-9CF08BED9089}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98FAB7D8-0C64-43B0-B03C-9CF08BED9089}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98FAB7D8-0C64-43B0-B03C-9CF08BED9089}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
129 changes: 129 additions & 0 deletions src/Robot Gravity/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
> This is a challenge developed for the C# discord server.<br/>
> Want to Participate? Join the C# discord: <sub><a href="https://discord.gg/csharp"><img src="https://img.shields.io/discord/143867839282020352?logo=discord&logoColor=ffffff&color=7389D8" title="C# Discord Server" /></a></sub>

# Robot Gravity

You are making a robot to explore other planets. Your robot has a gravity sensor but you want to
have a back up way to determine the current gravity in case the sensor is damaged.Your robot has
the ability to jump and it has an height sensor that asynchronously scans about every .01 seconds.
Use those features to determine the current acceleration due to gravity as a positive number
within 0.1 units.

Use these members from `Robot robot`:
- `robot.Jump`
- `robot.MaxJumpForce`
- `robot.HeightSensor`
- `robot.Mass`

<details>
<summary>Hint #1</summary>

The equation for the vertical position of a projectile is `p = -.5*g*s^2 + v*s + i` where
- `p` is vertical position
- `g` is acceleration due to gravity
- `s` is time
- `v` is initial velocity (in this case initial velocity is the parameter to `robot.Jump` divided by `robot.Mass`)
- `i` is initial vertical position (in this case i is always 0)

</details>

<details>
<summary>Hint #2</summary>

`robot.HeightSensor` is an event. You need to make an event handler with the same method signature and subscribe to the event.

```cs
void HandleHeightSensor(double height, DateTime time)
{
// some code here...
}

robot.HeightSensor += HandleHeightSensor;
```

</details>

### Quick start

Cloning this repo is recommended.

Complete the challenge in the MS Test project here: [RobotGravityTests.cs](RobotGravityTests.cs)

### Feedback

If you have any feedback on the challenges, [please open an issue](https://github.com/discord-csharp/challenges/issues/new/choose), mention the challenge, and ping the contributor(s) of the challenge.

### Contributor(s)

- [@zacharypatten](https://github.com/ZacharyPatten)

### Source

This was an original challege. :)

---

Discord meta data. Do not edit. This is used for GitHub => Discord linking.

<table>
<tr>
<td>Name
<td>Robot Gravity Challenge
<tr>
<td>Description
<td>You are making a robot to explore other planets. Your robot has a gravity sensor but you want to have a back up way to determine the current gravity in case the sensor is damaged. Your robot has the ability to jump and it has an height sensor that asynchronously scans about every .01 seconds. Use those features to determine the current acceleration due to gravity as a positive number within 0.1 units.
<tr>
<td>Sample
<td>

Cloning the repo and complete the challenge in the MS Test project here: https://github.com/discord-csharp/challenges/tree/main/src/Robot%20Gravity/RobotGravityTests.cs

```cs
public double DetermineGravity(Robot robot)
{
// -----------------------
// Complete challenge here.
//
// - robot.Jump
// - robot.MaxJumpForce
// - robot.HeightSensor
// - robot.Mass
//
// -----------------------
}
```

<details>
<summary>Hint #1</summary>

The equation for the vertical position of a projectile is `p = -.5*g*s^2 + v*s + i` where
- `p` is vertical position
- `g` is acceleration due to gravity
- `s` is time
- `v` is initial velocity (in this case initial velocity is the parameter to `robot.Jump` divided by `robot.Mass`)
- `i` is initial vertical position (in this case i is always 0)

</details>

<details>
<summary>Hint #2</summary>

`robot.HeightSensor` is an event. You need to make an event handler with the same method signature and subscribe to the event.

```cs
void HandleHeightSensor(double height, DateTime time)
{
// some code here...
}

robot.HeightSensor += HandleHeightSensor;
```

</details>
<tr>
<td>Contributed by
<td>438382611929366537
<tr>
<td>Self link
<td>https://github.com/discord-csharp/challenges/tree/main/src/Robot%20Gravity
</table>
14 changes: 14 additions & 0 deletions src/Robot Gravity/Robot Gravity.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Space_Robot</RootNamespace>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="MSTest.TestAdapter" Version="2.2.7" />
<PackageReference Include="MSTest.TestFramework" Version="2.2.7" />
<PackageReference Include="coverlet.collector" Version="3.1.0" />
</ItemGroup>
</Project>
115 changes: 115 additions & 0 deletions src/Robot Gravity/RobotGravityTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Timers;

namespace Space_Robot
{
[TestClass]
public class RobotGravityTests
{
public static double DetermineGravity(Robot robot)
{
// -----------------------
// Complete challenge here.
//
// You are making a robot to explore other planets. Your robot has a gravity sensor but you want to
// have a back up way to determine the current gravity in case the sensor is damaged.Your robot has
// the ability to jump and it has an height sensor that asynchronously scans about every .01 seconds.
// Use those features to determine the current acceleration due to gravity as a positive number
// within 0.1 units.
//
// - robot.Jump
// - robot.MaxJumpForce
// - robot.HeightSensor
// - robot.Mass
//
// -----------------------
throw new NotImplementedException(); // <- delete
}

public class Robot
{
[Obsolete("You don't need to make any Robots. :P")]
public Robot(Func<(double, DateTime)> getHeight, Action<double> jump)
{
Timer timer = new((int)HeightSensorInterval.TotalMilliseconds);
timer.Elapsed += (o, e) =>
{
var (height, time) = getHeight();
HeightSensor?.Invoke(height, time);
};
timer.Enabled = true;
JumpCallback = jump;
}
private Action<double> JumpCallback { get; set; }
private readonly TimeSpan HeightSensorInterval = TimeSpan.FromSeconds(.01);
public double Mass { get; private set; } = 5;
public double MaxJumpForce { get; private set; } = 50d;
public event Action<double, DateTime>? HeightSensor;
public void Jump(double force) => JumpCallback?.Invoke(force);
}

// measurements in meters per second squared (m/s�)
[TestMethod] public void TestGravityOnMercury() => Test(3.7);
[TestMethod] public void TestGravityOnVenus() => Test(8.87);
[TestMethod] public void TestGravityOnEarth() => Test(9.807);
[TestMethod] public void TestGravityOnMars() => Test(3.721);
[TestMethod] public void TestGravityOnJupiter() => Test(24.79);
[TestMethod] public void TestGravityOnSaturn() => Test(10.44);
[TestMethod] public void TestGravityOnUranus() => Test(8.87);
[TestMethod] public void TestGravityOnNeptune() => Test(11.15);
[TestMethod] public void TestGravityOnPluto() => Test(0.62);
[TestMethod] public void TestGravityOnEarthMoon() => Test(1.62);

static void Test(double gravity)
{
try
{
Robot robot = InitializeRobot(gravity);
double determinedGravity = Math.Abs(DetermineGravity(robot));
Assert.IsTrue(Math.Abs(determinedGravity - gravity) <= 0.1, $"expected {gravity} but got {determinedGravity}");
}
catch (NotImplementedException)
{
Assert.Inconclusive();
}
}

static Robot InitializeRobot(double gravity)
{
(double InitialVelocity, DateTime Time)? jump = null;

Robot robot = default!;
#pragma warning disable CS0618 // Type or member is obsolete
robot = new(
getHeight: GetHeight,
jump: force =>
{
if (GetHeight().Height is 0)
{
jump = (force / robot.Mass, DateTime.Now);
}
});
#pragma warning restore CS0618 // Type or member is obsolete

(double Height, DateTime Time) GetHeight()
{
DateTime now = DateTime.Now;
if (jump is null)
{
return (0, now);
}
double seconds = (now - jump.Value.Time).TotalSeconds;
double height = -.5 * gravity * seconds * seconds + jump.Value.InitialVelocity * seconds;
if (height < 0)
{
jump = null;
height = 0;
}
return (height, now);
}

return robot;
}
}
}