diff --git a/.gitignore b/.gitignore
index 3e759b7..7728ebf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,7 @@
+obj
+bin
+TestResults
+.DS
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
diff --git a/Elevator.Tests/Elevator.Tests.csproj b/Elevator.Tests/Elevator.Tests.csproj
new file mode 100644
index 0000000..be37266
--- /dev/null
+++ b/Elevator.Tests/Elevator.Tests.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Elevator.Tests/ModelTests/ElevatorTests.cs b/Elevator.Tests/ModelTests/ElevatorTests.cs
new file mode 100644
index 0000000..9ab0e99
--- /dev/null
+++ b/Elevator.Tests/ModelTests/ElevatorTests.cs
@@ -0,0 +1,97 @@
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Elevator.Models;
+using System;
+using System.Collections.Generic;
+using Newtonsoft.Json;
+using System.Threading;
+
+namespace Elevator.Tests
+{
+ [TestClass]
+ public class ElevatorTests
+ {
+ [TestMethod]
+ // naming convention is MethodOrFieldName_Description_ReturnType
+ public void ElevatorConstructor_CreateInstanceOfElevator_Elevator()
+ {
+ ElevatorInBuilding newElevator = new ElevatorInBuilding();
+ Assert.AreEqual(typeof(ElevatorInBuilding), newElevator.GetType());
+ }
+
+ //get floor to visit
+ [TestMethod]
+ // naming convention is MethodOrFieldName_Description_ReturnType
+ public void AddFloor_AddFloorToVisit_ListOfInt()
+ {
+ ElevatorInBuilding newElevator = new ElevatorInBuilding();
+ int floorToVisit = 2;
+ newElevator.RequestFloor(floorToVisit);
+ List expectedAnswer = new List { 2 };
+ Console.WriteLine(JsonConvert.SerializeObject(newElevator.floorRequests));
+ CollectionAssert.AreEqual(expectedAnswer, newElevator.floorRequests);
+ }
+
+ [TestMethod]
+ public void RequestFloor_AddMultipleFloorsInSortedManner_Void()
+ {
+ ElevatorInBuilding newElevator = new ElevatorInBuilding();
+ int floorToVisit = 5;
+ int floorToVisit2 = 3;
+ newElevator.RequestFloor(floorToVisit);
+ newElevator.RequestFloor(floorToVisit2);
+ List expectedAnswer = new List { 3, 5 };
+ Console.WriteLine(JsonConvert.SerializeObject(newElevator.floorRequests));
+ Assert.AreEqual(newElevator.direction, Direction.Up);
+ CollectionAssert.AreEqual(expectedAnswer, newElevator.floorRequests);
+ }
+
+ [TestMethod]
+ public void RequestFloor_DirectionIsUp_Void()
+ {
+ ElevatorInBuilding newElevator = new ElevatorInBuilding();
+ int floorToVisit = 5;
+ int floorToVisit2 = 3;
+ newElevator.RequestFloor(floorToVisit);
+ newElevator.RequestFloor(floorToVisit2);
+ Assert.AreEqual(newElevator.direction, Direction.Up);
+ }
+
+ [TestMethod]
+ public void Run_NextFloorToVisitIsCalculated_Void()
+ {
+ ElevatorInBuilding newElevator = new ElevatorInBuilding();
+ int floorToVisit = 5;
+ newElevator.RequestFloor(floorToVisit);
+ newElevator.Run();
+ Assert.AreEqual(newElevator.nextFloorToVisit, floorToVisit);
+ }
+
+ [TestMethod]
+ public void Run_FloorRequestsAreRemovedAfterVisited_Void()
+ {
+ ElevatorInBuilding newElevator = new ElevatorInBuilding();
+ int floorToVisit = 5;
+ int floorToVisit2 = 3;
+ newElevator.RequestFloor(floorToVisit);
+ newElevator.RequestFloor(floorToVisit2);
+ newElevator.Run();
+ List blankList = new List() { };
+ CollectionAssert.AreEqual(newElevator.floorRequests, blankList);
+ }
+
+ [TestMethod]
+ public void Run_AddEventsToElevator_Void()
+ {
+ ElevatorInBuilding newElevator = new ElevatorInBuilding();
+ int floorToVisit = 3;
+ newElevator.RequestFloor(floorToVisit);
+ newElevator.Run();
+ ElevatorEvent newEvent1 = new ElevatorEvent(TypeOfEvent.FloorRequest);
+ ElevatorEvent newEvent2 = new ElevatorEvent(TypeOfEvent.PassFloor); // 1
+ ElevatorEvent newEvent3 = new ElevatorEvent(TypeOfEvent.PassFloor); // 2
+ ElevatorEvent newEvent4 = new ElevatorEvent(TypeOfEvent.StopFloor);
+ List eventList = new List { newEvent1, newEvent2, newEvent3, newEvent4 };
+ Assert.AreEqual(newElevator.events.Count, eventList.Count);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Elevator/Elevator.csproj b/Elevator/Elevator.csproj
new file mode 100644
index 0000000..48c94e1
--- /dev/null
+++ b/Elevator/Elevator.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/Elevator/Models/ElevatorEvent.cs b/Elevator/Models/ElevatorEvent.cs
new file mode 100644
index 0000000..c9618ad
--- /dev/null
+++ b/Elevator/Models/ElevatorEvent.cs
@@ -0,0 +1,27 @@
+using System;
+
+namespace Elevator.Models
+{
+ // 1-Timestamp and asynchronous floor request, every time one occurs.
+ // 2-Timestamp and floor, every time elevator passes a floor.
+ // 3-Timestamp and floor, every time elevator stops at a floor.
+
+ // 3 types are floor request, stop on floor, pass a floor-check if stopped if so 4 second wait otherwise 3 second wait, just add the needed seconds to the timestamp
+ public enum TypeOfEvent
+ {
+ FloorRequest,
+ PassFloor,
+ StopFloor
+ }
+ public class ElevatorEvent
+ {
+ public DateTimeOffset Now { get; set; }
+ public TypeOfEvent TypeOfEvent { get; set; }
+ public ElevatorEvent(TypeOfEvent type)
+ {
+ Now = (DateTimeOffset)DateTime.UtcNow;
+ TypeOfEvent = type;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Elevator/Models/ElevatorInBuilding.cs b/Elevator/Models/ElevatorInBuilding.cs
new file mode 100644
index 0000000..36f277f
--- /dev/null
+++ b/Elevator/Models/ElevatorInBuilding.cs
@@ -0,0 +1,113 @@
+using System.Collections.Generic;
+using System;
+using System.Threading;
+using System.Linq;
+using Newtonsoft.Json;
+
+namespace Elevator.Models
+{
+ public enum Direction
+ {
+ Up, //0
+ Down, //1
+ Idle //2
+ }
+ public class ElevatorInBuilding
+ {
+ public int currentFloor;
+ public Direction direction;
+ public List floorRequests = new List();
+ public int nextFloorToVisit;
+ public List events = new List();
+
+ public ElevatorInBuilding()
+ {
+ currentFloor = 1;
+ direction = Direction.Idle;
+ // floorRequests = new List();
+ }
+
+ public void RequestFloor(int floor)
+ {
+ if (floor == currentFloor)
+ {
+ return;
+ }
+ if (direction == Direction.Idle)
+ {
+ direction = (floor > currentFloor) ? Direction.Up : Direction.Down;
+ Console.WriteLine($"Direction was idle, now being set to {direction}");
+ }
+
+ floorRequests.Add(floor);
+ ElevatorEvent floorRequest = new ElevatorEvent(TypeOfEvent.FloorRequest);
+ events.Add(floorRequest);
+ //need to sort the floors here however if one floor away hold on for 3 seconds before doing the sort since the elevator cannot stop there on time
+ if (Math.Abs(floor - currentFloor) == 1)
+ {
+ Thread.Sleep(3000);
+ }
+ floorRequests.Sort();
+ }
+
+ // Run the elevator, note on request floor we set the direction
+ public void Run()
+ {
+ while (floorRequests.Count > 0)
+ {
+ Console.WriteLine("Calculating next floor");
+ int floor = GetNextFloor();
+ nextFloorToVisit = floor;
+ Console.WriteLine("Moving to next floor");
+ Console.WriteLine(nextFloorToVisit);
+ MoveToFloor(nextFloorToVisit);
+ }
+ direction = Direction.Idle;
+ }
+
+ private int GetNextFloor()
+ {
+ if (direction == Direction.Up)
+ {
+ return floorRequests.Where(someFloor => someFloor > currentFloor).DefaultIfEmpty(floorRequests.Max()).Min();
+ }
+ else if (direction == Direction.Down)
+ {
+ return floorRequests.Where(someFloor => someFloor < currentFloor).DefaultIfEmpty(floorRequests.Min()).Max();
+ }
+ return currentFloor;
+ }
+
+ private void MoveToFloor(int targetFloor)
+ {
+ if (currentFloor < targetFloor)
+ {
+ direction = Direction.Up;
+ while (currentFloor < targetFloor)
+ {
+ // wait 3 seconds for elevator to move
+ Thread.Sleep(3000);
+ currentFloor++;
+ Console.WriteLine($"Arrived at Floor {currentFloor}");
+ events.Add(new ElevatorEvent(TypeOfEvent.PassFloor));
+ }
+ }
+ else if (currentFloor > targetFloor)
+ {
+ direction = Direction.Down;
+ while (currentFloor > targetFloor)
+ {
+ Thread.Sleep(3000);
+ currentFloor--;
+ Console.WriteLine($"Arrived at Floor {currentFloor}");
+ events.Add(new ElevatorEvent(TypeOfEvent.PassFloor));
+ }
+ }
+ Console.WriteLine($"Elevator stopped at Floor {currentFloor}");
+ events.Add(new ElevatorEvent(TypeOfEvent.StopFloor));
+ floorRequests.Remove(currentFloor);
+ Thread.Sleep(1000);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/Elevator/Program.cs b/Elevator/Program.cs
new file mode 100644
index 0000000..fb2c8b4
--- /dev/null
+++ b/Elevator/Program.cs
@@ -0,0 +1,28 @@
+using Elevator.Models;
+// See https://aka.ms/new-console-template for more information
+ElevatorInBuilding elevator = new ElevatorInBuilding();
+
+while (true)
+{
+ Console.WriteLine("Input a floor request as a number and press enter or 'q' to quit then press enter, you can keep adding multiple floors just type them and press enter");
+ string input = Console.ReadLine().Trim();
+ if (input.Equals("q"))
+ {
+ break;
+ }
+ // check use of out
+ else if (int.TryParse(input, out int floor))
+ {
+ Console.WriteLine("Parsing inputted value to integer");
+ elevator.RequestFloor(floor);
+ elevator.Run();
+ }
+
+ if (elevator.direction == Direction.Idle)
+ {
+ Console.WriteLine("Elevator is idle (not moving).");
+ elevator.Run();
+ }
+}
+
+
diff --git a/README.md b/README.md
index 8ee9499..e6299ca 100644
--- a/README.md
+++ b/README.md
@@ -22,3 +22,90 @@ We like all individuals interested in joining our team to provide actual solutio
### The Challenge
1. **[Build an Elevator](elevator)** - In this challenge you will code an elevator that asynchronously accepts inputs in the form of button presses that call the elevator to a floor in a given direction (or to exit the elevator at a floor). Make your elevator function like it would in the real world.
+DK Notes, I had 2 approach ideas. First was to focus on the events on the elevator, this did not work as I had too may variables to track. I scrapped that approach and started fresh by focusing on the elevator and writing tests, I wrote the test before the code in some cases also to be doing test driven development. I built a way to store the floors the elevator has to visit and write testing for that. Then I added testing to confirm that the elevator could have floors requested not in order and that they could be sorted and have the elevator stop on the way up at floors above in order. Then I added testing to confirm the direction of the elevator was tracked, and the floors once visited are removed. I ended up adding in the events last using a test driven approach. I built a simple event object. Wrote tests that as the elevator was called to floor 3 from a starting point of floor 1 would have 4 events generate. Ran the test, confirmed it did not pass. Wrote the needed code, then ran the test again and confirmed it passed.
+
+What I would do with more time? I would take this console app and make this program run as a Web Api including making a controller with actions to collect different floors with a fun React based frontend.
+
+Prompt below and my notes are under that:
+Build an Elevator Coding Challenge!
+The Challenge
+Create an application that simulates the operation of a simple elevator.
+
+Requirements
+The elevator must travel in one direction at a time until it needs to go no further (e.g. keep going until the elevator has reached the top/bottom of the building, or no stop is requested on any floor ahead).
+Elevator floor request buttons can be pressed asynchronously from inside or outside the elevator while it is running.
+Elevator will stop at the closest floor first, in the direction of motion, then the next closest and so on. Any floors requested while the elevator is moving should be taken into account.
+Elevator will stop at all asynchronously requested floors, only if the request is made while the elevator is at least one floor away (e.g. if elevator is between 4th and 5th floor, going up, and the 5th floor is requested at that moment, elevator will not stop at the 5th floor while going up; it will stop there while going down).
+When elevator arrives at a requested floor, it waits for 1 second. It takes 3 seconds to travel between consecutive floors.
+A sensor tells the elevator its direction, next/current floor, state (stopped, moving) and if the elevator has reached its max weight limit.
+Use the sensor data plus the asynchronous floor request button data to work the elevator.
+Write meaningful unit tests that show the elevator works correctly, even if the application is not run.
+Log the following to a file, to verify elevator works well:
+Timestamp and asynchronous floor request, every time one occurs.
+Timestamp and floor, every time elevator passes a floor.
+Timestamp and floor, every time elevator stops at a floor.
+Bonus Enhancement:
+
+Enhance the application as follows: If the elevator has reached its weight limit, it should stop only at floors that were selected from inside the elevator (to let passengers out), until it is no longer at the max weight limit.
+Note: For simplicity, the asynchronous request buttons can be entered by the application user via the console, by entering "5U" (request from 5th floor wanting to go Up) or "8D" (request from 8th floor wanting to go Down) or "2" (request from inside elevator wanting to stop at 2nd floor). When the user enters "Q" on the console, the application must end after visiting all floors entered before "Q".
+
+/////// Notes from the project, note these notes contain the old event based approach as well as the new elevator based approach.
+
+DK ideas- use the elevator events to track what the elevator will do,
+
+Elevator fields and methods
+DirectionOfElevator
+CheckDirection aka if going up see events up has value if so keep going
+Events, note everytime a floor is visited you track if evelator is going up or down and resort events
+
+ElevatorEvents
+{
+ Timestamp (Date and time including seconds) - use for timing
+ DirectionOfElevator is Up or Down
+ DirectionOfEventUp bool used to determine if elevator will hit this floor when going up if true
+ FloorRequestedBool bool used when floor is Requested
+ FloorOn int is floor elevator has moved to
+ FloorPassedBool bool used when floor is passed
+ FloorStopped bool used when the floor is stoppedon
+ CompletedEvent bool event is done
+}
+
+-other items to keep in mind can add a floor async, add way to gather input
+
+example
+go to floor 2, 8, 5 note start on 1.
+
+idea is to go through elevator events, elevator events are key driver for how elevator will move
+-go up or go down
+
+idea the elevator will contain elevator events with floors above current floor, floors below current floor, completedEvents aka moved to completed events when the floor is reached
+
+so you determine if event is above or below current floor if same floor nothing happens, just log same floor requested and have a record
+
+// now the elevator, be able to gather inputs of what floors to visit.
+-once floors are gathered, turn that into event objects for tdd
+
+-do the timer last for now just add floors to visit and sort the floors in order, keep going the needed direction
+
+
+//notes on what I have
+I can collect floors to visit, this is made into event objects and events sorted ascending by floor are availible.
+
+
+// new idea focus on the direction the elevator goes and what happens between the floors
+Up, Down, Stopped(Idle)
+
+//setup notes
+git branch -M main
+git remote add origin https://github.com/dan-kiss-dev-this/dan-kiss-dev-this-SmaElevatorDk.git
+git push -u origin main
+
+log time Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+
+Timestamp and asynchronous floor request, every time one occurs.
+Timestamp and floor, every time elevator passes a floor.
+Timestamp and floor, every time elevator stops at a floor.
+
+
+//need a way to keep being able to accept input on the console
+//need to log the events