đŸ•Żïž Advent of Code 2019 đŸ•Żïž

PermalÀnk
Datavetare ★
●

Rust - dag 10

Sent svar idag p.g.a. julmiddag, Àr en imorgon ocksÄ...

Inte vÀrldens elegantaste lösning, men rÀtt svar i alla fall. AnvÀnder gcd() (största gemensamma nÀmnare) för att rÀkna ut riktningsvektorn till alla asteroider frÄn vald punkt för laserkanonen, det gör att alla asteroider utefter samma linje Àr garanterade att fÄ samma riktningsvektor. Sorterar allt efter detta, roterar det hela sÄ uppÄt fÄr lÀgsta vÀrde och tar bort duplikat. GÄr sedan runt i arrayen med riktningsvektorer och tar bort asteroider till det att 200 st Àr borttagna.

use super::Solution; use std::collections::HashSet; use MapContent::*; #[derive(PartialEq, Debug)] enum MapContent { Space, Astroid, } type Coord = (i32, i32); #[derive(Clone, Copy)] struct Visible { pos: Coord, count: usize, } // State required to solve day 10 pub struct State { map: Vec<Vec<MapContent>>, } fn is_on_map(pos: Coord, width: i32, height: i32) -> bool { pos.0 >= 0 && pos.1 >= 0 && pos.0 < width && pos.1 < height } fn hit( map: &Vec<Vec<MapContent>>, removed: &HashSet<Coord>, origin: Coord, dir: Coord, ) -> Option<Coord> { let mut pos = origin; loop { pos.0 = pos.0 + dir.0; pos.1 = pos.1 + dir.1; if !is_on_map(pos, map[0].len() as i32, map.len() as i32) { return None; } if !removed.contains(&pos) && map[pos.1 as usize][pos.0 as usize] == Astroid { return Some(pos); } } } fn is_visible(map: &Vec<Vec<MapContent>>, from: Coord, to: Coord, dir: Coord) -> bool { if let Some(pos) = hit(map, &HashSet::new(), from, dir) { if pos == to { return true } } false } fn dir_vector(base: Coord, pos: Coord) -> Coord { let dx = pos.0 - base.0; let dy = pos.1 - base.1; let gcd = num::integer::gcd(dx, dy); (dx / gcd, dy / gcd) } fn count_visible(map: &Vec<Vec<MapContent>>, pos: Coord) -> usize { let mut count = 0; for row in 0..map.len() { let y = row as i32; for col in 0..map[row].len() { let x = col as i32; if map[row][col] == Astroid && (x != pos.0 || y != pos.1) { if is_visible(map, pos, (x, y), dir_vector(pos, (x, y))) { count = count + 1; } } } } count } fn to_visibles(map: &Vec<Vec<MapContent>>) -> Vec<Visible> { let mut v = Vec::new(); for row in 0..map.len() { let y = row as i32; for col in 0..map[row].len() { let x = col as i32; if map[row][col] == Astroid { v.push(Visible { pos: (x, y), count: count_visible(map, (x, y)), }); } } } v } fn select_best_astroid(map: &Vec<Vec<MapContent>>) -> Visible { *to_visibles(map) .iter() .max_by(|a, b| a.count.cmp(&b.count)) .unwrap() } fn angle(pos: Coord) -> f64 { let a = (-pos.1 as f64).atan2(-pos.0 as f64) * 180.0 / 3.1415; if a < 90.0 { a + 360.0 } else { a } } fn unique_dir_vecs(map: &Vec<Vec<MapContent>>, laser_pos: Coord) -> Vec<Coord> { let mut dir_vecs = Vec::new(); for row in 0..map.len() { for col in 0..map[row].len() { let pos = (col as i32, row as i32); if map[row][col] == Astroid && laser_pos != pos { dir_vecs.push(dir_vector(laser_pos, pos)); } } } dir_vecs.sort_by(|&a, &b| angle(a).partial_cmp(&angle(b)).unwrap()); dir_vecs.dedup(); dir_vecs } fn nth_destroyed(nth: usize, map: &Vec<Vec<MapContent>>, laser_pos: Coord) -> Coord { let mut removed = HashSet::new(); let dir_vecs = unique_dir_vecs(&map, laser_pos); let mut n = nth; let mut dir_it = dir_vecs.iter().cycle(); loop { let &dir = dir_it.next().unwrap(); if let Some(pos) = hit(&map, &removed, laser_pos, dir) { removed.insert(pos); n = n - 1; if n == 0 { return pos; } } } } impl Solution for State { fn part1(&self) -> String { select_best_astroid(&self.map).count.to_string() } fn part2(&self) -> String { let best = select_best_astroid(&self.map).pos; let pos = nth_destroyed(200, &self.map, best); (pos.0 * 100 + pos.1).to_string() } } pub fn solution(lines: Vec<&str>) -> Box<dyn Solution> { Box::new(State { map: lines .iter() .map(|&row| { row.chars() .map(|pos| if pos == '.' { Space } else { Astroid }) .collect() }) .collect(), }) }

Lite av en brute-force lösning men ÀndÄ avklarad pÄ 20 ms pÄ en i7-5600U

fss

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 ★
●

Lugnare dag idag, men man börjar se ett mönster
* lÀgg till instruktinen reset till intcode som ÄsterstÀller alla fÀlt i programmet men fortsÀtter exekvera pÄ nuvarande position
* lÀgg till mode4 som istÀllet adresserar ett program i en annan intcode computer som körs parallellt, kör 10 program parallellt
* reset kan nu ta en parameter, reset 10 backar programkoden 10 steg. Kör program som kan backa tusentals steg
* allt ovan kör 100 parallella program som kan backa 1000-tals steg

PermalÀnk
●

Dag 10 i Kotlin

Satt uppe lite vÀl sent för att fixa denna igÄr, har tidigare Är haft problem med att bli smÄtt besatt och inte kan gÄ ivÀg frÄn problemet innan det Àr helt löst. Det har pÄverkat sömn och andra viktigare saker att göra. FÄr försöka ha bÀttre karaktÀr och slÀppa problemen efter en viss tid och fortsÀtta en annan dag istÀllet, annars fÄr jag nog lÀgga ner

Reflektion:

GrÀvde mig ner i en grop som till 99.9% fungerade sÄ hade svÄrt att slÀppa den och bankade huvudet mot skÀrmen innan jag kom pÄ att man kan anvÀnda atan2 rakt av.

Dold text

