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

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
*.txt

24
01a.py Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/python
with open('01a.txt') as f:
text = f.read().strip()
lines = text.split('\n')
a = [0] * len(lines)
b = a[:]
for i in range(len(lines)):
spl = lines[i].split(' ', maxsplit=1)
a[i] = int(spl[0].strip())
b[i] = int(spl[1].strip())
a.sort()
b.sort()
total = 0
for x, y in zip(a, b):
total += abs(x - y)
print(total)

40
01b.py Executable file
View File

@@ -0,0 +1,40 @@
#!/usr/bin/python
with open('01a.txt') as f:
text = f.read().strip()
lines = text.split('\n')
a = [None] * len(lines)
b = [None] * len(lines)
for i in range(len(lines)):
spl = lines[i].split(' ', maxsplit=1)
a[i] = int(spl[0].strip())
b[i] = int(spl[1].strip())
a.sort()
b.sort()
total = 0
# for x, y in zip(a, b):
# total += abs(x - y)
# print(total)
i_a = 0
i_b = 0
while i_a < len(lines) and i_b < len(lines):
x_a = a[i_a]
x_b = b[i_b]
if x_a == x_b:
total += x_b
i_b += 1
elif x_a < x_b:
i_a += 1
else:
i_b += 1
print(total)

19
02a.py Executable file
View File

@@ -0,0 +1,19 @@
with open('02a.txt') as f:
text = f.read().strip()
def make_report(line):
return [int(x.strip()) for x in line.split()]
reports = [make_report(x) for x in text.split('\n')]
def test_report(report):
if len(report) == 1:
return True
dir = 1 if report[1] - report[0] > 0 else -1
for i in range(len(report)-1):
diff = (report[i+1] - report[i]) * dir
if diff < 1 or diff > 3:
return False
return True
print(sum(test_report(x) for x in reports))

25
02b.py Executable file
View File

@@ -0,0 +1,25 @@
with open('02a.txt') as f:
text = f.read().strip()
def make_report(line):
return [int(x.strip()) for x in line.split()]
reports = [make_report(x) for x in text.split('\n')]
def test_report(report):
if len(report) == 1:
return True
dir = 1 if report[1] - report[0] > 0 else -1
for i in range(len(report)-1):
diff = (report[i+1] - report[i]) * dir
if diff < 1 or diff > 3:
return False
return True
def test_sub_reports(report):
for i in range(len(report)):
if test_report(report[:i] + report[i+1:]):
return True
return False
print(sum(test_sub_reports(x) for x in reports))

15
03a.py Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/python
import re
with open('03a.txt') as f:
text = f.read()
reg = re.compile(r'mul\((?P<num1>[0-9]+),(?P<num2>[0-9]+)\)')
total = 0
for match in reg.finditer(text):
total += int(match.group('num1')) * int(match.group('num2'))
print(total)

24
03b.py Executable file
View File

@@ -0,0 +1,24 @@
#!/usr/bin/python
import re
with open('03a.txt') as f:
text = f.read()
reg = re.compile(r'(?P<mul>mul\((?P<num1>[0-9]+),(?P<num2>[0-9]+)\))|(?P<do>do\(\))|(?P<dont>don\'t\(\))')
total = 0
enabled = True
for match in reg.finditer(text):
if match.group('do'):
enabled = True
elif match.group('dont'):
enabled = False
elif match.group('mul'):
if enabled:
total += int(match.group('num1')) * int(match.group('num2'))
else:
raise RuntimeError()
print(total)

42
04a.py Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/python
with open('04a.txt') as f:
lines = f.readlines()
lines = [x.strip() for x in lines if x.strip()]
count = 0
i_len = len(lines)
j_len = len(lines[0])
for i in range(i_len):
for j in range(j_len):
if lines[i][j] == 'X':
UP = i >= 3
DOWN = (i_len - i) >= 4
LEFT = j >= 3
RIGHT = (j_len - j) >= 4
if UP:
if lines[i-1][j] == 'M' and lines[i-2][j] == 'A' and lines[i-3][j] == 'S':
count += 1
if DOWN:
if lines[i+1][j] == 'M' and lines[i+2][j] == 'A' and lines[i+3][j] == 'S':
count += 1
if LEFT:
if lines[i][j-1] == 'M' and lines[i][j-2] == 'A' and lines[i][j-3] == 'S':
count += 1
if RIGHT:
if lines[i][j+1] == 'M' and lines[i][j+2] == 'A' and lines[i][j+3] == 'S':
count += 1
if UP and LEFT:
if lines[i-1][j-1] == 'M' and lines[i-2][j-2] == 'A' and lines[i-3][j-3] == 'S':
count += 1
if UP and RIGHT:
if lines[i-1][j+1] == 'M' and lines[i-2][j+2] == 'A' and lines[i-3][j+3] == 'S':
count += 1
if DOWN and LEFT:
if lines[i+1][j-1] == 'M' and lines[i+2][j-2] == 'A' and lines[i+3][j-3] == 'S':
count += 1
if DOWN and RIGHT:
if lines[i+1][j+1] == 'M' and lines[i+2][j+2] == 'A' and lines[i+3][j+3] == 'S':
count += 1
print(count)

