-
-
Notifications
You must be signed in to change notification settings - Fork 359
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
Add intergalactic transmission exercise #2398
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Instructions | ||
|
||
Your job is to help implement the message sequencer to add the parity bit to the messages and the decoder to receive messages. | ||
|
||
The entire message, itself, is sequence of a number of bytes. | ||
The transmitters and receivers can only transmit and receive one byte at a time, so parity bit needs to be added every eighth bit. | ||
The algorithm for adding the bits is as follows: | ||
1. Divide the message bits into groups of 7, starting from the left (the message is transmitted from left to right). | ||
2. If the last group has less than 7 bits, append some 0s to pad the group to 7 bits. | ||
3. For each group, determine if there are an odd or even number of 1s. | ||
4. If the group has even number of 1s or none at all, append a 0 to the group. Otherwise, append 1 if there is odd number. | ||
|
||
For example, consider the message 0xC0_01_C0_DE. | ||
Writing this out in binary and locating every 7th bit: | ||
|
||
```text | ||
C 0 0 1 C 0 D E | ||
1100_0000 0000_0001 1100_0000 1101_1110 | ||
↑ ↑ ↑ ↑ (7th bits) | ||
``` | ||
|
||
The last group has only 4 bits (0b1110), so three 0 bits are appended to make it 7 bits: | ||
|
||
```text | ||
| 1100_000 | 0000_000 | 0111_000 | 0001_101 | 1110_000 | | ||
``` | ||
|
||
The first group contains two 1s (an even number of 1s), so 0 is appended to the group. | ||
The second group has none, so append 0. | ||
The rest have three, so they append 1. | ||
|
||
```text | ||
| 1100_0000 | 0000_0000 | 0111_0001 | 0001_1011 | 1110_0001 | | ||
| C 0 | 0 0 | 7 1 | 1 B | E 1 | (in hex) | ||
``` | ||
|
||
Thus, the transmission sequence is 0xC0_00_71_1B_E1. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 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. | ||
|
||
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 ... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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. |
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 |
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); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
{ | ||
"authors": [ | ||
"kahgoh" | ||
], | ||
"files": { | ||
"solution": [ | ||
"IntergalacticTransmission.cs" | ||
], | ||
"test": [ | ||
"IntergalacticTransmissionTests.cs" | ||
], | ||
"example": [ | ||
".meta/Example.cs" | ||
] | ||
}, | ||
"blurb": "Help detect errors in transmissions to neighboring galaxies" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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."); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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> |
Unchanged files with check annotations Beta
if (count == 0 || count > 6) | ||
{ | ||
inListAfter = list; | ||
return null; | ||
Check warning on line 53 in exercises/practice/markdown/Markdown.cs
|
||
} | ||
var headerTag = "h" + count; | ||
} | ||
inListAfter = list; | ||
return null; | ||
Check warning on line 90 in exercises/practice/markdown/Markdown.cs
|
||
} | ||
private static string ParseParagraph(string markdown, bool list, out bool inListAfter) |
public int Id { get; set; } | ||
public int ParentId { get; set; } | ||
public List<Tree> Children { get; set; } | ||
Check warning on line 12 in exercises/practice/tree-building/TreeBuilding.cs
|
||
public bool IsLeaf => Children.Count == 0; | ||
} |
private static CultureInfo CreateCulture(string cur, string loc) | ||
{ | ||
string curSymb = null; | ||
int curNeg = 0; | ||
string datPat = null; | ||
if (cur != "USD" && cur != "EUR") | ||
{ | ||
} | ||
var culture = new CultureInfo(loc, false); | ||
culture.NumberFormat.CurrencySymbol = curSymb; | ||
culture.NumberFormat.CurrencyNegativePattern = curNeg; | ||
culture.DateTimeFormat.ShortDatePattern = datPat; | ||
return culture; | ||
} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fantastic backstory!