fun buildMap(input: Iterable<String>): Set<Pair<Int, Int>> { return input.withIndex().fold(setOf()) { acc, indexedRow -> indexedRow.value.withIndex().fold(acc) { accInner, indexedValue -> when (indexedValue.value) { '#' -> accInner + setOf(Pair(indexedValue.index, indexedRow.index)) '.' -> accInner else -> throw IllegalStateException() } } } } fun maxLineOfSight(asteroidMap: Set<Pair<Int, Int>>): Triple<Int, Int, Int>? = asteroidMap.map { (x, y) -> val angles = asteroidMap.fold(setOf<Double>()) { acc, (xx, yy) -> if (x == xx && y == yy) acc else acc + atan2(y.toDouble() - yy, x.toDouble() - xx) } Triple(x, y, angles.size) }.maxBy { it.third } fun part1(input: Iterable<String>): Triple<Int, Int, Int>? = maxLineOfSight(buildMap(input)) fun part2(input: Iterable<String>): List<Pair<Int, Int>> { val asteroidMap = buildMap(input) val (targetX, targetY, _) = maxLineOfSight(asteroidMap)!! val targetsByAngle = asteroidMap .fold(mapOf<Double, List<Pair<Int, Int>>>()) { acc, (x, y) -> if (x == targetX && y == targetY) acc else { val angle = atan2(y.toDouble() - targetY, x.toDouble() - targetX) acc + Pair(angle, (acc[angle] ?: listOf()) + Pair(x, y)) } } .toList() .sortedBy { it.first } val start = targetsByAngle.dropWhile { (angle, _) -> angle < -Math.PI / 2 } val end = targetsByAngle.takeWhile { (angle, _) -> angle < -Math.PI / 2 } val fireOrder = (start + end) .map { it.second .sortedBy { (x, y) -> sqrt((x.toDouble() - targetX).pow(2) + (y.toDouble() - targetY).pow(2)) } .toMutableList() } .toMutableList() val result = mutableListOf<Pair<Int, Int>>() while (fireOrder.isNotEmpty()) { fireOrder.forEach { result.add(it.removeAt(0)) } fireOrder.removeIf { it.isEmpty() } } return result }

Dold text
Visa signatur

"Knowledge amplification. What he learns, we all learn. What he knows, we all benefit from."

PermalÀnk
Medlem ★
●

Dag 11 Uppgift 1&2
SprÄk C#
IntCode behövde ej uppdateras. Snodde Yoshmans teckenbaserade lösning för att skippa bitmap.

private void button11_Click(object sender, EventArgs e) { string input = DailyInput.GetInput(11); System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew(); IntCode robot = new IntCode(input); Dictionary<string, ByteColor> hull = new Dictionary<string, ByteColor>(); HullCoord curPos = new HullCoord(0, 0); bool llContinue = true; int x = 0; int y = 0; if (this.numSubTask.Value==1) { hull.Add(curPos.ToString(), ByteColor.Black); } else { hull.Add(curPos.ToString(), ByteColor.White); } while (llContinue) { if (!hull.ContainsKey(curPos.ToString())) { hull.Add(curPos.ToString(), ByteColor.Black); } robot.AddInput((long)hull[curPos.ToString()]); long? colCode = robot.Compute(); if (colCode!=null) { hull[curPos.ToString()] = (ByteColor)colCode; long? turnCode = robot.Compute(); if (turnCode!=null) { curPos.Turn((TurnDirection)turnCode); curPos.Step(); } else { llContinue = false; } } else { llContinue = false; } } if (!robot.EndedCorrectly) { throw new Exception("Never got end code"); } if (this.numSubTask.Value==1) { this.txtAnswer.Text = hull.Count().ToString(); } else { Dictionary<ByteColor, string> colorCharacter = new Dictionary<ByteColor, string>(); colorCharacter.Add(ByteColor.Black, "█"); colorCharacter.Add(ByteColor.White, "▒"); colorCharacter.Add(ByteColor.Transparent, "."); int minx = 0; int miny = 0; int maxx = 0; int maxy = 0; foreach (KeyValuePair<string,ByteColor> item in hull) { HullCoord curCord = new HullCoord(item.Key); if (curCord.x<minx) { minx = curCord.x; } if (curCord.y<miny) { miny = curCord.y; } if (curCord.x>maxx) { maxx = curCord.x; } if (curCord.y>maxy) { maxy = curCord.y; } } int offsetx = 0 - minx; int offsety = 0 - miny; int width = maxx - minx +1; int height = maxy-miny +1; ByteColor[,] image = new ByteColor[width, height]; txtDebug.Clear(); for (int iy = 0; iy < height; iy++) { for (int ix = 0; ix < width; ix++) { string cCoord = (ix + offsetx).ToString() + "," + (iy + offsety).ToString(); image[ix, iy] = ByteColor.Black; if (hull.ContainsKey(cCoord)) { image[ix, iy] = hull[cCoord]; } txtDebug.AppendText(colorCharacter[image[ix, iy]]); } txtDebug.AppendText(System.Environment.NewLine); } } watch.Stop(); Int64 elapsedMs = watch.ElapsedMilliseconds; label1.Text = elapsedMs.ToString(); }

Dold text
PermalÀnk
Medlem
●

Dag: 11
SprÄk: Haskell

Trodde att vi skulle vara klara med Intcode, men nu var det iallafall bara applikation av den, och inte (nödvÀndigtvis) nÄgot direkt vidarearbete.

Fick Äterigen tillfÀlle att skriva en (enligt mig) snygg lösning mha. laziness i del 1. SÄnt e skoj!

type Pos = (Int, Int) part1 :: IO Int part1 = fmap (fst . paintShip Set.empty . parse) readInput part2 :: IO () part2 = putStrLn . drawHull . snd . paintShip (Set.singleton (0, 0)) . parse =<< readInput where drawHull h = let h' = Set.toList h (xs, ys) = (map fst h', map snd h') (bot, top) = (minimum ys, maximum ys) (left, right) = (minimum xs, maximum xs) in unlines $ flip map (reverse [bot .. top]) $ \y -> flip map [left .. right] $ \x -> if Set.member (x, y) h then '█' else ' ' paintShip :: Set Pos -> Mem -> (Int, Set Pos) paintShip initHull pgm = let os = run is pgm (colors, turns) = unzip (map head2 (chunksOf 2 os)) up = (0, 1) (poss, _) = unzip (scanl move ((0, 0), up) turns) hulls = scanl paint initHull (zip colors poss) is = zipWith (fromEnum .* Set.member) poss hulls nPanelsVisited = Set.size (Set.fromList poss) in (nPanelsVisited, last hulls) where move :: ((Int, Int), (Int, Int)) -> Int -> ((Int, Int), (Int, Int)) move (pos, dir) = \case 0 -> let dir' = turnLeft dir in (addPos pos dir', dir') _ -> let dir' = turnRight dir in (addPos pos dir', dir') turnLeft (dx, dy) = (-dy, dx) turnRight (dx, dy) = (dy, -dx) addPos (x, y) (dx, dy) = (x + dx, y + dy) paint hull (c, pos) = case c of 0 -> Set.delete pos hull _ -> Set.insert pos hull

Dold text
Visa signatur

Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4

PermalÀnk
Datavetare ★
●

Rust - day 11