45
04a_alt.py Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/python
import re
with open('04a.txt') as f:
chars = ''.join(c for c in f.read() if c in ['X', 'M', 'A', 'S'])
UP = r'S.{139}A.{139}M.{139}X'
DOWN = r'X.{139}M.{139}A.{139}S'
LEFT = r'SAMX'
RIGHT = r'XMAS'
UPLEFT = r'S.{140}A.{140}M.{140}X'
UPRIGHT = r'S.{138}A.{138}M.{138}X'
DOWNLEFT = r'X.{138}M.{138}A.{138}S'
DOWNRIGHT = r'X.{140}M.{140}A.{140}S'
ORED = '|'.join((UP, DOWN, LEFT, RIGHT, UPLEFT, UPRIGHT, DOWNLEFT, DOWNRIGHT))
REG = re.compile(f'(?={ORED})')
def lookahead(s):
return f'(?={s})'
up = next(re.finditer(UP, chars))
print(up.pos)
_UP = len(re.findall(UP, chars))
_DOWN = len(re.findall(DOWN, chars))
_LEFT = len(re.findall(LEFT, chars))
_RIGHT = len(re.findall(RIGHT, chars))
_UPLEFT = len(re.findall(UPLEFT, chars))
_UPRIGHT = len(re.findall(UPRIGHT, chars))
_DOWNLEFT = len(re.findall(DOWNLEFT, chars))
_DOWNRIGHT = len(re.findall(DOWNRIGHT, chars))
print(f'UP {_UP}')
print(f'DOWN {_DOWN}')
print(f'LEFT {_LEFT}')
print(f'RIGHT {_RIGHT}')
print(f'UPLEFT {_UPLEFT}')
print(f'UPRIGHT {_UPRIGHT}')
print(f'DOWNLEFT {_DOWNLEFT}')
print(f'DOWNRIGHT {_DOWNRIGHT}')
print(f'TOTAL {_UP + _DOWN + _LEFT + _RIGHT + _UPLEFT + _UPRIGHT + _DOWNLEFT + _DOWNRIGHT}')
print(len(REG.findall(chars)))

42
04b.py Executable file
View File

@@ -0,0 +1,42 @@
#!/usr/bin/python
with open('04a.txt') as f:
lines = f.readlines()
lines = [x.strip() for x in lines if x.strip()]
count = 0
i_len = len(lines)
j_len = len(lines[0])
for i in range(i_len):
for j in range(j_len):
if lines[i][j] == 'X':
UP = i >= 3
DOWN = (i_len - i) >= 4
LEFT = j >= 3
RIGHT = (j_len - j) >= 4
if UP:
if lines[i-1][j] == 'M' and lines[i-2][j] == 'A' and lines[i-3][j] == 'S':
count += 1
if DOWN:
if lines[i+1][j] == 'M' and lines[i+2][j] == 'A' and lines[i+3][j] == 'S':
count += 1
if LEFT:
if lines[i][j-1] == 'M' and lines[i][j-2] == 'A' and lines[i][j-3] == 'S':
count += 1
if RIGHT:
if lines[i][j+1] == 'M' and lines[i][j+2] == 'A' and lines[i][j+3] == 'S':
count += 1
if UP and LEFT:
if lines[i-1][j-1] == 'M' and lines[i-2][j-2] == 'A' and lines[i-3][j-3] == 'S':
count += 1
if UP and RIGHT:
if lines[i-1][j+1] == 'M' and lines[i-2][j+2] == 'A' and lines[i-3][j+3] == 'S':
count += 1
if DOWN and LEFT:
if lines[i+1][j-1] == 'M' and lines[i+2][j-2] == 'A' and lines[i+3][j-3] == 'S':
count += 1
if DOWN and RIGHT:
if lines[i+1][j+1] == 'M' and lines[i+2][j+2] == 'A' and lines[i+3][j+3] == 'S':
count += 1
print(count)

