-
-
Notifications
You must be signed in to change notification settings - Fork 373
Add intergalactic transmission exercise #2398
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
ErikSchierboom
merged 8 commits into
exercism:main
from
kahgoh:exercise/intergalactic-transmission
Apr 18, 2025
Merged
Changes from 5 commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
6ac2e04
Add intergalactic transmission exercise
kahgoh 219773d
Update exercises/practice/intergalactic-transmission/.docs/introducti…
kahgoh 83406dd
Adjust tests
kahgoh c1e3bd3
Merge branch 'main' of github.com:exercism/csharp into exercise/inter…
kahgoh f34951a
Sync intergalactic transmission with problem specs
kahgoh 9c92fd1
Add missing prerequisites
kahgoh 820dd19
Remove sln file
kahgoh ca17ff6
Fix Exercises.sln
kahgoh File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
exercises/practice/intergalactic-transmission/.docs/instructions.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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). |
23 changes: 23 additions & 0 deletions
23
exercises/practice/intergalactic-transmission/.docs/introduction.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
141 changes: 141 additions & 0 deletions
141
exercises/practice/intergalactic-transmission/.editorconfig
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 |
91 changes: 91 additions & 0 deletions
91
exercises/practice/intergalactic-transmission/.meta/Example.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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); | ||
| } | ||
| } |
19 changes: 19 additions & 0 deletions
19
exercises/practice/intergalactic-transmission/.meta/Generator.tpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 -}} | ||
| } |
22 changes: 22 additions & 0 deletions
22
exercises/practice/intergalactic-transmission/.meta/config.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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" | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.