initial commit, day 10

This commit is contained in:
Ikatono
2024-12-10 14:36:10 -06:00
commit e9df3737e1
19 changed files with 2157 additions and 0 deletions

484
dotnet/.gitignore vendored Normal file
View File

@@ -0,0 +1,484 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from `dotnet new gitignore`
# dotenv files
.env
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET
project.lock.json
project.fragment.lock.json
artifacts/
# Tye
.tye/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.tlog
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# 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
# Note: 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
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# 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/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# 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
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
*.vbp
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
*.dsw
*.dsp
# Visual Studio 6 technical files
*.ncb
*.aps
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# Visual Studio History (VSHistory) files
.vshistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
# VS Code files for those working on multiple tools
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/
# Windows Installer files from build outputs
*.cab
*.msi
*.msix
*.msm
*.msp
# JetBrains Rider
*.sln.iml
.idea
##
## Visual studio for Mac
##
# globs
Makefile.in
*.userprefs
*.usertasks
config.make
config.status
aclocal.m4
install-sh
autom4te.cache/
*.tar.gz
tarballs/
test-results/
# Mac bundle stuff
*.dmg
*.app
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# Vim temporary swap files
*.swp

167
dotnet/05/05a.cs Normal file
View File

@@ -0,0 +1,167 @@
void Main1()
{
var lines = File.ReadAllLines(Path.Join("..", "..", "05a.txt")).Select(l => l.Trim()).ToList();
if (lines.Last() == "")
lines.RemoveAt(lines.Count - 1);
List<Rule> rules = new();
foreach (var line in lines.TakeWhile(l => !string.IsNullOrWhiteSpace(l)))
{
var parts = line.Split('|');
rules.Add(new(
int.Parse(parts[0]),
int.Parse(parts[1])
));
}
List<Collection> collections = new();
foreach (var line in lines.SkipWhile(l => !string.IsNullOrWhiteSpace(l)).Skip(1))
{
var parts = line.Split(',').Select(int.Parse);
collections.Add(new(parts));
}
int total = 0;
foreach (var collection in collections.Where(c => rules.All(r => c.TestRule(r))))
{
total += collection.Middle();
}
Console.WriteLine(total);
}
void Main2()
{
var lines = File.ReadAllLines(Path.Join("..", "..", "05a.txt")).Select(l => l.Trim()).ToList();
if (lines.Last() == "")
lines.RemoveAt(lines.Count - 1);
List<Rule> rules = new();
RuleList rulelist = new();
foreach (var line in lines.TakeWhile(l => !string.IsNullOrWhiteSpace(l)))
{
var parts = line.Split('|');
Rule rule = new(
int.Parse(parts[0]),
int.Parse(parts[1])
);
rulelist.Add(rule);
rules.Add(rule);
}
List<Collection> collections = new();
foreach (var line in lines.SkipWhile(l => !string.IsNullOrWhiteSpace(l)).Skip(1))
{
var parts = line.Split(',').Select(int.Parse);
collections.Add(new(parts));
}
var total = 0;
var count = 0;
foreach (var collection in collections)
{
var r = collection.Pairs()
.Select(p => rulelist.ExtractRule(p.Item1, p.Item2))
.Where(r => r is not null)
.Select(r => (Rule)r)
.ToList();
if (!rules.All(collection.TestRule))
{
collection.Pages.Sort(rulelist.Compare);
total += collection.Pages[collection.Pages.Count / 2];
count++;
}
}
Console.WriteLine($"Collections: {collections.Count}");
Console.WriteLine($"With errors: {count}");
Console.WriteLine($"Solution: {total}");
}
Main2();
record struct Rule(int First, int Second);
class RuleList
{
Dictionary<(int,int), bool> Rules = new();
public RuleList()
{
}
public void Add(Rule rule)
{
bool ordered = rule.First < rule.Second;
var pair = ordered
? (rule.First, rule.Second)
: (rule.Second, rule.First);
Rules.Add(pair, ordered);
}
//true if correct order, null if no rule
public bool? Check(int a, int b)
{
bool ordered = a < b;
var pair = ordered
? (a, b)
: (b, a);
bool result;
return Rules.TryGetValue(pair, out result) ? result ^ ordered : null;
}
public int Compare(int a, int b)
{
var check = Check(a, b);
if (check is bool _check)
return _check ? -1 : 1;
return 0;
}
public Rule? ExtractRule(int a, int b)
{
var check = Check(a, b);
if (check is bool _check)
return _check ? new(a, b) : new(b, a);
return null;
}
}
class Collection
{
public readonly List<int> Pages;
public Collection(IEnumerable<int> pages)
{
Pages = pages.ToList();
}
public bool TestRule(Rule rule)
{
bool foundFirst = false;
bool foundSecond = false;
foreach (var page in Pages)
{
if (page == rule.First)
{
if (foundSecond)
return false;
foundFirst = true;
}
if (page == rule.Second)
{
if (foundFirst)
return true;
foundSecond = true;
}
}
return true;
}
public int Middle()
{
return Pages[Pages.Count / 2];
}
public List<(int,int)> Pairs()
{
List<(int,int)> pairs = new();
for (int i = 0; i < Pages.Count-1; i++)
{
for (int j = i+1; j < Pages.Count; j++)
{
pairs.Add((Pages[i], Pages[j]));
}
}
return pairs;
}
}