type Coord = (i32, i32); #[derive(Clone, Copy, Debug, PartialEq)] enum Paint { Black, White, } fn paint_hull(program: &Vec<Intcode>, start_tile_col: Paint) -> HashMap<Coord, Paint> { let (input, sink) = channel(); let output = exec(program, sink, None); let mut hull = HashMap::new(); let mut pos = (0, 0); let mut dir = (0, 1); // Facing up let mut color_cur_tile = start_tile_col; loop { if let Err(_) = input.send(if color_cur_tile == Paint::Black { 0 } else { 1 }) { break; }; let color = if let Ok(col) = output.recv() { if col == 0 { Paint::Black } else { Paint::White } } else { break; }; dir = match output.recv().unwrap() { 0 /* Left */ => (-dir.1, dir.0), _ /* Right */ => (dir.1, -dir.0), }; hull.insert(pos, color); pos.0 = pos.0 + dir.0; pos.1 = pos.1 + dir.1; color_cur_tile = if let Some(&color) = hull.get(&pos) { color } else { Paint::Black }; } hull } fn bound_box(hull: &HashMap<Coord, Paint>) -> (Coord, Coord) { let top = hull.keys().map(|p|p.1).min().unwrap(); let left = hull.keys().map(|p|p.0).min().unwrap(); let bottom = hull.keys().map(|p|p.1).max().unwrap(); let right = hull.keys().map(|p|p.0).max().unwrap(); ((left, top), (right, bottom)) } impl Solution for State { fn part1(&self) -> String { paint_hull(&self.program, Paint::Black).len().to_string() } fn part2(&self) -> String { let hull = paint_hull(&self.program, Paint::White); let (tl, br) = bound_box(&hull); let mut plate = Vec::new(); for y in (tl.1..=br.1).rev() { plate.push('\n'); for x in tl.0..=br.0 { let pos = (x as i32, y as i32); let ch = if let Some(&col) = hull.get(&pos) { if col == Paint::Black { '▒' } else { '█' } } else { '▒' }; plate.push(ch); } }; plate.iter().collect() } }

Utan Intcode kod dÄ den Àr samma som tidigare dagar som anvÀnder datorn
Visa signatur

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

PermalÀnk
●

Dag 11 i Kotlin

Min utskrift i del 2 blev spegelvÀnd och upp och ner först

kommentar

val translation = mapOf( Pair(Pair(0, 1), Pair(Pair(-1, 0), Pair(1, 0))), Pair(Pair(0, -1), Pair(Pair(1, 0), Pair(-1, 0))), Pair(Pair(1, 0), Pair(Pair(0, 1), Pair(0, -1))), Pair(Pair(-1, 0), Pair(Pair(0, -1), Pair(0, 1))) ) fun part1(input: String): Int { val computer = Day09.Computer(Day09.parse(input)) return travel(computer, Pair(0, 0), Pair(0, 1), mapOf()).size } fun part2(input: String): String { val computer = Day09.Computer(Day09.parse(input)) val result = travel(computer, Pair(0, 0), Pair(0, 1), mapOf(Pair(Pair(0, 0), listOf(1)))) val minX = result.keys.map { it.first }.min()!! val maxX = result.keys.map { it.first }.max()!! val minY = result.keys.map { it.second }.min()!! val maxY = result.keys.map { it.second }.max()!! return (minY..maxY).reversed().fold("") { accY, y -> (minX..maxX).fold(accY) { accX, x -> accX + if ((result[Pair(x, y)]?.last() ?: 0) == 1) "█" else " " } + "\n" } } tailrec fun travel(computer: Day09.Computer, coordinate: Pair<Int, Int>, direction: Pair<Int, Int>, state: Map<Pair<Int, Int>, List<Int>>): Map<Pair<Int, Int>, List<Int>> { val color = state[coordinate]?.last() ?: 0 val newState = when (computer.addInput(color.toLong()).getOutput()) { null -> return state 0L -> state + Pair(coordinate, (state[coordinate] ?: listOf()) + 0) 1L -> state + Pair(coordinate, (state[coordinate] ?: listOf()) + 1) else -> throw IllegalStateException() } val newDirection = when (computer.getOutput()) { 0L -> translation[direction]!!.first 1L -> translation[direction]!!.second else -> throw IllegalStateException() } val newCoordinate = Pair(coordinate.first + newDirection.first, coordinate.second + newDirection.second) return travel(computer, newCoordinate, newDirection, newState) }

kod
Visa signatur

"Knowledge amplification. What he learns, we all learn. What he knows, we all benefit from."

PermalÀnk
Datavetare ★
●

Rust - dag 12

En minimal 3D-vektor implementation gjorde del 1 superenkelt

đŸ•Żïž Part 1 : 7202 đŸ•Żïž Part 2 : 537881600740876 ⌚ Took : 19 ms

Kanske finns enklare sÀtt. Men en observation Àr i alla fall att rörelserna pÄ de olika axlarna Àr oberoende. GÄr dÀrför att separat rÀkna ut perioden per axel. Multiplicerar man sedan de tre perioderna sÄ har man en antal steg dÀr man garanterat Àr tillbaka till starten.

Problemet Àr att det kanske inte Àr perioden, utan perioden multiplicerad med nÄgon heltalsfaktor. Faktoriserade dÄ talet, kollande om nÄgon faktor Àr jÀmt delbar med perioden dividerat med var och en av de tre perioderna för axlarna, om ja minskar period med det. Sedan blir det nya perioden. rinse-and-repeat till dess att man bara kan dela med 1.

tankar kring del 2...

