diff --git a/config.json b/config.json index d27bbf7..8fac868 100644 --- a/config.json +++ b/config.json @@ -641,6 +641,14 @@ "text_formatting" ] }, + { + "slug": "custom-set", + "name": "Custom Set", + "uuid": "560b738f-c20d-43ac-9bc5-4821628adc00", + "practices": [], + "prerequisites": [], + "difficulty": 5 + }, { "slug": "kindergarten-garden", "name": "Kindergarten Garden", diff --git a/exercises/practice/custom-set/.docs/instructions.md b/exercises/practice/custom-set/.docs/instructions.md new file mode 100644 index 0000000..33b90e2 --- /dev/null +++ b/exercises/practice/custom-set/.docs/instructions.md @@ -0,0 +1,7 @@ +# Instructions + +Create a custom set type. + +Sometimes it is necessary to define a custom data structure of some type, like a set. +In this exercise you will define your own set. +How it works internally doesn't matter, as long as it behaves like a set of unique elements. diff --git a/exercises/practice/custom-set/.meta/config.json b/exercises/practice/custom-set/.meta/config.json new file mode 100644 index 0000000..5b76111 --- /dev/null +++ b/exercises/practice/custom-set/.meta/config.json @@ -0,0 +1,17 @@ +{ + "authors": [ + "BNAndras" + ], + "files": { + "solution": [ + "custom-set.coffee" + ], + "test": [ + "custom-set.spec.coffee" + ], + "example": [ + ".meta/example.coffee" + ] + }, + "blurb": "Create a custom set type." +} diff --git a/exercises/practice/custom-set/.meta/example.coffee b/exercises/practice/custom-set/.meta/example.coffee new file mode 100644 index 0000000..8286fa5 --- /dev/null +++ b/exercises/practice/custom-set/.meta/example.coffee @@ -0,0 +1,42 @@ +class CustomSet + constructor: (values) -> + values.sort() + @values = values.filter (value, index) -> + values.indexOf(value) is index + + empty: -> + @values.length == 0 + + contains: (value) -> + @values.indexOf(value) != -1 + + subset: (other) -> + @values.every (item) -> other.contains item + + disjoint: (other) -> + @values.every (item) -> !other.contains item + + equal: (other) -> + if @values.length != other.values.length + return false + else + + for elt, i in @values + return false if elt != other.values[i] + true + + add: (value) -> + if !(@contains value) + @values.push value + @values.sort() + + intersection: (other) -> + new CustomSet @values.filter (item) -> other.contains item + + difference: (other) -> + new CustomSet @values.filter (item) -> !other.contains item + + union: (other) -> + new CustomSet @values.concat other.values + +module.exports = CustomSet diff --git a/exercises/practice/custom-set/.meta/tests.toml b/exercises/practice/custom-set/.meta/tests.toml new file mode 100644 index 0000000..430c139 --- /dev/null +++ b/exercises/practice/custom-set/.meta/tests.toml @@ -0,0 +1,130 @@ +# 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. + +[20c5f855-f83a-44a7-abdd-fe75c6cf022b] +description = "Returns true if the set contains no elements -> sets with no elements are empty" + +[d506485d-5706-40db-b7d8-5ceb5acf88d2] +description = "Returns true if the set contains no elements -> sets with elements are not empty" + +[759b9740-3417-44c3-8ca3-262b3c281043] +description = "Sets can report if they contain an element -> nothing is contained in an empty set" + +[f83cd2d1-2a85-41bc-b6be-80adbff4be49] +description = "Sets can report if they contain an element -> when the element is in the set" + +[93423fc0-44d0-4bc0-a2ac-376de8d7af34] +description = "Sets can report if they contain an element -> when the element is not in the set" + +[c392923a-637b-4495-b28e-34742cd6157a] +description = "A set is a subset if all of its elements are contained in the other set -> empty set is a subset of another empty set" + +[5635b113-be8c-4c6f-b9a9-23c485193917] +description = "A set is a subset if all of its elements are contained in the other set -> empty set is a subset of non-empty set" + +[832eda58-6d6e-44e2-92c2-be8cf0173cee] +description = "A set is a subset if all of its elements are contained in the other set -> non-empty set is not a subset of empty set" + +[c830c578-8f97-4036-b082-89feda876131] +description = "A set is a subset if all of its elements are contained in the other set -> set is a subset of set with exact same elements" + +[476a4a1c-0fd1-430f-aa65-5b70cbc810c5] +description = "A set is a subset if all of its elements are contained in the other set -> set is a subset of larger set with same elements" + +[d2498999-3e46-48e4-9660-1e20c3329d3d] +description = "A set is a subset if all of its elements are contained in the other set -> set is not a subset of set that does not contain its elements" + +[7d38155e-f472-4a7e-9ad8-5c1f8f95e4cc] +description = "Sets are disjoint if they share no elements -> the empty set is disjoint with itself" + +[7a2b3938-64b6-4b32-901a-fe16891998a6] +description = "Sets are disjoint if they share no elements -> empty set is disjoint with non-empty set" + +[589574a0-8b48-48ea-88b0-b652c5fe476f] +description = "Sets are disjoint if they share no elements -> non-empty set is disjoint with empty set" + +[febeaf4f-f180-4499-91fa-59165955a523] +description = "Sets are disjoint if they share no elements -> sets are not disjoint if they share an element" + +[0de20d2f-c952-468a-88c8-5e056740f020] +description = "Sets are disjoint if they share no elements -> sets are disjoint if they share no elements" + +[4bd24adb-45da-4320-9ff6-38c044e9dff8] +description = "Sets with the same elements are equal -> empty sets are equal" + +[f65c0a0e-6632-4b2d-b82c-b7c6da2ec224] +description = "Sets with the same elements are equal -> empty set is not equal to non-empty set" + +[81e53307-7683-4b1e-a30c-7e49155fe3ca] +description = "Sets with the same elements are equal -> non-empty set is not equal to empty set" + +[d57c5d7c-a7f3-48cc-a162-6b488c0fbbd0] +description = "Sets with the same elements are equal -> sets with the same elements are equal" + +[dd61bafc-6653-42cc-961a-ab071ee0ee85] +description = "Sets with the same elements are equal -> sets with different elements are not equal" + +[06059caf-9bf4-425e-aaff-88966cb3ea14] +description = "Sets with the same elements are equal -> set is not equal to larger set with same elements" + +[d4a1142f-09aa-4df9-8b83-4437dcf7ec24] +description = "Sets with the same elements are equal -> set is equal to a set constructed from an array with duplicates" + +[8a677c3c-a658-4d39-bb88-5b5b1a9659f4] +description = "Unique elements can be added to a set -> add to empty set" + +[0903dd45-904d-4cf2-bddd-0905e1a8d125] +description = "Unique elements can be added to a set -> add to non-empty set" + +[b0eb7bb7-5e5d-4733-b582-af771476cb99] +description = "Unique elements can be added to a set -> adding an existing element does not change the set" + +[893d5333-33b8-4151-a3d4-8f273358208a] +description = "Intersection returns a set of all shared elements -> intersection of two empty sets is an empty set" + +[d739940e-def2-41ab-a7bb-aaf60f7d782c] +description = "Intersection returns a set of all shared elements -> intersection of an empty set and non-empty set is an empty set" + +[3607d9d8-c895-4d6f-ac16-a14956e0a4b7] +description = "Intersection returns a set of all shared elements -> intersection of a non-empty set and an empty set is an empty set" + +[b5120abf-5b5e-41ab-aede-4de2ad85c34e] +description = "Intersection returns a set of all shared elements -> intersection of two sets with no shared elements is an empty set" + +[af21ca1b-fac9-499c-81c0-92a591653d49] +description = "Intersection returns a set of all shared elements -> intersection of two sets with shared elements is a set of the shared elements" + +[c5e6e2e4-50e9-4bc2-b89f-c518f015b57e] +description = "Difference (or Complement) of a set is a set of all elements that are only in the first set -> difference of two empty sets is an empty set" + +[2024cc92-5c26-44ed-aafd-e6ca27d6fcd2] +description = "Difference (or Complement) of a set is a set of all elements that are only in the first set -> difference of empty set and non-empty set is an empty set" + +[e79edee7-08aa-4c19-9382-f6820974b43e] +description = "Difference (or Complement) of a set is a set of all elements that are only in the first set -> difference of a non-empty set and an empty set is the non-empty set" + +[c5ac673e-d707-4db5-8d69-7082c3a5437e] +description = "Difference (or Complement) of a set is a set of all elements that are only in the first set -> difference of two non-empty sets is a set of elements that are only in the first set" + +[20d0a38f-7bb7-4c4a-ac15-90c7392ecf2b] +description = "Difference (or Complement) of a set is a set of all elements that are only in the first set -> difference removes all duplicates in the first set" + +[c45aed16-5494-455a-9033-5d4c93589dc6] +description = "Union returns a set of all elements in either set -> union of empty sets is an empty set" + +[9d258545-33c2-4fcb-a340-9f8aa69e7a41] +description = "Union returns a set of all elements in either set -> union of an empty set and non-empty set is the non-empty set" + +[3aade50c-80c7-4db8-853d-75bac5818b83] +description = "Union returns a set of all elements in either set -> union of a non-empty set and empty set is the non-empty set" + +[a00bb91f-c4b4-4844-8f77-c73e2e9df77c] +description = "Union returns a set of all elements in either set -> union of non-empty sets contains all unique elements" diff --git a/exercises/practice/custom-set/custom-set.coffee b/exercises/practice/custom-set/custom-set.coffee new file mode 100644 index 0000000..c0c1d5b --- /dev/null +++ b/exercises/practice/custom-set/custom-set.coffee @@ -0,0 +1,22 @@ +class CustomSet + constructor: (values) -> + + empty: -> + + contains: (value) -> + + subset: (other) -> + + disjoint: (other) -> + + equall: (other) -> + + add: (value) -> + + intersection: (other) -> + + difference: (other) -> + + union: (other) -> + +module.exports = CustomSet diff --git a/exercises/practice/custom-set/custom-set.spec.coffee b/exercises/practice/custom-set/custom-set.spec.coffee new file mode 100644 index 0000000..b786c11 --- /dev/null +++ b/exercises/practice/custom-set/custom-set.spec.coffee @@ -0,0 +1,206 @@ +CustomSet = require './custom-set' + +describe 'Custom Set', -> + describe 'Empty', -> + it 'sets with no elements are empty', -> + set = new CustomSet [] + expect(set.empty()).toEqual true + + xit 'sets with elements are not empty', -> + set = new CustomSet [1] + expect(set.empty()).toEqual false + + describe 'Contains', -> + xit 'nothing is contained in an empty set', -> + set = new CustomSet [] + expect(set.contains 1).toEqual false + + xit 'when the element is in the set', -> + set = new CustomSet [1, 2, 3] + expect(set.contains 1).toEqual true + + xit 'when the element is not in the set', -> + set = new CustomSet [1, 2, 3] + expect(set.contains 4).toEqual false + + describe 'Subset', -> + xit 'empty set is a subset of another empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [] + expect(set1.subset set2).toEqual true + + xit 'empty set is a subset of non-empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [1] + expect(set1.subset set2).toEqual true + + xit 'non-empty set is not a subset of empty set', -> + set1 = new CustomSet [1] + set2 = new CustomSet [] + expect(set1.subset set2).toEqual false + + xit 'set is a subset of set with exact same elements', -> + set1 = new CustomSet [1, 2, 3] + set2 = new CustomSet [1, 2, 3] + expect(set1.subset set2).toEqual true + + xit 'set is a subset of larger set with same elements', -> + set1 = new CustomSet [1, 2, 3] + set2 = new CustomSet [4, 1, 2, 3] + expect(set1.subset set2).toEqual true + + xit 'set is not a subset of set that does not contain its elements', -> + set1 = new CustomSet [1, 2, 3] + set2 = new CustomSet [4, 1, 3] + expect(set1.subset set2).toEqual false + + describe 'Disjoint', -> + xit 'the empty set is disjoint with itself', -> + set1 = new CustomSet [] + set2 = new CustomSet [] + expect(set1.disjoint set2).toEqual true + + xit 'empty set is disjoint with non-empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [1] + expect(set1.disjoint set2).toEqual true + + xit 'non-empty set is disjoint with empty set', -> + set1 = new CustomSet [1] + set2 = new CustomSet [] + expect(set1.disjoint set2).toEqual true + + xit 'sets are not disjoint if they share an element', -> + set1 = new CustomSet [1, 2] + set2 = new CustomSet [2, 3] + expect(set1.disjoint set2).toEqual false + + xit 'sets are disjoint if they share no elements', -> + set1 = new CustomSet [1, 2] + set2 = new CustomSet [3, 4] + expect(set1.disjoint set2).toEqual true + + describe 'Equal', -> + xit 'empty sets are equal', -> + set1 = new CustomSet [] + set2 = new CustomSet [] + expect(set1.equal set2).toEqual true + + xit 'empty set is not equal to non-empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [1, 2, 3] + expect(set1.equal set2).toEqual false + + xit 'non-empty set is not equal to empty set', -> + set1 = new CustomSet [1, 2, 3] + set2 = new CustomSet [] + expect(set1.equal set2).toEqual false + + xit 'sets with the same elements are equal', -> + set1 = new CustomSet [1, 2] + set2 = new CustomSet [2, 1] + expect(set1.equal set2).toEqual true + + xit 'sets with different elements are not equal', -> + set1 = new CustomSet [1, 2, 3] + set2 = new CustomSet [1, 2, 4] + expect(set1.equal set2).toEqual false + + xit 'set is not equal to larger set with same elements', -> + set1 = new CustomSet [1, 2, 3] + set2 = new CustomSet [1, 2, 3, 4] + expect(set1.equal set2).toEqual false + + xit 'set is equal to a set constructed from an array with duplicates', -> + set1 = new CustomSet [1] + set2 = new CustomSet [1, 1] + expect(set1.equal set2).toEqual true + + describe 'Add', -> + xit 'add to empty set', -> + set = new CustomSet [] + set.add 3 + expect(set.values).toEqual [3] + + xit 'add to non-empty set', -> + set = new CustomSet [1, 2, 4] + set.add 3 + expect(set.values).toEqual [1, 2, 3, 4] + + xit 'adding an existing element does not change the set', -> + set = new CustomSet [1, 2, 3] + set.add 3 + expect(set.values).toEqual [1, 2, 3] + + describe 'Intersection', -> + xit 'intersection of two empty sets is an empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [] + expect(set1.intersection set2).toEqual new CustomSet [] + + xit 'intersection of an empty set and non-empty set is an empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [3, 2, 5] + expect(set1.intersection set2).toEqual new CustomSet [] + + xit 'intersection of a non-empty set and an empty set is an empty set', -> + set1 = new CustomSet [1, 2, 3, 4] + set2 = new CustomSet [] + expect(set1.intersection set2).toEqual new CustomSet [] + + xit 'intersection of two sets with no shared elements is an empty set', -> + set1 = new CustomSet [1, 2, 3] + set2 = new CustomSet [4, 5, 6] + expect(set1.intersection set2).toEqual new CustomSet [] + + xit 'intersection of two sets with shared elements is a set of the shared elements', -> + set1 = new CustomSet [1, 2, 3, 4] + set2 = new CustomSet [3, 2, 5] + expect(set1.intersection set2).toEqual new CustomSet [2, 3] + + describe 'Difference', -> + xit 'difference of two empty sets is an empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [] + expect(set1.difference set2).toEqual new CustomSet [] + + xit 'difference of empty set and non-empty set is an empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [3, 2, 5] + expect(set1.difference set2).toEqual new CustomSet [] + + xit 'difference of a non-empty set and an empty set is the non-empty set', -> + set1 = new CustomSet [1, 2, 3, 4] + set2 = new CustomSet [] + expect(set1.difference set2).toEqual new CustomSet [1, 2, 3, 4] + + xit 'difference of two non-empty sets is a set of elements that are only in the first set', -> + set1 = new CustomSet [3, 2, 1] + set2 = new CustomSet [2, 4] + expect(set1.difference set2).toEqual new CustomSet [1, 3] + + xit 'difference removes all duplicates in the first set', -> + set1 = new CustomSet [1, 1] + set2 = new CustomSet [1] + expect(set1.difference set2).toEqual new CustomSet [] + + describe 'Union', -> + xit 'union of empty sets is an empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [] + expect(set1.union set2).toEqual new CustomSet [] + + xit 'union of an empty set and non-empty set is the non-empty set', -> + set1 = new CustomSet [] + set2 = new CustomSet [2] + expect(set1.union set2).toEqual new CustomSet [2] + + xit 'union of a non-empty set and empty set is the non-empty set', -> + set1 = new CustomSet [1, 3] + set2 = new CustomSet [] + expect(set1.union set2).toEqual new CustomSet [1, 3] + + xit 'union of non-empty sets contains all unique elements', -> + set1 = new CustomSet [1, 3] + set2 = new CustomSet [2, 3] + expect(set1.union set2).toEqual new CustomSet [3, 2, 1]