238
dotnet/06/06.cs Normal file
View File

@@ -0,0 +1,238 @@
void Main1()
{
(var map, var pos) = LoadMap(Path.Join("..", "..", "06a.txt"));
Guard guard = new(pos, Direction.North);
HashSet<(int,int)> visited = new();
while (map.InBounds(guard.position))
{
var next = Next(guard);
if (map.Check(next.position))
{
guard = new(guard.position, guard.direction.Turn());
continue;
}
else
{
visited.Add(guard.position);
guard = next;
}
}
Console.WriteLine(visited.Count());
}
void Main2()
{
(var map, var pos) = LoadMap(Path.Join("..", "..", "06a.txt"));
Guard guard = new(pos, Direction.North);
// for (int i = 0; i < 4; i++)
// {
// foreach (var obs in map.Obstacles)
// {
// var row = map.GetRow(obs.Item1 + 1).Where(c => c > obs.Item2);
// foreach (var candidate in row)
// {
// var col = map.GetColumn(candidate - 1).Where(r => r > candidate);
// foreach (var third in col)
// {
// var idea = (third - 1, obs.Item2 - 1);
// if (!map.Check(idea))
// map.Ideas.Add(idea);
// }
// }
// }
// map = map.Rotated();
// }
// Console.WriteLine($"Ideas {map.Ideas.Count()}");
int count = 0;
// foreach (var idea in map.Ideas)
// {
// Guard guard = new(pos, Direction.North);
// // the 5th time the guard hits the obstacle, he must have hit twice from the same side
// int hits = 0;
// while (map.InBounds(guard.position))
// {
// var next = Next(guard);
// if (next.position == idea)
// {
// hits++;
// if (hits >= 5)
// {
// count++;
// break;
// }
// guard = new(guard.position, guard.direction.Turn());
// }
// else if (map.Check(next.position))
// {
// guard = new(guard.position, guard.direction.Turn());
// }
// else
// {
// guard = next;
// }
// }
// }
HashSet<(int,int)> visited = new();
int ideaIndex = 0;
while (map.InBounds(guard.position))
{
ideaIndex++;
var next = Next(guard);
if (map.Check(next.position))
{
guard = new(guard.position, guard.direction.Turn());
continue;
}
else
{
visited.Add(guard.position);
if (!visited.Contains(next.position) && TestIdea(next.position, guard, map))
count++;
// Console.WriteLine($"Idea {ideaIndex}");
guard = next;
}
}
Console.WriteLine($"Solution {count}");
}
// Main1();
Main2();
(Map,(int,int)) LoadMap(string filename)
{
var lines = File.ReadAllLines(filename)
.Where(s => !string.IsNullOrWhiteSpace(s))
.ToList();
var guard = (-1,-1);
Map map = new();
for (int i = 0; i < lines.Count(); i++)
{
for (int j = 0; j < lines[i].Count(); j++)
{
if (lines[i][j] == '#')
map.Add((i, j));
else if (lines[i][j] == '^')
guard = (i, j);
}
}
map.XBound = lines[0].Count();
map.YBound = lines.Count();
return (map, guard);
}
bool TestIdea((int,int) idea, Guard guard, Map map)
{
HashSet<Guard> history = new();
while (map.InBounds(guard.position))
{
if (history.Contains(guard))
return true;
history.Add(guard);
var next = Next(guard);
if (map.Check(next.position) || next.position == idea)
{
guard = new(guard.position, guard.direction.Turn());
}
else
{
guard = next;
}
}
return false;
}
//next position IF NO OBSTACLE
Guard Next(Guard guard)
{
var pos = guard.position;
return new(guard.direction switch
{
Direction.North => (pos.Item1-1, pos.Item2),
Direction.East => (pos.Item1, pos.Item2+1),
Direction.South => (pos.Item1+1, pos.Item2),
Direction.West => (pos.Item1, pos.Item2-1),
_ => throw new Exception(),
}, guard.direction);
}
class Map
{
public HashSet<(int,int)> Obstacles = new();
//1 greater than largest value
public int XBound = 0;
public int YBound = 0;
public HashSet<(int,int)> Ideas = new();
public Map()
{
}
public void Add((int,int) obstacle)
{
Obstacles.Add(obstacle);
}
public bool Check((int,int) pos)
{
return Obstacles.Contains(pos);
}
public bool InBounds((int,int) pos)
{
return pos.Item1 >= 0 && pos.Item2 >= 0
&& pos.Item1 < XBound && pos.Item2 < YBound;
}
//get list of columns with an obstacle in this row
public List<int> GetRow(int row)
{
List<int> items = [];
foreach (var pos in Obstacles)
{
if (pos.Item1 == row)
items.Add(pos.Item2);
}
items.Sort();
return items;
}
//get list of rows with an obstacle in this column
public List<int> GetColumn(int column)
{
List<int> items = [];
foreach (var pos in Obstacles)
{
if (pos.Item2 == column)
items.Add(pos.Item1);
}
items.Sort();
return items;
}
//counterclockwise rotation
public Map Rotated()
{
(int,int) rotate((int,int) o) => (o.Item2, XBound - o.Item1);
Map newmap = new();
newmap.Obstacles = new(Obstacles.Select(rotate));
newmap.Ideas = new(Ideas.Select(rotate));
newmap.XBound = YBound;
newmap.YBound = XBound;
return newmap;
}
}
enum Direction
{
North,
East,
South,
West,
}
readonly record struct Guard((int,int) position, Direction direction);
static class Extensions
{
public static Direction Turn(this Direction direction)
{
return direction switch
{
Direction.West => Direction.North,
Direction d => d + 1,
};
}
}

