From b9f86db3052b4b38990ef35d456442d99e54eeea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Sun, 2 Aug 2026 19:31:50 -0700 Subject: [PATCH 1/2] Add `strain` --- config.json | 8 + exercises/Exercises.slnx | 1 + .../practice/strain/.docs/instructions.md | 29 +++ exercises/practice/strain/.editorconfig | 89 ++++++++++ exercises/practice/strain/.meta/Example.vb | 34 ++++ exercises/practice/strain/.meta/config.json | 19 ++ exercises/practice/strain/.meta/tests.toml | 52 ++++++ exercises/practice/strain/Strain.vb | 19 ++ exercises/practice/strain/Strain.vbproj | 19 ++ exercises/practice/strain/StrainTests.vb | 130 ++++++++++++++ exercises/practice/strain/packages.lock.json | 168 ++++++++++++++++++ 11 files changed, 568 insertions(+) create mode 100644 exercises/practice/strain/.docs/instructions.md create mode 100644 exercises/practice/strain/.editorconfig create mode 100644 exercises/practice/strain/.meta/Example.vb create mode 100644 exercises/practice/strain/.meta/config.json create mode 100644 exercises/practice/strain/.meta/tests.toml create mode 100644 exercises/practice/strain/Strain.vb create mode 100644 exercises/practice/strain/Strain.vbproj create mode 100644 exercises/practice/strain/StrainTests.vb create mode 100644 exercises/practice/strain/packages.lock.json diff --git a/config.json b/config.json index 64b2d8f8..3427e58c 100644 --- a/config.json +++ b/config.json @@ -690,6 +690,14 @@ ], "difficulty": 2 }, + { + "slug": "strain", + "name": "Strain", + "uuid": "cb9e7d32-db32-4de7-a588-940a3551d24f", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "triangle", "name": "Triangle", diff --git a/exercises/Exercises.slnx b/exercises/Exercises.slnx index 299f9e42..6f87409c 100644 --- a/exercises/Exercises.slnx +++ b/exercises/Exercises.slnx @@ -97,6 +97,7 @@ + diff --git a/exercises/practice/strain/.docs/instructions.md b/exercises/practice/strain/.docs/instructions.md new file mode 100644 index 00000000..3469ae65 --- /dev/null +++ b/exercises/practice/strain/.docs/instructions.md @@ -0,0 +1,29 @@ +# Instructions + +Implement the `keep` and `discard` operation on collections. +Given a collection and a predicate on the collection's elements, `keep` returns a new collection containing those elements where the predicate is true, while `discard` returns a new collection containing those elements where the predicate is false. + +For example, given the collection of numbers: + +- 1, 2, 3, 4, 5 + +And the predicate: + +- is the number even? + +Then your keep operation should produce: + +- 2, 4 + +While your discard operation should produce: + +- 1, 3, 5 + +Note that the union of keep and discard is all the elements. + +The functions may be called `keep` and `discard`, or they may need different names in order to not clash with existing functions or concepts in your language. + +## Restrictions + +Keep your hands off that filter/reject/whatchamacallit functionality provided by your standard library! +Solve this one yourself using other basic tools instead. diff --git a/exercises/practice/strain/.editorconfig b/exercises/practice/strain/.editorconfig new file mode 100644 index 00000000..11f55d27 --- /dev/null +++ b/exercises/practice/strain/.editorconfig @@ -0,0 +1,89 @@ +############################### +# 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-2022 +; https://docs.microsoft.com/en-us/visualstudio/ide/create-portable-custom-editor-options?view=vs-2022 + +root = true + +[*] +end_of_line = lf +indent_style = space +trim_trailing_whitespace = true +insert_final_newline = true + +[*.{vbproj,slnx}] +indent_size = 2 + +[*.vb] +indent_size = 4 +charset = utf-8 + +############################### +# .NET Coding Conventions # +############################### + +# Organize imports +dotnet_sort_system_directives_first = true +dotnet_separate_import_directive_groups = true + +# Me. 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 + +################################### +# Visual Basic Coding Conventions # +################################### +visual_basic_preferred_modifier_order = Partial, Default, Private, Protected, Public, Friend, NotOverridable, Overridable, MustOverride, Overloads, Overrides, MustInherit, NotInheritable, Static, Shared, Shadows, ReadOnly, WriteOnly, Dim, Const, WithEvents, Widening, Narrowing, Custom, Async:suggestion +visual_basic_style_unused_variable_expression_statement_preference = unused_local_variable:suggestion +visual_basic_style_unused_value_assignment_preference = unused_local_variable:suggestion +visual_basic_style_prefer_isnot_expression = true:suggestion +visual_basic_style_prefer_simplified_object_creation = false:none +dotnet_diagnostic.IDE0090.severity = none diff --git a/exercises/practice/strain/.meta/Example.vb b/exercises/practice/strain/.meta/Example.vb new file mode 100644 index 00000000..1b04ef02 --- /dev/null +++ b/exercises/practice/strain/.meta/Example.vb @@ -0,0 +1,34 @@ +Imports System.Runtime.CompilerServices + +Public Module Strain + + Public Function Keep(Of T)( + ByVal collection As IEnumerable(Of T), + ByVal predicate As Func(Of T, Boolean)) As IEnumerable(Of T) + + Return Filtered(collection, predicate) + End Function + + + Public Function Discard(Of T)( + ByVal collection As IEnumerable(Of T), + ByVal predicate As Func(Of T, Boolean)) As IEnumerable(Of T) + + Return Filtered(collection, Function(item) Not predicate(item)) + End Function + + Private Function Filtered(Of T)( + ByVal collection As IEnumerable(Of T), + ByVal predicate As Func(Of T, Boolean)) As IEnumerable(Of T) + + Dim matches As New List(Of T) + + For Each item In collection + If predicate(item) Then + matches.Add(item) + End If + Next + + Return matches + End Function +End Module diff --git a/exercises/practice/strain/.meta/config.json b/exercises/practice/strain/.meta/config.json new file mode 100644 index 00000000..4ffcb886 --- /dev/null +++ b/exercises/practice/strain/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "Strain.vb" + ], + "test": [ + "StrainTests.vb" + ], + "example": [ + ".meta/Example.vb" + ] + }, + "blurb": "Implement the `keep` and `discard` operation on collections.", + "source": "Conversation with James Edward Gray II", + "source_url": "http://graysoftinc.com/" +} diff --git a/exercises/practice/strain/.meta/tests.toml b/exercises/practice/strain/.meta/tests.toml new file mode 100644 index 00000000..3a617b4a --- /dev/null +++ b/exercises/practice/strain/.meta/tests.toml @@ -0,0 +1,52 @@ +# 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. + +[26af8c32-ba6a-4eb3-aa0a-ebd8f136e003] +description = "keep on empty list returns empty list" + +[f535cb4d-e99b-472a-bd52-9fa0ffccf454] +description = "keeps everything" + +[950b8e8e-f628-42a8-85e2-9b30f09cde38] +description = "keeps nothing" + +[92694259-6e76-470c-af87-156bdf75018a] +description = "keeps first and last" + +[938f7867-bfc7-449e-a21b-7b00cbb56994] +description = "keeps neither first nor last" + +[8908e351-4437-4d2b-a0f7-770811e48816] +description = "keeps strings" + +[2728036b-102a-4f1e-a3ef-eac6160d876a] +description = "keeps lists" + +[ef16beb9-8d84-451a-996a-14e80607fce6] +description = "discard on empty list returns empty list" + +[2f42f9bc-8e06-4afe-a222-051b5d8cd12a] +description = "discards everything" + +[ca990fdd-08c2-4f95-aa50-e0f5e1d6802b] +description = "discards nothing" + +[71595dae-d283-48ca-a52b-45fa96819d2f] +description = "discards first and last" + +[ae141f79-f86d-4567-b407-919eaca0f3dd] +description = "discards neither first nor last" + +[daf25b36-a59f-4f29-bcfe-302eb4e43609] +description = "discards strings" + +[a38d03f9-95ad-4459-80d1-48e937e4acaf] +description = "discards lists" diff --git a/exercises/practice/strain/Strain.vb b/exercises/practice/strain/Strain.vb new file mode 100644 index 00000000..9c4e1db9 --- /dev/null +++ b/exercises/practice/strain/Strain.vb @@ -0,0 +1,19 @@ +Imports System.Runtime.CompilerServices + +Public Module Strain + + Public Function Keep(Of T)( + ByVal collection As IEnumerable(Of T), + ByVal predicate As Func(Of T, Boolean)) As IEnumerable(Of T) + + Throw New NotImplementedException("You need to implement this function.") + End Function + + + Public Function Discard(Of T)( + ByVal collection As IEnumerable(Of T), + ByVal predicate As Func(Of T, Boolean)) As IEnumerable(Of T) + + Throw New NotImplementedException("You need to implement this function.") + End Function +End Module diff --git a/exercises/practice/strain/Strain.vbproj b/exercises/practice/strain/Strain.vbproj new file mode 100644 index 00000000..b4587f0b --- /dev/null +++ b/exercises/practice/strain/Strain.vbproj @@ -0,0 +1,19 @@ + + + + net10.0 + Exe + true + + + + + + + + + + + + + diff --git a/exercises/practice/strain/StrainTests.vb b/exercises/practice/strain/StrainTests.vb new file mode 100644 index 00000000..6fe35d09 --- /dev/null +++ b/exercises/practice/strain/StrainTests.vb @@ -0,0 +1,130 @@ +Public Class StrainTests + + Public Sub Keep_On_Empty_List_Returns_Empty_List() + Dim input = Array.Empty(Of Integer)() + + Assert.Empty(input.Keep(Function(value) True)) + End Sub + + + Public Sub Keeps_Everything() + Dim input = {1, 3, 5} + Dim expected = {1, 3, 5} + + Assert.Equal(expected, input.Keep(Function(value) True)) + End Sub + + + Public Sub Keeps_Nothing() + Dim input = {1, 3, 5} + + Assert.Empty(input.Keep(Function(value) False)) + End Sub + + + Public Sub Keeps_First_And_Last() + Dim input = {1, 2, 3} + Dim expected = {1, 3} + + Assert.Equal(expected, input.Keep(Function(value) value Mod 2 = 1)) + End Sub + + + Public Sub Keeps_Neither_First_Nor_Last() + Dim input = {1, 2, 3} + Dim expected = {2} + + Assert.Equal(expected, input.Keep(Function(value) value Mod 2 = 0)) + End Sub + + + Public Sub Keeps_Strings() + Dim input = {"apple", "zebra", "banana", "zombies", "cherimoya", "zealot"} + Dim expected = {"zebra", "zombies", "zealot"} + + Assert.Equal(expected, input.Keep(Function(word) word.StartsWith("z"))) + End Sub + + + Public Sub Keeps_Lists() + Dim input = { + New List(Of Integer) From {1, 2, 3}, + New List(Of Integer) From {5, 5, 5}, + New List(Of Integer) From {5, 1, 2}, + New List(Of Integer) From {2, 1, 2}, + New List(Of Integer) From {1, 5, 2}, + New List(Of Integer) From {2, 2, 1}, + New List(Of Integer) From {1, 2, 5}} + Dim expected = { + New List(Of Integer) From {5, 5, 5}, + New List(Of Integer) From {5, 1, 2}, + New List(Of Integer) From {1, 5, 2}, + New List(Of Integer) From {1, 2, 5}} + + Assert.Equal(expected, input.Keep(Function(values) values.Contains(5))) + End Sub + + + Public Sub Discard_On_Empty_List_Returns_Empty_List() + Dim input = Array.Empty(Of Integer)() + + Assert.Empty(input.Discard(Function(value) True)) + End Sub + + + Public Sub Discards_Everything() + Dim input = {1, 3, 5} + + Assert.Empty(input.Discard(Function(value) True)) + End Sub + + + Public Sub Discards_Nothing() + Dim input = {1, 3, 5} + Dim expected = {1, 3, 5} + + Assert.Equal(expected, input.Discard(Function(value) False)) + End Sub + + + Public Sub Discards_First_And_Last() + Dim input = {1, 2, 3} + Dim expected = {2} + + Assert.Equal(expected, input.Discard(Function(value) value Mod 2 = 1)) + End Sub + + + Public Sub Discards_Neither_First_Nor_Last() + Dim input = {1, 2, 3} + Dim expected = {1, 3} + + Assert.Equal(expected, input.Discard(Function(value) value Mod 2 = 0)) + End Sub + + + Public Sub Discards_Strings() + Dim input = {"apple", "zebra", "banana", "zombies", "cherimoya", "zealot"} + Dim expected = {"apple", "banana", "cherimoya"} + + Assert.Equal(expected, input.Discard(Function(word) word.StartsWith("z"))) + End Sub + + + Public Sub Discards_Lists() + Dim input = { + New List(Of Integer) From {1, 2, 3}, + New List(Of Integer) From {5, 5, 5}, + New List(Of Integer) From {5, 1, 2}, + New List(Of Integer) From {2, 1, 2}, + New List(Of Integer) From {1, 5, 2}, + New List(Of Integer) From {2, 2, 1}, + New List(Of Integer) From {1, 2, 5}} + Dim expected = { + New List(Of Integer) From {1, 2, 3}, + New List(Of Integer) From {2, 1, 2}, + New List(Of Integer) From {2, 2, 1}} + + Assert.Equal(expected, input.Discard(Function(values) values.Contains(5))) + End Sub +End Class diff --git a/exercises/practice/strain/packages.lock.json b/exercises/practice/strain/packages.lock.json new file mode 100644 index 00000000..8da1f14a --- /dev/null +++ b/exercises/practice/strain/packages.lock.json @@ -0,0 +1,168 @@ +{ + "version": 1, + "dependencies": { + "net10.0": { + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[18.3.0, )", + "resolved": "18.3.0", + "contentHash": "xW3kXuWRQtgoxJp4J+gdhHSQyK+6Wb/AZDSd7lMvuMRYlZ1tnpkojyfZlWilB5G4dmZ0Y0ZxU/M23TlubndNkw==", + "dependencies": { + "Microsoft.CodeCoverage": "18.3.0", + "Microsoft.TestPlatform.TestHost": "18.3.0" + } + }, + "xunit.runner.visualstudio": { + "type": "Direct", + "requested": "[3.1.5, )", + "resolved": "3.1.5", + "contentHash": "tKi7dSTwP4m5m9eXPM2Ime4Kn7xNf4x4zT9sdLO/G4hZVnQCRiMTWoSZqI/pYTVeI27oPPqHBKYI/DjJ9GsYgA==" + }, + "xunit.v3": { + "type": "Direct", + "requested": "[3.2.2, )", + "resolved": "3.2.2", + "contentHash": "L+4/4y0Uqcg8/d6hfnxhnwh4j9FaeULvefTwrk30rr1o4n/vdPfyUQ8k0yzH8VJx7bmFEkDdcRfbtbjEHlaYcA==", + "dependencies": { + "xunit.v3.mtp-v1": "[3.2.2]" + } + }, + "Microsoft.ApplicationInsights": { + "type": "Transitive", + "resolved": "2.23.0", + "contentHash": "nWArUZTdU7iqZLycLKWe0TDms48KKGE6pONH2terYNa8REXiqixrMOkf1sk5DHGMaUTqONU2YkS4SAXBhLStgw==" + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "18.3.0", + "contentHash": "23BNy/vziREC20Wwhb50K7+kZe0m07KlLWDQv4qjJ9tt3QjpDpDIqJFrhYHmMEo9xDkuSp55U/8h4bMF7MiB+g==" + }, + "Microsoft.Testing.Extensions.Telemetry": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "No5AudZMmSb+uNXjlgL2y3/stHD2IT4uxqc5yHwkE+/nNux9jbKcaJMvcp9SwgP4DVD8L9/P3OUz8mmmcvEIdQ==", + "dependencies": { + "Microsoft.ApplicationInsights": "2.23.0", + "Microsoft.Testing.Platform": "1.9.1" + } + }, + "Microsoft.Testing.Extensions.TrxReport.Abstractions": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "AL46Xe1WBi85Ntd4mNPvat5ZSsZ2uejiVqoKCypr8J3wK0elA5xJ3AN4G/Q4GIwzUFnggZoH/DBjnr9J18IO/g==", + "dependencies": { + "Microsoft.Testing.Platform": "1.9.1" + } + }, + "Microsoft.Testing.Platform": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "QafNtNSmEI0zazdebnsIkDKmFtTSpmx/5PLOjURWwozcPb3tvRxzosQSL8xwYNM1iPhhKiBksXZyRSE2COisrA==" + }, + "Microsoft.Testing.Platform.MSBuild": { + "type": "Transitive", + "resolved": "1.9.1", + "contentHash": "oTUtyR4X/s9ytuiNA29FGsNCCH0rNmY5Wdm14NCKLjTM1cT9edVSlA+rGS/mVmusPqcP0l/x9qOnMXg16v87RQ==", + "dependencies": { + "Microsoft.Testing.Platform": "1.9.1" + } + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "18.3.0", + "contentHash": "AEIEX2aWdPO9XbtR96eBaJxmXRD9vaI9uQ1T/JbPEKlTAZwYx0ZrMzKyULMdh/HH9Sg03kXCoN7LszQ90o6nPQ==" + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "18.3.0", + "contentHash": "twmsoelXnp1uWMU3VGip9f0Jr1mZ0PZqgJdF35CIrdYgYrkHIJMV1m8uKyhcdjLdsQDESHAgkR7KhS9i1qpJag==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "18.3.0", + "Newtonsoft.Json": "13.0.3" + } + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==" + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.3", + "contentHash": "HrC5BXdl00IP9zeV+0Z848QWPAoCr9P3bDEZguI+gkLcBKAOxix/tLEAAHC+UvDNPv4a2d18lOReHMOagPa+zQ==" + }, + "xunit.analyzers": { + "type": "Transitive", + "resolved": "1.27.0", + "contentHash": "y/pxIQaLvk/kxAoDkZW9GnHLCEqzwl5TW0vtX3pweyQpjizB9y3DXhb9pkw2dGeUqhLjsxvvJM1k89JowU6z3g==" + }, + "xunit.v3.assert": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "BPciBghgEEaJN/JG00QfCYDfEfnLgQhfnYEy+j1izoeHVNYd5+3Wm8GJ6JgYysOhpBPYGE+sbf75JtrRc7jrdA==" + }, + "xunit.v3.common": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "Hj775PEH6GTbbg0wfKRvG2hNspDCvTH9irXhH4qIWgdrOSV1sQlqPie+DOvFeigsFg2fxSM3ZAaaCDQs+KreFA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "6.0.0" + } + }, + "xunit.v3.core.mtp-v1": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "Ga5aA2Ca9ktz+5k3g5ukzwfexwoqwDUpV6z7atSEUvqtd6JuybU1XopHqg1oFd78QdTfZgZE9h5sHpO4qYIi5w==", + "dependencies": { + "Microsoft.Testing.Extensions.Telemetry": "1.9.1", + "Microsoft.Testing.Extensions.TrxReport.Abstractions": "1.9.1", + "Microsoft.Testing.Platform": "1.9.1", + "Microsoft.Testing.Platform.MSBuild": "1.9.1", + "xunit.v3.extensibility.core": "[3.2.2]", + "xunit.v3.runner.inproc.console": "[3.2.2]" + } + }, + "xunit.v3.extensibility.core": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "srY8z/oMPvh/t8axtO2DwrHajhFMH7tnqKildvYrVQIfICi8fOn3yIBWkVPAcrKmHMwvXRJ/XsQM3VMR6DOYfQ==", + "dependencies": { + "xunit.v3.common": "[3.2.2]" + } + }, + "xunit.v3.mtp-v1": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "O41aAzYKBT5PWqATa1oEWVNCyEUypFQ4va6K0kz37dduV3EKzXNMaV2UnEhufzU4Cce1I33gg0oldS8tGL5I0A==", + "dependencies": { + "xunit.analyzers": "1.27.0", + "xunit.v3.assert": "[3.2.2]", + "xunit.v3.core.mtp-v1": "[3.2.2]" + } + }, + "xunit.v3.runner.common": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "/hkHkQCzGrugelOAehprm7RIWdsUFVmIVaD6jDH/8DNGCymTlKKPTbGokD5czbAfqfex47mBP0sb0zbHYwrO/g==", + "dependencies": { + "Microsoft.Win32.Registry": "[5.0.0]", + "xunit.v3.common": "[3.2.2]" + } + }, + "xunit.v3.runner.inproc.console": { + "type": "Transitive", + "resolved": "3.2.2", + "contentHash": "ulWOdSvCk+bPXijJZ73bth9NyoOHsAs1ZOvamYbCkD4DNLX/Bd29Ve2ZNUwBbK0MqfIYWXHZViy/HKrdEC/izw==", + "dependencies": { + "xunit.v3.extensibility.core": "[3.2.2]", + "xunit.v3.runner.common": "[3.2.2]" + } + } + } + } +} \ No newline at end of file From ea32ace8b07939763b80b82ca98492b4eab5e250 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A1s=20B=20Nagy?= <20251272+BNAndras@users.noreply.github.com> Date: Sun, 2 Aug 2026 19:34:03 -0700 Subject: [PATCH 2/2] Fix exercise order --- config.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config.json b/config.json index 3427e58c..b9b65b32 100644 --- a/config.json +++ b/config.json @@ -673,6 +673,14 @@ "prerequisites": [], "difficulty": 2 }, + { + "slug": "strain", + "name": "Strain", + "uuid": "cb9e7d32-db32-4de7-a588-940a3551d24f", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "sum-of-multiples", "name": "Sum of Multiples", @@ -690,14 +698,6 @@ ], "difficulty": 2 }, - { - "slug": "strain", - "name": "Strain", - "uuid": "cb9e7d32-db32-4de7-a588-940a3551d24f", - "practices": [], - "prerequisites": [], - "difficulty": 2 - }, { "slug": "triangle", "name": "Triangle",