From 14781d73cecc8cdcec2d1a1ce3b3342192bc8b99 Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Sun, 17 May 2026 15:56:08 -0400 Subject: [PATCH 1/4] fix existing approaches --- .../practice/sublist/.approaches/config.json | 9 ++-- .../sublist/.approaches/introduction.md | 25 ++++++----- .../.approaches/list-manipulation/content.md | 11 ++--- .../.approaches/using-strings/content.md | 44 +++++++++++-------- .../.approaches/using-strings/snippet.txt | 2 +- 5 files changed, 54 insertions(+), 37 deletions(-) diff --git a/exercises/practice/sublist/.approaches/config.json b/exercises/practice/sublist/.approaches/config.json index ce54db9c14e..e0899343e6a 100644 --- a/exercises/practice/sublist/.approaches/config.json +++ b/exercises/practice/sublist/.approaches/config.json @@ -1,6 +1,7 @@ { "introduction": { - "authors": ["safwansamsudeen"] + "authors": ["safwansamsudeen"], + "contributors": ["yrahcaz7"] }, "approaches": [ { @@ -8,14 +9,16 @@ "slug": "list-manipulation", "title": "List manipulation", "blurb": "Manipulate and check lists to solve the exercise", - "authors": ["safwansamsudeen"] + "authors": ["safwansamsudeen"], + "contributors": ["yrahcaz7"] }, { "uuid": "61366160-c859-4d16-9085-171428209b8d", "slug": "using-strings", "title": "Using strings", "blurb": "Convert the lists to string and use string manipulation to solve the exercise", - "authors": ["safwansamsudeen"] + "authors": ["safwansamsudeen"], + "contributors": ["yrahcaz7"] } ] } diff --git a/exercises/practice/sublist/.approaches/introduction.md b/exercises/practice/sublist/.approaches/introduction.md index 42f991ef086..a7894fea2f3 100644 --- a/exercises/practice/sublist/.approaches/introduction.md +++ b/exercises/practice/sublist/.approaches/introduction.md @@ -1,10 +1,13 @@ # Introduction -There are two broad ways to solve Sublist. + +There are two broad ways to solve Sublist. ## General guidance -To write the code, you need to branch out (probably with `if`) into the four different possible conditions, and return the appropriate name of the category. + +To write the code, you need to branch out (probably with `if`) into the four different possible conditions, and return the appropriate name of the category. ## Approach: list manipulation + The direct approach would be to manipulate and check the given lists to solve this. This solution uses a helper function, which simplifies things, but the approach can be implemented without it. @@ -18,7 +21,7 @@ def check_sub_sequences(list_one, list_two): n1 = len(list_one) n2 = len(list_two) return any(list_two[i:i+n1] == list_one for i in range(n2 - n1 + 1)) - + def sublist(list_one, list_two): if list_one == list_two: return EQUAL @@ -32,9 +35,10 @@ def sublist(list_one, list_two): Read more on the [detail of this approach][approach-list-manipulation]. ## Approach: using strings -Another seemingly clever approach is to convert the lists to strings and then -use the `in` operator to check for sub-sequences. + +Another seemingly clever approach is to convert the lists to strings and then use the `in` operator to check for sub-sequences. **However, this does not work.** + ```python SUBLIST = 1 SUPERLIST = 2 @@ -42,17 +46,18 @@ EQUAL = 3 UNEQUAL = 4 def sublist(list_one, list_two): - list_one_check = (str(list_one).strip("[]") + ",") - list_two_check = (str(list_two).strip("[]") + ",") - + list_one_check = str(list_one).strip("[]") + "," + list_two_check = str(list_two).strip("[]") + "," + if list_one_check == list_two_check: return EQUAL - elif list_one_check in list_two_check: + if list_one_check in list_two_check: return SUBLIST - elif list_two_check in list_one_check: + if list_two_check in list_one_check: return SUPERLIST return UNEQUAL ``` + To understand more about this approach and **why it fails**, [read here][approach-using-strings]. [approach-list-manipulation]: https://exercism.org/tracks/python/exercises/sublist/approaches/list-manipulation diff --git a/exercises/practice/sublist/.approaches/list-manipulation/content.md b/exercises/practice/sublist/.approaches/list-manipulation/content.md index ac374b730e7..82e49b6794e 100644 --- a/exercises/practice/sublist/.approaches/list-manipulation/content.md +++ b/exercises/practice/sublist/.approaches/list-manipulation/content.md @@ -1,4 +1,5 @@ # List manipulation + The direct approach would be to manipulate and check the given lists to solve this. This solution uses a helper function, which simplifies things, but the approach can be implemented without it. @@ -12,7 +13,7 @@ def check_sub_sequences(list_one, list_two): n1 = len(list_one) n2 = len(list_two) return any(list_two[i:i+n1] == list_one for i in range(n2 - n1 + 1)) - + def sublist(list_one, list_two): if list_one == list_two: return EQUAL @@ -23,16 +24,16 @@ def sublist(list_one, list_two): return UNEQUAL ``` -We first check for equality using the `==` operator, if so, then we return `EQUAL`. -A common way to do this differently would be to return `1` directly, but this is better practice as we [remove magic values][magic values]. +We first check for equality using the `==` operator, if so, then we return `EQUAL`. +A common way to do this differently would be to return `1` directly, but this is better practice as we [remove magic values][magic values]. After that we call `check_sub_sequences` passing in `list_one` and `list_two`. In the helper function, we check if `any` of the possible sub-sequences in `list_two` of length `n1` (the length of the first list) are equal to the first list. -If so, then we conclude that `list_one` is a `SUBLIST` of `list_two`. +If so, then we conclude that `list_one` is a `SUBLIST` of `list_two`. To find whether `list_one` is a `SUPERLIST` of `list_two`, we just reverse this process - pass in the lists in the opposite order. Thus, we check if `any` of the possible sub-sequences in `list_one` of length `n2` (the length of the second list) are equal to the second list. If none of the above conditions are true, we conclude that the two lists are unequal. -[magic values]: https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad \ No newline at end of file +[magic values]: https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad diff --git a/exercises/practice/sublist/.approaches/using-strings/content.md b/exercises/practice/sublist/.approaches/using-strings/content.md index ff960902dc9..e419d620564 100644 --- a/exercises/practice/sublist/.approaches/using-strings/content.md +++ b/exercises/practice/sublist/.approaches/using-strings/content.md @@ -1,13 +1,13 @@ # Using strings + ~~~~exercism/caution -**This approach does not work, and this document exists to explain that.** +**This approach does not work, and this document exists to explain that.** Please do not use it in your code. ~~~~ -Another seemingly clever solution is to convert the lists to strings and then -use the `in` operator to check for sub-sequences. -Note that this approach, even if it worked, is not as performant as the -previous one. +Another seemingly clever solution is to convert the lists to strings and then use the `in` operator to check for sub-sequences. +Note that this approach, even if it worked, is not as performant as the previous one. + ```python SUBLIST = 1 SUPERLIST = 2 @@ -20,28 +20,36 @@ def sublist(list_one, list_two): if list_one_check == list_two_check: return EQUAL - elif list_one_check in list_two_check: + if list_one_check in list_two_check: return SUBLIST - elif list_two_check in list_one_check: + if list_two_check in list_one_check: return SUPERLIST return UNEQUAL ``` + Let's parse the code to see what it does. -In this approach, we convert the lists to strings, so `[1, 2, 3]` becomes `"[1, 2, 3]"`, remove the brackets `"1, 2, 3"`, and add a comma `"1, 2, 3,"`. +In this approach, we convert the lists to strings, so `[1, 2, 3]` becomes `"[1, 2, 3]"`, remove the brackets `"1, 2, 3"`, and add a comma `"1, 2, 3,"`. We check equality and then use the `in` operator to check for `SUBLIST` or `SUPERLIST`, and finally return `UNEQUAL`. -We add a comma because, say, we call `sublist` with `[1, 2]` and `[1, 22]`. `"1, 2" in "1, 22"` evaluates to `True`, so -the **function would wrongly mark it as `SUBLIST`**. +We add a comma because, say, we call `sublist` with `[1, 2]` and `[1, 22]`. `"1, 2" in "1, 22"` evaluates to `True`, so the **function would wrongly mark it as `SUBLIST`**. + +This case can be handled by changing the code like this: + +```python +list_one_check = str(list_one).strip("[]") + "," +list_two_check = str(list_two).strip("[]") + "," +``` + +Yet, even though the code would pass all of the tests in the Exercism test suite, it would still fail in some cases. +For example, if we call `sublist` with `[1, 2]` and `[5, "1, 2,", 7]`, the function would return `SUBLIST` when it should actually return `UNEQUAL`. + +This could be avoided by changing the code to use a separator that isn't the default one: -This test can be overridden by changing the code like this: ```python -list_one_check = str(list_one).strip("[]") + ',' -list_two_check = str(list_two).strip("[]") + ',' +list_one_check = "|".join(str(item) for item in list_one) + "|" +list_two_check = "|".join(str(item) for item in list_two) + "|" ``` -Yet, the test case (which doesn't exist in the Exercism test suite) `["1", "2"]` and `["5", "'1', '2',", "7"]` would -fail. -Students can add any arbitrary string into the representation to try to "defeat" this test - `list_one_check = str -(list_one) + TOKEN`. The test suite currently test `TOKEN = ''`, but not others. +However, this only avoids the (theoretical) test and does not fix the solution. For example, a test with the inputs `[1, 2]` and `[5, "1|2|", 7]` would now fail. -[gen-exp]: https://www.programiz.com/python-programming/generator \ No newline at end of file +No matter what separator is chosen, there will always be at least one input for which the function will return the wrong result. **This is why no approach that converts the lists to strings can ever be correct for all possible inputs.** diff --git a/exercises/practice/sublist/.approaches/using-strings/snippet.txt b/exercises/practice/sublist/.approaches/using-strings/snippet.txt index 26fc3ec0ec7..1f993c2a04d 100644 --- a/exercises/practice/sublist/.approaches/using-strings/snippet.txt +++ b/exercises/practice/sublist/.approaches/using-strings/snippet.txt @@ -2,7 +2,7 @@ def sublist(list_one, list_two): list_one_check = str(list_one).strip("[]") ... - elif list_one_check in list_two_check: + if list_one_check in list_two_check: return SUBLIST ... return UNEQUAL \ No newline at end of file From 13ce6e43525a61bbfe232712ddd0311f40fe26f3 Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Sun, 17 May 2026 17:07:44 -0400 Subject: [PATCH 2/4] add `manual-loop` approach also move the note about magic values into `introduction.md` and remove unverified statement about performance --- .../practice/sublist/.approaches/config.json | 7 +++ .../sublist/.approaches/introduction.md | 57 ++++++++++++++----- .../.approaches/list-manipulation/content.md | 5 +- .../.approaches/manual-loop/content.md | 50 ++++++++++++++++ .../.approaches/manual-loop/snippet.txt | 8 +++ .../.approaches/using-strings/content.md | 1 - 6 files changed, 109 insertions(+), 19 deletions(-) create mode 100644 exercises/practice/sublist/.approaches/manual-loop/content.md create mode 100644 exercises/practice/sublist/.approaches/manual-loop/snippet.txt diff --git a/exercises/practice/sublist/.approaches/config.json b/exercises/practice/sublist/.approaches/config.json index e0899343e6a..64c41b9b02e 100644 --- a/exercises/practice/sublist/.approaches/config.json +++ b/exercises/practice/sublist/.approaches/config.json @@ -19,6 +19,13 @@ "blurb": "Convert the lists to string and use string manipulation to solve the exercise", "authors": ["safwansamsudeen"], "contributors": ["yrahcaz7"] + }, + { + "uuid": "b2695c39-c1c7-47f0-bfcd-5e9703674bea", + "slug": "manual-loop", + "title": "Manual looping", + "blurb": "Manually track indexes while looping through the lists to solve the exercise", + "authors": ["yrahcaz7"] } ] } diff --git a/exercises/practice/sublist/.approaches/introduction.md b/exercises/practice/sublist/.approaches/introduction.md index a7894fea2f3..853d439254e 100644 --- a/exercises/practice/sublist/.approaches/introduction.md +++ b/exercises/practice/sublist/.approaches/introduction.md @@ -4,19 +4,16 @@ There are two broad ways to solve Sublist. ## General guidance -To write the code, you need to branch out (probably with `if`) into the four different possible conditions, and return the appropriate name of the category. +To write the code, you need to branch out (probably with `if`) into the four different possible conditions, and return the appropriate category (`SUBLIST`, `SUPERLIST`, `EQUAL`, or `UNEQUAL`). -## Approach: list manipulation +Note that you shouldn't return the category's value directly, as that would introduce [magic values][magic-values] into your code. + +## Approach: List manipulation The direct approach would be to manipulate and check the given lists to solve this. This solution uses a helper function, which simplifies things, but the approach can be implemented without it. ```python -SUBLIST = 1 -SUPERLIST = 2 -EQUAL = 3 -UNEQUAL = 4 - def check_sub_sequences(list_one, list_two): n1 = len(list_one) n2 = len(list_two) @@ -34,21 +31,51 @@ def sublist(list_one, list_two): Read more on the [detail of this approach][approach-list-manipulation]. -## Approach: using strings +## Approach: Manual looping + +This approach uses a helper function that manually loops through the lists to determine if the first list is a sublist of the second one. +This approach is the longest one by far, though it may be more comprehensible to some. + +```python +def check_sub_sequences(list_one, list_two): + index_one = 0 + index_two = 0 + next_index_two = 1 + + while index_one < len(list_one) and index_two < len(list_two): + if list_one[index_one] == list_two[index_two]: + index_one += 1 + else: + index_one = 0 + index_two = next_index_two + next_index_two += 1 + index_two += 1 + + if index_one == len(list_one): + if len(list_one) == len(list_two): + return EQUAL + return SUBLIST + return UNEQUAL + +def sublist(list_one, list_two): + result = check_sub_sequences(list_one, list_two) + if result == UNEQUAL and check_sub_sequences(list_two, list_one) == SUBLIST: + result = SUPERLIST + return result +``` + +Learn more about the [details of this approach here][approach-manual-loop]. + +## Approach: Using strings Another seemingly clever approach is to convert the lists to strings and then use the `in` operator to check for sub-sequences. **However, this does not work.** ```python -SUBLIST = 1 -SUPERLIST = 2 -EQUAL = 3 -UNEQUAL = 4 - def sublist(list_one, list_two): list_one_check = str(list_one).strip("[]") + "," list_two_check = str(list_two).strip("[]") + "," - + if list_one_check == list_two_check: return EQUAL if list_one_check in list_two_check: @@ -60,5 +87,7 @@ def sublist(list_one, list_two): To understand more about this approach and **why it fails**, [read here][approach-using-strings]. +[magic-values]: https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad [approach-list-manipulation]: https://exercism.org/tracks/python/exercises/sublist/approaches/list-manipulation +[approach-manual-loop]: https://exercism.org/tracks/python/exercises/sublist/approaches/manual-loop [approach-using-strings]: https://exercism.org/tracks/python/exercises/sublist/approaches/using-strings diff --git a/exercises/practice/sublist/.approaches/list-manipulation/content.md b/exercises/practice/sublist/.approaches/list-manipulation/content.md index 82e49b6794e..ee19d3c1a49 100644 --- a/exercises/practice/sublist/.approaches/list-manipulation/content.md +++ b/exercises/practice/sublist/.approaches/list-manipulation/content.md @@ -25,9 +25,8 @@ def sublist(list_one, list_two): ``` We first check for equality using the `==` operator, if so, then we return `EQUAL`. -A common way to do this differently would be to return `1` directly, but this is better practice as we [remove magic values][magic values]. +After that, we call `check_sub_sequences` passing in `list_one` and `list_two`. -After that we call `check_sub_sequences` passing in `list_one` and `list_two`. In the helper function, we check if `any` of the possible sub-sequences in `list_two` of length `n1` (the length of the first list) are equal to the first list. If so, then we conclude that `list_one` is a `SUBLIST` of `list_two`. @@ -35,5 +34,3 @@ To find whether `list_one` is a `SUPERLIST` of `list_two`, we just reverse this Thus, we check if `any` of the possible sub-sequences in `list_one` of length `n2` (the length of the second list) are equal to the second list. If none of the above conditions are true, we conclude that the two lists are unequal. - -[magic values]: https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad diff --git a/exercises/practice/sublist/.approaches/manual-loop/content.md b/exercises/practice/sublist/.approaches/manual-loop/content.md new file mode 100644 index 00000000000..3d3cfe4907e --- /dev/null +++ b/exercises/practice/sublist/.approaches/manual-loop/content.md @@ -0,0 +1,50 @@ +# Manual looping + +This approach uses a helper function that manually loops through the lists to determine if the first list is a sublist of the second one. +This approach is significantly longer than the [list manipulation approach][approach-list-manipulation], though it may be more comprehensible to some. + +```python +SUBLIST = 1 +SUPERLIST = 2 +EQUAL = 3 +UNEQUAL = 4 + +def check_sub_sequences(list_one, list_two): + index_one = 0 + index_two = 0 + next_index_two = 1 + + while index_one < len(list_one) and index_two < len(list_two): + if list_one[index_one] == list_two[index_two]: + index_one += 1 + else: + index_one = 0 + index_two = next_index_two + next_index_two += 1 + index_two += 1 + + if index_one == len(list_one): + if len(list_one) == len(list_two): + return EQUAL + return SUBLIST + return UNEQUAL + +def sublist(list_one, list_two): + result = check_sub_sequences(list_one, list_two) + if result == UNEQUAL and check_sub_sequences(list_two, list_one) == SUBLIST: + result = SUPERLIST + return result +``` + +In this approach, the first thing `sublist()` does is call the helper function. +That function then loops through the lists, keeping track of an index for both lists so it can test all necessary combinations to determine if `list_one` is a sublist of `list_two`. + +However, the helper function only determines if `list_one` is equal to or a sublist of `list_two`, not if `list_one` is a superlist of `list_two`. +That is why if the helper function returns `UNEQUAL`, `sublist()` needs to make sure that it isn't acutally a superlist. + +`sublist()` does this by calling the helper function with its arguments reversed: `check_sub_sequences(list_two, list_one)`. +If the result is `SUBLIST`, that means `list_two` is a sublist of `list_one`, thus `list_one` must be a superlist of `list_two`. + +Thus all possibilities are covered, and `sublist()` returns the result. + +[approach-list-manipulation]: https://exercism.org/tracks/python/exercises/sublist/approaches/list-manipulation diff --git a/exercises/practice/sublist/.approaches/manual-loop/snippet.txt b/exercises/practice/sublist/.approaches/manual-loop/snippet.txt new file mode 100644 index 00000000000..081ed4aae12 --- /dev/null +++ b/exercises/practice/sublist/.approaches/manual-loop/snippet.txt @@ -0,0 +1,8 @@ +while index_one < len(list_one) and index_two < len(list_two): + if list_one[index_one] == list_two[index_two]: + index_one += 1 + else: + index_one = 0 + index_two = next_index_two + next_index_two += 1 + index_two += 1 \ No newline at end of file diff --git a/exercises/practice/sublist/.approaches/using-strings/content.md b/exercises/practice/sublist/.approaches/using-strings/content.md index e419d620564..a9aef137613 100644 --- a/exercises/practice/sublist/.approaches/using-strings/content.md +++ b/exercises/practice/sublist/.approaches/using-strings/content.md @@ -6,7 +6,6 @@ Please do not use it in your code. ~~~~ Another seemingly clever solution is to convert the lists to strings and then use the `in` operator to check for sub-sequences. -Note that this approach, even if it worked, is not as performant as the previous one. ```python SUBLIST = 1 From 3c882ae699d01610c2dd9a1b8457fb9aecce0faf Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Sun, 17 May 2026 19:30:25 -0400 Subject: [PATCH 3/4] add `sort-lists` approach --- .../practice/sublist/.approaches/config.json | 7 +++ .../sublist/.approaches/introduction.md | 33 +++++++++++++- .../.approaches/list-manipulation/content.md | 4 +- .../.approaches/manual-loop/content.md | 4 +- .../sublist/.approaches/sort-lists/content.md | 44 +++++++++++++++++++ .../.approaches/sort-lists/snippet.txt | 8 ++++ .../.approaches/using-strings/content.md | 2 +- .../.approaches/using-strings/snippet.txt | 2 +- 8 files changed, 96 insertions(+), 8 deletions(-) create mode 100644 exercises/practice/sublist/.approaches/sort-lists/content.md create mode 100644 exercises/practice/sublist/.approaches/sort-lists/snippet.txt diff --git a/exercises/practice/sublist/.approaches/config.json b/exercises/practice/sublist/.approaches/config.json index 64c41b9b02e..22ae02518b8 100644 --- a/exercises/practice/sublist/.approaches/config.json +++ b/exercises/practice/sublist/.approaches/config.json @@ -26,6 +26,13 @@ "title": "Manual looping", "blurb": "Manually track indexes while looping through the lists to solve the exercise", "authors": ["yrahcaz7"] + }, + { + "uuid": "a1eeaf9b-a9b3-421e-bfad-44f7e1575450", + "slug": "sort-lists", + "title": "Sorting lists", + "blurb": "Sort the lists to determine the shorter and longer ones to solve the exercise", + "authors": ["yrahcaz7"] } ] } diff --git a/exercises/practice/sublist/.approaches/introduction.md b/exercises/practice/sublist/.approaches/introduction.md index 853d439254e..35cbff8c418 100644 --- a/exercises/practice/sublist/.approaches/introduction.md +++ b/exercises/practice/sublist/.approaches/introduction.md @@ -1,6 +1,6 @@ # Introduction -There are two broad ways to solve Sublist. +There are four broad ways to solve Sublist, though one of them ("using strings") is not recommended. ## General guidance @@ -66,6 +66,36 @@ def sublist(list_one, list_two): Learn more about the [details of this approach here][approach-manual-loop]. +## Approach: Sorting lists + +This approach uses the `sorted()` function to determine which list is shorter and which is longer. +Knowing this information, one can implement a simplified version of the list manipulation approach. + +```python +SUBLIST = 1 +SUPERLIST = 2 +EQUAL = 3 +UNEQUAL = 4 + +def sublist(list_one, list_two): + if list_one == list_two: + return EQUAL + if not list_one: + return SUBLIST + if not list_two: + return SUPERLIST + + shorter, longer = sorted((list_one, list_two), key=len) + + for index in range(len(longer) - len(shorter) + 1): + if longer[index : index + len(shorter)] == shorter: + return SUPERLIST if longer is list_one else SUBLIST + + return UNEQUAL +``` + +Read more on the [detail of this approach][approach-sort-lists]. + ## Approach: Using strings Another seemingly clever approach is to convert the lists to strings and then use the `in` operator to check for sub-sequences. @@ -90,4 +120,5 @@ To understand more about this approach and **why it fails**, [read here][approac [magic-values]: https://stackoverflow.com/questions/47882/what-is-a-magic-number-and-why-is-it-bad [approach-list-manipulation]: https://exercism.org/tracks/python/exercises/sublist/approaches/list-manipulation [approach-manual-loop]: https://exercism.org/tracks/python/exercises/sublist/approaches/manual-loop +[approach-sort-lists]: https://exercism.org/tracks/python/exercises/sublist/approaches/sort-lists [approach-using-strings]: https://exercism.org/tracks/python/exercises/sublist/approaches/using-strings diff --git a/exercises/practice/sublist/.approaches/list-manipulation/content.md b/exercises/practice/sublist/.approaches/list-manipulation/content.md index ee19d3c1a49..861da0ae49f 100644 --- a/exercises/practice/sublist/.approaches/list-manipulation/content.md +++ b/exercises/practice/sublist/.approaches/list-manipulation/content.md @@ -24,8 +24,8 @@ def sublist(list_one, list_two): return UNEQUAL ``` -We first check for equality using the `==` operator, if so, then we return `EQUAL`. -After that, we call `check_sub_sequences` passing in `list_one` and `list_two`. +We first check for equality using the `==` operator, and if the lists are equal, then we return `EQUAL`. +After that, we call `check_sub_sequences()`, passing in `list_one` and `list_two`. In the helper function, we check if `any` of the possible sub-sequences in `list_two` of length `n1` (the length of the first list) are equal to the first list. If so, then we conclude that `list_one` is a `SUBLIST` of `list_two`. diff --git a/exercises/practice/sublist/.approaches/manual-loop/content.md b/exercises/practice/sublist/.approaches/manual-loop/content.md index 3d3cfe4907e..180e42e8d59 100644 --- a/exercises/practice/sublist/.approaches/manual-loop/content.md +++ b/exercises/practice/sublist/.approaches/manual-loop/content.md @@ -1,7 +1,7 @@ # Manual looping This approach uses a helper function that manually loops through the lists to determine if the first list is a sublist of the second one. -This approach is significantly longer than the [list manipulation approach][approach-list-manipulation], though it may be more comprehensible to some. +This approach is the longest one by far, though it may be more comprehensible to some. ```python SUBLIST = 1 @@ -46,5 +46,3 @@ That is why if the helper function returns `UNEQUAL`, `sublist()` needs to make If the result is `SUBLIST`, that means `list_two` is a sublist of `list_one`, thus `list_one` must be a superlist of `list_two`. Thus all possibilities are covered, and `sublist()` returns the result. - -[approach-list-manipulation]: https://exercism.org/tracks/python/exercises/sublist/approaches/list-manipulation diff --git a/exercises/practice/sublist/.approaches/sort-lists/content.md b/exercises/practice/sublist/.approaches/sort-lists/content.md new file mode 100644 index 00000000000..ede91c1fac2 --- /dev/null +++ b/exercises/practice/sublist/.approaches/sort-lists/content.md @@ -0,0 +1,44 @@ +# Sorting lists + +This approach uses the `sorted()` function to determine which list is shorter and which is longer. +Knowing this information, one can implement a simplified version of the [list manipulation approach][approach-list-manipulation]. + +```python +SUBLIST = 1 +SUPERLIST = 2 +EQUAL = 3 +UNEQUAL = 4 + +def sublist(list_one, list_two): + if list_one == list_two: + return EQUAL + if not list_one: + return SUBLIST + if not list_two: + return SUPERLIST + + shorter, longer = sorted((list_one, list_two), key=len) + + for index in range(len(longer) - len(shorter) + 1): + if longer[index : index + len(shorter)] == shorter: + return SUPERLIST if longer is list_one else SUBLIST + + return UNEQUAL +``` + +Here, the case of the lists being equal is checked first. +Then the special cases of empty lists are handled, returning `SUBLIST` or `SUPERLIST` as necessary. + +Once those simple cases are out of the way, the `sorted()` function is used with the keyword argument `key` set to the `len()` function. +This makes `sorted()` sort the items according to their length. + +Once `sorted()` does its work, we use multiple assignment to unpack the results into the `shorter` and `longer` variables. +Then, for each slice of length `len(shorter)` in `longer`, we test if that slice is equal to `shorter`. + +If we find such a slice, that means `shorter` is a sublist of `longer`. +Then we use a [conditional expression][conditional-expression] along with the `is` operator to return `SUBLIST` or `SUPERLIST` depending on which of the original lists is `longer`. + +If we do not find such a slice, we can eliminate `SUBLIST` and `SUPERLIST` from the possible categories, thus the two lists must be `UNEQUAL`. + +[approach-list-manipulation]: https://exercism.org/tracks/python/exercises/sublist/approaches/list-manipulation +[conditional-expression]: https://docs.python.org/3/reference/expressions.html#conditional-expressions diff --git a/exercises/practice/sublist/.approaches/sort-lists/snippet.txt b/exercises/practice/sublist/.approaches/sort-lists/snippet.txt new file mode 100644 index 00000000000..f106f76255f --- /dev/null +++ b/exercises/practice/sublist/.approaches/sort-lists/snippet.txt @@ -0,0 +1,8 @@ +def sublist(list_one, list_two): + ... + shorter, longer = sorted((list_one, list_two), key=len) + + for index in range(len(longer) - len(shorter) + 1): + if longer[index : index + len(shorter)] == shorter: + return SUPERLIST if longer is list_one else SUBLIST + return UNEQUAL \ No newline at end of file diff --git a/exercises/practice/sublist/.approaches/using-strings/content.md b/exercises/practice/sublist/.approaches/using-strings/content.md index a9aef137613..d5f2f728234 100644 --- a/exercises/practice/sublist/.approaches/using-strings/content.md +++ b/exercises/practice/sublist/.approaches/using-strings/content.md @@ -39,7 +39,7 @@ list_one_check = str(list_one).strip("[]") + "," list_two_check = str(list_two).strip("[]") + "," ``` -Yet, even though the code would pass all of the tests in the Exercism test suite, it would still fail in some cases. +Yet, even though this code would pass all of the tests in the Exercism test suite, it would still fail in some cases. For example, if we call `sublist` with `[1, 2]` and `[5, "1, 2,", 7]`, the function would return `SUBLIST` when it should actually return `UNEQUAL`. This could be avoided by changing the code to use a separator that isn't the default one: diff --git a/exercises/practice/sublist/.approaches/using-strings/snippet.txt b/exercises/practice/sublist/.approaches/using-strings/snippet.txt index 1f993c2a04d..4d4b6439294 100644 --- a/exercises/practice/sublist/.approaches/using-strings/snippet.txt +++ b/exercises/practice/sublist/.approaches/using-strings/snippet.txt @@ -1,4 +1,4 @@ -# Failing approach +# WARNING: Failing approach def sublist(list_one, list_two): list_one_check = str(list_one).strip("[]") ... From 5057d93ef1d4d4ba6cf05d1a52da6479e9954ada Mon Sep 17 00:00:00 2001 From: Yrahcaz7 <74512479+Yrahcaz7@users.noreply.github.com> Date: Sun, 17 May 2026 19:48:27 -0400 Subject: [PATCH 4/4] remove stray enum variables in `introduction.md` --- exercises/practice/sublist/.approaches/introduction.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/exercises/practice/sublist/.approaches/introduction.md b/exercises/practice/sublist/.approaches/introduction.md index 35cbff8c418..96761d6610e 100644 --- a/exercises/practice/sublist/.approaches/introduction.md +++ b/exercises/practice/sublist/.approaches/introduction.md @@ -72,11 +72,6 @@ This approach uses the `sorted()` function to determine which list is shorter an Knowing this information, one can implement a simplified version of the list manipulation approach. ```python -SUBLIST = 1 -SUPERLIST = 2 -EQUAL = 3 -UNEQUAL = 4 - def sublist(list_one, list_two): if list_one == list_two: return EQUAL