27
04b_alt.py Executable file
View File

@@ -0,0 +1,27 @@
#!/usr/bin/python
import re
with open('04a.txt') as f:
text = f.read().strip().replace('\n', 'Z')
TOP = r'M[^Z]M.{139}A.{139}S[^Z]S'
LEFT = r'M[^Z]S.{139}A.{139}M[^Z]S'
BOTTOM = r'S[^Z]S.{139}A.{139}M[^Z]M'
RIGHT = r'S[^Z]M.{139}A.{139}S[^Z]M'
T = re.compile(f'(?={TOP})')
L = re.compile(f'(?={LEFT})')
B = re.compile(f'(?={BOTTOM})')
R = re.compile(f'(?={RIGHT})')
T_ = len(T.findall(text))
L_ = len(L.findall(text))
B_ = len(B.findall(text))
R_ = len(R.findall(text))
print(f'TOP {T_}')
print(f'LEFT {L_}')
print(f'BOTTOM {B_}')
print(f'RIGHT {R_}')
print(f'TOTAL {T_ + L_ + B_ + R_}')

129
10.cpp Normal file
View File

@@ -0,0 +1,129 @@
#include <iostream>
#include <array>
#include <cstdint>
#include <fstream>
#include <iterator>
#include <unordered_set>
using map_t = std::array<std::array<uint8_t, 55>, 54>;
struct Point
{
int16_t Row;
int16_t Col;
};
using sols_t = std::unordered_set<uint32_t>;
void load_map(map_t& map, const char* filepath)
{
std::fstream in(filepath);
std::istreambuf_iterator<char> iter(in);
// std::istream_iterator<char> end;
for (auto& row : map)
{
for (auto& cell : row)
{
cell = *(iter++);
}
}
}
void branch(const map_t& map, sols_t& terminals, char height, Point pos)
{
if (height == '9')
terminals.emplace((pos.Row << 16) + pos.Col);
else
{
if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1)
{
branch(map, terminals, height+1, {pos.Row-1, pos.Col});
}
if (pos.Row < map.size()-1 && map[pos.Row+1][pos.Col] == height+1)
{
branch(map, terminals, height+1, {pos.Row+1, pos.Col});
}
if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1)
{
branch(map, terminals, height+1, {pos.Row, pos.Col-1});
}
if (pos.Col < map[0].size()-2 && map[pos.Row][pos.Col+1] == height+1)
{
branch(map, terminals, height+1, {pos.Row, pos.Col+1});
}
}
}
int64_t branch2(const map_t& map, char height, Point pos)
{
if (height == '9')
return 1;
else
{
int64_t total = 0;
if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1)
{
total += branch2(map, height+1, {pos.Row-1, pos.Col});
}
if (pos.Row < map.size()-1 && map[pos.Row+1][pos.Col] == height+1)
{
total += branch2(map, height+1, {pos.Row+1, pos.Col});
}
if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1)
{
total += branch2(map, height+1, {pos.Row, pos.Col-1});
}
if (pos.Col < map[0].size()-2 && map[pos.Row][pos.Col+1] == height+1)
{
total += branch2(map, height+1, {pos.Row, pos.Col+1});
}
return total;
}
}
void main1(const map_t& map)
{
int total = 0;
// for (const auto& row : map)
// for (const auto& cell : row)
// std::cout << cell;
// std::cout << std::endl;
for (int16_t r = 0; r < map.size(); r++)
{
for (int16_t c = 0; c < map[r].size()-1; c++)
{
if (map[r][c] == '0')
{
sols_t terminals;
branch(map, terminals, '0', {r, c});
total += terminals.size();
}
}
}
std::cout << "Part1 " << total << std::endl;
}
void main2(const map_t& map)
{
int64_t total = 0;
for (int16_t r = 0; r < map.size(); r++)
{
for (int16_t c = 0; c < map[r].size()-1; c++)
{
if (map[r][c] == '0')
{
total += branch2(map, '0', {r, c});
}
}
}
std::cout << "Part2 " << total << std::endl;
}
int main()
{
map_t map;
load_map(map, "10.txt");
main1(map);
main2(map);
return 0;
}

260
10_extraquick.cpp Normal file
View File

