🌟 Advent of Code (AoC) 2022 🌟

PermalÀnk
Medlem ★
●
Skrivet av GLaDER:

Dag: 3
SprÄk: Python 3
Lösning: GitHub

Idag var rolig, men det var tydligen fler Àn jag som tyckte det för inte blev det nÄgon framskjuten plats pÄ leaderboarden

Nyckeln till dagens uppgift -- för mig -- Àr att anvÀnda set för att hitta icke unika bokstÀver i de olika strÀngarna.

Var det nÄgon som gjorde pÄ nÄgot annat sÀtt?

Dold text

Dag: 4
SprÄk: Python 3
Lösning: GitHub

Ugh. Det hÀr var inte min morgon. FrÄn att ha varit nÀstan Top 1 000 igÄr till en bit över 8 000 idag

Snurrade bort mig totalt pÄ bÄda delarna. I del 1 försökte jag lÀnge implementera min egna issubset-metod innan jag kom pÄ att det var just konceptet sub set jag letade efter.

I del 2 gick jag bort mig pÄ att jag började leta efter överlappet för samtliga tilldelningar, samt hur stort det totala överlappet var. Det var inte förrÀn jag lÀste igenom tredje gÄngen som jag förstod att det bara var huruvida det existerade ett överlapp för varje par som var intressant. Tyckte vÀl att över 85 000 var lite stort...

Dold text
Visa signatur

:(){ :|:& };:

đŸŠđŸ»â€â™‚ïž   đŸšŽđŸ»â€â™‚ïž   đŸƒđŸ»â€â™‚ïž   ☕

PermalÀnk
Datavetare ★
●

Dag: 4
SprÄk: Go

package main import "fmt" type cleaningSection struct { start int end int } type sectionAssignment struct { a cleaningSection b cleaningSection } func isRedundantAssignment(sa sectionAssignment) bool { return (sa.a.start <= sa.b.start && sa.a.end >= sa.b.end) || (sa.b.start <= sa.a.start && sa.b.end >= sa.a.end) } func isOverlappingAssignment(sa sectionAssignment) bool { return (sa.a.start <= sa.b.start && sa.a.end >= sa.b.start) || (sa.b.start <= sa.a.start && sa.b.end >= sa.a.start) } func countAssignmentsWhere(sas []sectionAssignment, predicate func(sectionAssignment) bool) int { cnt := 0 for _, sa := range sas { if predicate(sa) { cnt++ } } return cnt } func parseSectionAssignments(input []string) []sectionAssignment { sas := []sectionAssignment{} for _, row := range input { var sa sectionAssignment _, err := fmt.Sscanf(row, "%d-%d,%d-%d", &sa.a.start, &sa.a.end, &sa.b.start, &sa.b.end) if err != nil { panic("Invalid input: " + err.Error()) } sas = append(sas, sa) } return sas } func day4(input []string) { assignments := parseSectionAssignments(input) fmt.Println(countAssignmentsWhere(assignments, isRedundantAssignment)) fmt.Println(countAssignmentsWhere(assignments, isOverlappingAssignment)) } func init() { Solutions[4] = day4 }

Lösning:

Inget fancy alls utan "simple boring for-loops" som jÀmför heltal...

Dold text
Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

PermalÀnk
Medlem
●

Dag: 4
SprÄk: Golang

InsÄg ganska fort att min if hade blivit helt galen för del 2 sÄ fick byta approach.

package main import ( "bufio" "fmt" "os" "strconv" "strings" ) type Section struct { Start int End int } type Pair struct { Left Section Right Section } func getPartOne(pairs []Pair) int { count := 0 for i := range pairs { pair := pairs[i] if (pair.Left.Start <= pair.Right.Start && pair.Right.End <= pair.Left.End) || (pair.Right.Start <= pair.Left.Start && pair.Left.End <= pair.Right.End){ count++ } } return count } func getPartTwo(pairs []Pair) int { count := 0 for i := range pairs { pair := pairs[i] numbers := make([]int,100) for j := pair.Left.Start; j <= pair.Left.End; j++ { numbers[j]++ } for j := pair.Right.Start; j <= pair.Right.End; j++ { if(numbers[j]) == 1 { count++ break } } } return count } func getRows(filename string) []Pair { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() scanner := bufio.NewScanner(file) rows := make([]Pair, 0) for scanner.Scan() { row := scanner.Text() fields := strings.Split(row, ",") pair := Pair{} left := strings.Split(fields[0], "-") pair.Left.Start, _ = strconv.Atoi(left[0]) pair.Left.End, _ = strconv.Atoi(left[1]) right := strings.Split(fields[1], "-") pair.Right.Start, _ = strconv.Atoi(right[0]) pair.Right.End, _ = strconv.Atoi(right[1]) rows = append(rows, pair) } return rows } func main() { fmt.Println("Part one:", getPartOne(getRows("../input.txt"))) fmt.Println("Part two:", getPartTwo(getRows("../input.txt"))) }

Dold text
PermalÀnk
Medlem
●
Skrivet av Yoshman:

Dag: 4
SprÄk: Go

package main import "fmt" type cleaningSection struct { start int end int } type sectionAssignment struct { a cleaningSection b cleaningSection } func isRedundantAssignment(sa sectionAssignment) bool { return (sa.a.start <= sa.b.start && sa.a.end >= sa.b.end) || (sa.b.start <= sa.a.start && sa.b.end >= sa.a.end) } func isOverlappingAssignment(sa sectionAssignment) bool { return (sa.a.start <= sa.b.start && sa.a.end >= sa.b.start) || (sa.b.start <= sa.a.start && sa.b.end >= sa.a.start) } func countAssignmentsWhere(sas []sectionAssignment, predicate func(sectionAssignment) bool) int { cnt := 0 for _, sa := range sas { if predicate(sa) { cnt++ } } return cnt } func parseSectionAssignments(input []string) []sectionAssignment { sas := []sectionAssignment{} for _, row := range input { var sa sectionAssignment _, err := fmt.Sscanf(row, "%d-%d,%d-%d", &sa.a.start, &sa.a.end, &sa.b.start, &sa.b.end) if err != nil { panic("Invalid input: " + err.Error()) } sas = append(sas, sa) } return sas } func day4(input []string) { assignments := parseSectionAssignments(input) fmt.Println(countAssignmentsWhere(assignments, isRedundantAssignment)) fmt.Println(countAssignmentsWhere(assignments, isOverlappingAssignment)) } func init() { Solutions[4] = day4 }

