// 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; }