type PlanetSystem = Vec<Moon>; fn energy(planet_system: &PlanetSystem) -> i32 { planet_system.iter().fold(0, |energy, moon| { energy + moon.pos.energy() * moon.vel.energy() }) } #[derive(Clone, Copy, Debug, PartialEq)] struct Vec3 { x: i32, y: i32, z: i32, } impl Vec3 { fn energy(&self) -> i32 { self.x.abs() + self.y.abs() + self.z.abs() } fn c_cmp(&self, other: Vec3) -> Vec3 { let cmp = |a: i32, b: i32| match a.cmp(&b) { Ordering::Less => -1, Ordering::Greater => 1, Ordering::Equal => 0, }; Vec3 { x: cmp(self.x, other.x), y: cmp(self.y, other.y), z: cmp(self.z, other.z), } } } impl Add for Vec3 { type Output = Vec3; fn add(self, other: Vec3) -> Vec3 { Vec3 { x: self.x + other.x, y: self.y + other.y, z: self.z + other.z, } } } impl Default for Vec3 { fn default() -> Self { Vec3 { x: 0, y: 0, z: 0 } } } #[derive(Clone, Copy, Debug, PartialEq)] struct Moon { pos: Vec3, vel: Vec3, } impl Moon { fn step_time(&self, moons: &PlanetSystem) -> Moon { let vel = moons .iter() .fold(self.vel, |new_vel, moon| new_vel + moon.pos.c_cmp(self.pos)); Moon { pos: self.pos + vel, vel: vel, } } } fn step_time(moons: &PlanetSystem) -> PlanetSystem { let mut next_moons = Vec::new(); for moon in moons { next_moons.push(moon.step_time(moons)); } next_moons } // State required to solve day 12 pub struct State { moons: PlanetSystem, } impl Solution for State { fn part1(&self) -> String { energy(&(0..1000).fold(self.moons.clone(), |cur_moons, _| step_time(&cur_moons))) .to_string() } fn part2(&self) -> String { let get_x = |v: Vec3| v.x; let get_y = |v: Vec3| v.y; let get_z = |v: Vec3| v.z; let chk = |moons: &PlanetSystem, get: &dyn Fn(Vec3) -> i32| { moons.iter().zip(self.moons.iter()).fold(true, |pred, m| { pred && get(m.0.vel) == 0 && get(m.0.pos) == get(m.1.pos) }) }; let mut x = 0; let mut y = 0; let mut z = 0; let mut steps: u64 = 0; let mut moons = self.moons.clone(); while x == 0 || y == 0 || z == 0 { moons = step_time(&moons); steps = steps + 1; if x == 0 && chk(&moons, &get_x) { x = steps; } if y == 0 && chk(&moons, &get_y) { y = steps; } if z == 0 && chk(&moons, &get_z) { z = steps; } } let mut steps = x * y * z; loop { let fact = factors_uniq(steps); if let Some(denom) = fact .iter() .filter(|&d| (steps / x) % d == 0 && (steps / y) % d == 0 && (steps / z) % d == 0) .next() { steps = steps / denom; } else { break; } } steps.to_string() } }

Del 2 Àr inte vacker, fungerade inte pÄ första försöket om man sÀger sÄ...
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: 12
SprÄk: Haskell

Ojoj, denna var tÀmligen lurig allt. Behövde sitta flera timmar till och frÄn bara för att klura ut knepet för att göra del 2 berÀkningsbar i rimlig tid. Kom till samma insikt som @Yoshman, till slut.

module Day12 (part1, part2) where import Control.Applicative import Data.Foldable import Parse import Vec type Pos = Vec3 Int type Vel = Vec3 Int type Moon = (Pos, Vel) part1 :: IO Int part1 = fmap (systemEnergy . stepN 1000 . parse) readInput where systemEnergy = sum . map moonEnergy moonEnergy m = potential m * kinetic m potential = sum . fmap abs . fst kinetic = sum . fmap abs . snd part2 :: IO Int part2 = fmap (periodByAxes . parse) readInput where periodByAxes ms = let (xms, yms, zms) = unzip3 $ map (\(Vec3 x y z, Vec3 a b c) -> ((x, a), (y, b), (z, c))) ms (xperiod, yperiod, zperiod) = (period xms, period yms, period zms) in leastCommonMultiple [xperiod, yperiod, zperiod] leastCommonMultiple = foldr1 lcm period ms = period' ms 1 (step ms) period' init n ms = if ms == init then n else period' init (n + 1) (step ms) stepN :: Num a => Int -> [(a, a)] -> [(a, a)] stepN n ms = iterate step ms !! n step :: Num a => [(a, a)] -> [(a, a)] step ms = map (\m -> stepMoon m ms) ms stepMoon :: Num a => (a, a) -> [(a, a)] -> (a, a) stepMoon (p, v) ms = let v' = foldl' (\u (q, _) -> u + signum (q - p)) v ms in (p + v', v') parse :: String -> [Moon] parse = map (\s -> (parsePos s, pure 0)) . lines where parsePos = applyParser $ liftA3 Vec3 (string "<x=" *> int) (string ", y=" *> int) (string ", z=" *> int <* string ">") readInput :: IO String readInput = readFile "inputs/day-12"

Dold text
Visa signatur

Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4

PermalÀnk
Medlem ★
●

Jag blir galen. FĂ„r inte till test 2 i del 2.
Denna input
<x=-8, y=-10, z=0>
<x=5, y=5, z=10>
<x=2, y=-7, z=3>
<x=9, y=-8, z=-3>
ger mig
Moon 0 axis[0] found at step 2028 factors[2, 3, 13]
Moon 0 axis[1] found at step 60 factors[2, 3, 5]
Moon 0 axis[2] found at step 57 factors[3, 19]
Moon 1 axis[0] found at step 21 factors[3, 7]
Moon 1 axis[1] found at step 5898 factors[2, 3, 983]
Moon 1 axis[2] found at step 1824 factors[2, 3, 19]
Moon 2 axis[0] found at step 2028 factors[2, 3, 13]
Moon 2 axis[1] found at step 5898 factors[2, 3, 983]
Moon 2 axis[2] found at step 232 factors[2, 29]
Moon 3 axis[0] found at step 857 factors[857]
Moon 3 axis[1] found at step 2670 factors[2, 3, 5, 89]
Moon 3 axis[2] found at step 4702 factors[2, 2351]

Varav det pÄstÄdda svaret 4686774924 bara har i fem av mina elva primtal

PermalÀnk
Medlem ★
●

SĂ„ oberoende var inte variablerna.
Alla fyra mÄnars (x) mÄste Äterkomma till samma vÀrde samtidigt .

PermalÀnk
Medlem ★
●
Skrivet av pacc:

SĂ„ oberoende var inte variablerna.
Alla fyra mÄnars (x) mÄste Äterkomma till samma vÀrde samtidigt .

Jag fÄr alltsÄ ett mycket högre vÀrde... nÀr jag fÄtt ut alla faktorer multiplicerar jag dessa med varandra.

PermalÀnk
Datavetare ★
●
Skrivet av pacc:

SĂ„ oberoende var inte variablerna.
Alla fyra mÄnars (x) mÄste Äterkomma till samma vÀrde samtidigt .

Axlarna Àr oberoende.

SÄ man kan separata rÀkna ut fallet dÀr alla fyra planeter kommer tillbaka till punkten dÀr alla hastighetsvektorer Àr noll (X-komponenten) samtidigt som man Àr tillbaka i utgÄngspositionen (X-komponenten). Sedan gör man samma sak för Y- och Z-komponenten.

Skrivet av Mordekai:

Jag fÄr alltsÄ ett mycket högre vÀrde... nÀr jag fÄtt ut alla faktorer multiplicerar jag dessa med varandra.

Jag gjorde precis som skrivs ovan, rÀknade ut antal steg i X-, Y- samt Z-led. Multiplicerade dessa dÄ alla Àr jÀmt delbar med produkten av respektive period. Det gav ett flera gÄnger för stort vÀrde dÄ man nu har nÄgot som visade sig vara en multipel av den faktiska perioden.

