using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace D13._2 { class Track : Dictionary<(int x, int y), char> { }; class Carts : List<(int x, int y, int vx, int vy, int t)> { }; class Program { static void Main(string[] args) { if (args.Length < 1) return; if (File.Exists(args[0]) == false) return; var file = File.OpenText(args[0]); var track = new Track(); var carts = new Carts(); FillTrack(file, track, carts); int? last = null; do { carts.Sort((a, b) => { if (a.y == b.y) return a.x-b.x; return a.y-b.y; }); last = lastCart(carts); if (last == null)tick(track, carts); } while (last == null); var l = carts[last.Value]; Console.WriteLine($"The answer is \"{l.x},{l.y}\" ({l.vx},{l.vy})"); } private static void FillTrack(StreamReader file, Track track, Carts carts) { int y = 0; do { var line = file.ReadLine(); if (line == null) break; for (int x = 0; x < line.Length; ++x) { char c = line[x]; if (c == ' ') continue; if (isCart(c)) { carts.Add(getCart(c, x, y)); c = c == '>' || c == '<' ? '-' : '|'; } track[(x, y)] = c; } y++; } while (true); } private static void tick(Track track, Carts carts) { for (var i = 0; i < carts.Count; ++i) { var cart = carts[i]; if (cart == default) continue; cart.x += cart.vx; cart.y += cart.vy; var c = track[(cart.x, cart.y)]; var ncart = getCart(c, cart); carts[i] = ncart; if (inter(carts, cart, i)) continue; } } static int? lastCart(Carts carts) { int count = 0; int? cart = null; for (var i = 0; i < carts.Count; ++i) { if (carts[i] == default) continue; cart = i; count++; } return count == 1 ? cart : null; } static bool inter(Carts carts, (int x, int y, int vx, int vy, int t) cj, int skip) { for (var i = 0; i < carts.Count; ++i) { if (i == skip) continue; var ci = carts[i]; if (ci == default) continue; if (ci.x == cj.x && ci.y == cj.y) { carts[i] = default; carts[skip] = default; return true; } } return false; } static bool isCart(char c) { return c == '>' || c == '<' || c == '^' || c == 'v'; } static (int x, int y, int vx, int vy, int t) getCart(char c, int x, int y) { switch (c) { case '>': return (x, y, +1, +0, 0); case '<': return (x, y, -1, +0, 0); case '^': return (x, y, +0, -1, 0); case 'v': return (x, y, +0, +1, 0); } return default; } static (int x, int y, int vx, int vy, int t) getCart(char c, (int x, int y, int vx, int vy, int t) cart) { if (c == '|' || c == '-') return cart; if (c == '+' && cart.t == 1) { cart.t++; return cart; } switch (cart) { case var t when t.vx == 1 && t.vy == 0: if (c == '/') return (cart.x, cart.y, +0, -1, cart.t); if (c == '\\') return (cart.x, cart.y, +0, +1, cart.t); if (c == '+' && cart.t == 0) return (cart.x, cart.y, +0, -1, 1); if (c == '+' && cart.t == 2) return (cart.x, cart.y, +0, +1, 0); return default; case var t when t.vx == -1 && t.vy == 0: if (c == '/') return (cart.x, cart.y, +0, +1, cart.t); if (c == '\\') return (cart.x, cart.y, +0, -1, cart.t); if (c == '+' && cart.t == 0) return (cart.x, cart.y, +0, +1, 1); if (c == '+' && cart.t == 2) return (cart.x, cart.y, +0, -1, 0); return default; case var t when t.vx == 0 && t.vy == 1: if (c == '/') return (cart.x, cart.y, -1, +0, cart.t); if (c == '\\') return (cart.x, cart.y, +1, +0, cart.t); if (c == '+' && cart.t == 0) return (cart.x, cart.y, +1, +0, 1); if (c == '+' && cart.t == 2) return (cart.x, cart.y, -1, +0, 0); return default; case var t when t.vx == 0 && t.vy == -1: if (c == '/') return (cart.x, cart.y, +1, +0, cart.t); if (c == '\\') return (cart.x, cart.y, -1, +0, cart.t); if (c == '+' && cart.t == 0) return (cart.x, cart.y, -1, +0, 1); if (c == '+' && cart.t == 2) return (cart.x, cart.y, +1, +0, 0); return default; } return default; } } }