Lösning:

Inget fancy alls utan "simple boring for-loops" som jÀmför heltal...

Dold text

Wow trodde del 2 var omöjlig med ifs, dags att brygga lite kaffe.

Dold text
PermalÀnk
●

Sen pÄ bollen! FÄr se om jag kommer göra fler. Har inte mycket tid i veckorna. Hursomhelst!

Dag: 1
SprÄk: C

#include <stdio.h> unsigned parse_num(FILE *fp) { unsigned num = 0; for (;;) { const int ch = getc(fp); if (ch >= '0' && ch <= '9') { num = num * 10 + ch - '0'; } else { ungetc(ch, fp); break; } } return num; } int skip_to_next_num(FILE *fp) { int nl_count = 0; for (;;) { const int ch = getc(fp); if (ch == '\n') { nl_count += 1; } else if (ch >= '0' && ch <= '9') { ungetc(ch, fp); return nl_count; } else if (ch == EOF) { return 0; } } } unsigned parse_calories_entry(FILE *fp) { unsigned cur_calories = 0; do { cur_calories += parse_num(fp); } while (skip_to_next_num(fp) == 1); return cur_calories; } void update_top_calories(unsigned *top_calories, unsigned top_size, unsigned value) { unsigned tmp; for (unsigned i = 0; i < top_size; ++i) { if (value > top_calories[i]) { tmp = value; value = top_calories[i]; top_calories[i] = tmp; } } } int main(void) { unsigned top3_calories[3] = {}; do { const unsigned calories = parse_calories_entry(stdin); update_top_calories(top3_calories, 3, calories); } while (!feof(stdin)); printf("Most calories: %u.\n", top3_calories[0]); printf("Top 3 calories sum: %u.\n", top3_calories[0] + top3_calories[1] + top3_calories[2]); return 0; }

Dold text
PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: VB.Net

Imports System.IO Module Program Sub Main(args As String()) Dim part1 As Integer = 0 Dim part2 As Integer = 0 Using reader As New StreamReader("input.txt") While Not reader.EndOfStream Dim pair = reader.ReadLine.Split(","c) Dim firstElf = pair(0).Split("-"c) Dim secondElf = pair(1).Split("-"c) Dim sections1 As New HashSet(Of Integer) For i = Integer.Parse(firstElf(0)) To Integer.Parse(firstElf(1)) sections1.Add(i) Next Dim sections2 As New HashSet(Of Integer) For i = Integer.Parse(secondElf(0)) To Integer.Parse(secondElf(1)) sections2.Add(i) Next If sections1.IsSubsetOf(sections2) Or sections2.IsSubsetOf(sections1) Then part1 += 1 End If If sections1.Overlaps(sections2) Then part2 += 1 End If End While End Using Console.WriteLine("Part1:" & part1) Console.WriteLine("Part2:" & part2) End Sub End Module

Dold text
PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: Tafflig F#

open System.IO let parsePart (input:string) = let parts = input.Split '-' |> Array.map int (parts[0], parts[1]) let parseRow (row:string) = let parts = row.Split ',' |> Array.map parsePart (parts[0], parts[1]) let hasDistinctOverlap ((l1, u1), (l2, u2)) = (l1 <= l2 && u1 >= u2) || (l2 <= l1 && u2 >= u1) let hasSomeOverlap ((l1, u1), (l2, u2)) = (l1 <= l2 && u1 >= l2) || (l2 <= l1 && u2 >= l1) || (l1 <= u2 && u1 >= u2) || (l2 <= u1 && u2 >= u1) let input = File.ReadLines "input.txt" |> Seq.map parseRow printfn "Task 1: %i" (input |> Seq.filter hasDistinctOverlap |> Seq.length) printfn "Task 2: %i" (input |> Seq.filter hasSomeOverlap |> Seq.length)

Dold text
Visa signatur

Jag Àr en optimist; det Àr aldrig sÄ dÄligt sÄ att det inte kan bli sÀmre.

PermalÀnk
Medlem ★
●

Dag: 3
SprÄk: Rust

Nu kommer jag en dag efter, men hade inte tid igÄr. Tycker nog det blev relativt bra, för att inte anvÀnda (lÀs kunna) en enda specialkonstruktion i sprÄket.

fn calculate_one(first: &str, second: &str) -> u32 { for c in first.chars() { if second.contains(c) { return if c.is_uppercase() { c as u32 - 38 } else { c as u32 - 96 }; } } return 0; } fn calculate_two(first: &str, second: &str, third: &str) -> u32 { for c in first.chars() { if second.contains(c) && third.contains(c) { return if c.is_uppercase() { c as u32 - 38 } else { c as u32 - 96 }; } } return 0; } fn main() { let input = include_str!("./input.txt"); let mut total_score1 = 0; let mut total_score2 = 0; let mut input_vec = Vec::new(); for line in input.lines() { input_vec.push(line); } let mut i = 0; while i < input_vec.len() { for j in 0..3 { total_score1 += calculate_one(&input_vec[i + j][(..&input_vec[i + j].len() / 2)], &input_vec[i + j][(&input_vec[i + j].len() / 2)..]); } total_score2 += calculate_two(&input_vec[i], &input_vec[i + 1], &input_vec[i + 2]); i += 3; } println!("Total Score 1 {}", total_score1); println!("Total Score 2 {}", total_score2); }

Dold text
PermalÀnk
●

Dag: 4
SprÄk: Nim
Lösning: Github

Nim har en inbyggd range-typ sÄ blev hyffsat enkelt att representera och kolla ifall dom innehöll varandra. Var lite frestad att anvÀnda sets som igÄr annars.