Plockade ut faktorerna ur detta stora vÀrde, kollad om nÄgon av faktorerna gick jÀmt upp med X-, Y- resp Z-perioden. Om nej, visa svaret. Om ja, dividera X-, Y- resp Z-perioden med faktorn och kör ett varv till frÄn "Plockade ut faktorerna...".

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 ★
●
Skrivet av Yoshman:

Axlarna Àr oberoende.

SÄ man kan separata rÀkna ut fallet dÀr alla fyra planeter kommer tillbaka till punkten dÀr alla hastighetsvektorer Àr noll (X-komponenten) samtidigt som man Àr tillbaka i utgÄngspositionen (X-komponenten). Sedan gör man samma sak för Y- och Z-komponenten.

Jag gjorde precis som skrivs ovan, rÀknade ut antal steg i X-, Y- samt Z-led. Multiplicerade dessa dÄ alla Àr jÀmt delbar med produkten av respektive period. Det gav ett flera gÄnger för stort vÀrde dÄ man nu har nÄgot som visade sig vara en multipel av den faktiska perioden.

Plockade ut faktorerna ur detta stora vÀrde, kollad om nÄgon av faktorerna gick jÀmt upp med X-, Y- resp Z-perioden. Om nej, visa svaret. Om ja, dividera X-, Y- resp Z-perioden med faktorn och kör ett varv till frÄn "Plockade ut faktorerna...".

Jag har alltsÄ redan gjort primtalsfaktorisering och tagit bort dubletter, kan nÄgon visa de tolv (4 mÄnar x 3 axlar) cyklernas vÀrde, frÄn exempel 2? PÄ exempel 1 fÄr jag 462 som jag sedan mÄste multiplicera med 2 och 3 igen (dessa finns redan i min primtalsfaktorisering i exempel 1) för att alla axlar ska fÄ fulla rotationer.

PermalÀnk
Datavetare ★
●

Rust - dag 13

Min "AI" in action

type Screen = HashMap<Vec2D, Tile>; #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] struct Vec2D { x: i32, y: i32, } impl Default for Vec2D { fn default() -> Self { Vec2D { x: 0, y: 0 } } } #[derive(Copy, Clone, Debug, Eq, PartialEq)] enum Tile { Empty, Wall, Block, Paddle, Ball, Score(i32), } fn to_tile(tile_id: Intcode, x: Intcode, y: Intcode) -> Tile { if x == -1 && y == 0 { return Tile::Score(tile_id as i32); } match tile_id { 0 => Tile::Empty, 1 => Tile::Wall, 2 => Tile::Block, 3 => Tile::Paddle, 4 => Tile::Ball, _ => panic!("Invalid tile ID"), } } fn next_tile(output: &Receiver<Intcode>) -> Option<(Vec2D, Tile)> { if let Ok(x) = output.recv() { let y = output.recv().unwrap(); let tile_id = output.recv().unwrap(); Some(( Vec2D { x: x as i32, y: y as i32, }, to_tile(tile_id, x, y), )) } else { None } } fn render(screen: &Screen) { let mut line = 0; let mut x = 0; let max_y = screen.keys().max_by(|a, b| a.y.cmp(&b.y)).unwrap().y; print!("{}[2J", 27 as char); // clear console if let Some(Tile::Score(val)) = screen.get(&Vec2D { x: -1, y: 0 }) { println!("Score: {}", val); } loop { let pos = Vec2D { x: x, y: line }; x = x + 1; if let Some(tile) = screen.get(&pos) { print!( "{}", match tile { Tile::Ball => "⚟", Tile::Block => "▒▒", Tile::Empty => " ", Tile::Paddle => "▃▃", _ => "██", } ) } else { x = 0; println!(""); line = line + 1; if line == max_y + 1 { break; } } } std::thread::sleep(std::time::Duration::from_millis(50)); } impl Solution for State { fn part1(&self) -> String { let (_, sink) = channel(); let output = exec(&self.program, sink, None); let mut blocks = 0; while let Some(tile) = next_tile(&output) { if tile.1 == Tile::Block { blocks = blocks + 1; } } blocks.to_string() } fn part2(&self) -> String { let mut free_play_program = self.program.clone(); free_play_program[0] = 2; let (joystick, sink) = channel(); let output = exec(&free_play_program, sink, None); let mut paddle = Vec2D::default(); let mut final_score = 0; let mut screen = Screen::new(); while let Some(tile) = next_tile(&output) { screen.insert(tile.0, tile.1); match tile.1 { Tile::Score(val) => final_score = val, Tile::Paddle => { paddle = tile.0; render(&screen); } Tile::Ball => { let ball_x = tile.0.x; joystick.send( if ball_x < paddle.x { -1 } else if ball_x > paddle.x { 1 } else { 0 }) .unwrap(); } _ => (), } } final_score.to_string() } }

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
Datavetare ★
●
Skrivet av Mordekai:

Jag har alltsÄ redan gjort primtalsfaktorisering och tagit bort dubletter, kan nÄgon visa de tolv (4 mÄnar x 3 axlar) cyklernas vÀrde, frÄn exempel 2? PÄ exempel 1 fÄr jag 462 som jag sedan mÄste multiplicera med 2 och 3 igen (dessa finns redan i min primtalsfaktorisering i exempel 1) för att alla axlar ska fÄ fulla rotationer.

Jag fÄr dessa vÀrden med min indata (om du laddar ner rustup och tar ner min kod frÄn github kan du testa sjÀlv)

x: 231614 y: 96236 z: 193052 Prime factors: [2, 7, 17, 167, 491, 115807] Divide with: 2 x: 115807 y: 48118 z: 96526 Prime factors: [2, 7, 17, 167, 491, 115807] đŸ•Żïž Part 2 : 537881600740876

Första utskriften Àr antal steg pÄ varje axel, i mitt fall var det tydligen bara en faktor 2 fel.

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 ★
●
Skrivet av Yoshman:

Jag fÄr dessa vÀrden med min indata (om du laddar ner rustup och tar ner min kod frÄn github kan du testa sjÀlv)

x: 231614 y: 96236 z: 193052 Prime factors: [2, 7, 17, 167, 491, 115807] Divide with: 2 x: 115807 y: 48118 z: 96526 Prime factors: [2, 7, 17, 167, 491, 115807] đŸ•Żïž Part 2 : 537881600740876

Första utskriften Àr antal steg pÄ varje axel, i mitt fall var det tydligen bara en faktor 2 fel.

Jag menade inte pÄ ditt uppgiftsdata utan pÄ exempeldatat;

<x=-8, y=-10, z=0> <x=5, y=5, z=10> <x=2, y=-7, z=3> <x=9, y=-8, z=-3>

som gav mig;