263
dotnet/07/07a.cs Normal file
View File

@@ -0,0 +1,263 @@
void Main1()
{
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
long total = 0;
foreach (var eq in eqs)
{
if (eq.Test1())
{
total += eq.Target;
}
}
Console.WriteLine($"Solution {total}");
}
void Main2()
{
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
long total = 0;
foreach (var eq in eqs)
{
if (eq.Test2())
{
total += eq.Target;
}
}
Console.WriteLine($"Solution1 {total}");
}
void Main2_take2()
{
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
long total = 0;
foreach (var eq in eqs)
{
if (eq.Test3())
{
total += eq.Target;
}
}
Console.WriteLine($"Solution (exp) {total}");
}
void Main2_take3()
{
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
long total = 0;
foreach (var eq in eqs)
{
if (eq.Test4())
{
total += eq.Target;
}
}
Console.WriteLine($"Solution {total}");
}
void Main2_take2and3()
{
var eqs = LoadEqs(Path.Join("..", "..", "07a.txt"));
long total = 0;
foreach (var eq in eqs)
{
var t3 = eq.Test3();
var t4 = eq.Test4();
if (t3 != t4)
{
Console.WriteLine((t4 ? "Pass " : "Fail ") + eq.ToString());
}
}
}
// Main1();
Main2();
// Main2_take2();
// Main2_take3();
// Main2_take2and3();
List<EQ> LoadEqs(string filepath)
{
var lines = File.ReadAllLines(filepath).ToList();
if (string.IsNullOrWhiteSpace(lines.Last()))
lines.RemoveAt(lines.Count()-1);
List<EQ> eqs = new();
foreach (var line in lines)
{
var parts = line.Split(':');
eqs.Add(new(
long.Parse(parts[0]),
parts[1].Trim().Split(' ').Select(long.Parse)
));
}
return eqs;
}
class EQ
{
public long Target;
public List<long> Terms;
public EQ(long target, IEnumerable<long> terms)
{
Target = target;
Terms = terms.ToList();
}
public override string ToString()
{
return $"{Target}: {string.Join(' ', Terms)}";
}
public bool Test1()
{
return InnerTest1(Target, Terms.First(), Terms.Skip(1));
}
private static bool InnerTest1(long target, long current, IEnumerable<long> terms)
{
if (current > target)
return false;
var term = terms.Cast<long?>().FirstOrDefault();
if (term is long _term)
{
return InnerTest1(target, current + _term, terms.Skip(1))
|| InnerTest1(target, current * _term, terms.Skip(1));
}
else
{
return target == current;
}
}
public bool Test2()
{
return InnerTest2(Target, Terms.First(), Terms, 1);
}
private static bool InnerTest2(long target, long current, IList<long> terms, int index)
{
if (current > target)
return false;
if (index >= terms.Count())
return target == current;
var term = terms[index];
return InnerTest2(target, current + term, terms, index + 1)
|| InnerTest2(target, current * term, terms, index + 1)
|| InnerTest2(target, Concat(current, term), terms, index + 1);
}
public bool Test3()
{
return InnerTest3(Target, Terms.First(), Terms.Skip(1)) == Result.Success;
}
private static Result InnerTest3(long target, long current, IEnumerable<long> terms)
{
if (current > target)
return Result.AllOverflow;
var term = terms.Cast<long?>().FirstOrDefault();
var remaining = terms.Skip(1);
if (term is long _term)
{
return current switch
{
1 => InnerTest3(target, _term, remaining) switch
{
Result.MixedFailures => InnerTest3(target, 1 + _term, remaining) switch
{
Result.Success => Result.Success,
Result.AllOverflow => Result.MixedFailures,
_ => InnerTest3(target, Concat(1, _term), remaining) switch
{
Result.Success => Result.Success,
_ => Result.MixedFailures,
},
},
Result res => res,
},
0 => InnerTest3(target, 0, remaining) switch
{
Result.MixedFailures => InnerTest3(target, _term, remaining) switch
{
Result.Success => Result.Success,
_ => Result.MixedFailures,
},
Result res => res,
},
long _current => _term switch
{
1 => InnerTest3(target, _current, remaining) switch
{
Result.MixedFailures => InnerTest3(target, _current + 1, remaining) switch
{
Result.Success => Result.Success,
Result.MixedFailures => InnerTest3(target, _current * 10 + 1, remaining) switch
{
Result.Success => Result.Success,
_ => Result.MixedFailures,
},
_ => Result.MixedFailures,
},
Result res => res,
},
_ => InnerTest3(target, _current + _term, remaining) switch
{
Result.MixedFailures => InnerTest3(target, _current * _term, remaining) switch
{
Result.Success => Result.Success,
Result.AllOverflow => Result.MixedFailures,
_ => InnerTest3(target, Concat(_current, _term), remaining) switch
{
Result.Success => Result.Success,
_ => Result.MixedFailures,
},
},
Result res => res,
},
},
};
}
else
{
return (target - current) switch
{
//should be impossible due to earlier check
< 0 => Result.AllOverflow,
0 => Result.Success,
> 0 => Result.MixedFailures,
};
}
}
private static long Concat(long first, long second)
{
return first * Shift(second) + second;
}
public bool Test4()
{
return InnerTest4(Target, Terms, Terms.Count() - 1);
}
private static bool InnerTest4(long current, IList<long> terms, int index)
{
long term = terms[index];
if (index == 0)
return current == term;
if (InnerTest4(current - term, terms, index - 1))
return true;
if (current % term == 0 && InnerTest4(current / term, terms, index - 1))
return true;
var shift = Shift(term);
if ((current % shift == term) && InnerTest4(current / shift, terms, index - 1))
return true;
return false;
}
private static long Shift(long num)
{
var digits = ((long)Math.Log10(num+0.5)) + 1;
long shift = 1;
while (digits > 0)
{
shift *= 10;
digits--;
}
return shift;
}
enum Result
{
AllOverflow,
MixedFailures,
Success,
}
}