include prelude import std / [strscans] proc readInput(input: string): seq[(HSlice[int, int], HSlice[int, int])] = for line in input.splitLines: let (success, a1, b1, a2, b2) = scanTuple(line, "$i-$i,$i-$i") assert success result.add (a1 .. b1, a2 .. b2) proc fullyContained(r1, r2: HSlice[int, int]): bool = (r1.a in r2 and r1.b in r2) or (r2.a in r1 and r2.b in r1) proc part1(input: string) = let ranges = readInput(input) var nFullyContained = 0 for (r1, r2) in ranges: if fullyContained(r1, r2): nFullyContained += 1 echo "Part 1: ", nFullyContained proc partiallyContained(r1, r2: HSlice[int, int]): bool = (r1.a in r2 or r1.b in r2) or (r2.a in r1 or r2.b in r1) proc part2(input: string) = let ranges = readInput(input) var nPartiallyContained = 0 for (r1, r2) in ranges: if partiallyContained(r1, r2): nPartiallyContained += 1 echo "Part 2: ", nPartiallyContained when isMainModule: let input = readFile("input.txt") part1(input) part2(input)

Dold text
PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: Python (oneliner)

print([sum([(lambda l1, h1, l2, h2, f: f(set(range(l1, h1 + 1)), set(range(l2, h2 + 1))))(*map(int, l.replace("-", ",").split(",")), f) for l in open("input04").readlines()]) for f in [lambda r1, r2: r1 & r2 in [r1, r2], lambda r1, r2: bool(r1 & r2)]])

Inte vÀrldens mest effektiva lösning med tanke pÄ att jag genererar ett set med alla medlemmar i bÄda rangerna, men logiken blir ganska enkel. Sedan gör jag det tvÄ gÄnger.

Dold text
Förenklade lite
PermalÀnk
Medlem
●

Dag: 4
SprÄk: C#

namespace AOC2022.Puzzles; internal class Puzzle4 : Puzzle<int> { protected override void Solve(string[] lines) { var overlaps = lines .Select(x => x.Split(',') .Select(range => range.Split('-').Select(int.Parse).ToList()) .ToList()) .Where(ranges => ranges[0][0] <= ranges[1][1] && ranges[1][0] <= ranges[0][1]) .ToList(); One = overlaps.Count(ranges => (ranges[0][0] <= ranges[1][0] && ranges[0][1] >= ranges[1][1]) || (ranges[1][0] <= ranges[0][0] && ranges[1][1] >= ranges[0][1])); Two = overlaps.Count; } }

Dold text
PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: C#

Gjorde tvÄ varianter pÄ del tvÄ för att se. Tycker Range varianten Àr snyggare Àn if-satserna men prestandamÀssigt Àr det "katastrof"

| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |---------- |-----------:|--------:|--------:|---------:|--------:|-----------:| | Run | 412.2 us | 6.83 us | 6.39 us | 52.7344 | 17.0898 | 418.45 KB | | Run_Range | 1,212.9 us | 3.49 us | 2.73 us | 294.9219 | 95.7031 | 2398.27 KB |

