Inlägg
Dag: 4
Språk: C#
public static void Run()
{
var scratchies = FileReader.ReadLines("Day4.txt")
.Select(x =>
{
var idAndGameDetails = x.Split(":", StringSplitOptions.RemoveEmptyEntries);
var id = int.Parse(idAndGameDetails[0].Split(" ", StringSplitOptions.RemoveEmptyEntries)[1]);
var numbers = idAndGameDetails[1].Split("|", StringSplitOptions.TrimEntries);
var winningNumbers = numbers[0].Split(" ", StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
var scratchyNumbers = numbers[1].Split(" ", StringSplitOptions.RemoveEmptyEntries).Select(x => int.Parse(x)).ToList();
return new Scratchy(id, winningNumbers, scratchyNumbers);
}).ToList();
var part1Res = scratchies.Select(x =>
{
var numOfIntersection = x.WinningNumbers.Intersect(x.ScratchysNumbers).Count();
return numOfIntersection > 1 ? Math.Floor(Math.Pow(2, numOfIntersection-1)) : numOfIntersection;
}).Sum();
Console.WriteLine(part1Res);
for (int i = 0; i < scratchies.Count; i++)
{
var scratchy = scratchies[i];
for (int j = 0; j < scratchy.Instances; j++)
{
var numOfIntersection = scratchy.WinningNumbers.Intersect(scratchy.ScratchysNumbers).Count();
var lastIndex = numOfIntersection <= scratchies.Count - 1 ? numOfIntersection + i + 1 : scratchies.Count - 1;
for (int k = i + 1; k < lastIndex; k++)
{
var scratchyCopy = scratchies[k] with { Instances = scratchies[k].Instances + 1 };
scratchies[k] = scratchyCopy;
}
}
}
Console.WriteLine(scratchies.Sum(x => x.Instances));
}
internal record Scratchy(int Id, IReadOnlyList<int> WinningNumbers, IReadOnlyList<int> ScratchysNumbers, int Instances = 1);
Dag: 1
Språk: C#
Kommentar: Not great, not terrible
var day1Res = FileReader.ReadLines("Day1.txt")
.Select(x =>
{
var first = x.ToCharArray().First(possibleNum => char.IsNumber(possibleNum));
var last = x.ToCharArray().Last(possibleNum => char.IsNumber(possibleNum));
return char.GetNumericValue(first) * 10 + char.GetNumericValue(last);
}).Sum();
Console.WriteLine(day1Res);
var day1Res2 = FileReader.ReadLines("Day1.txt")
.Select(x =>
{
var firstIndex = int.MaxValue;
var firstValue = 0;
var secondIndex = int.MinValue;
var secondValue = 0;
foreach (var item in numToInt)
{
var indexOfFirstKey = x.IndexOf(item.Key);
if (indexOfFirstKey >= 0 && indexOfFirstKey < firstIndex)
{
firstIndex = indexOfFirstKey;
firstValue = item.Value;
}
var indexOfSecondKey = x.LastIndexOf(item.Key);
if (indexOfSecondKey >= 0 && indexOfSecondKey > secondIndex)
{
secondIndex = indexOfSecondKey;
secondValue = item.Value;
}
}
return firstValue*10 + secondValue;
}).Sum();
Console.WriteLine(day1Res2);
}
Dag: 2
Språk: C#
Kommentar: Nöjd med denna
public static void Run()
{
var games = FileReader.ReadLines("Day2.txt")
.Select(GameMaker)
.ToList();
var day1Res = games.Where(x => x.Possible).Select(x => x.Id).Sum();
Console.WriteLine(day1Res);
var day2Res = games.Select(x => x.Blue * x.Red * x.Green).Sum();
Console.WriteLine(day2Res);
}
private static Game GameMaker(string input)
{
var idAndCubesSeparation = input.Split(":", StringSplitOptions.RemoveEmptyEntries);
string id = idAndCubesSeparation[0].Split(" ")[1];
var game = new Game(int.Parse(id));
var gameSections = idAndCubesSeparation[1].Split(";", StringSplitOptions.RemoveEmptyEntries);
foreach (var section in gameSections)
{
var sectionColorParts = section.Split(",", StringSplitOptions.RemoveEmptyEntries);
foreach (var colorPart in sectionColorParts)
{
var numCubesAndColor = colorPart.Split(" ", StringSplitOptions.RemoveEmptyEntries);
var num = int.Parse(numCubesAndColor[0]);
var color = numCubesAndColor[1];
//if Possible has been set to false, it will stay false, otherwise do the value check
game = (color) switch
{
"blue" => game with { Possible = !game.Possible ? game.Possible : num <= Game.BLUE_LIMIT, Blue = int.Max(game.Blue, num) },
"red" => game with { Possible = !game.Possible ? game.Possible : num <= Game.RED_LIMIT, Red = int.Max(game.Red, num) },
"green" => game with { Possible = !game.Possible ? game.Possible : num <= Game.GREEN_LIMIT, Green = int.Max(game.Green, num) },
_ => game
};
}
}
return game;
}
private record Game(int Id, int Blue = 0, int Red = 0, int Green = 0, bool Possible = true)
{
internal const int BLUE_LIMIT = 14;
internal const int RED_LIMIT = 12;
internal const int GREEN_LIMIT = 13;
}
Dag: 3
Språk: C#
Kommentar: Fy fan jag borde sluta koda och bli jordgubbsförsäljare var känslan jag fick
public static void Run()
{
var lines = FileReader.ReadLines("Day3.txt");
var lineDetails = lines
.Select((line, index) =>
{
List<Gear> gears = [];
List<LineNumber> lineNumbers = [];
string currNumber = "";
for (int i = 0; i < line.Length; i++)
{
var currChar = line[i];
if (currChar == '*')
{
gears.Add(new Gear(i, []));
}
if (!char.IsNumber(currChar))
{
if (currNumber != "")
{
lineNumbers.Add(new LineNumber(int.Parse(currNumber), i - currNumber.Length, i));
currNumber = "";
}
}
else
{
currNumber += currChar;
}
}
if (currNumber != "")
{
lineNumbers.Add(new LineNumber(int.Parse(currNumber), line.Length - currNumber.Length, line.Length));
}
return new LineDetails(line, index, index == 0, index == lines.Length - 1, lineNumbers, gears);
})
.ToList();
lineDetails.ForEach(ld => ld.Numbers.ForEach(ln => ln.CheckSurrounding(ld, lineDetails)));
var part1Res = lineDetails.SelectMany(ld =>
{
return ld.Numbers.Where(ldn => ldn.SymbolSurrounded);
}).Sum(x => x.Number);
var part2Res = lineDetails
.SelectMany(ld => ld.Gears)
.Where(x => x.Numbers.Count == 2)
.Select(x => x.Numbers.Aggregate((a, b) => a * b))
.Sum();
Console.WriteLine(part1Res);
Console.WriteLine(part2Res);
}
internal record LineDetails(string Line, int Index, bool IsTop, bool IsBottom, List<LineNumber> Numbers, List<Gear> Gears);
internal class LineNumber()
{
public int Number { get; init; }
public int StartIndex { get; init; }
public int EndIndex { get; init; }
public bool SymbolSurrounded { get; set; }
readonly Func<char, bool> _isSymbol = (char c) => (!char.IsNumber(c) && c != '.');
readonly Func<char, bool> _isGear = (char c) => (c == '*');
public LineNumber(int number, int startIndex, int endIndex, bool symbolSurrounded = false) : this()
{
Number = number;
StartIndex = startIndex;
EndIndex = endIndex;
SymbolSurrounded = symbolSurrounded;
}
public void CheckSurrounding(LineDetails ld, List<LineDetails> allLines)
{
bool addedTopAlready = false;
bool addedBottomAlready = false;
for (int i = StartIndex; i < EndIndex; i++)
{
if (!ld.IsTop)
{
var lineDescriptionAbove = allLines[ld.Index - 1];
var upperleftIndex = i > 0 ? i - 1 : -1;
var upperRightIndex = i < ld.Line.Length - 1 ? i + 1 : -1;
if (upperleftIndex > 0)
{
if (_isGear(lineDescriptionAbove.Line[upperleftIndex]) && !addedTopAlready)
{
lineDescriptionAbove.Gears.First(x => x.Index == upperleftIndex).Numbers.Add(Number);
addedTopAlready = true;
}
if (!SymbolSurrounded && _isSymbol(lineDescriptionAbove.Line[upperleftIndex])) this.SymbolSurrounded = true;
}
if (_isGear(lineDescriptionAbove.Line[i]) && !addedTopAlready)
{
lineDescriptionAbove.Gears.First(x => x.Index == i).Numbers.Add(Number);
addedTopAlready = true;
}
if (!SymbolSurrounded && _isSymbol(lineDescriptionAbove.Line[i])) this.SymbolSurrounded = true;
if (upperRightIndex > 0)
{
if (_isGear(lineDescriptionAbove.Line[upperRightIndex]) && !addedTopAlready)
{
lineDescriptionAbove.Gears.First(x => x.Index == upperRightIndex).Numbers.Add(Number);
addedTopAlready = true;
}
if (!SymbolSurrounded && _isSymbol(lineDescriptionAbove.Line[upperRightIndex])) this.SymbolSurrounded = true;
}
}
if (!ld.IsBottom)
{
var lineDescriptionBelow = allLines[ld.Index + 1];
var lowerleftIndex = i > 0 ? i - 1 : -1;
var lowerRightIndex = i < ld.Line.Length - 1 ? i + 1 : -1;
if (lowerleftIndex > 0)
{
if (_isGear(lineDescriptionBelow.Line[lowerleftIndex]) && !addedBottomAlready)
{
lineDescriptionBelow.Gears.First(x => x.Index == lowerleftIndex).Numbers.Add(Number);
addedBottomAlready = true;
}
if (!SymbolSurrounded && _isSymbol(lineDescriptionBelow.Line[lowerleftIndex])) this.SymbolSurrounded = true;
}
if (_isGear(lineDescriptionBelow.Line[i]) && !addedBottomAlready)
{
lineDescriptionBelow.Gears.First(x => x.Index == i).Numbers.Add(Number);
addedBottomAlready = true;
}
if (!SymbolSurrounded && _isSymbol(lineDescriptionBelow.Line[i])) this.SymbolSurrounded = true;
if (lowerRightIndex > 0)
{
if (_isGear(lineDescriptionBelow.Line[lowerRightIndex]) && !addedBottomAlready)
{
lineDescriptionBelow.Gears.First(x => x.Index == lowerRightIndex).Numbers.Add(Number);
addedBottomAlready = true;
}
if (!SymbolSurrounded && _isSymbol(lineDescriptionBelow.Line[lowerRightIndex])) this.SymbolSurrounded = true;
}
}
if (i > 0)
{
if (_isGear(ld.Line[i - 1])) ld.Gears.First(x => x.Index == i - 1).Numbers.Add(Number);
if (!SymbolSurrounded && _isSymbol(ld.Line[i-1])) this.SymbolSurrounded = true;
}
if (i < ld.Line.Length - 1)
{
if (_isGear(ld.Line[i + 1])) ld.Gears.First(x => x.Index == i+1).Numbers.Add(Number);
if (!SymbolSurrounded && _isSymbol(ld.Line[i + 1])) this.SymbolSurrounded = true;
}
}
}
}
internal record Gear(int Index, List<int> Numbers);
Inte svaret du söker men det viktigaste är definitivt du själv och att du redan nu börjar plugga mer om du har intresset. Se skolan mer som en vägledning.
Provade massa olika pushnotistjänster för RN ungefär 2 år sedan och då tyckte jag expo push notification var lättast. Kan ju ha hänt en del på den tiden så klart men ta en titt.
Här är kursen som fick mig att bli så intresserad att jag tillslut bytte karriär till utvecklare.
Börjar från noll och slutar med att bygga en fullstackapp, du kommer inte att kunna gå och jobba efter kursen men du har kommit en bra bit på vägen.
Det blev lite grötigt med att använda enums när man behöver dom i strängar.
Så jag gjorde om koden och använde bara strängar helt enkelt.
Och istället använde jag mallar.
template <typename T, std::size_t N>
int Tools_Software_Algorithms_findIndexOf(const T(&arr)[N], const T& value) {
for (std::size_t i = 0; i < N; i++) {
if (arr[i] == value) {
return i;
}
}
return -1; // Not found
}
template <typename T, std::size_t N>
constexpr std::size_t Tools_Software_Algorithms_getArraySize(const T(&)[N]) {
return N;
}
Jag hoppas att detta ska fungera bättre.
Jag kan inte C++ så bra men har sett dig skriva i andra trådar att prestanda är väldigt viktigt för dig. Den här lösningen verkar ha en annan filosofi om vi säger så, åtminstone jämfört med lösningarna ovan?
Nu när tråden är varm, då tänkte jag ställa en liten fråga som berör struktur.
Jag jobbar inte som mjukvarutuvecklare, men jag håller på programmera mycket på fritiden och även inom jobbet.
När jag programmerar så har jag en tendens att strukturera om mina filer hela tiden i mappar. Jag har liksom många mappar där bara enskilda filer ligger.
Detta tar dock en tid, men när jag hittar min struktur så blir projektet allt lättare att modifiera vid behov.
Känner ni igen er också att varje projekt tar sin tid att få sin struktur och när strukturen är klar, ja då är det 10X lättare att programmera?
Jag försöker undvika till varje pris att få spagettikod. Jag skriver aldrig sådant dock, så jag är mycket noga på att från vissa t.ex. .cpp filer så skall man ej kunna anropa vissa funktioner.
Jag kör inte OOP, om inte behovet finns tydligt.
Oftast så följer man nog en etablerad standard, åtminstone på jobbet. Databasfiler ligger där, controllers ligger där, e t c.
De som säger att språk Y kommer att döda/byta ut språk X är väl mest click baiters, det förstår nog de flesta. Det är samma sak som när det kommer nya JS-ramverk eller exempelvis Microsoft Blazor, de har lärt sig av sina föregångare och kanske har coola features som löser vanliga problem från sina föregångare men det finns nog ingen som tror att alla kommer sluta rakt av med de äldre sakerna då för mycket tid har investerats, både i arbetstid och kompetensmässigt.
Så om det sker en förändring är den nog mer långsam, över ett decennium eller mer.
Tror du kan behöva visa mer kod för att se vad som händer på andra ställen.
Rekommenderar Visual Studio 2022 istället för 2019, åtminstone i C# så känns den mycket smartare än 2019.
Vad som är värt att veta här är att kompilatorn ofta har svårare att göra något riktigt optimalt med det sista.
Testar man dina två exempel så är är "foreach" versionen ungefär 2x så snabb som den deklarativa versionen.
Vidare kanske nedan är mer vad man rimligen borde ha skrivit om man siktade på en imperativ version, den är 6x snabbare än den deklarativa versionen (bench:at med BenchmarkDotNet) och .NET 7.0.
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
double sumDoubledEvenNumbers = 0;
int numEvenNumbers = 0;
foreach (var number in ints) {
if (number % 2 == 0) {
sumDoubledEvenNumbers += number * 2;
numEvenNumbers++;
}
}
double average = sumDoubledEvenNumbers / numEvenNumbers;
Prestanda är definitivt inte allt och helt klart kan den deklarativa varianten vara betydligt enklare att förstå i vissa lägen. Men den stilen är inte helt icke-kontroversiell, det är fullt möjligt att skriva kod på det sättet i Golang (finns bibliotek som gör det möjligt) men där är det i stort sätt konsensus att "for-loop" är lättare för andra att förstå och därför att föredra.
Men finns lägen där den deklarativa versionen kan ge prestandafördelar. Java parallel streams, Rust Rayon, standard C++ par/par_unseq execution policies och liknande kan med rätt typ av problem ge en rätt fin prestandaboost som ofta är betydlig svårare att få till med imperativ stil.
Så som det mesta inom programmeringsvärlden, vad som är "bäst" är långt ifrån entydigt...
Ja just i C#-LINQ är implementationen att först görs din collection om till en IEnumerable, och att varenda metod du sedan kedjar på blir en loop som skapar upp en ny IEnumerable med förändringen (eller aggregerar ihop den som med t ex Average, Sum och så klart Aggregate). Så inge vidare om det är högsta möjliga prestanda man jagar.
Ja. Vad betyder det där liksom.
Jag förstår idén med att skriva allt på en enda rad, men det blir grötigt.
Jag ogillar C++ auto som finns överallt. Är detta något sätt för att komma bort från int, float, long, double, short, uint16_t osv?
Nu kan jag inte just den där syntaxen men det är väl som fluid interfaces i alla språk, om man inte läsa det så ser det fruktansvärt komplicerat ut men när man kan det så blir det mycket mer läsligt. Påhittat krysstat exempel i C#:
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var evenDoubledInts = new List<int>();
foreach(var number in ints)
{
if(number % 2 == 0)
{
evenDoubledInts.Add(number*2);
}
}
int totalSum = 0;
foreach(var number in evenDoubledInts)
{
totalSum += number;
}
double average = totalSum / evenDoubledInts.Count;
var ints = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
double average = ints
.Where(x => x % 2 == 0)
.Select(x => x*2)
.Average();
Vi beskriver för kompilatorn deklarativt vad vi vill göra och låter den oroa sig för detaljerna, jag vill bara ha de jämna talen, jag vill att de dubbleras och till sist vill jag veta medelvärdet. Hur du gör bryr jag mig inte om.
Så där försöker den skriva ut "bleh" innan fetch-anropet hinner slutföras? Rent förenklat talat, hur bör man då kombinera det med await så det blir som önskat? Typ något i stil med:
let bleh;
const getBleh = fetchBs().then( (asd) =>{ //asynkront anrop
bleh = asd;
})
console.log(await getBleh);
Nu har jag inte börjat lära mig ES6 ännu men det jag tänker är att nyckelordet "await" används för att förhindra kod direkt under koden som innehåller "await" från att köras? Samtidigt så verkar det inte gå att skriva await varsomhelst i kod? Så då verkar det nästan som om allt måste vara async-funktioner för att man ska ha koll på exekveringsflödet?
För det vi vill se till är att console.log() inte får köras förrän async-anropet är färdigt och hur gör man det om inte console.log själv är inuti samma async-anrop för att "await" ska få användas?
För att använda await i js måste man vara i ett asyncblock vilket kan bli awkward ibland. Lättaste i det där fallet vore att skapa en ny . then-kedja eller antagligen ännu bättre göra allt innanför den första .thenfunktionen
Som nybörjare kommer de verka som samma språk nästan. När man börjar komma igång med mer avancerade grejer skulle jag säga att C# definitivt har lite roligare funktioner som object initializersyntaxen, LINQ slår Java streams lätt, anonyma objekt i LINQ, string interpolation och async/await syntaxen.
Men mina Javakunskaper är några år nu så det kanske har kommit ikapp/förbi på de områdena eller andra.
Är nog lättast om du hittar en youtubevideo där du kan se exakt vad de klickar på och vad som ändras, auto layout är jäkligt klurig och drar du sedan i komponenten så försvinner auto layouten... massa bök.
Bygga på "traditionellt" sätt, betyder det t ex bygga SPA-applikationer eller menar du bokstavligen old school HTML/CSS/sprinkla lite JS?
Men problemet är att när jag skapar min release-applikation, alltså mappen. Så hamnar alla mina .dll och .exe filer där, men ingen "minFil.txt" finns där.
Menar du att de kommer med när du bygger din debug? I såna fall har du inte ändrat konfigureringen för ditt releaseprojekt utan bara debug.
Ska man inte klicka på filen och ändra "copy to output directory" i file properties? Eller funkar inte det i för C++-solutions?
Dag 7 Kotlin
class Day7 {
fun run() {
val input = java.io.File("src/input/day7.txt").readLines();
val fileStructure = addChildren(input)
var root = fileStructure
while (root?.parentDirectory != null) {
root = root?.parentDirectory
}
val part1Answer = root!!.part1()
val part2Answer = root!!.part2(30000000).minByOrNull { it.totalSize }!!
println(part1Answer)
println(part2Answer.totalSize)
println(root!!.part1test())
}
private tailrec fun addChildren(instructions: List<String>, currentDirectory: Directory? = null): Directory? {
if (instructions.isEmpty()) {
return currentDirectory
}
val instruction = instructions.first()
when {
instruction.startsWith("dir ") -> {
val directoryName = instruction.split(" ")[1]
val newDirectory = Directory(currentDirectory, mutableListOf(), mutableListOf(), directoryName)
currentDirectory?.subDirectories?.add(newDirectory)
return addChildren(instructions.drop(1), currentDirectory)
}
instruction.split(" ")[0].all { it.isDigit() } -> {
val fileParts = instruction.split(" ")
val newFile = File(currentDirectory!!, fileParts[1], fileParts[0].toInt())
currentDirectory?.files?.add(newFile)
return addChildren(instructions.drop(1), currentDirectory)
}
instruction == "$ ls" -> return addChildren(instructions.drop(1), currentDirectory)
instruction.startsWith("$ cd") -> {
val targetDirectory = instruction.split(" ")[2]
if (targetDirectory == "/") {
return addChildren(
instructions.drop(1),
Directory(null, mutableListOf(), mutableListOf(), targetDirectory)
)
}
if (targetDirectory == "..") {
return addChildren(instructions.drop(1), currentDirectory?.parentDirectory)
}
return addChildren(
instructions.drop(1),
currentDirectory?.subDirectories?.find { it.name == targetDirectory })
}
}
throw IllegalArgumentException("nu blev det tokigt igen")
}
class Directory(
val parentDirectory: Directory?,
val subDirectories: MutableList<Directory>,
val files: MutableList<File>,
val name: String
) {
val totalSize: Int by lazy {
files.sumOf { it.size } + this.subDirectories.sumOf { it.totalSize }
}
fun part1(): Int {
val size = if (totalSize < 100000) totalSize else 0
return size + this.subDirectories.sumOf { it.part1() }
}
fun part1test(): Int {
println(this.name + ": " + this.totalSize)
return totalSize + this.subDirectories.sumOf { it.part1test() }
}
fun part2(
targetFreeSpace: Int,
currentFreeSpace: Int = 70000000 - this.totalSize,
directoriesForDelete: MutableList<Directory> = mutableListOf()
): List<Directory> {
if (currentFreeSpace + this.totalSize >= targetFreeSpace) {
directoriesForDelete.add(this)
}
for (childDirectory in this.subDirectories) {
childDirectory.part2(targetFreeSpace, currentFreeSpace, directoriesForDelete)
}
return directoriesForDelete
}
}
class File(val parentDirectory: Directory, val name: String, val size: Int)
}
Dag 8 Koltin
class Day8 {
fun run(){
//val input = "30373\n25512\n65332\n33549\n35390".split("\n")
val input = File("src/input/day8.txt").readLines();
val allTrees: List<List<Tree>> = input.mapIndexed { y, treeLine ->
val trees = treeLine.split("").subList(1, treeLine.length+1)
trees.mapIndexed { x, tree ->
Tree(x, y, tree.toInt())
}
}
val forest = Forest(allTrees)
println(forest.treesVisibleFromAnywhere)
println(forest.highestScenicValue)
}
}
class Forest(val trees: List<List<Tree>>)
{
val treesVisibleFromAnywhere: Int by lazy {
var visibleTrees = 0
for (y in trees.indices)
{
for(x in trees[0].indices)
{
val currentTree = trees[y][x]
val treeLineHorizontal = trees[y]
val treeLineVertical = getVerticalTreeLine(x)
val hasAnyHeigherLeft = treeLineHorizontal.filter { it != currentTree && it.x < currentTree.x }.all { it.height < currentTree.height }
val hasAnyHeigheRight = treeLineHorizontal.filter { it != currentTree && it.x > currentTree.x }.all { it.height < currentTree.height }
val hasAnyHeigherAbove = treeLineVertical.filter { it != currentTree && it.y < currentTree.y }.all { it.height < currentTree.height }
val hasAnyHeigherBelow = treeLineVertical.filter { it != currentTree && it.y > currentTree.y }.all { it.height < currentTree.height }
visibleTrees += when{
y == 0 || y == trees.size-1 -> 1
x == 0 || x == trees[0].size-1 -> 1
hasAnyHeigherLeft || hasAnyHeigheRight -> 1
hasAnyHeigherAbove || hasAnyHeigherBelow -> 1
else -> 0
}
}
}
visibleTrees
}
val highestScenicValue: Int get(){
var highestScore = 0
val treeCounter = {treesToCount: List<Tree>, treeCountDirection: TreeCountDirection, currentTree: Tree ->
val treesOnSpecifiedSide = when(treeCountDirection){
TreeCountDirection.LEFT -> treesToCount.filter { it != currentTree && it.x < currentTree.x}.reversed()
TreeCountDirection.RIGHT -> treesToCount.filter { it != currentTree && it.x > currentTree.x }
TreeCountDirection.UP -> treesToCount.filter { it != currentTree && it.y < currentTree.y }.reversed()
TreeCountDirection.DOWN -> treesToCount.filter { it != currentTree && it.y > currentTree.y }
}.takeWhile { it.height < currentTree.height }
treesOnSpecifiedSide.count() + when(treeCountDirection){
TreeCountDirection.LEFT -> if (treesOnSpecifiedSide.lastOrNull()?.x != 0) 1 else 0
TreeCountDirection.RIGHT -> if (treesOnSpecifiedSide.lastOrNull()?.x != treesToCount.size-1) 1 else 0
TreeCountDirection.UP -> if (treesOnSpecifiedSide.lastOrNull()?.y != 0) 1 else 0
TreeCountDirection.DOWN -> if (treesOnSpecifiedSide.lastOrNull()?.y != trees.size-1) 1 else 0
}
}
for (y in 1 .. trees.size - 2)
{
for(x in 1 .. trees[0].size - 2)
{
val currentTree = trees[y][x]
val treeLineHorizontal = trees[y]
val treeLineVertical = getVerticalTreeLine(x)
val scoreLeft = treeCounter(treeLineHorizontal, TreeCountDirection.LEFT, currentTree)
val scoreRight = treeCounter(treeLineHorizontal, TreeCountDirection.RIGHT, currentTree)
val scoreAbove = treeCounter(treeLineVertical, TreeCountDirection.UP, currentTree)
val scoreBelow = treeCounter(treeLineVertical, TreeCountDirection.DOWN, currentTree)
val score = scoreLeft*scoreRight*scoreAbove*scoreBelow
if(score > highestScore)
{
highestScore = score
}
}
}
return highestScore
}
private fun getVerticalTreeLine(x: Int): List<Tree>
{
var verticalTrees: MutableList<Tree> = mutableListOf()
for(treeLine in trees)
{
verticalTrees.add(treeLine[x])
}
return verticalTrees.toList()
}
}
data class Tree(val x: Int, val y: Int, val height: Int)
enum class TreeCountDirection{
LEFT, RIGHT, UP, DOWN
}
Dag 9 Koltin
class Day9 {
fun run() {
val input = File("src/input/day9.txt").readLines()
val moves = input.map {
val moveParts = it.trim().split(" ")
val moveDirection = when (moveParts[0]) {
"U" -> MoveCommand.Direction.UP
"D" -> MoveCommand.Direction.DOWN
"L" -> MoveCommand.Direction.LEFT
"R" -> MoveCommand.Direction.RIGHT
else -> throw IllegalArgumentException()
}
MoveCommand(moveDirection, moveParts[1].toInt())
}
println(Knots(2).moveAround(moves))
println(Knots(10).moveAround(moves))
}
}
class MoveCommand(val direction: Direction, val totalSteps: Int) {
val isVertical: Boolean by lazy { direction == Direction.UP || direction == Direction.DOWN }
enum class Direction(val step: Int) {
UP(1), DOWN(-1), LEFT(-1), RIGHT(1)
}
}
data class Knot(var current: Point, val isHead: Boolean = false)
class Knots(numberOfKnots: Int){
private val allKnots: LinkedList<Knot> = LinkedList()
init {
val head = Knot(Point(0, 0), true)
allKnots.addFirst(head)
IntRange(1, numberOfKnots-1).forEach { _ -> allKnots.add(Knot(Point(0,0))) }
}
fun moveAround(commands: List<MoveCommand>): Int {
val uniqueLocations: MutableSet<Pair<Int, Int>> = mutableSetOf(Pair(0, 0))
commands.forEach {command ->
for (step in 0 until command.totalSteps) {
allKnots.forEachIndexed{knotIndex, knot ->
if(knot.isHead)
{
moveHead(knot, command)
}
else
{
val lastKnot = allKnots[knotIndex-1]
moveTailPart(knot, lastKnot)
}
}
val tailCurrentLocation = Pair(allKnots.last.current.x, allKnots.last.current.y)
uniqueLocations.add(tailCurrentLocation)
}
}
return uniqueLocations.size
}
companion object {
private fun moveHead(head: Knot, command: MoveCommand) =
if (command.isVertical)
head.current.move(head.current.x, head.current.y + command.direction.step)
else
head.current.move(head.current.x + command.direction.step, head.current.y)
private fun moveTailPart(tailPart: Knot, lastPart: Knot){
val currentPoint = tailPart.current
val lastPoint = lastPart.current
if(currentPoint.distance(lastPoint) == 2.0)
{
val newX = (lastPoint.x + currentPoint.x) / 2
val newY = (lastPoint.y + currentPoint.y) / 2
currentPoint.move(newX, newY)
}
else if (currentPoint.distance(lastPoint) > 2.0)
{
val newX = when{
lastPoint.x > currentPoint.x -> currentPoint.x+1
lastPoint.x < currentPoint.x -> currentPoint.x-1
else -> currentPoint.x
}
val newY = when{
lastPoint.y > currentPoint.y -> currentPoint.y+1
lastPoint.y < currentPoint.y -> currentPoint.y-1
else -> currentPoint.y
}
currentPoint.move(newX, newY)
}
}
}
}
Dag 10 Koltin
class Day10 {
fun run()
{
val input = File("src/input/day10.txt").readLines()
val display = Display(input)
println(display.runInstructions())
println(display.part2Sb.toString())
}
}
class Display(private val instructions: List<String>){
private var x: Int = 1
val part2Sb: StringBuilder = java.lang.StringBuilder()
private var cycleNumber: Int by Delegates.observable(0){prop, oldValue, newValue ->
if(newValue % 20 == 0 && newValue % 40 != 0)
{
signalStrengths.add(x*newValue)
}
val currentPositionOnRow = (newValue - 1) % 40
val spriteIsInView = currentPositionOnRow == x-1 || currentPositionOnRow == x || currentPositionOnRow == x+1
if (spriteIsInView) part2Sb.append("#") else part2Sb.append(".")
if(currentPositionOnRow == 39)
{
part2Sb.append("\n")
}
}
private val signalStrengths: MutableList<Int> = mutableListOf()
fun runInstructions(): Int
{
for ( instruction in instructions)
{
when{
instruction == "noop" -> cycleNumber++
instruction.startsWith("addx") -> {
val value = instruction.split(" ")[1].toInt()
repeat(2){cycleNumber++}
x += value
}
}
}
return signalStrengths.sum()
}
}
Jag har inte lekt med Kotlin innan det här så om någon ser något uppenbart jättekonstigt jag gör så vill jag gärna veta Tyckte om observablen i del 10 i a f. Trevligt språk!
- Idag EU förbjuder svaga lösenord i smarta hemmet-prylar 20
- Idag ShowCase: Prestanda för pengarna med Nvidia Geforce RTX 4060 17
- Idag Apple kan släppa ny Ipad Pro med M4-krets 33
- Igår Intel skyller Raptor Lake-krascher på moderkortstillverkare 37
- Igår TSMC utvecklar enorma kretsar med effekt mätt i kilowatt 11
- Senaste klarade spel?675
- Ryskt spelbolag sponsrar Dreamhack-turneringar39
- Spela Fallout-variant i smyg i Excel1
- Microsoft släpper källkoden till MS‑DOS 4.0026
- Riktigt kass FPS i vissa spel - bör uppgradera?8
- Ljudproblem på ny dator från inet0
- [LEK] Gissa spelet15532
- Söker ett tangentbord liknande K7408
- Elbilar - Tråden för intresserade23202
- LegoClockers - Samlingstråd för allt med Lego630
- Köpes Söker Ryzen 5600 eller bättre + mobo
- Säljes Samsung Tab S8 5G 128 GB
- Säljes Supermicro C7X99-OCE + Intel Xeon E5-2699 v3 + Corsair 32GB DDR4
- Köpes B460/Z490 eller B560/Z590 moderkort
- Säljes PG27AQDM 240hz oled 1440p
- Säljes Samsung Odyssey G5 S27 IPS 165hz
- Säljes Serverdelar Asus C621 Sage + x2 Intel Xeon Gold 6138 + 256GB DDR4 ECC + Noctua CPU Kylare
- Köpes Letar efter ryzen 5700x3d eller 5800x3d
- Säljes Nvidia Quadro P2000 5GB (PNY)
- Säljes LG 27GP850-B, AOC Q27G2S, headset
Tester av chassi, grafikkort, processorer m.m.
- Corsair Platform 6: För dig som inte nöjer dig med Ikea-skrivbord11
- Airtec Pro Type1 – batteridrivet alternativ till tryckluft på burk108
- Snabbtest: Bli mer Pro med mindre tangentbord41
- Snabbtest: Högre spelprestanda med Intel APO46
- Snabbtest: Asus ROG Swift PG32UCDM – kryss i nästan alla rutor38
- Cooler Master Ncore 100 Max – lättbyggt minstingchassi17
- Gömda strömkontakter med Asus och Corsair37
- Grafikprestanda i Horizon Forbidden West108
- Snabbtest: Streacom VU1 – analoga mätare i en digital värld25
- Corsair A115 – en kraftfull kylare med bristfällig ljudprofil15