@@ -0,0 +1,260 @@
#include <iostream>
#include <array>
#include <cstdint>
#include <fstream>
#include <iterator>
#include <bitset>
#define WIDTH 54
#define HEIGHT 54
using map_t = std::array<std::array<uint8_t, WIDTH>, HEIGHT>;
struct Point
{
int_fast8_t Row;
int_fast8_t Col;
};
struct sols_t
{
std::bitset<WIDTH*HEIGHT> bits;
void emplace(Point point)
{
bits.set(point.Row * WIDTH + point.Col);
}
int size() const
{
return bits.count();
}
void clear()
{
bits.reset();
}
};
void load_map(map_t& map, const char* filepath)
{
std::fstream in(filepath);
std::istreambuf_iterator iter(in);
for (auto& row : map)
{
for (auto& cell : row)
{
cell = *(iter++) - '0';
}
iter++;
}
}
void quick_branch(const map_t& map, sols_t& terminals, Point init)
{
std::array<int_fast8_t, 9> path;
int_fast8_t height = 0;
path[0] = 0;
Point pos = init;
while (height >= 0)
{
// const auto& pos = path[height].pos;
switch (path[height]++)
{
case 0:
if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1)
{
if (height == 8)
terminals.emplace({static_cast<int_fast8_t>(pos.Row-1), pos.Col});
else
{
path[++height] = 0;
pos.Row--;
}
}
break;
case 1:
if (pos.Col < WIDTH-1 && map[pos.Row][pos.Col+1] == height+1)
{
if (height == 8)
terminals.emplace({pos.Row, static_cast<int_fast8_t>(pos.Col+1)});
else
{
path[++height] = 0;
pos.Col++;
}
}
break;
case 2:
if (pos.Row < HEIGHT-1 && map[pos.Row+1][pos.Col] == height+1)
{
if (height == 8)
terminals.emplace({static_cast<int_fast8_t>(pos.Row+1), pos.Col});
else
{
path[++height] = 0;
pos.Row++;
}
}
break;
case 3:
if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1)
{
if (height == 8)
terminals.emplace({pos.Row, static_cast<int_fast8_t>(pos.Col-1)});
else
{
path[++height] = 0;
pos.Col--;
}
}
break;
default:
if (height > 0)
//remember that the previous path was already incremented
switch (path[height-1])
{
case 1:
pos.Row++;
break;
case 2:
pos.Col--;
break;
case 3:
pos.Row--;
break;
case 4:
pos.Col++;
break;
}
height--;
break;
}
}
}
int quick_branch2(const map_t& map, Point init)
{
std::array<int_fast8_t, 9> path;
int_fast8_t height = 0;
path[0] = 0;
int total = 0;
Point pos = init;
while (height >= 0)
{
switch (path[height]++)
{
case 0:
if (pos.Row > 0 && map[pos.Row-1][pos.Col] == height+1)
{
if (height == 8)
total++;
else
{
path[++height] = 0;
pos.Row--;
}
}
break;
case 1:
if (pos.Col < WIDTH-1 && map[pos.Row][pos.Col+1] == height+1)
{
if (height == 8)
total++;
else
{
path[++height] = 0;
pos.Col++;
}
}
break;
case 2:
if (pos.Row < HEIGHT-1 && map[pos.Row+1][pos.Col] == height+1)
{
if (height == 8)
total++;
else
{
path[++height] = 0;
pos.Row++;
}
}
break;
case 3:
if (pos.Col > 0 && map[pos.Row][pos.Col-1] == height+1)
{
if (height == 8)
total++;
else
{
path[++height] = 0;
pos.Col--;
}
}
break;
default:
if (height > 0)
//remember that the previous path was already incremented
switch (path[height-1])
{
case 1:
pos.Row++;
break;
case 2:
pos.Col--;
break;
case 3:
pos.Row--;
break;
case 4:
pos.Col++;
break;
}
height--;
break;
}
}
return total;
}
void main1(const map_t& map)
{
int total = 0;
sols_t terminals;
terminals.clear();
for (int8_t r = 0; r < map.size(); r++)
{
for (int8_t c = 0; c < map[r].size(); c++)
{
if (map[r][c] == 0)
{
quick_branch(map, terminals, {r, c});
total += terminals.size();
terminals.clear();
}
}
}
std::cout << "Part1 " << total << std::endl;
}
void main2(const map_t& map)
{
int32_t total = 0;
for (int8_t r = 0; r < map.size(); r++)
{
for (int8_t c = 0; c < map[r].size(); c++)
{
if (map[r][c] == 0)
{
total += quick_branch2(map, {r, c});
}
}
}
std::cout << "Part2 " << total << std::endl;
}
int main()
{
map_t map;
load_map(map, "10.txt");
main1(map);
main2(map);
return 0;
}

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;
// }