174
dotnet/08/08a.cs Normal file
View File

@@ -0,0 +1,174 @@
Main1();
Main2();
void Main1()
{
var map = LoadMap(Path.Join("..", "..", "08a.txt"));
HashSet<Point> antinodes = new();
foreach (var (ch, points) in map.Antennae)
{
for (int i = 0; i < points.Count-1; i++)
{
for (int j = i+1; j < points.Count; j++)
{
antinodes.UnionWith(points[i].GetAntinodes(points[j]).Where(map.Validate));
}
}
}
Console.WriteLine($"Solution {antinodes.Count}");
}
void Main2()
{
var map = LoadMap(Path.Join("..", "..", "08a.txt"));
HashSet<Point> antinodes = new();
foreach (var (ch, points) in map.Antennae)
{
for (int i = 0; i < points.Count-1; i++)
{
for (int j = i+1; j < points.Count; j++)
{
antinodes.UnionWith(points[i].GetAntinodes2(points[j], map));
}
}
}
Console.WriteLine($"Solution {antinodes.Count}");
}
Map LoadMap(string filepath)
{
var lines = File.ReadAllLines(filepath)
.Where(l => !string.IsNullOrWhiteSpace(l))
.Select(s => s.Trim())
.ToList();
Map map = new();
foreach (var (line, row) in lines.Select((l, i) => (l, i)))
{
foreach (var (c, col) in line.Select((ch, i) => (ch, i)))
{
if (c != '.')
{
Point p = new(row, col);
if (map.Antennae.TryGetValue(c, out var points))
{
points.Add(p);
}
else
{
map.Antennae[c] = new(Enumerable.Repeat(p, 1));
}
}
}
}
map.Width = lines[0].Length;
map.Height = lines.Count;
return map;
}
public static class Stuff
{
//I forgot the good algorithm
public static int TerribleGcf(int first, int second)
{
int gcf = 1;
while (first % 2 == 0 && second % 2 == 0)
{
gcf *= 2;
first /= 2;
second /= 2;
}
for (int prime = 3; prime < first && prime < second; prime += 2)
{
while (first % prime == 0 && second % prime == 0)
{
gcf *= prime;
first /= prime;
second /= prime;
}
}
return gcf;
}
//I had to look up the right way
public static int EuclideanGcf(int first, int second)
{
if (first == 0 || second == 0)
return 0;
first = Math.Abs(first);
second = Math.Abs(second);
while (first != second)
{
if (second > first)
{
first = first ^ second;
second = first ^ second;
first = first ^ second;
}
first = first - second;
}
return first;
}
}
class Map
{
public Dictionary<char, List<Point>> Antennae = new();
public int Width;
public int Height;
public Map()
{
}
public bool Validate(Point p)
=> p.Row >= 0 && p.Row < Width && p.Col >= 0 && p.Col < Height;
}
record struct Point(int Row, int Col)
{
public static Vector operator -(Point first, Point second)
=> new(first.Row - second.Row, first.Col - second.Col);
public static Point operator +(Point first, Vector second)
=> new(first.Row + second.Row, first.Col + second.Col);
public static Point operator -(Point first, Vector second)
=> new(first.Row - second.Row, first.Col - second.Col);
public readonly IEnumerable<Point> GetAntinodes(Point other)
{
var diff = this - other;
yield return this + diff;
yield return other - diff;
if (diff.Row % 3 == 0 && diff.Col % 3 == 0)
{
Console.WriteLine("inline");
yield return other + (diff / 3);
yield return other + (diff * 2 / 3);
}
}
public IEnumerable<Point> GetAntinodes2(Point other, Map map)
{
var diff = this - other;
// diff /= Stuff.TerribleGcf(diff.Row, diff.Col);
diff /= Stuff.EuclideanGcf(diff.Row, diff.Col);
var running = this;
while (map.Validate(running))
{
yield return running;
running -= diff;
}
running = this + diff;
while (map.Validate(running))
{
yield return running;
running += diff;
}
}
}
record struct Vector(int Row, int Col)
{
public static Vector operator +(Vector first, Vector second)
=> new(first.Row + second.Row, first.Col + second.Col);
public static Vector operator *(Vector first, int second)
=> new(first.Row * second, first.Col * second);
public static Vector operator /(Vector first, int second)
=> new(first.Row / second, first.Col / second);
}