public override async Task A() { var result = (await File.ReadAllTextAsync(InputPath)) .Split(Environment.NewLine) .Select(l => l.Split(',')) .Sum(pair => { var (leftLower, leftUpper) = GetLowerUpper(pair, 0); var (rightLower, rightUpper) = GetLowerUpper(pair, 1); if ((leftLower >= rightLower && leftUpper <= rightUpper) || (rightLower >= leftLower && rightUpper <= leftUpper)) return 1; return 0; }); //Console.WriteLine(result); } public override async Task B() { var result = (await File.ReadAllTextAsync(InputPath)) .Split(Environment.NewLine) .Select(l => l.Split(',')) .Sum(pair => { //var left = ToRange(pair, 0); //var right = ToRange(pair, 1); //return left.Intersect(right).Any() ? 1 : 0; var (leftLower, leftUpper) = GetLowerUpper(pair, 0); var (rightLower, rightUpper) = GetLowerUpper(pair, 1); if ((leftLower >= rightLower && leftLower <= rightUpper) || (rightLower >= leftLower && rightLower <= leftUpper)) return 1; return 0; }); //Console.WriteLine(result); } private IEnumerable<int> ToRange(string[] pair, int index) { var split = pair[index].Split('-'); var x = int.Parse(split[0]); var y = int.Parse(split[1]); var range = Enumerable.Range(x, y - x + 1); return range; } private (int lower, int upper) GetLowerUpper(string[] pairs, int index) { var pair = pairs[index].Split('-'); return (int.Parse(pair[0]), int.Parse(pair[1])); }

Dold text
PermalÀnk
Datavetare ★
●
Skrivet av l4nky:

Dag: 4
SprÄk: C#

Gjorde tvÄ varianter pÄ del tvÄ för att se. Tycker Range varianten Àr snyggare Àn if-satserna men prestandamÀssigt Àr det "katastrof"

| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |---------- |-----------:|--------:|--------:|---------:|--------:|-----------:| | Run | 412.2 us | 6.83 us | 6.39 us | 52.7344 | 17.0898 | 418.45 KB | | Run_Range | 1,212.9 us | 3.49 us | 2.73 us | 294.9219 | 95.7031 | 2398.27 KB |

public override async Task A() { var result = (await File.ReadAllTextAsync(InputPath)) .Split(Environment.NewLine) .Select(l => l.Split(',')) .Sum(pair => { var (leftLower, leftUpper) = GetLowerUpper(pair, 0); var (rightLower, rightUpper) = GetLowerUpper(pair, 1); if ((leftLower >= rightLower && leftUpper <= rightUpper) || (rightLower >= leftLower && rightUpper <= leftUpper)) return 1; return 0; }); //Console.WriteLine(result); } public override async Task B() { var result = (await File.ReadAllTextAsync(InputPath)) .Split(Environment.NewLine) .Select(l => l.Split(',')) .Sum(pair => { //var left = ToRange(pair, 0); //var right = ToRange(pair, 1); //return left.Intersect(right).Any() ? 1 : 0; var (leftLower, leftUpper) = GetLowerUpper(pair, 0); var (rightLower, rightUpper) = GetLowerUpper(pair, 1); if ((leftLower >= rightLower && leftLower <= rightUpper) || (rightLower >= leftLower && rightLower <= leftUpper)) return 1; return 0; }); //Console.WriteLine(result); } private IEnumerable<int> ToRange(string[] pair, int index) { var split = pair[index].Split('-'); var x = int.Parse(split[0]); var y = int.Parse(split[1]); var range = Enumerable.Range(x, y - x + 1); return range; } private (int lower, int upper) GetLowerUpper(string[] pairs, int index) { var pair = pairs[index].Split('-'); return (int.Parse(pair[0]), int.Parse(pair[1])); }

Dold text

Har du med inlĂ€sning av fil/parsning av data i det (gissar att svaret Ă€r: "ja")? I annat fall Ă€r det mĂ€rkligt att skillnaden i prestanda Ă€r sĂ„ pass liten. Gissar att I/O i ditt fall Ă€r vĂ€ldigt nĂ€ra 100 % 412 ÎŒs som "if-sats" varianten tar.

MĂ€ter jag min Go lösning ovan tar sjĂ€lva berĂ€kningen tar en mycket liten del av CPU-tiden, övrigt Ă€r I/O (fillĂ€sning + fmt.Sscanf). BerĂ€kningen (med if-satser) tar ca 2,3 ÎŒs pĂ„ en M1 (vilket kan kapas till strax över hĂ€lften om man löser bĂ„da problemen samtidigt i stĂ€llet för i serie).

BTW: passar Äter igen pÄ att köra i ett för mig "nytt" sprÄk detta Är (har testat pÄ bl.a. Rust och Swift tidigare Är). Har precis börjat anvÀnda Go i arbetet, sÄ passar perfekt.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer

PermalÀnk
Medlem ★
●

Lite sen pÄ bollen men nu har jag kommit ikapp, provar Kotlin i Är.

Dag 1

val allElfCalories = File("src/input/day1.txt") .readText() .split("\r\n\r\n") .flatMap { it.split("\r\n").map { calorie -> calorie.toInt() } } .sortedDescending() println(allElfCalories.first()) println(allElfCalories.take(3).sum())

Dold text

Dag 2

private val part1 = mapOf( "A X" to 4, "A Y" to 8, "A Z" to 3, "B X" to 1, "B Y" to 5, "B Z" to 9, "C X" to 7, "C Y" to 2, "C Z" to 6 ) private val part2 = mapOf( "A X" to 3, "A Y" to 4, "A Z" to 8, "B X" to 1, "B Y" to 5, "B Z" to 9, "C X" to 2, "C Y" to 6, "C Z" to 7 ) fun run(){ val allPlayPoints = File("src/input/day2.txt") .readLines() val part1Answer = allPlayPoints.groupBy { it } .map { it.value.size * part1[it.key]!! } .sum() val part2Answer = allPlayPoints.groupBy { it } .map { it.value.size * part2[it.key]!! } .sum() println(part1Answer) println(part2Answer) }

Dold text

Dag 3

val rucksackContents = File("src/input/day3.txt") .readLines() val part1Answer = rucksackContents .flatMap { row -> val strFirstPartAsArray = row.substring(0, row.length / 2).toCharArray() val strSecondPartAsArray = row.substring(row.length/2).toCharArray() strFirstPartAsArray.intersect(strSecondPartAsArray.toSet()) .map { if (it.isLowerCase()) it.code - 96 else it.code - 38 } } val part2Answer = rucksackContents .chunked(3) .flatMap { chunk -> val firstElf = chunk[0].toCharArray() val secondElf = chunk[1].toCharArray() val thirdElf = chunk[2].toCharArray() firstElf.intersect(secondElf.toSet()).intersect(thirdElf.toSet()) .map { if (it.isLowerCase()) it.code - 96 else it.code - 38 } } println(part1Answer.sum()) println(part2Answer.sum())

Dold text

Dag 4

fun run() { val sectionPairs = File("src/input/day4.txt") .readLines() .map { row -> val pairs = row.split(",") Pair(buildSectionsArr(pairs[0]), buildSectionsArr(pairs[1])) } val part1Answer = sectionPairs.count { it.first.containsAll(it.second) || it.second.containsAll(it.first) } val part2Answer = sectionPairs.count { it.first.intersect(it.second).isNotEmpty() || it.second.intersect(it.first).isNotEmpty() } println(part1Answer) println(part2Answer) } private fun buildSectionsArr(sections: String): List<Int> { val startAndEnd = sections.split("-") val start = startAndEnd[0].toInt() val end = startAndEnd[1].toInt() return IntRange(start, end).toList() }

Dold text
PermalÀnk
Medlem
●

Dag: 4
SprÄk: Java
Lösning: Github

public class DayFour { public static void main(String[] args) { List<String> pair = new ArrayList<>(); try { File file = new File("C:\\AoC 22\\inputDay4.txt"); FileReader filereader = new FileReader(file); BufferedReader bufferedreader = new BufferedReader(filereader); String line; while((line = bufferedreader.readLine()) != null) { pair.add(line); } filereader.close(); } catch(IOException e) { e.printStackTrace(); } int counter = 0; for(int i = 0; i < pair.size(); i++) { String first = pair.get(i).substring(0,pair.get(i).indexOf(',')); String last = pair.get(i).substring(pair.get(i).indexOf(',')+1,pair.get(i).length()); int firstStart = Integer.parseInt(first.substring(0,first.indexOf('-'))); int firstEnd = Integer.parseInt(first.substring(first.indexOf('-')+1,first.length())); int lastStart = Integer.parseInt(last.substring(0,last.indexOf('-'))); int lastEnd = Integer.parseInt(last.substring(last.indexOf('-')+1,last.length())); if(firstStart >= lastStart && firstEnd <= lastEnd) { counter++; } else if(lastStart >= firstStart && lastEnd <= firstEnd) { counter++; } } System.out.println("amount of fully containing pairs: " + counter); int counterNew = 0; for(int i = 0; i < pair.size(); i++) { String first = pair.get(i).substring(0,pair.get(i).indexOf(',')); String last = pair.get(i).substring(pair.get(i).indexOf(',')+1,pair.get(i).length()); int firstStart = Integer.parseInt(first.substring(0,first.indexOf('-'))); int firstEnd = Integer.parseInt(first.substring(first.indexOf('-')+1,first.length())); int lastStart = Integer.parseInt(last.substring(0,last.indexOf('-'))); int lastEnd = Integer.parseInt(last.substring(last.indexOf('-')+1,last.length())); if((firstStart >= lastStart && firstStart <= lastEnd) || (firstEnd <= lastEnd && firstEnd >= lastStart)) { counterNew++; } else if(firstStart >= lastStart && firstEnd <= lastEnd) { counterNew++; } else if(lastStart >= firstStart && lastEnd <= firstEnd) { counterNew++; } } System.out.println("amount of overlapping pairs: " + counterNew); } }

Dold text
PermalÀnk
Medlem ★
●

Dag 4
SprÄk C#
Lite smÄpill pÄ del 2 nÀr jag fick rÀtt svar pÄ sample men inte pÄ input, men sÄ Àr det ju ibland...

using var sr = new StreamReader("input.txt"); int pt1score = 0; int pt2score = 0; while (!sr.EndOfStream) { var line = sr.ReadLine()!.Split(',').Select(x => x.Split('-').Select(int.Parse)); if ((line.First().First() >= line.Last().First() && line.First().Last() <= line.Last().Last()) || (line.Last().First() >= line.First().First() && line.Last().Last() <= line.First().Last())) { pt1score++; } if (int.Max(line.First().First(),line.Last().First()) <= int.Min(line.First().Last(), line.Last().Last())) { pt2score++; } } Console.WriteLine("Part 1 " + pt1score); Console.WriteLine("Part 2 " + pt2score);

Dold text
Visa signatur

The power of GNU compiles you!
"Often statistics are used as a drunken man uses lampposts -- for support rather than illumination."

PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: Kotlin

Även nĂ€r man inte försöker vara löjligt kompakt sĂ„ Ă€r Kotlins förbyggda funktioner helt underbara

println( input.lines().map { it.split(",").map { it.split("-") }.map { (it[0].toInt()..it[1].toInt()).toList()} }.count { it[0].containsAll(it[1]) || it[1].containsAll(it[0]) }) println(input.lines().map { line -> line.split(",").map { elf -> elf.split("-") }.map { (it[0].toInt()..it[1].toInt()).toList()} } .count {pair -> (pair[0] + pair[1]).size != ((pair[0] + pair[1]).toSet().size)})

Dold text
Visa signatur

i5-7600k . GTX 1080 . 16 GB

PermalÀnk
Medlem ★
●
Skrivet av Yoshman:

Har du med inlĂ€sning av fil/parsning av data i det (gissar att svaret Ă€r: "ja")? I annat fall Ă€r det mĂ€rkligt att skillnaden i prestanda Ă€r sĂ„ pass liten. Gissar att I/O i ditt fall Ă€r vĂ€ldigt nĂ€ra 100 % 412 ÎŒs som "if-sats" varianten tar.

MĂ€ter jag min Go lösning ovan tar sjĂ€lva berĂ€kningen tar en mycket liten del av CPU-tiden, övrigt Ă€r I/O (fillĂ€sning + fmt.Sscanf). BerĂ€kningen (med if-satser) tar ca 2,3 ÎŒs pĂ„ en M1 (vilket kan kapas till strax över hĂ€lften om man löser bĂ„da problemen samtidigt i stĂ€llet för i serie).

BTW: passar Äter igen pÄ att köra i ett för mig "nytt" sprÄk detta Är (har testat pÄ bl.a. Rust och Swift tidigare Är). Har precis börjat anvÀnda Go i arbetet, sÄ passar perfekt.

HÀr Àr bench utan IO. Det intressanta Àr att int.Parse Àr det som tar mest tid i bÄda fallen(utöver IO dÄ). Vid profilering tar int.Parse 19ms för icke range versionen och 28ms för range versionen. Trodde ocksÄ det skulle ta mycket lÀngre tid med skapandet av alla enumerables och sen iteration i intersect. Men tydligen inte.

| Method | Mean | Error | StdDev | Gen0 | Gen1 | Allocated | |-------- |-----------:|---------:|---------:|---------:|--------:|-----------:| | B | 219.7 us | 3.40 us | 3.18 us | 42.9688 | 6.5918 | 352.77 KB | | B_Range | 1,085.9 us | 20.68 us | 19.35 us | 285.1563 | 46.8750 | 2332.59 KB |

Lite större ranges sÄ blir det lite tydligare HÀr Àr resultatet med 1-1000000,1-1000000 * 1000 rader

| Method | Mean | Error | StdDev | Gen0 | Gen1 | Gen2 | Allocated | |-------- |----------------:|--------------:|--------------:|------------:|------------:|------------:|--------------:| | B | 226.2 us | 1.96 us | 1.74 us | 47.6074 | 9.2773 | - | 390.78 KB | | B_Range | 22,869,480.4 us | 449,556.06 us | 420,515.02 us | 980000.0000 | 954000.0000 | 952000.0000 | 42101876.7 KB |

La till större datamÀngder
PermalÀnk
Medlem
●

Dag: 2
SprÄk: C
Lösning:

#include <stdio.h> #define ROW_LEN_MAX 5 enum { PART_ONE, PART_TWO } part; __uint8_t getIndex(char inp) { if (inp == 'A' || inp == 'X') { return 0; } else if (inp == 'B' || inp == 'Y') { return 1; } return 2; } __uint8_t getIndexFromRes(__uint8_t inp, char res) { if (res == 'Y') { return inp; } else if (res == 'X') { return (inp > 0)? (inp - 1) : 2; } return (inp < 2)? (inp + 1) : 0; } __uint16_t* solve_day_02() { __uint8_t pointsTable[3][3] = { {4, 8, 3}, {1, 5, 9}, {7, 2, 6} }; FILE* inputFile; char lineBuf[ROW_LEN_MAX]; char you, me; static __uint16_t points[2] = {0, 0}; inputFile = fopen("input/day_02.txt", "r"); while(fgets(lineBuf, ROW_LEN_MAX, inputFile)) { you = getIndex(lineBuf[0]); me = getIndex(lineBuf[2]); points[PART_ONE] += pointsTable[you][me]; me = getIndexFromRes(you, lineBuf[2]); points[PART_TWO] += pointsTable[you][me]; } fclose(inputFile); return &points[0]; } int main(void) { __uint16_t* res = solve_day_02(); printf("**AoC-2022 day 2 part 1: %d **\n", res[PART_ONE]); printf("**AoC-2022 day 2 part 2: %d **\n", res[PART_TWO]); }

Dold text

Impad av @That Maniacs lösning!

PermalÀnk
●

Dag 4
SprÄk: Rust
Lösning: Github

Försökte fÄ splitten med filter och sÄnt att spotta ut i32 direkt, men fastnade för lÀnge sÄ fick bli lite fulare lösning.

use std::fs; pub fn run() { let data = fs::read_to_string("dec_04.txt").expect("unable to read file"); let mut overlaps = 0; let mut contains = 0; for line in data.lines() { let pairs: Vec<&str> = line.split(|c| c == '-' || c == ',').collect(); let a1 = pairs[0].parse::<i32>().unwrap(); let a2 = pairs[1].parse::<i32>().unwrap(); let b1 = pairs[2].parse::<i32>().unwrap(); let b2 = pairs[3].parse::<i32>().unwrap(); if overlaps_at_all(a1, a2, b1, b2) { overlaps += 1; } if fully_contain(a1, a2, b1, b2) { contains += 1; } } println!("Part1 = {}", contains); println!("Part2 = {}", overlaps); } fn overlaps_at_all(a1: i32, a2: i32, b1: i32, b2: i32) -> bool { //If a ends in range b //Or a begins in range b //Or a is fully contained by b if a2 >= b1 && b2 >= a2 { return true; } else if a1 >= b1 && b2 >= a1 { return true; } else if a1 <= b1 && b2 <= a2 { return true; } else { return false; } } fn fully_contain(a1: i32, a2: i32, b1: i32, b2: i32) -> bool { if a1 <= b1 && b2 <= a2 { return true; } else if b1 <= a1 && a2 <= b2 { return true; } else { return false; } }

Dold text

Redigering: Sneglade pÄ nÄgra lösningar och fick fram den filter funktionen jag ville ha.

use std::fs; pub fn run() { let data = fs::read_to_string("dec_04.txt").expect("unable to read file"); let mut overlaps = 0; let mut contains = 0; for line in data.lines() { let pairs: Vec<i32> = line .split(|c| c == '-' || c == ',') .filter_map(|s| s.parse::<i32>().ok()) .collect(); if overlaps_at_all(pairs[0], pairs[1], pairs[2], pairs[3]) { overlaps += 1; } if fully_contain(pairs[0], pairs[1], pairs[2], pairs[3]) { contains += 1; } } println!("Part1 = {}", contains); println!("Part2 = {}", overlaps); } fn overlaps_at_all(a1: i32, a2: i32, b1: i32, b2: i32) -> bool { //If a ends in range b //Or a begins in range b //Or a is fully contained by b if a2 >= b1 && b2 >= a2 { return true; } else if a1 >= b1 && b2 >= a1 { return true; } else if a1 <= b1 && b2 <= a2 { return true; } else { return false; } } fn fully_contain(a1: i32, a2: i32, b1: i32, b2: i32) -> bool { if a1 <= b1 && b2 <= a2 { return true; } else if b1 <= a1 && a2 <= b2 { return true; } else { return false; } }

Dold text
PermalÀnk
Medlem
●

Dag: 3
SprÄk: C
Lösning:

#include <stdio.h> #include <string.h> #include "common.h" #define MAX_ROW_LEN 64 __uint16_t* solve_day_03(void) { static __uint16_t result[2] = {0, 0}; FILE* inputFile; char lineBuf[MAX_ROW_LEN]; __uint64_t chars[2]; __uint64_t group = ~0; __uint8_t prio; __uint8_t numInGroup = 0; inputFile = fopen("input/day_03.txt", "r"); while (fgets(lineBuf, MAX_ROW_LEN, inputFile)) { numInGroup++; chars[0] = 0; chars[1] = 0; for (int i = 0, n = strlen(lineBuf)-1; i < n; i++) { prio = (lineBuf[i] >= 'a')? (lineBuf[i] - 96) : (lineBuf[i] - 38); chars[i/(n/2)] |= (1ULL << prio); if ((chars[0] & chars[1]) && !(chars[0] & 1ULL)) { result[0] += prio; chars[0] |= 1ULL; } } chars[0] &= ~1ULL; group &= (chars[0] |= chars[1]); if (numInGroup == 3) { numInGroup = 0; for (int i = 1; i < 53; i ++) { if (group & (1ULL << i)) { result[1] += i; break; } } group = ~0; } } return &result[0]; } int main(void) { __uint16_t* res = solve_day_03(); printf("**AoC-2022 day 2 part 1: %d **\n", res[PART_ONE]); printf("**AoC-2022 day 2 part 2: %d **\n", res[PART_TWO]); solve_day_03(); }

Dold text
PermalÀnk
Medlem
●

Min första advent of code, kul grej. Jag blev vÀldigt hooked och vÀntar pÄ nÀsta dag.
Kör i C++ men orkar inte dela min kod som Àr ganska osnygg, men det Àr ocksÄ tjusningen, man skulle kunna sitta med penna och papper för att lösa problemen. Blir ingen time out för din lösning inte Àr optimerade.
FÄr se hur lÀnge jag hÀnger pÄ.

PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: Elixir
Lösning: Github

Visa signatur

AMD Ryzen 7 1700X 3.8 GHz 20MB | ASUS PRIME X370-PRO | MSI GeForce GTX 1080 Gaming X 8GB | G.Skill 16GB DDR4 3200 MHz CL14 Flare X | Corsair RM650x 650W

PermalÀnk
Medlem
●

Dag: 4
SprÄk: Python

with open('Day4/data.txt') as file: data = file.readlines() sunbset = 0 intersect = 0 for pairs in data: pairs = pairs.strip().replace("-",",").split(",") first_area = range(int(pairs[0]), int(pairs[1])+1) second_area = range(int(pairs[2]), int(pairs[3])+1) if set(first_area).issubset(second_area) or set(second_area).issubset(first_area): sunbset+=1 if len(set(first_area).intersection(second_area)) > 0: intersect+=1 print(sunbset) #Part 1 print(intersect) #Part 2

Dold text
PermalÀnk
Medlem
●
Skrivet av Yoshman:

Har du med inlĂ€sning av fil/parsning av data i det (gissar att svaret Ă€r: "ja")? I annat fall Ă€r det mĂ€rkligt att skillnaden i prestanda Ă€r sĂ„ pass liten. Gissar att I/O i ditt fall Ă€r vĂ€ldigt nĂ€ra 100 % 412 ÎŒs som "if-sats" varianten tar.

MĂ€ter jag min Go lösning ovan tar sjĂ€lva berĂ€kningen tar en mycket liten del av CPU-tiden, övrigt Ă€r I/O (fillĂ€sning + fmt.Sscanf). BerĂ€kningen (med if-satser) tar ca 2,3 ÎŒs pĂ„ en M1 (vilket kan kapas till strax över hĂ€lften om man löser bĂ„da problemen samtidigt i stĂ€llet för i serie).

BTW: passar Äter igen pÄ att köra i ett för mig "nytt" sprÄk detta Är (har testat pÄ bl.a. Rust och Swift tidigare Är). Har precis börjat anvÀnda Go i arbetet, sÄ passar perfekt.

Borde inte din M1 vara överlÀgsen min MBP2017, 15"?

go test -bench=. ./... goos: darwin goarch: amd64 pkg: aoc2022/04/a cpu: Intel(R) Core(TM) i7-7920HQ CPU @ 3.10GHz BenchmarkPartOne-8 1053571 1083 ns/op BenchmarkPartTwo-8 959959 1102 ns/op BenchmarkPartTwoUsingArray-8 31125 37462 ns/op BenchmarkPartTwoUsingSet-8 777 1619922 ns/op PASS ok aoc2022/04/a 6.211s

Dag: 4

main.go

package main import ( "bufio" "fmt" "os" ) type Section struct { Start int End int } type Pair struct { First Section Second Section } func getPartOne(pairs []Pair) int { count := 0 for _, pair := range pairs { if (pair.First.Start <= pair.Second.Start && pair.Second.End <= pair.First.End) || (pair.Second.Start <= pair.First.Start && pair.First.End <= pair.Second.End) { count++ } } return count } func getPartTwo(pairs []Pair) int { count := 0 for _, pair := range pairs { if (pair.First.Start <= pair.Second.Start && pair.First.End >= pair.Second.Start) || (pair.Second.Start <= pair.First.Start && pair.Second.End >= pair.First.Start) { count++ } } return count } func getPartTwoUsingArray(pairs []Pair) int { count := 0 for _, pair := range pairs { numbers := make([]bool, 100) for j := pair.First.Start; j <= pair.First.End; j++ { numbers[j] = true } for j := pair.Second.Start; j <= pair.Second.End; j++ { if numbers[j] { count++ break } } } return count } func getPartTwoUsingSet(pairs []Pair) int { count := 0 for _, pair := range pairs { numbers := make(map[int]bool, getMax(pair.First.End, pair.Second.End)) for j := pair.First.Start; j <= pair.First.End; j++ { numbers[j] = true } for j := pair.Second.Start; j <= pair.Second.End; j++ { if _, ok := numbers[j]; ok { count++ break } } } return count } func getMax(a int, b int) int { if a > b { return a + 1 } return b + 1 } func getRows(filename string) []Pair { file, err := os.Open(filename) if err != nil { panic(err) } defer file.Close() scanner := bufio.NewScanner(file) rows := make([]Pair, 0) for scanner.Scan() { pair := Pair{} fmt.Sscanf(scanner.Text(), "%d-%d,%d-%d", &pair.First.Start, &pair.First.End, &pair.Second.Start, &pair.Second.End) rows = append(rows, pair) } return rows } func main() { fmt.Println("Part one:", getPartOne(getRows("../input.txt"))) fmt.Println("Part two:", getPartTwo(getRows("../input.txt"))) }

main_test.go

package main import "testing" func BenchmarkPartOne(b *testing.B) { // run the Fib function b.N times rows := getRows("../input.txt") for n := 0; n < b.N; n++ { getPartOne(rows) } } func BenchmarkPartTwo(b *testing.B) { // run the Fib function b.N times rows := getRows("../input.txt") for n := 0; n < b.N; n++ { getPartTwo(rows) } } func BenchmarkPartTwoUsingArray(b *testing.B) { // run the Fib function b.N times rows := getRows("../input.txt") for n := 0; n < b.N; n++ { getPartTwoUsingArray(rows) } } func BenchmarkPartTwoUsingSet(b *testing.B) { // run the Fib function b.N times rows := getRows("../input.txt") for n := 0; n < b.N; n++ { getPartTwoUsingSet(rows) } }

Dold text
Utökade med set
PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: C++

#include "../AoCHelper/AoCHelper.h" #include <vector> std::vector<std::string> split(const std::string &s, char delimiter) { std::vector<std::string> tokens; std::string token; std::istringstream tokenStream(s); while (std::getline(tokenStream, token, delimiter)) { tokens.push_back(token); } return tokens; } void puzzle_one(std::vector<std::string> input) { int answer{}; for (std::string row : input) { std::vector<std::string> elfs = split(row, ','); std::string firstElf = elfs[0]; std::string secondElf = elfs[1]; int firstElfStart{std::stoi(split(firstElf, '-')[0])}; int firstElfEnd{std::stoi(split(firstElf, '-')[1])}; int secondElfStart{std::stoi(split(secondElf, '-')[0])}; int secondElfEnd{std::stoi(split(secondElf, '-')[1])}; if (firstElfStart <= secondElfStart && firstElfEnd >= secondElfEnd) { answer++; } else if (secondElfStart <= firstElfStart && secondElfEnd >= firstElfEnd) { answer++; } } std::cout << "Puzzle one: " << answer << std::endl; } void puzzle_two(std::vector<std::string> input) { int answer{}; for (std::string row : input) { std::vector<std::string> elfs = split(row, ','); std::string firstElf = elfs[0]; std::string secondElf = elfs[1]; int firstElfStart{std::stoi(split(firstElf, '-')[0])}; int firstElfEnd{std::stoi(split(firstElf, '-')[1])}; int secondElfStart{std::stoi(split(secondElf, '-')[0])}; int secondElfEnd{std::stoi(split(secondElf, '-')[1])}; if (firstElfStart >= secondElfStart && firstElfStart <= secondElfEnd) { answer++; } else if (secondElfStart >= firstElfStart && secondElfStart <= firstElfEnd) { answer++; } } std::cout << "Puzzle two: " << answer << std::endl; } int main() { std::vector<std::string> exampleInput{"2-4,6-8", "2-3,4-5", "5-7,7-9", "2-8,3-7", "6-6,4-6", "2-6,4-8"}; AoCHelper a1{"2022", "4"}; std::vector<std::string> result = a1.get_input(); puzzle_one(result); puzzle_two(result); }

Dold text
PermalÀnk
Medlem ★
●

Dag:4
SprÄk: Go

type elf struct { minSegmentID, maxSegmentID int } func main() { lines, err := helpers.ReadLines(os.Args[1]) if err != nil { panic(err) } fullOverlapse := 0 overlapseAtAll := 0 for _, line := range lines { l := strings.Split(line, ",") r1, r2 := strings.Split(l[0], "-"), strings.Split(l[1], "-") elf1 := elf{minSegmentID: helpers.GetInt(r1[0]), maxSegmentID: helpers.GetInt(r1[1])} elf2 := elf{minSegmentID: helpers.GetInt(r2[0]), maxSegmentID: helpers.GetInt(r2[1])} if elf1.minSegmentID <= elf2.minSegmentID && elf1.maxSegmentID >= elf2.maxSegmentID { fullOverlapse++ } else if elf2.minSegmentID <= elf1.minSegmentID && elf2.maxSegmentID >= elf1.maxSegmentID { fullOverlapse++ } if elf1.minSegmentID >= elf2.minSegmentID && elf1.minSegmentID <= elf2.maxSegmentID { overlapseAtAll++ } else if elf2.minSegmentID >= elf1.minSegmentID && elf2.minSegmentID <= elf1.maxSegmentID { overlapseAtAll++ } } fmt.Println(fullOverlapse) fmt.Println(overlapseAtAll) }

Dold text
PermalÀnk
Medlem
●
Skrivet av fredda11:

Tycker din lösning för dag 3 var snygg. Men hÀnger inte riktigt med pÄ hur alla bit operationer gÄr ihop sig, har du lust att förklara?

Vet inte riktigt vad du vill veta men tanken Àr att bit 0-25 representerar A-Z och bit 32->57 a-z.
exempel: ADBDCCBB ger bitmönster fack 1: 0b1011 och fack 2: 0b0110
Det gÄr alltsÄ inte att veta hur mÄnga av varje som finns men i det hÀr fallet behövdes det inte.
För att veta vad som finns i bÀgge facken anvÀnds bitvis AND vilket ger 0b0010 som betyder B.
ffs returnerar bitnummer för första etta sett frÄn minst signifikanta bit sÄ om man arrangerar input rÀtt sÄ blir det ocksÄ bokstavens prioritet.

Dag 3 lösningsförslag
PermalÀnk
Medlem
●

Dag: 4
SprÄk: C

#include <errno.h> #include <inttypes.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define GENMASK(h, l) \ (((~((__uint128_t)0)) - (((__uint128_t)1) << (l)) + 1) & \ (~((__uint128_t)0) >> (8*sizeof(__uint128_t) - 1 - (h)))) int parseInt(const char *str) { char *endptr; int ret; errno = 0; ret = strtol(str, &endptr, 10); if (errno != 0) { perror("Failed to parse string"); exit(EXIT_FAILURE); } if (endptr == str) { fprintf(stderr, "No digits were found\n"); exit(EXIT_FAILURE); } if (*endptr != '\0') printf("Warning: further characters after number: \"%s\"\n", endptr); return ret; } __uint128_t getBitMask(char *assignment) { int start, stop; char *tok; tok = strtok(assignment, "-\n"); if (!tok) exit(EXIT_FAILURE); start = parseInt(tok); tok = strtok(NULL, "-\n"); if (!tok) exit(EXIT_FAILURE); stop = parseInt(tok); return GENMASK(stop, start); } int main(void) { char *line = NULL; size_t len = 0; ssize_t nread; uint32_t totalCompleteOverlaps = 0; uint32_t totalAnyOverlaps = 0; FILE *fp = fopen("d4_input.txt", "r"); if (!fp) { perror("Failed to open file"); exit(EXIT_FAILURE); } while ((nread = getline(&line, &len, fp)) != -1) { char *assignment, *state; __uint128_t first, second, overlap; assignment = strtok_r(line, ",\n", &state); first = getBitMask(assignment); assignment = strtok_r(NULL, ",\n", &state); second = getBitMask(assignment); overlap = first & second; if (overlap == first || overlap == second) totalCompleteOverlaps += 1; // Part 2 if (overlap) totalAnyOverlaps += 1; } free(line); fclose(fp); printf("Total complete overlappings: %"PRIu32"\n", totalCompleteOverlaps); printf("Total any overlappings: %"PRIu32"\n", totalAnyOverlaps); exit(EXIT_SUCCESS); }

Dold text
PermalÀnk
Medlem ★
●

Dag: 4
SprÄk: Rust

Tycker nog den hÀr var enklare Àn flera av de förra, men i steg tvÄ fick man hÄlla tungan rÀtt i mun med de logiska operationerna.

fn calculate_one(l1: u32, h1: u32, l2: u32, h2: u32) -> usize { return (l1 >= l2 && h1 <= h2 || l2 >= l1 && h2 <= h1) as usize; } fn calculate_two(l1: u32, h1: u32, l2: u32, h2: u32) -> usize { return ((l2 <= h1 && l2 >= l1) || (h2 >= l1 && h2 <= h1) || (l1 <= h2 && l1 >= l2) || (h1 >= l2 && h1 <= h2)) as usize; } fn main() { let input = include_str!("./input.txt"); let mut total_score1 = 0; let mut total_score2 = 0; for line in input.lines() { let split: Vec<&str> = line.split(",").collect(); let first: Vec<&str> = split[0].split("-").collect(); let second: Vec<&str> = split[1].split("-").collect(); total_score1 += calculate_one( first[0].parse::<u32>().unwrap(), first[1].parse::<u32>().unwrap(), second[0].parse::<u32>().unwrap(), second[1].parse::<u32>().unwrap(), ); total_score2 += calculate_two( first[0].parse::<u32>().unwrap(), first[1].parse::<u32>().unwrap(), second[0].parse::<u32>().unwrap(), second[1].parse::<u32>().unwrap(), ); } println!("Total Score 1 {}", total_score1); println!("Total Score 2 {}", total_score2); }

Dold text