Initial Commit

pull/1/head
Alexander Sigler 2 years ago
commit aa90506943

263
.gitignore vendored

@ -0,0 +1,263 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
###################
# compiled source #
###################
*.com
*.class
*.dll
*.exe
*.pdb
*.dll.config
*.cache
*.suo
# Include dlls if theyre in the NuGet packages directory
!/packages/*/lib/*.dll
# Include dlls if they're in the CommonReferences directory
!*CommonReferences/*.dll
####################
# VS Upgrade stuff #
####################
_UpgradeReport_Files/
###############
# Directories #
###############
bin/
obj/
TestResults/
###################
# Web publish log #
###################
*.Publish.xml
#############
# Resharper #
#############
/_ReSharper.*
*.ReSharper.*
############
# Packages #
############
# its better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
######################
# Logs and databases #
######################
*.log
*.sqlite
# OS generated files #
######################
.DS_Store?
ehthumbs.db
Icon?
Thumbs.db
# User-specific files
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
build/
bld/
[Bb]in/
[Oo]bj/
# Visual Studo 2015 cache/options directory
.vs/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# Windows Azure Build Output
csx/
*.build.csdef
# Windows Store app package directory
AppPackages/
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.pfx
*.publishsettings
node_modules/
bower_components/
orleans.codegen.cs
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32929.386
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdventOfCode", "AdventOfCode\AdventOfCode.csproj", "{30F2887D-526F-4068-A581-E20BAF52F900}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{30F2887D-526F-4068-A581-E20BAF52F900}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30F2887D-526F-4068-A581-E20BAF52F900}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30F2887D-526F-4068-A581-E20BAF52F900}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30F2887D-526F-4068-A581-E20BAF52F900}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9B8E4DE0-580A-4E29-91F9-90720A6A5230}
EndGlobalSection
EndGlobal

@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
<PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="6.4.0" />
</ItemGroup>
<ItemGroup>
<Folder Include="Models\" />
<Folder Include="_2021\" />
<Folder Include="_2022\Models\" />
</ItemGroup>
</Project>

@ -0,0 +1,15 @@
using System;
namespace AdventOfCode.Common
{
public class AOCAttribute : Attribute
{
public int Year { get; set; }
public int Day { get; set; }
public AOCAttribute(int year, int day)
{
this.Year = year;
this.Day = day;
}
}
}

@ -0,0 +1,12 @@
using System;
namespace AOC2021.Helper
{
public static class AOCExtensions
{
public static int ToInt(this string str)
{
return Convert.ToInt32(str);
}
}
}

@ -0,0 +1,35 @@
using Microsoft.AspNetCore.Mvc.Formatters;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace AOC2021.Helper
{
public class TextPlainInputFormatter : InputFormatter
{
private const string ContentType = "text/plain";
public TextPlainInputFormatter()
{
SupportedMediaTypes.Add(ContentType);
}
public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context)
{
var request = context.HttpContext.Request;
using (var reader = new StreamReader(request.Body))
{
var content = await reader.ReadToEndAsync();
return await InputFormatterResult.SuccessAsync(content);
}
}
public override bool CanRead(InputFormatterContext context)
{
var contentType = context.HttpContext.Request.ContentType;
return contentType.StartsWith(ContentType);
}
}
}

@ -0,0 +1,51 @@
using AdventOfCode.Common;
using AdventOfCode.Models;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Linq;
namespace AdventOfCode.Controllers
{
[ApiController]
[Route("[controller]")]
public class AdventOfCodeController : ControllerBase
{
private readonly ILogger<AdventOfCodeController> _logger;
public AdventOfCodeController(ILogger<AdventOfCodeController> logger)
{
_logger = logger;
}
[HttpPost]
[Consumes("text/plain")]
public AOCResponse Day(int year, int day, AOCVersion version, [FromBody] string input, bool IgnoreLogMessages = false)
{
AOCRequest request = new AOCRequest() { Input = input, Version = version, IgnoreLogMessages = IgnoreLogMessages };
return GetAOCDay(year, day).ExecuteDay(request);
}
private AOCDay GetAOCDay(int year, int day)
{
AOCDay aocDay = null;
var type = typeof(AOCDay);
var types = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(s => s.GetTypes())
.Where(p => type.IsAssignableFrom(p) && !p.IsInterface && !p.IsAbstract);
foreach (var x in types)
{
var aocAttribute = (AOCAttribute) Attribute.GetCustomAttribute(x, typeof(AOCAttribute));
if (aocAttribute != null)
{
if (aocAttribute.Year == year && aocAttribute.Day == day)
{
aocDay = (AOCDay)(IAOCService)Activator.CreateInstance(x);
aocDay.SetLogger(this._logger);
}
}
}
return aocDay;
}
}
}

@ -0,0 +1,79 @@

using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Diagnostics;
namespace AdventOfCode.Models
{
public abstract class AOCDay : IAOCService
{
protected AOCRequest _request;
protected AOCResponse _response;
protected ILogger _logger;
private List<string> _debugMessages;
protected object Answer { set { this._response.Answer = value; } }
public AOCDay()
{
this._response = new AOCResponse()
{
Status = false
};
this._debugMessages = new List<string>();
}
public AOCResponse ExecuteDay(AOCRequest request)
{
_request = request;
var timer = new Stopwatch();
try
{
timer.Start();
switch (request.Version)
{
case AOCVersion.A:
this._response = ExecutePartA();
break;
case AOCVersion.B:
this._response = ExecutePartB();
break;
}
timer.Stop();
this._response.RunTime = timer.ElapsedTicks.ToString();
this._response.Status = true;
}
catch (Exception e)
{
this._response.Answer = e.Message;
this._response.Status = false;
this._response.StackTrace = e.StackTrace;
}
if (!request.IgnoreLogMessages)
this._response.Debug = this._debugMessages;
return this._response;
}
protected abstract AOCResponse ExecutePartA();
protected abstract AOCResponse ExecutePartB();
protected string[] GetSplitInput()
{
return this._request.Input.Trim().Replace("\r", "").Split("\n");
}
protected string[] GetSplitRowInput()
{
return this._request.Input.Trim().Replace("\r", "").Split("\n");
}
public void SetLogger(ILogger logger)
{
this._logger = logger;
}
protected void Log(object message, params object[] args)
{
if (_logger != null && !this._request.IgnoreLogMessages)
_logger.LogInformation(message.ToString(), args);
_debugMessages.Add(string.Format(message.ToString(), args));
}
}
}

@ -0,0 +1,17 @@
using System;
using System.Runtime.Serialization;
namespace AdventOfCode.Models
{
[DataContract]
[Serializable]
public class AOCRequest
{
[DataMember]
public AOCVersion Version { get; set; }
[DataMember]
public string Input { get; set; }
[DataMember]
public bool IgnoreLogMessages { get; set; }
}
}

@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace AdventOfCode.Models
{
[DataContract]
[Serializable]
public class AOCResponse
{
[DataMember]
public DateTime Date { get { return DateTime.Now; } }
[DataMember]
public object Answer { get; set; }
[DataMember]
public bool Status { get; set; }
[DataMember]
public IEnumerable<string> Debug { get; set; }
[DataMember]
public string StackTrace { get; set; }
private string timeInTicks;
[DataMember]
public string RunTime { get { return FormatRunTime(); } set { timeInTicks = value; } }
public string FormatRunTime()
{
var ts = TimeSpan.FromTicks((long)Convert.ToDouble(timeInTicks));
var microseconds = (ts.Ticks - (ts.Milliseconds * TimeSpan.TicksPerMillisecond)) / (TimeSpan.TicksPerMillisecond / 1000);
return $"Run time is {ts.Minutes}min {ts.Seconds}sec {ts.Milliseconds}ms {microseconds}µs";
}
}
}

@ -0,0 +1,15 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Runtime.Serialization;
namespace AdventOfCode.Models
{
[JsonConverter(typeof(StringEnumConverter))]
public enum AOCVersion
{
[EnumMember(Value = "A")]
A,
[EnumMember(Value = "B")]
B
}
}

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AdventOfCode.Models
{
public interface IAOCService
{
public AOCResponse ExecuteDay(AOCRequest request);
}
}

@ -0,0 +1,26 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AdventOfCode
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

@ -0,0 +1,31 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:20379",
"sslPort": 44329
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"AdventOfCode": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

@ -0,0 +1,70 @@
using AOC2021.Helper;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AdventOfCode
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AnyOrigin", builder =>
{
builder
.AllowAnyOrigin()
.AllowAnyMethod();
});
});
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "AdventofCode", Version = "v1" });
});
services.AddControllers(o => o.InputFormatters.Insert(o.InputFormatters.Count, new TextPlainInputFormatter()));
services.AddSwaggerGenNewtonsoftSupport();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "AdventOfCode v1"));
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

@ -0,0 +1,65 @@
using AdventOfCode.Common;
using AdventOfCode.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace AdventOfCode._2022
{
[AOC(year: 2022, day: 1)]
public class Day1 : AOCDay
{
protected override AOCResponse ExecutePartA()
{
var rows = GetSplitInput();
var elves = new List<string[]>();
int elfSet = 0;
for (int i = 0; i < rows.Length; i++)
{
if (string.IsNullOrWhiteSpace(rows[i]))
{
elves.Add(rows.Skip(elfSet).Take(i - elfSet).ToArray());
elfSet = i+1;
}
if (i == rows.Length-1)
{
elves.Add(rows.Skip(elfSet).ToArray());
}
}
var highestCalories = 0;
foreach (var elf in elves)
{
highestCalories = Math.Max(highestCalories, elf.Select(x => int.Parse(x)).Sum());
}
_response.Answer = highestCalories;
return _response;
}
protected override AOCResponse ExecutePartB()
{
var rows = GetSplitInput();
var elves = new List<string[]>();
int elfSet = 0;
for (int i = 0; i < rows.Length; i++)
{
if (string.IsNullOrWhiteSpace(rows[i]))
{
elves.Add(rows.Skip(elfSet).Take(i - elfSet).ToArray());
elfSet = i + 1;
}
if (i == rows.Length - 1)
{
elves.Add(rows.Skip(elfSet).ToArray());
}
}
var highestCalories = new List<int>();
foreach (var elf in elves)
{
highestCalories.Add(elf.Select(x => int.Parse(x)).Sum());
}
_response.Answer = highestCalories.OrderByDescending(x => x).Take(3).Sum();
return _response;
}
}
}

@ -0,0 +1,114 @@
using AdventOfCode.Common;
using AdventOfCode.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace AdventOfCode._2022
{
[AOC(year: 2022, day: 2)]
public class Day2 : AOCDay
{
protected override AOCResponse ExecutePartA()
{
var rows = GetSplitInput();
var totalScore = 0;
foreach (var row in rows)
{
var opponent = row.Split(" ")[0];
var mine = row.Split(" ")[1];
var score = ScoreRound(opponent, mine);
Log(score);
totalScore += score;
}
_response.Answer = totalScore;
return _response;
}
protected override AOCResponse ExecutePartB()
{
var rows = GetSplitInput();
var totalScore = 0;
foreach (var row in rows)
{
var opponent = row.Split(" ")[0];
var mine = DeduceCorrectShape(opponent, row.Split(" ")[1]);
var score = ScoreRound(opponent, mine);
Log(score);
totalScore += score;
}
_response.Answer = totalScore;
return _response;
}
private string DeduceCorrectShape(string opponent, string mine)
{
var oppScore = GetShapeScore(opponent);
if (mine == "X") //Lose
{
if (oppScore == 1) return "C";
else if (oppScore == 2) return "A";
else if (oppScore == 3) return "B";
}else if (mine == "Y") //Draw
{
if (oppScore == 1) return "A";
else if (oppScore == 2) return "B";
else if (oppScore == 3) return "C";
}
else //Win
{
if (oppScore == 1) return "B";
else if (oppScore == 2) return "C";
else if (oppScore == 3) return "A";
}
return "";
}
private int ScoreRound(string o, string m)
{
//Its a draw
if (GetShapeScore(o) == GetShapeScore(m))
{
return 3 + GetShapeScore(m); //Tied
}else if (DidYouWin(o, m))
{
return 6 + GetShapeScore(m); //Won
}
return GetShapeScore(m); //Lost
}
private bool DidYouWin(string o, string m)
{
var opp = GetShapeScore(o);
var mine = GetShapeScore(m);
if (opp == 1 && mine == 2) return true;
if (opp == 1 && mine == 3) return false;
if (opp == 2 && mine == 1) return false;
if (opp == 2 && mine == 3) return true;
if (opp == 3 && mine == 1) return true;
if (opp == 3 && mine == 2) return false;
return false;
}
private int GetShapeScore(string s)
{
switch (s)
{
//Rock
case "A":
case "X":
return 1;
//Paper
case "B":
case "Y":
return 2;
//Scissors
case "C":
case "Z":
return 3;
}
return 0;
}
}
}

@ -0,0 +1,66 @@
using AdventOfCode.Common;
using AdventOfCode.Models;
using System;
using System.Collections.Generic;
using System.Linq;
namespace AdventOfCode._2022
{
[AOC(year: 2022, day: 3)]
public class Day3 : AOCDay
{
protected override AOCResponse ExecutePartA()
{
var rows = GetSplitInput();
int total = 0;
foreach (var row in rows)
{
var first = row.Substring(0, row.Length / 2);
var second = row.Substring((row.Length / 2));
var invalidItem = first.ToCharArray().Intersect(second.ToCharArray()).First();
total += GetPriority(invalidItem);
}
_response.Answer = total;
return _response;
}
protected override AOCResponse ExecutePartB()
{
var rows = GetSplitInput();
var elves = new List<string[]>();
int elfSet = 0;
for (int i = 0; i < rows.Length; i++)
{
if (string.IsNullOrWhiteSpace(rows[i]))
{
elves.Add(rows.Skip(elfSet).Take(i - elfSet).ToArray());
elfSet = i + 1;
}
if (i == rows.Length - 1)
{
elves.Add(rows.Skip(elfSet).ToArray());
}
}
var highestCalories = new List<int>();
foreach (var elf in elves)
{
highestCalories.Add(elf.Select(x => int.Parse(x)).Sum());
}
_response.Answer = highestCalories.OrderByDescending(x => x).Take(3).Sum();
return _response;
}
private int GetPriority(char c)
{
if (Char.IsUpper(c))
{
return (c - 'A' + 27);
}
if (Char.IsLower(c))
{
return (c - 'a' + 1);
}
return 0;
}
}
}

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
}
Loading…
Cancel
Save