Moon 0 axis[x] found at step 2028 factors[2, 3, 13] Moon 0 axis[y] found at step 60 factors[2, 3, 5] Moon 0 axis[z] found at step 57 factors[3, 19] Moon 1 axis[x] found at step 21 factors[3, 7] Moon 1 axis[y] found at step 5898 factors[2, 3, 983] Moon 1 axis[z] found at step 1824 factors[2, 3, 19] Moon 2 axis[x] found at step 2028 factors[2, 3, 13] Moon 2 axis[y] found at step 5898 factors[2, 3, 983] Moon 2 axis[z] found at step 232 factors[2, 29] Moon 3 axis[x] found at step 857 factors[857] Moon 3 axis[y] found at step 2670 factors[2, 3, 5, 89] Moon 3 axis[z] found at step 4702 factors[2, 2351]

edit; jag försökte tidigare installera rust men fattar inte hur jag gör för att editera, kompilera, debugga. Att bara köra koden utan att kunna debugga ger mig ju inte sÄ mycket dÄ jag behöver se var jag fallerar, just nu Àr det tvÄ möjligheter, jag hittar inte rÀtt första förekomst av varje mÄnes axels Äterkomst till sin startposition och hastighet, det andra alternativet att jag hittar rÀtt men gör nÄgot fel i faktoriseringen.

PermalÀnk
Medlem
●

Vad kul med Ànnu mer intcode. Förutom dag 12 del 2 sÄ har ju alla utmaningar bara krÀvt att man gör precis som det stÄr utan att missförstÄ nÄgot eller missa nÄn liten detalj i texten. Det Àr dessutom ingen större skillnad pÄ dag 11 och 13. Inte sÄ mycket variation och vÀldigt mycket ÄteranvÀndande av gammal kod.

Dag: 13
SprÄk: Scala

