feat(*): Update 2021-06 files (part 1 working, part 2 not I think, but unable to test on laptop due to CPU limitations)

This resolves the out of memory issue, but still takes too long to run. It's either CPU or IO bound.
This commit is contained in:
Josh Creek
2021-12-06 13:09:24 +00:00
committed by GitHub
parent 3feeeb566c
commit 259637aa6e
7 changed files with 216 additions and 14 deletions
+8
View File
@@ -8,4 +8,12 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.0" />
</ItemGroup>
</Project>
@@ -0,0 +1,37 @@
// <auto-generated />
using Day06;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace _06.Migrations
{
[DbContext(typeof(FishContext))]
[Migration("20211206123902_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "6.0.0");
modelBuilder.Entity("Day06.Fish", b =>
{
b.Property<int>("FishId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("InternalTimer")
.HasColumnType("INTEGER");
b.HasKey("FishId");
b.ToTable("Fishes");
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,31 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace _06.Migrations
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Fishes",
columns: table => new
{
FishId = table.Column<int>(type: "INTEGER", nullable: false)
.Annotation("Sqlite:Autoincrement", true),
InternalTimer = table.Column<int>(type: "INTEGER", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Fishes", x => x.FishId);
});
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Fishes");
}
}
}
@@ -0,0 +1,35 @@
// <auto-generated />
using Day06;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
#nullable disable
namespace _06.Migrations
{
[DbContext(typeof(FishContext))]
partial class FishContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "6.0.0");
modelBuilder.Entity("Day06.Fish", b =>
{
b.Property<int>("FishId")
.ValueGeneratedOnAdd()
.HasColumnType("INTEGER");
b.Property<int>("InternalTimer")
.HasColumnType("INTEGER");
b.HasKey("FishId");
b.ToTable("Fishes");
});
#pragma warning restore 612, 618
}
}
}
+31
View File
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using Microsoft.EntityFrameworkCore;
namespace Day06
{
public class FishContext : DbContext
{
public DbSet<Fish> Fishes { get; set; }
public string DbPath { get; }
public FishContext()
{
var folder = Environment.SpecialFolder.LocalApplicationData;
var path = Environment.GetFolderPath(folder);
DbPath = System.IO.Path.Join(path, "fishes.db");
}
// The following configures EF to create a Sqlite database file in the
// special "local" folder for your platform.
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite($"Data Source={DbPath}");
}
public class Fish
{
public int FishId { get; set; }
public int InternalTimer { get; set; }
}
}
+71 -14
View File
@@ -23,18 +23,18 @@
Console.WriteLine($"Day: {currentDay} - there are {lanternFishPopulation.Count()} lantern fish");
for (int i = 0; i < lanternFishPopulation.Count; i++)
{
switch(lanternFishPopulation[i])
switch (lanternFishPopulation[i])
{
case 0:
// its internal timer would reset to 6, and it would create a new lanternfish with an internal timer of 8.
lanternFishPopulation[i] = 6;
// Adding a new one with 9 though it should be 8 as this loop will catch new fish and decrement them. It's dirty, but fast way to solve the issue
lanternFishPopulation.Add(9);
break;
default:
// remove one day from the fish's countdown
lanternFishPopulation[i] -= 1;
break;
case 0:
// its internal timer would reset to 6, and it would create a new lanternfish with an internal timer of 8.
lanternFishPopulation[i] = 6;
// Adding a new one with 9 though it should be 8 as this loop will catch new fish and decrement them. It's dirty, but fast way to solve the issue
lanternFishPopulation.Add(9);
break;
default:
// remove one day from the fish's countdown
lanternFishPopulation[i] -= 1;
break;
}
}
@@ -42,6 +42,58 @@
}
}
static void SimulateLanternFishBigDatasets(ref List<int> lanternFishPopulation, int daysToSimulate)
{
// A lanternfish that creates a new fish resets its timer to 6, not 7 (because 0 is included as a valid timer value). The new lanternfish starts with an internal timer of 8 and does not start counting down until the next day.
// Store dataset into db
using (var db = new FishContext())
{
foreach (var fish in lanternFishPopulation)
{
db.Add(new Fish { InternalTimer = fish });
db.SaveChanges();
}
}
int currentDay = 1;
while (currentDay <= daysToSimulate)
{
using (var db = new FishContext())
{
int fishCount = db.Fishes.Count();
Console.WriteLine($"Day: {currentDay} - there are {fishCount} lantern fish");
List<int> fishIds = db.Fishes.Select(x => x.FishId).ToList();
foreach (int fishId in fishIds)
{
Fish fish = db.Fishes.First(x => x.FishId == fishId);
switch (fish.InternalTimer)
{
case 0:
// its internal timer would reset to 6, and it would create a new lanternfish with an internal timer of 8.
fish.InternalTimer = 6;
// Adding a new one with 9 though it should be 8 as this loop will catch new fish and decrement them. It's dirty, but fast way to solve the issue
db.Add(new Fish { InternalTimer = 9 });
break;
default:
// remove one day from the fish's countdown
fish.InternalTimer -= 1;
break;
}
}
db.SaveChanges();
}
currentDay += 1;
}
}
static void Part1(List<int> lanternFish)
{
SimulateLanternFish(ref lanternFish, 80);
@@ -51,11 +103,16 @@
static void Part2(List<int> lanternFish)
{
SimulateLanternFish(ref lanternFish, 256);
SimulateLanternFishBigDatasets(ref lanternFish, 256);
// TODO - redo this using a database for large datasets, and entity framework, so as to avoid the HUGE memory usage
Console.WriteLine($"After 256 days there are {lanternFish.Count()} lantern fish.");
using (var db = new FishContext())
{
int fishCount = db.Fishes.Count();
Console.WriteLine($"After 256 days there are {fishCount} lantern fish.");
}
}
}
}
+3
View File
@@ -0,0 +1,3 @@
Run dotnet ef database update to initialise the database
Delete the database if you want to run the code again
It's at C:\Users\Josh\AppData\Local as fishes.db and other associated files