Repository: exercism/csharp
Pull request #2398: Add intergalactic transmission exercise
Author: login: kahgoh
Created: 2025-03-03T14:40:36Z | Merged: 2025-04-18T07:06:09Z

Exercise for parity bit (http://forum.exercism.org/t/add-new-practice-exercises/16050/4)


Diff:
diff --git a/config.json b/config.json
index 908da5831..df37a59b1 100644
--- a/config.json
+++ b/config.json
@@ -2714,6 +2714,23 @@
         ],
         "difficulty": 7
       },
+      {
+        "slug": "intergalactic-transmission",
+        "name": "intergalactic-transmission",
+        "uuid": "845c8cf4-207c-438f-9d18-c5e7875ee729",
+        "practices": [
+          "bit-manipulation"
+        ],
+        "prerequisites": [
+          "bit-manipulation",
+          "arrays",
+          "exceptions",
+          "integral-numbers",
+          "for-loops",
+          "if-statements"
+        ],
+        "difficulty": 6
+      },
       {
         "slug": "split-second-stopwatch",
         "name": "Split-Second Stopwatch",
diff --git a/exercises/Exercises.sln b/exercises/Exercises.sln
index 006267b96..08e9a3d9c 100644
--- a/exercises/Exercises.sln
+++ b/exercises/Exercises.sln
@@ -357,6 +357,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StateOfTicTacToe", "practic
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BottleSong", "practice\bottle-song\BottleSong.csproj", "{6BD384E6-225E-4F8A-856C-3079957C6E36}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "IntergalacticTransmission", "practice\intergalactic-transmission\IntergalacticTransmission.csproj", "{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}"
+EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SplitSecondStopwatch", "practice\split-second-stopwatch\SplitSecondStopwatch.csproj", "{0A6CD51A-2120-4A72-A17B-08CCC2E6D365}"
 EndProject
 Global
@@ -2469,18 +2471,18 @@ Global
 		{6BD384E6-225E-4F8A-856C-3079957C6E36}.Release|x64.Build.0 = Release|Any CPU
 		{6BD384E6-225E-4F8A-856C-3079957C6E36}.Release|x86.ActiveCfg = Release|Any CPU
 		{6BD384E6-225E-4F8A-856C-3079957C6E36}.Release|x86.Build.0 = Release|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Debug|x64.ActiveCfg = Debug|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Debug|x64.Build.0 = Debug|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Debug|x86.Build.0 = Debug|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Release|Any CPU.Build.0 = Release|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Release|x64.ActiveCfg = Release|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Release|x64.Build.0 = Release|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Release|x86.ActiveCfg = Release|Any CPU
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692}.Release|x86.Build.0 = Release|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Debug|x64.Build.0 = Debug|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Debug|x86.Build.0 = Debug|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Release|x64.ActiveCfg = Release|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Release|x64.Build.0 = Release|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Release|x86.ActiveCfg = Release|Any CPU
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5}.Release|x86.Build.0 = Release|Any CPU
 		{0A6CD51A-2120-4A72-A17B-08CCC2E6D365}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{0A6CD51A-2120-4A72-A17B-08CCC2E6D365}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{0A6CD51A-2120-4A72-A17B-08CCC2E6D365}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -2673,9 +2675,8 @@ Global
 		{8E276065-1371-4CFA-BA20-95225EC6AEBC} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
 		{67E9BAB3-9805-42F1-9298-E9BBB795140E} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
 		{6BD384E6-225E-4F8A-856C-3079957C6E36} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