138
dotnet/09/09.cs Normal file
View File

@@ -0,0 +1,138 @@
using System.Numerics;
using System.Security.Cryptography.X509Certificates;
// Main1();
Main2();
void Main1()
{
var data = LoadData1(Path.Join("..", "..", "09a.txt"));
int i = 0;
int j = data.Length - 1;
while (i < j)
{
if (data[i] == -1)
{
while (data[j] == -1)
j--;
data[i] = data[j];
data[j] = -1;
}
i++;
}
i--;
BigInteger checksum = 0;
while (i >= 0)
{
if (data[i] < 0)
throw new Exception($"Index {i} Value {data[i]}");
checksum += i * data[i];
i--;
}
Console.WriteLine($"Part1: {checksum,15}");
}
void Main2()
{
var (files, empties) = LoadData2(Path.Join("..", "..", "09a.txt"));
for (int i = files.Count-1; i >= 1; i--)
{
var file = files[i];
for (int j = 0; j < empties.Count; j++)
{
var empty = empties[j];
if (file.Location < empty.Location)
break;
if (file.Length <= empty.Length)
{
file.Location = empty.Location;
empties[j] = new(empty.Location + file.Length, empty.Length - file.Length);
break;
}
}
}
//long is big enough but changing it didn't help execution time so...
BigInteger checksum = 0;
foreach (var f in files)
{
for (int i = 0; i < f.Length; i++)
{
checksum += f.Id * (f.Location + i);
}
}
Console.WriteLine($"Part2: {checksum,15}");
}
int[] LoadData1(string filepath)
{
int next_id = 0;
bool next_is_blank = false;
int GetId()
{
if (next_is_blank)
{
next_is_blank = false;
return -1;
}
else
{
next_is_blank = true;
return next_id++;
}
}
var data = File.ReadAllText(filepath).Trim().SelectMany(c => Enumerable.Repeat(GetId(), c - '0')).ToArray();
return data;
}
(List<Filelike>,List<Empty>) LoadData2(string filepath)
{
short next_id = 0;
bool next_is_blank = false;
int location = 0;
List<Filelike> files = [];
List<Empty> empties = [];
foreach (char c in File.ReadAllText(filepath).Trim())
{
int length = c - '0';
if (next_is_blank)
{
if (length > 0)
empties.Add(new (location, length));
next_is_blank = false;
location += length;
}
else
{
next_is_blank = true;
if (length > 0)
files.Add(new (location, length, next_id));
location += length;
next_id++;
}
}
return (files,empties);
}
class Filelike(int Location, int Length, short Id)
{
public int Location = Location;
public int Length = Length;
public short Id = Id;
}
class Empty(int Location, int Length)
{
public int Location = Location;
public int Length = Length;
}
// class Filelike(int Location, int Length, int Id)
// {
// public int Location = Location;
// public int Length = Length;
// public int Id = Id;
// }
// class Empty(int Location, int Length)
// {
// public int Location = Location;
// public int Length = Length;
// }