back to switch :)
This commit is contained in:
		
							
								
								
									
										66
									
								
								day23.cpp
									
									
									
									
									
								
							
							
						
						
									
										66
									
								
								day23.cpp
									
									
									
									
									
								
							| @@ -13,37 +13,43 @@ using namespace intcode; | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| using Packet = std::pair<ValueType, ValueType>; | ||||
| using Ethernet = std::deque<std::pair<std::size_t, Packet>>; | ||||
| struct Payload { ValueType x, y; }; | ||||
| struct Packet { ValueType destination; Payload payload; }; | ||||
| using Ethernet = std::deque<Packet>; | ||||
|  | ||||
| auto BuildNetwork(Machine m) -> std::vector<Machine> { | ||||
|   auto& i = std::get<Input>(Step(m)).pos; | ||||
|   std::vector<Machine> machines; | ||||
|   auto& i = std::get<Input>(Step(m)).pos; | ||||
|   for (i = 0; i < 50; i++) { | ||||
|     machines.push_back(m); | ||||
|   } | ||||
|   return machines; | ||||
| } | ||||
|  | ||||
| auto Interact(Ethernet & ethernet, Machine & m, std::optional<Packet> p) -> void { | ||||
|   std::visit(overloaded{ | ||||
|   [&](Input i) { | ||||
|     if (p) { | ||||
|       i.pos = p->first; | ||||
|       StepInput(m, p->second); | ||||
|       Interact(ethernet, m, {}); | ||||
|     } else { | ||||
|       i.pos = -1; // no packet | ||||
| auto Interact(Ethernet & ethernet, Machine & m, std::optional<Payload> p) -> void { | ||||
|   for(;;) { | ||||
|     auto e = Step(m); | ||||
|     switch (e.index()) { | ||||
|       default: throw std::runtime_error{"unexpected halt"}; | ||||
|       case 0: { | ||||
|         auto& i = std::get<0>(e).pos; | ||||
|         if (p) { | ||||
|           i = p->x; | ||||
|           StepInput(m, p->y); | ||||
|           p = {}; | ||||
|           break; | ||||
|         } | ||||
|         i = -1; // no packet | ||||
|         return; | ||||
|       } | ||||
|       case 1: { | ||||
|         auto d = std::get<1>(e).val; | ||||
|         auto x = StepOutput(m); | ||||
|         auto y = StepOutput(m); | ||||
|         ethernet.push_back({d, {x,y}}); | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   [&](Output d) { | ||||
|     auto x = StepOutput(m); | ||||
|     auto y = StepOutput(m); | ||||
|     ethernet.push_back({d.val, {x,y}}); | ||||
|     Interact(ethernet, m, p); | ||||
|   }, | ||||
|   [](Halt) -> void { throw std::runtime_error{"unexpected halt"}; }, | ||||
|   }, Step(m)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| } // namespace | ||||
| @@ -55,24 +61,24 @@ auto main() -> int { | ||||
|  | ||||
|   std::optional<ValueType> part1; | ||||
|   std::optional<ValueType> part2; | ||||
|   std::optional<Packet> nat; | ||||
|   std::optional<Payload> nat; | ||||
|  | ||||
|   for(;;) { | ||||
|     if (!ethernet.empty()) { | ||||
|       auto [dest, p] = ethernet.front(); | ||||
|       auto packet = ethernet.front(); | ||||
|       ethernet.pop_front(); | ||||
|       if (dest == 255) { | ||||
|         nat = p; | ||||
|         if (!part1) { part1 = p.second; } | ||||
|       if (packet.destination == 255) { | ||||
|         nat = packet.payload; | ||||
|         if (!part1) { part1 = packet.payload.y; } | ||||
|       } else { | ||||
|         Interact(ethernet, machines.at(dest), p); | ||||
|         Interact(ethernet, machines.at(packet.destination), packet.payload); | ||||
|       } | ||||
|     } else if (nat) { | ||||
|       if (nat->second == part2) { break; } | ||||
|       part2 = nat->second; | ||||
|       if (part2 == nat->y) { break; } | ||||
|       part2 = nat->y; | ||||
|       Interact(ethernet, machines[0], nat); | ||||
|     } else { | ||||
|       for (auto && m : machines) { | ||||
|       for (auto & m : machines) { | ||||
|         Interact(ethernet, m, {}); | ||||
|       } | ||||
|     } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user