// If the citizens are put in 2 lines, each which can see the other line, but not themselves, they need to determine which hats to guess
		// based on the set of hats in the other line. So there are 2 signals being sent, 1 by each line. There are 2 responses, 1 by each line.
		//
		// So we need to create a signal for the smaller line to send to the larger line, such that it's possible to create a signal that the larger
		// line can send.
		//
		// So this takes in the code from the smaller line to the larger line and computes the code that the larger line needs to return
		public OneWayCode GetSecondCodeFromFirstCode(OneWayCode code, int numDifferentColors)
		{
			var numPeopleInLineSendingFirstCode = code.OneWaySignals.First().Signal.Assignment.Length;
			var numPeopleInLineSendingSecondCode = code.OneWaySignals.First().Response.Assignment.Length;

			var keySetOfFirstCode = this.GenerateAllPossibleHatAssignments(
				numPeopleInLineSendingFirstCode,
				numDifferentColors,
				1);
			var keySetOfSecondCode = this.GenerateAllPossibleHatAssignments(
				numPeopleInLineSendingSecondCode,
				numDifferentColors,
				1 + numPeopleInLineSendingFirstCode);		

			var signals = new List<OneWaySignal>();
			foreach(var signal in keySetOfSecondCode)
			{
				var response = this.GetResponseFromSignal(signal, code, keySetOfFirstCode);
				var signalCopy = signal.DeepCopyHatAssignment();
				var responseCopy = response?.DeepCopyHatAssignment();
				signals.Add(new OneWaySignal
				{
					Signal = signalCopy,
					Response = responseCopy
				});
			}
			return new OneWayCode { OneWaySignals = signals };
		}
		public HatAssignment GetResponseFromSignal(HatAssignment signal, OneWayCode code, List<HatAssignment> keySetOfFirstCode)
		{
			var responsesToMatch = new List<HatAssignment>();
			foreach (var oldSignal in code.OneWaySignals)
			{
				if (!this.PairContainsAtLeastOneMatchingHat(signal, oldSignal.Response))
				{
					responsesToMatch.Add(oldSignal.Signal);
				}
			}

			foreach (var possibleResponse in keySetOfFirstCode)
			{
				if (responsesToMatch.All(r => this.PairContainsAtLeastOneMatchingHat(possibleResponse, r)))
				{
					
					return possibleResponse;
				}
			}
			return null;			
		}