47
loading...
This website collects cookies to deliver better user experience
delta
and epsilon
, corresponding to the power consumption of the submarine. It will be easier to follow the calculations if we consider our dataset to be a two-dimensional array of bits.delta
value is a sequence generated by locating the most common value on each column of our two-dimensional array. The epsilon
value is a sequence of the least common values of each column.delta
and epsilon
values, we have to convert the binary numbers to decimals. Finally, we need the product of those two numbers.POWER_CONSUMPTION(Values)
Input: A list of binary numbers
Output: The product of delta times epsilon values
FOR i=0 TO Length(Values[0])
common += GetMostCommon(Values, i)
uncommon += GetLeastCommon(Values, i)
ENDFOR
common = ConvertToDecimal(common)
uncommon = ConvertToDecimal(uncommon)
return common * uncommon
GetBitsAt
method:private static string[] GetBitsAt(string[] sequence, int index)
{
if (index > sequence[0].Length)
throw new ArgumentOutOfRangeException(nameof(index));
string[] bits = new string[sequence.Length];
for (int i = 0; i < sequence.Length; i++)
{
bits[i] = sequence[i][index].ToString();
}
return bits;
}
index
argument.MostCommon
method:public static string MostCommon(string[] sequence)
=> sequence.GroupBy(v => v)
.OrderByDescending(g => g.Count())
.First()
.Key;
GroupBy(v => v)
: The sequence elements will be grouped to 0
and 1
.OrderByDescending(g => g.Count())
: The two groups will be ordered in descending order based on their respective element counts.First()
: This will return the first element of the first group.Key
: The value of the extracted element.var gammaRate = "";
var epsilonRate = "";
for (int i = 0; i < data[0].Length; i++)
{
string mostCommon = MostCommon(GetBitsAt(data, i));
gammaRate += mostCommon;
if (mostCommon.Equals("1"))
epsilonRate += "0";
else
epsilonRate += "1";
}
var result = Convert.ToInt32(gammaRate, 2) * Convert.ToInt32(epsilonRate, 2);
delta
value from the previous puzzle. Keep only the sequences that have the most common bit on each position. The only difference is that if there are an equal number of 0
bits and 1
bits, keep the sequences with 1
in that position.0
in that position.MostCommon
and GetBitAt
methods from the previous puzzle. I am not proud of this solution because it has some code replication, and some refactoring is definitely of order, but this is the solution I came up with when I first solved it. I guess this is the downside of competitive programming.HasMostCommon
method checks if the given sequence has the most common bit on that position.private static bool HasMostCommon(string sequence, string bit, int position)
=> sequence[position].ToString().Equals(bit);
GetOxygenRating
and GetCO2Rating
calculate the oxygen and CO2 ratings respectively, in a recursive manner.private static string GetOxygenRating(string[] sequences, int index)
{
if (sequences.Length == 1)
return sequences[0];
string mostCommon = Utils.MostCommon(GetBitsAt(sequences, index));
List<string> common = new();
List<string> uncommon = new();
foreach (var sequence in sequences)
{
if (HasMostCommon(sequence, mostCommon, index))
common.Add(sequence);
else
uncommon.Add(sequence);
}
if (common.Count == uncommon.Count)
if (uncommon[0][index].ToString().Equals("1"))
return GetOxygenRating(uncommon.ToArray(), index + 1);
return GetOxygenRating(common.ToArray(), index + 1);
}
private static string GetCO2Rating(string[] sequences, int index)
{
if (sequences.Length == 1)
return sequences[0];
string mostCommon = Utils.MostCommon(GetBitsAt(sequences, index));
List<string> common = new List<string>();
List<string> uncommon = new List<string>();
foreach (var sequence in sequences)
{
if (HasMostCommon(sequence, mostCommon, index))
common.Add(sequence);
else
uncommon.Add(sequence);
}
if (common.Count == uncommon.Count)
if (common[0][index].ToString().Equals("0"))
return GetCO2Rating(common.ToArray(), index + 1);
return GetCO2Rating(uncommon.ToArray(), index + 1);
}
HasMostCommon
method checks if the given sequence has the most common bit on that position.string oxygen = GetOxygenRating(data, 0);
string co2 = GetCO2Rating(data, 0);
var result = (Convert.ToInt32(oxygen, 2) * Convert.ToInt32(co2, 2))