-		{DA4856F5-A260-43A0-9C9C-6DD2E2B08692} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
-		{B587F905-CC4E-0FB1-25B1-84C433FD33E0} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
-		{0A6CD51A-2120-4A72-A17B-08CCC2E6D365} = {B587F905-CC4E-0FB1-25B1-84C433FD33E0}
+		{E81F1BA3-1F99-4DCB-B875-78D1F4750BD5} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
+		{0A6CD51A-2120-4A72-A17B-08CCC2E6D365} = {E276EF69-669A-43E0-88AC-8ABB17A9C026}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {AB4EA6C9-5461-4024-BDC7-2AE0C3A85CD1}
diff --git a/exercises/practice/intergalactic-transmission/.docs/instructions.md b/exercises/practice/intergalactic-transmission/.docs/instructions.md
new file mode 100644
index 000000000..63fe661e0
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/.docs/instructions.md
@@ -0,0 +1,54 @@
+# Instructions
+
+Your job is to help implement
+
+- the transmitter, which calculates the transmission sequence, and
+- the receiver, which decodes it.
+
+A parity bit is simple way of detecting transmission errors.
+The transmitters and receivers can only transmit and receive _exactly_ eight bits at a time (including the parity bit).
+The parity bit is set so that there is an _even_ number 1s in each transmission and is always the first bit from the right.
+So if the receiver receives `11000001`, `01110101` or `01000000` (i.e. a transmission with an odd number of 1 bits), it knows there is an error.
+
+However, messages are rarely this short, and need to be transmitted in a sequence when they are longer.
+
+For example, consider the message `11000000 00000001 11000000 11011110` (or `C0 01 C0 DE` in hex).
+
+Since each transmission contains exactly eight bits, it can only contain seven bits of data and the parity bit.
+A parity bit must then be inserted after every seven bits of data:
+
+```text
+11000000 00000001 11000000 11011110
+      ↑       ↑       ↑       ↑          (7th bits)
+```
+
+The transmission sequence for this message looks like this:
+
+```text
+1100000_ 0000000_ 0111000_ 0001101_ 1110
+       ↑        ↑        ↑        ↑      (parity bits)
+```
+
+The data in the first transmission in the sequence (`1100000`) has two 1 bits (an even number), so the parity bit is 0.
+The first transmission becomes `11000000` (or `C0` in hex).
+
+The data in the next transmission (`0000000`) has zero 1 bits (an even number again), so the parity bit is 0 again.
+The second transmission thus becomes `00000000` (or `00` in hex).
+
+The data for the next two transmissions (`0111000` and `0001101`) have three 1 bits.
+Their parity bits are set to 1 so that they have an even number of 1 bits in the transmission.
+They are transmitted as `01110001` and `00011011` (or `71` and `1B` in hex).
+
+The last transmission (`1110`) has only four bits of data.
+Since exactly eight bits are transmitted at a time and the parity bit is the right most bit, three 0 bits and then the parity bit are added to make up eight bits.
+It now looks like this (where `_` is the parity bit):
+
+```text
+1110 000_
+     ↑↑↑   (added 0 bits)
+```
+
+There is an odd number of 1 bits again, so the parity bit is 1.
+The last transmission in the sequence becomes `11100001` (or `E1` in hex).
+
+The entire transmission sequence for this message is `11000000 00000000 01110001 00011011 11100001` (or `C0 00 71 1B E1` in hex).
diff --git a/exercises/practice/intergalactic-transmission/.docs/introduction.md b/exercises/practice/intergalactic-transmission/.docs/introduction.md
new file mode 100644
index 000000000..f19dffbea
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/.docs/introduction.md
@@ -0,0 +1,23 @@
+# Introduction
+
+Trillions upon trillions of messages zip between Earth and neighboring galaxies every millisecond.
+But transmitting over such long distances is tricky.
+Pesky solar flares, temporal distortions, stray forces, and even the flap of a space butterfly's wing can cause a random bit to change during transmission.
+
+Now imagine the consequences:
+
+- Crashing the Intergalactic Share Market when "buy low" turns to "sell now".
+- Losing contact with the Kepler Whirl system when "save new worm hole" becomes "cave new worm hole".
+- Or plunging the universe into existential horror by replacing a cowboy emoji 🤠 with a clown emoji 🤡.
+
+Detecting corrupted messages isn't just important — it's critical.
+The receiver _must_ know when something has gone wrong before disaster strikes.
+
+But how?
+Scientists and engineers from across the universe have been battling this problem for eons.
+Entire cosmic AI superclusters churn through the data.
+And then, one day, a legend resurfaces — an ancient, powerful method, whispered in debugging forums, muttered by engineers who've seen too much...
+
+The Parity Bit!
+
+A method so simple, so powerful, that it might just save interstellar communication.
diff --git a/exercises/practice/intergalactic-transmission/.editorconfig b/exercises/practice/intergalactic-transmission/.editorconfig
new file mode 100644
index 000000000..182213a7d
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/.editorconfig
@@ -0,0 +1,141 @@
+###############################
+# Core EditorConfig Options   #
+###############################
+
+; This file is for unifying the coding style for different editors and IDEs.
+; More information at:
+; https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference?view=vs-2017
+; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2017
+
+root = true
+
+[*]
+indent_style = space
+
+[IntergalacticTransmission.cs]
+indent_size = 4
+
+###############################
+# .NET Coding Conventions     #
+###############################
+
+# Organize usings
+dotnet_sort_system_directives_first = true
+dotnet_separate_import_directive_groups = true
+
+# this. preferences
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+
+# Language keywords vs BCL types preferences
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# Parentheses preferences
+dotnet_style_parentheses_in_arithmetic_binary_operators = never_if_unnecessary:none
+dotnet_style_parentheses_in_relational_binary_operators = never_if_unnecessary:none
+dotnet_style_parentheses_in_other_binary_operators = never_if_unnecessary:none
+dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
+
+# Modifier preferences
+dotnet_style_require_accessibility_modifiers = always:suggestion
+dotnet_style_readonly_field = true:suggestion
+
+# Expression-level preferences
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_tuple_names = true:suggestion
+dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
+dotnet_style_prefer_auto_properties = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+dotnet_style_prefer_conditional_expression_over_assignment = true:suggestion
+dotnet_style_prefer_conditional_expression_over_return = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+
+###############################
+# Naming Conventions          #
+###############################
+
+# Style Definitions
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+
+# Use PascalCase for constant fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
+dotnet_naming_symbols.constant_fields.applicable_kinds = field
+dotnet_naming_symbols.constant_fields.applicable_accessibilities = *
+dotnet_naming_symbols.constant_fields.required_modifiers = const
+
+###############################
+# C# Code Style Rules         #
+###############################
+
+# var preferences
+csharp_style_var_for_built_in_types = true:none
+csharp_style_var_when_type_is_apparent = true:none
+csharp_style_var_elsewhere = true:none
+
+# Expression-bodied members
+csharp_style_expression_bodied_methods = true:suggestion
+csharp_style_expression_bodied_constructors = true:suggestion
+csharp_style_expression_bodied_operators = true:suggestion
+csharp_style_expression_bodied_properties = true:suggestion
+csharp_style_expression_bodied_indexers = true:suggestion
+csharp_style_expression_bodied_accessors = true:suggestion
+
+# Pattern-matching preferences
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+
+# Null-checking preferences
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Modifier preferences
+csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion
+
+# Expression-level preferences
+csharp_prefer_braces = true:none
+csharp_prefer_simple_default_expression = true:suggestion
+csharp_style_deconstructed_variable_declaration = true:suggestion
+csharp_style_pattern_local_over_anonymous_function = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+
+###############################
+# C# Formatting Rules         #
+###############################
+
+# New line preferences
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = false
+csharp_new_line_before_members_in_anonymous_types = false
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = flush_left
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+
+# Wrapping preferences
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = true
diff --git a/exercises/practice/intergalactic-transmission/.meta/Example.cs b/exercises/practice/intergalactic-transmission/.meta/Example.cs
new file mode 100644
index 000000000..bf1af354e
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/.meta/Example.cs
@@ -0,0 +1,91 @@
+public static class IntergalacticTransmission
+{
+    private const byte InitUpperMask = (byte)0xFE;
+
+    public static byte[] GetTransmitSequence(byte[] message)
+    {
+        List<byte> transmitSeq = new List<byte>();
+        byte carry = 0;
+        byte upperMask = InitUpperMask;
+
+        for (int i = 0; i < message.Length; i++)
+        {
+            if (upperMask == 0)
+            {
+                // The carry now contains 7 bits. Flush the carry out.
+                transmitSeq.Add(AddParity(carry));
+                carry = 0;
+                upperMask = 0xFE;
+            }
+
+            int shiftPlaces = byte.TrailingZeroCount(upperMask);
+            int current = (carry << (8 - shiftPlaces)) | (message[i] >>> shiftPlaces);
+            transmitSeq.Add(AddParity((byte)current));
+
+            // Update parameters for next round.
+            carry = (byte)(message[i] & (~upperMask));
+
+            // Shorten the upper mask.
+            upperMask = (byte)(upperMask << 1);
+        }
+
+        if (upperMask != InitUpperMask)
+        {
+            byte lastGroup = (byte)(carry << byte.PopCount(upperMask));
+            // We have left over carry data
+            transmitSeq.Add(AddParity(lastGroup));
+        }
+        return transmitSeq.ToArray();
+    }
+
+    private static byte AddParity(byte source)
+    {
+        if (byte.PopCount((byte)(source & 0x7F)) % 2 == 0)
+        {
+            return (byte)(source << 1);
+        }
+        return (byte)((source << 1) | 1);
+    }
+
+    public static byte[] DecodeSequence(byte[] receivedSeq)
+    {
+        if (receivedSeq.Length == 0)
+        {
+            return [];
+        }
+
+        List<byte> decodedMessage = new List<byte>();
+        byte byteToAdd = 0x00;
+        byte upperMask = 0xFF;
+        for (int i = 0; i < receivedSeq.Length; i++)
+        {
+            if (upperMask == 0xFF)
+            {
+                // We've completed a complete round.
+                // Current byte too short.
+                byteToAdd = GetByteData(receivedSeq[i]);
+                upperMask = 0x80;
+                continue;
+            }
+
+            byte currentByteData = GetByteData(receivedSeq[i]);
+            byte contribution = (byte)(currentByteData >>> byte.TrailingZeroCount(upperMask));
+            decodedMessage.Add((byte)(byteToAdd | contribution));
+
+            // Update parameters for next round
+            byteToAdd = (byte)((currentByteData & ~(upperMask | 0x01)) << byte.PopCount(upperMask));
+            upperMask = (byte)((upperMask >> 1) | 0x80);
+        }
+        return decodedMessage.ToArray();
+    }
+
+    private static byte GetByteData(byte data)
+    {
+        if (byte.PopCount(data) % 2 != 0)
+        {
+            throw new ArgumentException("Byte has incorrect parity");
+        }
+
+        return (byte)(data & 0xFE);
+    }
+}
diff --git a/exercises/practice/intergalactic-transmission/.meta/Generator.tpl b/exercises/practice/intergalactic-transmission/.meta/Generator.tpl
new file mode 100644
index 000000000..e8f41982a
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/.meta/Generator.tpl
@@ -0,0 +1,19 @@
+public class {{ testClass }}
+{
+    {{- for test in tests }}
+    [Fact{{ if !for.first }}(Skip = "Remove this Skip property to run this test"){{ end }}]
+    public void {{ test.testMethod }}()
+    {
+        {{- message = string.replace test.input.message "\"" "" }}
+        {{- if test.property == "transmitSequence" }}
+        Assert.Equal({{ string.replace test.expected "\"" "" }}, IntergalacticTransmission.GetTransmitSequence({{ message }}));
+        {{- else if test.property == "decodeMessage" }}
+        {{- if test.expected.error }}
+        Assert.Throws<ArgumentException>(() => IntergalacticTransmission.DecodeSequence({{ message }}));        
+        {{- else }}
+        Assert.Equal({{ string.replace test.expected "\"" "" }}, IntergalacticTransmission.DecodeSequence({{ message }}));
+        {{ end -}}
+        {{ end -}}
+    }
+    {{ end -}}
+}
diff --git a/exercises/practice/intergalactic-transmission/.meta/config.json b/exercises/practice/intergalactic-transmission/.meta/config.json
new file mode 100644
index 000000000..f9f6fdd34
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/.meta/config.json
@@ -0,0 +1,22 @@
+{
+  "authors": [
+    "kahgoh"
+  ],
+  "files": {
+    "solution": [
+      "IntergalacticTransmission.cs"
+    ],
+    "test": [
+      "IntergalacticTransmissionTests.cs"
+    ],
+    "example": [
+      ".meta/Example.cs"
+    ],
+    "invalidator": [
+      "IntergalacticTransmission.csproj"
+    ]
+  },
+  "blurb": "Add parity bits to a message for transmission",
+  "source": "Kah Goh",
+  "source_url": "https://github.com/exercism/problem-specifications/pull/2543"
+}
diff --git a/exercises/practice/intergalactic-transmission/.meta/tests.toml b/exercises/practice/intergalactic-transmission/.meta/tests.toml
new file mode 100644
index 000000000..37ebc138e
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/.meta/tests.toml
@@ -0,0 +1,82 @@
+# This is an auto-generated file.
+#
+# Regenerating this file via `configlet sync` will:
+# - Recreate every `description` key/value pair
+# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
+# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
+# - Preserve any other key/value pair
+#
+# As user-added comments (using the # character) will be removed when this file
+# is regenerated, comments can be added via a `comment` key.
+
+[f99d4046-b429-4582-9324-f0bcac7ab51c]
+description = "calculate transmit sequences -> empty message"
+
+[ee27ea2d-8999-4f23-9275-8f6879545f86]
+description = "calculate transmit sequences -> 0x00 is transmitted as 0x0000"
+
+[97f27f98-8020-402d-be85-f21ba54a6df0]
+description = "calculate transmit sequences -> 0x02 is transmitted as 0x0300"
+
+[24712fb9-0336-4e2f-835e-d2350f29c420]
+description = "calculate transmit sequences -> 0x06 is transmitted as 0x0600"
+
+[7630b5a9-dba1-4178-b2a0-4a376f7414e0]
+description = "calculate transmit sequences -> 0x05 is transmitted as 0x0581"
+
+[ab4fe80b-ef8e-4a99-b4fb-001937af415d]
+description = "calculate transmit sequences -> 0x29 is transmitted as 0x2881"
+
+[4e200d84-593b-4449-b7c0-4de1b6a0955e]
+description = "calculate transmit sequences -> 0xc001c0de is transmitted as 0xc000711be1"
+
+[fbc537e9-6b21-4f4a-8c2b-9cf9b702a9b7]
+description = "calculate transmit sequences -> six byte message"
+
+[d5b75adf-b5fc-4f77-b4ab-77653e30f07c]
+description = "calculate transmit sequences -> seven byte message"
+
+[6d8b297b-da1d-435e-bcd7-55fbb1400e73]
+description = "calculate transmit sequences -> eight byte message"
+
+[54a0642a-d5aa-490c-be89-8e171a0cab6f]
+description = "calculate transmit sequences -> twenty byte message"
+
+[879af739-0094-4736-9127-bd441b1ddbbf]
+description = "decode received messages -> zero message"
+
+[7a89eeef-96c5-4329-a246-ec181a8e959a]
+description = "decode received messages -> 0x0300 is decoded to 0x02"
+
+[3e515af7-8b62-417f-960c-3454bca7f806]
+description = "decode received messages -> 0x0581 is decoded to 0x05"
+
+[a1b4a3f7-9f05-4b7a-b86e-d7c6fc3f16a9]
+description = "decode received messages -> 0x2881 is decoded to 0x29"
+
+[2e99d617-4c91-4ad5-9217-e4b2447d6e4a]
+description = "decode received messages -> first byte has wrong parity"
+
+[507e212d-3dae-42e8-88b4-2223838ff8d2]
+description = "decode received messages -> second byte has wrong parity"
+
+[b985692e-6338-46c7-8cea-bc38996d4dfd]
+description = "decode received messages -> 0xcf4b00 is decoded to 0xce94"
+
+[467549dc-a558-443b-80c5-ff3d4eb305d4]
+description = "decode received messages -> six byte message"
+
+[1f3be5fb-093a-4661-9951-c1c4781c71ea]
+description = "decode received messages -> seven byte message"
+
+[6065b8b3-9dcd-45c9-918c-b427cfdb28c1]
+description = "decode received messages -> last byte has wrong parity"
+
+[98af97b7-9cca-4c4c-9de3-f70e227a4cb1]
+description = "decode received messages -> eight byte message"
+
+[aa7d4785-2bb9-43a4-a38a-203325c464fb]
+description = "decode received messages -> twenty byte message"
+
+[4c86e034-b066-42ac-8497-48f9bc1723c1]
+description = "decode received messages -> wrong parity on 16th byte"
diff --git a/exercises/practice/intergalactic-transmission/IntergalacticTransmission.cs b/exercises/practice/intergalactic-transmission/IntergalacticTransmission.cs
new file mode 100644
index 000000000..5c4612df8
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/IntergalacticTransmission.cs
@@ -0,0 +1,12 @@
+public static class IntergalacticTransmission
+{
+    public static byte[] GetTransmitSequence(byte[] message)
+    {
+        throw new NotImplementedException("You need to implement this method.");
+    }
+
+    public static byte[] DecodeSequence(byte[] receivedSeq)
+    {
+        throw new NotImplementedException("You need to implement this method.");
+    }
+}
diff --git a/exercises/practice/intergalactic-transmission/IntergalacticTransmission.csproj b/exercises/practice/intergalactic-transmission/IntergalacticTransmission.csproj
new file mode 100644
index 000000000..725e436c6
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/IntergalacticTransmission.csproj
@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+  <PropertyGroup>
+    <TargetFramework>net9.0</TargetFramework>
+    <OutputType>Exe</OutputType>
+    <Nullable>enable</Nullable>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Using Include="Xunit" />
+  </ItemGroup>
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
+    <PackageReference Include="xunit.v3" Version="1.1.0" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="3.0.1" />
+    <PackageReference Include="Exercism.Tests.xunit.v3" Version="0.1.0-beta1" />
+  </ItemGroup>
+</Project>
diff --git a/exercises/practice/intergalactic-transmission/IntergalacticTransmissionTests.cs b/exercises/practice/intergalactic-transmission/IntergalacticTransmissionTests.cs
new file mode 100644
index 000000000..3081d5c43
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/IntergalacticTransmissionTests.cs
@@ -0,0 +1,158 @@
+public class IntergalacticTransmissionTests
+{
+    [Fact]
+    public void Calculate_transmit_sequences_empty_message()
+    {
+        Assert.Equal([], IntergalacticTransmission.GetTransmitSequence([]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_0x00_is_transmitted_as_0x0000()
+    {
+        Assert.Equal([0x00, 0x00], IntergalacticTransmission.GetTransmitSequence([0x00]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_0x02_is_transmitted_as_0x0300()
+    {
+        Assert.Equal([0x03, 0x00], IntergalacticTransmission.GetTransmitSequence([0x02]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_0x06_is_transmitted_as_0x0600()
+    {
+        Assert.Equal([0x06, 0x00], IntergalacticTransmission.GetTransmitSequence([0x06]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_0x05_is_transmitted_as_0x0581()
+    {
+        Assert.Equal([0x05, 0x81], IntergalacticTransmission.GetTransmitSequence([0x05]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_0x29_is_transmitted_as_0x2881()
+    {
+        Assert.Equal([0x28, 0x81], IntergalacticTransmission.GetTransmitSequence([0x29]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_0xc001c0de_is_transmitted_as_0xc000711be1()
+    {
+        Assert.Equal([0xc0, 0x00, 0x71, 0x1b, 0xe1], IntergalacticTransmission.GetTransmitSequence([0xc0, 0x01, 0xc0, 0xde]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_six_byte_message()
+    {
+        Assert.Equal([0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0x84], IntergalacticTransmission.GetTransmitSequence([0x47, 0x72, 0x65, 0x61, 0x74, 0x21]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_seven_byte_message()
+    {
+        Assert.Equal([0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0xc5, 0x42], IntergalacticTransmission.GetTransmitSequence([0x47, 0x72, 0x65, 0x61, 0x74, 0x31, 0x21]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_eight_byte_message()
+    {
+        Assert.Equal([0xc0, 0x00, 0x44, 0x66, 0x7d, 0x06, 0x78, 0x42, 0x21, 0x81], IntergalacticTransmission.GetTransmitSequence([0xc0, 0x01, 0x13, 0x37, 0xc0, 0xde, 0x21, 0x21]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Calculate_transmit_sequences_twenty_byte_message()
+    {
+        Assert.Equal([0x44, 0xbd, 0x18, 0xaf, 0x27, 0x1b, 0xa5, 0xe7, 0x6c, 0x90, 0x1b, 0x2e, 0x33, 0x03, 0x84, 0xee, 0x65, 0xb8, 0xdb, 0xed, 0xd7, 0x28, 0x84], IntergalacticTransmission.GetTransmitSequence([0x45, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x6d, 0x20, 0x69, 0x73, 0x20, 0x61, 0x77, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x21]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_empty_message()
+    {
+        Assert.Equal([], IntergalacticTransmission.DecodeSequence([]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_zero_message()
+    {
+        Assert.Equal([0x00], IntergalacticTransmission.DecodeSequence([0x00, 0x00]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_0x0300_is_decoded_to_0x02()
+    {
+        Assert.Equal([0x02], IntergalacticTransmission.DecodeSequence([0x03, 0x00]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_0x0581_is_decoded_to_0x05()
+    {
+        Assert.Equal([0x05], IntergalacticTransmission.DecodeSequence([0x05, 0x81]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_0x2881_is_decoded_to_0x29()
+    {
+        Assert.Equal([0x29], IntergalacticTransmission.DecodeSequence([0x28, 0x81]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_first_byte_has_wrong_parity()
+    {
+        Assert.Throws<ArgumentException>(() => IntergalacticTransmission.DecodeSequence([0x07, 0x00]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_second_byte_has_wrong_parity()
+    {
+        Assert.Throws<ArgumentException>(() => IntergalacticTransmission.DecodeSequence([0x03, 0x68]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_0xcf4b00_is_decoded_to_0xce94()
+    {
+        Assert.Equal([0xce, 0x94], IntergalacticTransmission.DecodeSequence([0xcf, 0x4b, 0x00]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_0xe2566500_is_decoded_to_0xe2ad90()
+    {
+        Assert.Equal([0xe2, 0xad, 0x90], IntergalacticTransmission.DecodeSequence([0xe2, 0x56, 0x65, 0x00]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_six_byte_message()
+    {
+        Assert.Equal([0x47, 0x72, 0x65, 0x61, 0x74, 0x21], IntergalacticTransmission.DecodeSequence([0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0x84]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_seven_byte_message()
+    {
+        Assert.Equal([0x47, 0x72, 0x65, 0x61, 0x74, 0x31, 0x21], IntergalacticTransmission.DecodeSequence([0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0xc5, 0x42]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_last_byte_has_wrong_parity()
+    {
+        Assert.Throws<ArgumentException>(() => IntergalacticTransmission.DecodeSequence([0x47, 0xb8, 0x99, 0xac, 0x17, 0xa0, 0xc5, 0x43]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_eight_byte_message()
+    {
+        Assert.Equal([0xc0, 0x01, 0x13, 0x37, 0xc0, 0xde, 0x21, 0x21], IntergalacticTransmission.DecodeSequence([0xc0, 0x00, 0x44, 0x66, 0x7d, 0x06, 0x78, 0x42, 0x21, 0x81]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_twenty_byte_message()
+    {
+        Assert.Equal([0x45, 0x78, 0x65, 0x72, 0x63, 0x69, 0x73, 0x6d, 0x20, 0x69, 0x73, 0x20, 0x61, 0x77, 0x65, 0x73, 0x6f, 0x6d, 0x65, 0x21], IntergalacticTransmission.DecodeSequence([0x44, 0xbd, 0x18, 0xaf, 0x27, 0x1b, 0xa5, 0xe7, 0x6c, 0x90, 0x1b, 0x2e, 0x33, 0x03, 0x84, 0xee, 0x65, 0xb8, 0xdb, 0xed, 0xd7, 0x28, 0x84]));
+    }
+
+    [Fact(Skip = "Remove this Skip property to run this test")]
+    public void Decode_received_messages_wrong_parity_on_16th_byte()
+    {
+        Assert.Throws<ArgumentException>(() => IntergalacticTransmission.DecodeSequence([0x44, 0xbd, 0x18, 0xaf, 0x27, 0x1b, 0xa5, 0xe7, 0x6c, 0x90, 0x1b, 0x2e, 0x33, 0x03, 0x84, 0xef, 0x65, 0xb8, 0xdb, 0xed, 0xd7, 0x28, 0x84]));
+    }
+}
diff --git a/exercises/practice/intergalactic-transmission/packages.lock.json b/exercises/practice/intergalactic-transmission/packages.lock.json
new file mode 100644
index 000000000..6b3387771
--- /dev/null
+++ b/exercises/practice/intergalactic-transmission/packages.lock.json
@@ -0,0 +1,170 @@
+{
+  "version": 1,
+  "dependencies": {
+    "net9.0": {
+      "Exercism.Tests.xunit.v3": {
+        "type": "Direct",
+        "requested": "[0.1.0-beta1, )",
+        "resolved": "0.1.0-beta1",
+        "contentHash": "XjVtQWWxmHDDj7UMdkPKpBFFKnsW0tkBhlyJSfFFh+fWwGemyyJwJYhdsvWhiKKCY7zItB+mI/o0OQtOKQxUhA==",
+        "dependencies": {
+          "xunit.v3.extensibility.core": "1.1.0"
+        }
+      },
+      "Microsoft.NET.Test.Sdk": {
+        "type": "Direct",
+        "requested": "[17.12.0, )",
+        "resolved": "17.12.0",
+        "contentHash": "kt/PKBZ91rFCWxVIJZSgVLk+YR+4KxTuHf799ho8WNiK5ZQpJNAEZCAWX86vcKrs+DiYjiibpYKdGZP6+/N17w==",
+        "dependencies": {
+          "Microsoft.CodeCoverage": "17.12.0",
+          "Microsoft.TestPlatform.TestHost": "17.12.0"
+        }
+      },
+      "xunit.runner.visualstudio": {
+        "type": "Direct",
+        "requested": "[3.0.1, )",
+        "resolved": "3.0.1",
+        "contentHash": "lbyYtsBxA8Pz8kaf5Xn/Mj1mL9z2nlBWdZhqFaj66nxXBa4JwiTDm4eGcpSMet6du9TOWI6bfha+gQR6+IHawg=="
+      },
+      "xunit.v3": {
+        "type": "Direct",
+        "requested": "[1.1.0, )",
+        "resolved": "1.1.0",
+        "contentHash": "1ckSz5GVswlM9TCk5bGdHOjnYwqAWjkeqxckoHawQIA8sTeuN+RCBUypCi5A/Um0XlczRx5TjAK5W6BbN0HLcQ==",
+        "dependencies": {
+          "xunit.analyzers": "1.20.0",
+          "xunit.v3.assert": "[1.1.0]",
+          "xunit.v3.core": "[1.1.0]"
+        }
+      },
+      "Microsoft.Bcl.AsyncInterfaces": {
+        "type": "Transitive",
+        "resolved": "6.0.0",
+        "contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg=="
+      },
+      "Microsoft.CodeCoverage": {
+        "type": "Transitive",
+        "resolved": "17.12.0",
+        "contentHash": "4svMznBd5JM21JIG2xZKGNanAHNXplxf/kQDFfLHXQ3OnpJkayRK/TjacFjA+EYmoyuNXHo/sOETEfcYtAzIrA=="
+      },
+      "Microsoft.Testing.Extensions.TrxReport.Abstractions": {
+        "type": "Transitive",
+        "resolved": "1.5.3",
+        "contentHash": "h34zKNpGyni66VH738mRHeXSnf3klSShUdavUWNhSfWICUUi5aXeI0LBvoX/ad93N0+9xBDU3Fyi6WfxrwKQGw==",
+        "dependencies": {
+          "Microsoft.Testing.Platform": "1.5.3"
+        }
+      },
+      "Microsoft.Testing.Platform": {
+        "type": "Transitive",
+        "resolved": "1.5.3",
+        "contentHash": "WqJydnJ99dEKtquR9HwINz104ehWJKTXbQQrydGatlLRw14bmsx0pa8+E6KUXMYXZAimN0swWlDmcJGjjW4TIg=="
+      },
+      "Microsoft.Testing.Platform.MSBuild": {
+        "type": "Transitive",
+        "resolved": "1.5.3",
+        "contentHash": "bOtpRMSPeT5YLQo+NNY8EtdNTphAUcmALjW4ABU7P0rb6yR2XAZau3TzNieLmR3lRuwudguWzzBhgcLRXwZh0A==",
+        "dependencies": {
+          "Microsoft.Testing.Platform": "1.5.3"
+        }
+      },
+      "Microsoft.TestPlatform.ObjectModel": {
+        "type": "Transitive",
+        "resolved": "17.12.0",
+        "contentHash": "TDqkTKLfQuAaPcEb3pDDWnh7b3SyZF+/W9OZvWFp6eJCIiiYFdSB6taE2I6tWrFw5ywhzOb6sreoGJTI6m3rSQ==",
+        "dependencies": {
+          "System.Reflection.Metadata": "1.6.0"
+        }
+      },
+      "Microsoft.TestPlatform.TestHost": {
+        "type": "Transitive",
+        "resolved": "17.12.0",
+        "contentHash": "MiPEJQNyADfwZ4pJNpQex+t9/jOClBGMiCiVVFuELCMSX2nmNfvUor3uFVxNNCg30uxDP8JDYfPnMXQzsfzYyg==",
+        "dependencies": {
+          "Microsoft.TestPlatform.ObjectModel": "17.12.0",
+          "Newtonsoft.Json": "13.0.1"
+        }
+      },
+      "Newtonsoft.Json": {
+        "type": "Transitive",
+        "resolved": "13.0.1",
+        "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A=="
+      },
+      "System.Collections.Immutable": {
+        "type": "Transitive",
+        "resolved": "8.0.0",
+        "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg=="
+      },
+      "System.Memory": {
+        "type": "Transitive",
+        "resolved": "4.6.0",
+        "contentHash": "OEkbBQoklHngJ8UD8ez2AERSk2g+/qpAaSWWCBFbpH727HxDq5ydVkuncBaKcKfwRqXGWx64dS6G1SUScMsitg=="
+      },
+      "System.Reflection.Metadata": {
+        "type": "Transitive",
+        "resolved": "1.6.0",
+        "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ=="
+      },
+      "xunit.analyzers": {
+        "type": "Transitive",
+        "resolved": "1.20.0",
+        "contentHash": "HElev2E9vFbPxwKRQtpCSSzLOu8M/N9EWBCB37v7SRx6z4Lbj19FxfLEig3v9jiI6s4b0l2uena91nEsTWl9jA=="
+      },
+      "xunit.v3.assert": {
+        "type": "Transitive",
+        "resolved": "1.1.0",
+        "contentHash": "4D+eM08ImfhA+zLbRzi8HA4qsT98zDxgaCD7vCg8yFesokKsgSsqWsAmImHFjVymGVhVS7WFGb19d6v1k9i0xQ==",
+        "dependencies": {
+          "System.Collections.Immutable": "8.0.0",
+          "System.Memory": "4.6.0"
+        }
+      },
+      "xunit.v3.common": {
+        "type": "Transitive",
+        "resolved": "1.1.0",
+        "contentHash": "Cq55z8pC7fOkfj+3TB/YQ6OW96qWqxKiMd15CtkIl37VtV9EsiUL4B4HsR6VLJCzkk7cBiXQ1ABVIcp3TCm6HQ==",
+        "dependencies": {
+          "Microsoft.Bcl.AsyncInterfaces": "6.0.0"
+        }
+      },
+      "xunit.v3.core": {
+        "type": "Transitive",
+        "resolved": "1.1.0",
+        "contentHash": "kXP/1d3jnQ2m4skcdM3gSMmubI6P747D6KVswzeedysgFkLj2xJlfo7p7slsmtEnp8BZb8X6D92Hssd/UtVPMw==",
+        "dependencies": {
+          "Microsoft.Testing.Platform.MSBuild": "1.5.3",
+          "xunit.v3.extensibility.core": "[1.1.0]",
+          "xunit.v3.runner.inproc.console": "[1.1.0]"
+        }
+      },
+      "xunit.v3.extensibility.core": {
+        "type": "Transitive",
+        "resolved": "1.1.0",
+        "contentHash": "AeQbbYN001x0c+B9pqwml6jZPovHz8O/sOp7jmrjz90rUzz/QPal12SlHLKYszR44CMnW4MsDam3RYT5pkYUxw==",
+        "dependencies": {
+          "xunit.v3.common": "[1.1.0]"
+        }
+      },
+      "xunit.v3.runner.common": {
+        "type": "Transitive",
+        "resolved": "1.1.0",
+        "contentHash": "Q81J0VPuu8fpF+/1CIjThqKKUjnqh0TQrLlD0iORkF75KdsOV+iGWT8c3AVuY96kDoxXxkTf0ZvJsK6o9osc1A==",
+        "dependencies": {
+          "xunit.v3.common": "[1.1.0]"
+        }
+      },
+      "xunit.v3.runner.inproc.console": {
+        "type": "Transitive",
+        "resolved": "1.1.0",
+        "contentHash": "lX/4TwIJe9ysCd5dqLk/Doq8ieYaZGivgf95xR59wRuSV+nHzHnyhpjXfaPUp8nkncUH1rOmJ85o1KebipisXQ==",
+        "dependencies": {
+          "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.5.3",
+          "Microsoft.Testing.Platform": "1.5.3",
+          "xunit.v3.extensibility.core": "[1.1.0]",
+          "xunit.v3.runner.common": "[1.1.0]"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file


Reviews:
user: login: ErikSchierboom
body: Love this! I think this is perfect for a PR to prob-specs. Do you fancy doing that too?
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-03T18:20:19Z
user: login: ErikSchierboom
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-17T17:15:16Z
user: login: kahgoh
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-18T01:30:56Z
user: login: ErikSchierboom
state: APPROVED
author_association: MEMBER
submitted_at: 2025-04-18T07:06:03Z

Review comments:
diff_hunk: @@ -0,0 +1,10 @@
+# Introduction
+
+Trillions upon trillions of messages are exchanged between Earth and the neighboring galaxies every millisecond. 
+But transmission over such long distances faces many obstacles.
+Pesky solar flares, worm holes, temporal distortions, stray forces, heck even the flap of a space butterfly wing can cause a random bit to flip during transmission.
+The difference between an "o" and a "k", a "[" and "{" or a cowboy emoji and a clown emoji can have huge ramifications, from missed orders to Galactic Stockmarket crashes.
+It is important for the receiver to know when the message has been corrupted so that the receiver can ask for the message to sent again.
path: exercises/practice/intergalactic-transmission/.docs/introduction.md
user: login: ErikSchierboom
body: ```suggestion
It is thus important for the receiver to know if a message has been corrupted so that the receiver can ask for the message to be sent again.
```
created_at: 2025-03-03T18:17:52Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,10 @@
+# Introduction
+
+Trillions upon trillions of messages are exchanged between Earth and the neighboring galaxies every millisecond. 
+But transmission over such long distances faces many obstacles.
+Pesky solar flares, worm holes, temporal distortions, stray forces, heck even the flap of a space butterfly wing can cause a random bit to flip during transmission.
+The difference between an "o" and a "k", a "[" and "{" or a cowboy emoji and a clown emoji can have huge ramifications, from missed orders to Galactic Stockmarket crashes.
path: exercises/practice/intergalactic-transmission/.docs/introduction.md
user: login: ErikSchierboom
body: Fantastic backstory!
created_at: 2025-03-03T18:18:00Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,10 @@
+# Introduction
+
+Trillions upon trillions of messages are exchanged between Earth and the neighboring galaxies every millisecond. 
+But transmission over such long distances faces many obstacles.
+Pesky solar flares, worm holes, temporal distortions, stray forces, heck even the flap of a space butterfly wing can cause a random bit to flip during transmission.
+The difference between an "o" and a "k", a "[" and "{" or a cowboy emoji and a clown emoji can have huge ramifications, from missed orders to Galactic Stockmarket crashes.
+It is important for the receiver to know when the message has been corrupted so that the receiver can ask for the message to sent again.
+
+One day, an important message comes through.
+People have just heard about the legend about a way of transmitting in such a way that the receiver can tell when bit flipped ... the parity bit ...
path: exercises/practice/intergalactic-transmission/.docs/introduction.md
user: login: ErikSchierboom
body: I'm not sure I know a better phrasing, but this sentence reads a little weird to me. But we can leave it for now and have others comment on it when we do a prob-specs PR.
created_at: 2025-03-03T18:18:41Z
author_association: MEMBER
diff_hunk: @@ -2714,6 +2714,18 @@
         ],
         "difficulty": 7
       },
+      {
+        "slug": "intergalactic-transmission",
+        "name": "intergalactic-transmission",
+        "uuid": "845c8cf4-207c-438f-9d18-c5e7875ee729",
+        "practices": [
+          "bit-manipulation"
+        ],
+        "prerequisites": [
+          "bit-manipulation"
path: config.json
user: login: ErikSchierboom
body: My only suggestion is to add some more prerequisites.

```suggestion
          "bit-manipulation",
          "arrays",
          "exceptions",
          "integral-numbers",
          "for-loops",
          "if-statements"
```
created_at: 2025-04-17T17:15:11Z
author_association: MEMBER
diff_hunk: @@ -2714,6 +2714,18 @@
         ],
         "difficulty": 7
       },
+      {
+        "slug": "intergalactic-transmission",
+        "name": "intergalactic-transmission",
+        "uuid": "845c8cf4-207c-438f-9d18-c5e7875ee729",
+        "practices": [
+          "bit-manipulation"
+        ],
+        "prerequisites": [
+          "bit-manipulation"
path: config.json
user: login: kahgoh
body: Looks good!
created_at: 2025-04-18T01:30:56Z
author_association: MEMBER

PR comments:
user: login: kahgoh
created_at: 2025-03-03T23:03:07Z
body: > Love this! I think this is perfect for a PR to prob-specs. Do you fancy doing that too?

Thanks for the feedback! Yes, I'd love to create the PR to add this to the problem spec. I'll look to create the PR over the next couple of days.
author_association: MEMBER
user: login: ErikSchierboom
created_at: 2025-04-16T12:53:00Z
body: @kahgoh Now that your probspecs PR has been merged, do you want to make this a proper exercise? It'll require adding a test generator template. See https://github.com/exercism/csharp/blob/main/docs/GENERATORS.md
author_association: MEMBER
user: login: kahgoh
created_at: 2025-04-16T12:59:13Z
body: @ErikSchierboom Yes, I'd like to turn this into a proper exercise. I'll update the PR when ready.
author_association: MEMBER
user: login: kahgoh
created_at: 2025-04-17T12:35:12Z
body: @ErikSchierboom I've just updated the implementation, ready for review! 
author_association: MEMBER
user: login: kahgoh
created_at: 2025-04-18T05:12:30Z
body: I'm not quite sure what happened, but I noticed the [CI started failing](https://github.com/exercism/csharp/actions/runs/14527882624/job/40762666921#step:4:51) on the `exercises/Exercises.sln` (something about a nested project couldn't be found) after adding the prerequisites. In any case, I've added a commit to fix this.
author_association: MEMBER