sealed trait Action final case class MapEntity(position: Vec2, tileId: Int) extends Action final case class Score(value: Int) extends Action final case class GameState(blocks: Map[Vec2, Int], pad: Vec2, ball: Vec2, score: Int, out: Option[Long]) { def next(action: Action): GameState = action match { case MapEntity(pos, 0) => copy(blocks = blocks.updated(pos, 0), out = None) case MapEntity(pos, 1) => copy(blocks = blocks.updated(pos, 1), out = None) case MapEntity(pos, 2) => copy(blocks = blocks.updated(pos, 2), out = None) case MapEntity(pos, 3) => copy(pad = pos, out = None) case MapEntity(pos, 4) => copy(ball = pos, out = Some(pos.x.compareTo(pad.x))) case Score(score) => copy(score = score, out = None) } } val input = Using.resource(Source.fromFile(filePath.toFile))(_.mkString.split(",")).flatMap(_.toLongOption) val memory = Iterator.from(0).map(_.toLong).zip(input).toMap.withDefaultValue(0L) def run(memory: Map[Long, Long]): LazyList[GameState] = { val initState = GameState(Map.empty[Vec2, Int].withDefaultValue(0), Vec2.Zero, Vec2.Zero, 0, None) lazy val actions = Iterator .unfold(ProgramState(memory, gameStates.flatMap(_.out)))(_.next.map(ps => ps.outs -> ps)) .flatten .grouped(3) .map { case ArraySeq(-1, 0, score) => Score(score.toInt) case ArraySeq(x, y, tid) => MapEntity(Vec2(x.toInt, y.toInt), tid.toInt) } lazy val gameStates: LazyList[GameState] = initState #:: gameStates .zip(actions) .map { case (gs, action) => gs.next(action) } gameStates } val part2history = run(memory.updated(0, 2)) part2history.filter(_.out.nonEmpty).foreach { gs => val symbols: Map[Int, Char] = Map(0 -> ' ', 1 -> '▉', 2 -> '░', 3 -> '_', 4 -> '⚫') println(s"score: ${gs.score}") println(mapToConsoleGraphics(gs.blocks.updated(gs.ball, 4).updated(gs.pad, 3), symbols)) print("\u001b[2J") } run(memory).pipe(gs => println(s"part1: ${gs.last.blocks.values.count(_ == 2)}")) part2history.pipe(gs => println(s"part2: ${gs.last.score}"))

Vec2/Vec3 gemensam för alla och gör ungefÀr vad man kan förvÀnta sig..

final case class Vec2(x: Int, y: Int) { def +(that: Vec2): Vec2 = Vec2(x + that.x, y + that.y) def -(that: Vec2): Vec2 = Vec2(x - that.x, y - that.y) def *(scalar: Int): Vec2 = Vec2(x * scalar, y * scalar) def /(scalar: Int): Vec2 = Vec2(x / scalar, y / scalar) def ∘(that: Vec2): Int = x * that.x + y * that.y def ×(that: Vec2): Int = x * that.y - y * that.x def sign: Vec2 = Vec2(x.sign, y.sign) def l1: Int = x.abs + y.abs def l2: Double = Math.hypot(x, y) def gcdRescale: Vec2 = this / gcd(x, y).abs ...

Har ett par funktioner för att skriva ut Vec2 hashmaps grafiskt ocksÄ..

def mapToConsoleGraphics(map: Map[Vec2, Int], symbols: Map[Int, Char]): String = { val (xMin, xMax, yMin, yMax) = map.keysIterator.foldLeft((Int.MaxValue, Int.MinValue, Int.MaxValue, Int.MinValue)) { case ((xMin, xMax, yMin, yMax), Vec2(x, y)) => (xMin min x, xMax max x, yMin min y, yMax max y) } val sb = new StringBuilder (yMin to yMax).foreach { y => (xMin to xMax).foreach { x => sb += symbols(map(Vec2(x, y))) } sb += '\n' } sb.toString() }

Dold text

Dag: 12
SprÄk: Scala

val input = Using.resource(Source.fromFile(filePath.toFile))(_.getLines().toVector) val moons = input.map { str => val s"<x=${x}, y=${y}, z=${z}>" = str Vec3(x.toInt, y.toInt, z.toInt) } def simulation = Iterator .iterate(moons -> Vector.fill(4)(Vec3.Zero)) { case (pos, vel) => val newVel = pos .map(u => pos.filter(_ != u).foldLeft(Vec3.Zero)((acc, v) => acc + (v - u).sign)) .lazyZip(vel) .map(_ + _) val newPos = pos.lazyZip(newVel).map(_ + _) newPos -> newVel } simulation .drop(1000) .next() .pipe { case (positions, velocities) => println(positions.lazyZip(velocities).map(_.l1 * _.l1).sum) } simulation.zipWithIndex .drop(1) .scanLeft((Option.empty[Int], Option.empty[Int], Option.empty[Int])) { case ((ox, oy, oz), ((pos, vel), idx)) => ( ox.orElse(Option.when(vel.map(_.x).forall(_ == 0) && pos.map(_.x) == moons.map(_.x))(idx)), oy.orElse(Option.when(vel.map(_.y).forall(_ == 0) && pos.map(_.y) == moons.map(_.y))(idx)), oz.orElse(Option.when(vel.map(_.z).forall(_ == 0) && pos.map(_.z) == moons.map(_.z))(idx))) } .find { case (ox, oy, oz) => ox.isDefined && oy.isDefined && oz.isDefined } .flatMap { case (ox, oy, oz) => ox.flatMap(x => oy.flatMap(y => oz.map(z => lcm(x, lcm(y, z))))) } .foreach(println) }

Dold text

Dag: 11
SprÄk: Scala

final case class Action(color: Int, turnLeft: Boolean) final case class RobotState(painted: Map[Vec2, Int], pos: Vec2, dir: Vec2) { private def turn(turnLeft: Boolean): Vec2 = dir match { case Vec2.Up => if (turnLeft) Vec2.Left else Vec2.Right case Vec2.Left => if (turnLeft) Vec2.Down else Vec2.Up case Vec2.Down => if (turnLeft) Vec2.Right else Vec2.Left case Vec2.Right => if (turnLeft) Vec2.Up else Vec2.Down } def next(action: Action): RobotState = { val newDir = turn(action.turnLeft) RobotState(painted + (pos -> action.color), pos + newDir, newDir) } } val input = Using.resource(Source.fromFile(filePath.toFile))(_.mkString.split(",")).flatMap(_.toLongOption) val memory = Iterator.from(0).map(_.toLong).zip(input).toMap.withDefaultValue(0L) def run(firstColor: Int): Map[Vec2, Int] = { val initState = RobotState(Map(Vec2.Zero -> firstColor).withDefaultValue(0), Vec2.Zero, Vec2.Up) lazy val actions = Iterator .unfold(ProgramState(memory, robotStates.map(rs => rs.painted(rs.pos))))(_.next.map(ps => ps.outs -> ps)) .flatten .grouped(2) .map { case ArraySeq(color, turn) => Action(color.toInt, turn == 0) } lazy val robotStates: LazyList[RobotState] = initState #:: robotStates .zip(actions) .map { case (rs, action) => rs.next(action) } robotStates.last.painted } run(firstColor = 0).size.pipe(sz => println(s"part1: $sz")) println(mapToConsoleGraphics(run(firstColor = 1), Map(0 -> ' ', 1 -> '█')))

Dold text

ProgramState (IntCode):

final case class ProgramState( mem: Map[Long, Long], ins: LazyList[Long] = LazyList.empty, outs: List[Long] = Nil, rb: Long = 0, ip: Long = 0) { private def mode(n: Int): Long = (mem(ip) / math.pow(10, n + 1).toInt) % 10 private def read(n: Int): Long = mode(n) match { case 0 => mem(mem(ip + n)) case 1 => mem(ip + n) case 2 => mem(rb + mem(ip + n)) } private def write(n: Int)(value: Long): Map[Long, Long] = mode(n) match { case 0 => mem.updated(mem(ip + n), value) case 2 => mem.updated(rb + mem(ip + n), value) } def next: Option[ProgramState] = mem(ip) % 100 match { case 1 => Some(copy(mem = write(3)(read(1) + read(2)), outs = Nil, ip = ip + 4)) case 2 => Some(copy(mem = write(3)(read(1) * read(2)), outs = Nil, ip = ip + 4)) case 3 => Some(copy(mem = write(1)(ins.head), ins = ins.tail, outs = Nil, ip = ip + 2)) case 4 => Some(copy(outs = read(1) :: Nil, ip = ip + 2)) case 5 => if (read(1) != 0) Some(copy(outs = Nil, ip = read(2))) else Some(copy(outs = Nil, ip = ip + 3)) case 6 => if (read(1) == 0) Some(copy(outs = Nil, ip = read(2))) else Some(copy(outs = Nil, ip = ip + 3)) case 7 => Some(copy(mem = write(3)(if (read(1) < read(2)) 1 else 0), outs = Nil, ip = ip + 4)) case 8 => Some(copy(mem = write(3)(if (read(1) == read(2)) 1 else 0), outs = Nil, ip = ip + 4)) case 9 => Some(copy(outs = Nil, rb = rb + read(1), ip = ip + 2)) case 99 => None } }

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

Jag menade inte pÄ ditt uppgiftsdata utan pÄ exempeldatat;

<x=-8, y=-10, z=0> <x=5, y=5, z=10> <x=2, y=-7, z=3> <x=9, y=-8, z=-3>

som gav mig;

Moon 0 axis[x] found at step 2028 factors[2, 3, 13] Moon 0 axis[y] found at step 60 factors[2, 3, 5] Moon 0 axis[z] found at step 57 factors[3, 19] Moon 1 axis[x] found at step 21 factors[3, 7] Moon 1 axis[y] found at step 5898 factors[2, 3, 983] Moon 1 axis[z] found at step 1824 factors[2, 3, 19] Moon 2 axis[x] found at step 2028 factors[2, 3, 13] Moon 2 axis[y] found at step 5898 factors[2, 3, 983] Moon 2 axis[z] found at step 232 factors[2, 29] Moon 3 axis[x] found at step 857 factors[857] Moon 3 axis[y] found at step 2670 factors[2, 3, 5, 89] Moon 3 axis[z] found at step 4702 factors[2, 2351]

edit; jag försökte tidigare installera rust men fattar inte hur jag gör för att editera, kompilera, debugga. Att bara köra koden utan att kunna debugga ger mig ju inte sÄ mycket dÄ jag behöver se var jag fallerar, just nu Àr det tvÄ möjligheter, jag hittar inte rÀtt första förekomst av varje mÄnes axels Äterkomst till sin startposition och hastighet, det andra alternativet att jag hittar rÀtt men gör nÄgot fel i faktoriseringen.

Gjorde en tankevurpa, rĂ„kade bara fungera pĂ„ min "riktiga" input. Är denna logik du mĂ„ste köra för att reducera perioden pĂ„ korrekt sĂ€tt

let mut steps = x * y * z; loop { let fact = factors_uniq(steps); if let Some(denom) = fact .iter() .filter(|&d| (steps / x) % d == 0 && (steps / y) % d == 0 && (steps / z) % d == 0) .next() { steps = steps / denom; } else { break; } } steps.to_string()

Kolla filter() steget, Àr sÄ man ska filtrera. Notera ocksÄ att det Àr produkten, inte resp. axels antal steg, som man ska dividera ned. Att det rÄkade fungera för mig var för att jag skulle dividera med 8 (och delade dÄ med 2 * 2 * 2 första rundan...)

Exemplet ska divideras med 12!

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 ★
●

Ett tips för mÄnarna Àr ju annars LCM.

PermalÀnk
Datavetare ★
●
Skrivet av xilli:

Ett tips för mÄnarna Àr ju annars LCM.

Danke! DÄ blev ovan vÀldigt enkelt

lcm(x, lcm(y, z)).to_string()

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 ★
●
Skrivet av xilli:

Ett tips för mÄnarna Àr ju annars LCM.

Jag fÄr exakt samma svar pÄ exempel 2 med LCM som min metod (vilket iofs redan var en LCM baserad pÄ primtalsfaktorisering);
13393440017439845952 ska vara 4686774924.

Jag börjar starkt misstÀnka att jag fÄr fram fel cykler, har alla samma exempeldata? I sÄ fall vad fick ni för cykellÀngder pÄ de olika axlarna?

EDIT dessutom fÄr jag ju helt rÀtt svar för exempel 1, varenda steg som visas har jag samma vÀrden för.

PermalÀnk
Medlem ★
●

Jag var en off pÄ varje cykel, har inte orkat förstÄ varför...

PermalÀnk
Medlem
●

@Mordekai:
AnvÀnder jag test2 som input fÄr jag:
x: 2028 y: 5898 z: 4702 -> 4686774924

PermalÀnk
Medlem ★
●
Skrivet av jclr:

@Mordekai:
AnvÀnder jag test2 som input fÄr jag:
x: 2028 y: 5898 z: 4702 -> 4686774924

vilken mÄne?

PermalÀnk
Medlem
●

@Mordekai:
FörstÄr inte riktigt vad du menar med viken mÄne? För varje nytt steg kollar jag om alla mÄnars x koordinat stÀmmer med vad de hade som x koordinat frÄn start och om x-velocity Àr noll för alla mÄnar. StÀmmer allt har man hittat cykellÀngden för x. Efter 2028 steg Àr alla mÄnar tillbaka pÄ samma x koordinat de startade frÄn med 0 i velocity i x-led. Gör samma sak för y/z samtidigt.
Min kod för dag 12 finns en bit upp.

PermalÀnk
Medlem ★
●

NÀr ni hittar cykeln, skiter ni vad velocity Àr dÄ? Jag tittar bara efter fall dÄ velocity Àr 0 och dÄ kommer x-koordinaten för fjÀrde mÄnen efter 857 steg vilket svaret pÄ exempel 2 inte Àr delbart med...

PermalÀnk
Medlem ★
●

Tack allihopa, nu fattar jag vad jag har för fel.

PermalÀnk
Medlem
●

Dag: 13
SprÄk: Haskell

Hmm, jag har tidigare avskrivit lat evaluering som en rolig men för verkligt bruk opraktisk feature av prestandaskÀl och dylikt. Nu nÀr jag dock mer eller mindre varit tvungen att anvÀnda lathet de senaste dagarna pga. icke-muterbarhet i Haskell, sÄ inser jag att det hade varit vÀldigt svÄrt att skriva fin funktionell kod om jag inte med lathet hade kunnat "knyta knuten", sÄ att sÀga. Riktig tankestÀllare.

{-# LANGUAGE LambdaCase #-} module Day13 (part1, part2) where import Data.List.Split import qualified Data.Sequence as Seq import Data.Bifunctor import Lib import Intcode part1 :: IO Int part1 = fmap (length . filter (== 2) . everyNth 3 . drop 2 . evalIntcode [] . parseIntcode ) readInput part2 :: IO Int part2 = fmap (beatGame . parseIntcode) readInput where beatGame pgm = let outs = evalIntcode ins (insertCoins pgm) insertCoins = Seq.update 0 2 tiles = map head3 (chunksOf 3 outs) (score, ins) = play (0, 0, 0) tiles play (bx, px, s) = \case (-1, 0, s') : ts -> play (bx, px, s') ts (px', _, 3) : ts -> play (bx, px', s) ts (bx', _, 4) : ts -> let i = calcMove bx' px result = play (bx', px, s) ts in second (i :) result _ : ts -> play (bx, px, s) ts [] -> (s, []) calcMove bx px = if bx > px then 1 else if bx == px then 0 else (-1) in score readInput :: IO String readInput = readFile "inputs/day-13"

Dold text
Visa signatur

Arbets- / Spelstation: Arch Linux - Ryzen 5 3600 - RX 7900 XT - 32G DDR4
Server: Arch Linux - Core i5-10400F - 16G DDR4

PermalÀnk
Datavetare ★
●

Rust - dag 14

SÀtter upp en mappning (HashMap frÄn namnet pÄ resultatÀmne till syntesbeskrivning) frÄn resultat av en syntes givet vissa reagens. GÄr rekursivt i den mappningen upp till Àmnet Àr malm ("ORE"), det finns det ju oÀndligt av sÄ bara att ge tillbaka sÄ mycket som behövs.

Den lösningen höll inte riktigt i del 2 (tar linjÀrt lÀngre tid ju mer brÀnsle man framstÀller). Lade till en liten optimeringen som rÀknar ut direkt hur mÄnga gÄnger en viss syntes mÄste köras för att ge tillrÀckligt med resultat material direkt.

Efter det var det bara att köra intervallhalvering pÄ FUEL(ore_guess) till dess att man hittat ore_guess som ger precis över och precis under billion malm-bitar.

type Count = u64; #[derive(Clone, Debug)] struct Chemical { name: String, units: Count, } type Syntheses = HashMap<String, Vec<Chemical>>; type Inventory = HashMap<String, Count>; fn get_chemical(chemical: &Chemical, syntheses: &Syntheses, inventory: &mut Inventory) -> Count { if chemical.name == "ORE" { // Unlimited supply of ore return chemical.units; } let mut cnt = 0; loop { let inv = *inventory.get(&chemical.name).unwrap_or(&0); if chemical.units <= inv { // Use left-over from earlier synthesis inventory.insert(chemical.name.clone(), inv - chemical.units); return cnt } let syn = syntheses.get(&chemical.name).unwrap(); let res = syn.last().unwrap(); // Number of times this synthesis should run to get sufficient result chemical let syn_mul = (chemical.units - inv + res.units - 1) / res.units; for reagent in &syn[0..(syn.len() - 1)] { let mut r = reagent.clone(); r.units = r.units * syn_mul; cnt = cnt + get_chemical(&r, syntheses, inventory); } inventory.insert(chemical.name.clone(), inv + syn_mul * res.units); } } fn ore_per_n_fuel(n: Count, syntheses: &Syntheses) -> Count { let fuel = Chemical { name: "FUEL".to_string(), units: n, }; let mut inventory = HashMap::new(); get_chemical(&fuel, syntheses, &mut inventory) } impl Solution for State { fn part1(&self) -> String { ore_per_n_fuel(1, &self.syntheses).to_string() } fn part2(&self) -> String { let mut lo = 1; let mut hi = 10; let ore = 1000000000000; while ore_per_n_fuel(hi, &self.syntheses) < ore { hi = hi * 10; } loop { let mid = (lo + hi) / 2; let this_ore = ore_per_n_fuel(mid, &self.syntheses); if hi - lo <= 1 { break lo } if this_ore < ore { lo = mid; } else { hi = mid } }.to_string() } }

Tar bara totalt 4 ms att lösa del 1&2 pÄ en i7-8559U.
Visa signatur

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