From ed4fd1084fbc2b23a64f8dbcf33d75186e2ae61d Mon Sep 17 00:00:00 2001 From: meatball <69751659+meatball133@users.noreply.github.com> Date: Mon, 23 Dec 2024 21:41:10 +0100 Subject: [PATCH] Sync branch (#809) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Sync docs and metadata (#771) * Bump actions/checkout from 4.1.7 to 4.2.0 (#772) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.7 to 4.2.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/692973e3d937129bcbf40652eb9f2f61becf3332...d632683dd7b4114ad314bca15554477dd762a938) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix avogadro constant (#777) * Update about.md (#778) * Update about.md Fix word-choice error. * Also make fixes in concept:numbers:introduction.md and exercises:freelancer-rates:introduction.md * Fix `NESButtons` typo (#779) * Fix `NESButtons` typo Just a little typo in the enum name. * fix other mentions of `NESButtons` * Bump actions/checkout from 4.2.0 to 4.2.2 (#775) Bumps [actions/checkout](https://github.com/actions/checkout) from 4.2.0 to 4.2.2. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/d632683dd7b4114ad314bca15554477dd762a938...11bd71901bbe5b1630ceea73d27597364c9af683) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * [New Exercise]: Armstrong Numbers (#708) * Add Armstrong Numbers exercise * Add author * [Armstrong number]: Fix formatting (#783) * Fix formatting * Fix * [New Exercise]: Darts (#707) * Add Darts exercise * Add author * Fix * Sync exercise to problem spec * Update CI configuration and add Swift Numerics dependency (#806) * Update CI configuration and add Swift Numerics dependency * Check if swift6 is available in macos 15 --------- Signed-off-by: dependabot[bot] Co-authored-by: András B Nagy <20251272+BNAndras@users.noreply.github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Mike Shaver --- .github/workflows/ci.yml | 9 ++- Package.swift | 5 +- concepts/dictionaries/about.md | 2 +- concepts/dictionaries/introduction.md | 2 +- concepts/enumerations/about.md | 2 +- concepts/enumerations/introduction.md | 2 +- concepts/numbers/about.md | 2 +- concepts/numbers/introduction.md | 2 +- config.json | 16 +++++ .../freelancer-rates/.docs/introduction.md | 2 +- .../high-score-board/.docs/introduction.md | 2 +- .../concept/log-lines/.docs/introduction.md | 2 +- .../practice/accumulate/.meta/config.json | 2 +- .../practice/acronym/.docs/instructions.md | 10 +-- .../practice/allergies/.docs/instructions.md | 2 +- .../practice/anagram/.docs/instructions.md | 6 +- .../practice/anagram/.docs/introduction.md | 12 ++++ .../armstrong-numbers/.docs/instructions.md | 14 ++++ .../ArmstrongNumbersExample.swift | 8 +++ .../armstrong-numbers/.meta/config.json | 19 +++++ .../armstrong-numbers/.meta/template.swift | 20 ++++++ .../armstrong-numbers/.meta/tests.toml | 45 ++++++++++++ .../practice/armstrong-numbers/Package.swift | 21 ++++++ .../ArmstrongNumbers/ArmstrongNumbers.swift | 3 + .../ArmstrongNumbersTests.swift | 51 +++++++++++++ .../binary-search-tree/.meta/config.json | 3 +- .../binary-search/.docs/instructions.md | 2 +- .../practice/bowling/.docs/instructions.md | 6 +- .../circular-buffer/.docs/instructions.md | 48 ++++++++----- exercises/practice/clock/.meta/config.json | 3 +- .../practice/darts/.docs/instructions.md | 31 ++++++++ .../.meta/Sources/Darts/DartsExample.swift | 15 ++++ exercises/practice/darts/.meta/config.json | 18 +++++ exercises/practice/darts/.meta/template.swift | 16 +++++ exercises/practice/darts/.meta/tests.toml | 49 +++++++++++++ exercises/practice/darts/Package.swift | 21 ++++++ .../practice/darts/Sources/Darts/Darts.swift | 3 + .../darts/Tests/DartsTests/DartsTests.swift | 71 +++++++++++++++++++ .../flatten-array/.docs/instructions.md | 2 +- .../practice/hamming/.docs/instructions.md | 10 +-- .../practice/hello-world/.meta/config.json | 2 +- .../practice/isogram/.docs/instructions.md | 2 +- .../practice/list-ops/.docs/instructions.md | 18 ++--- exercises/practice/luhn/.docs/instructions.md | 3 +- .../matching-brackets/.docs/instructions.md | 3 +- .../matching-brackets/.docs/introduction.md | 8 +++ .../pascals-triangle/.docs/instructions.md | 27 ++++++- .../pascals-triangle/.docs/introduction.md | 22 ++++++ .../perfect-numbers/.docs/instructions.md | 53 +++++++++----- .../phone-number/.docs/instructions.md | 10 +-- .../practice/pig-latin/.docs/instructions.md | 4 +- .../practice/poker/.docs/instructions.md | 2 +- exercises/practice/poker/.meta/config.json | 2 +- .../protein-translation/.docs/instructions.md | 20 +++--- .../pythagorean-triplet/.meta/config.json | 2 +- .../queen-attack/.docs/instructions.md | 20 +++--- .../practice/raindrops/.meta/config.json | 2 +- .../rotational-cipher/.docs/instructions.md | 4 +- exercises/practice/say/.docs/instructions.md | 2 - .../scale-generator/.docs/instructions.md | 20 +++--- .../practice/series/.docs/instructions.md | 4 +- .../simple-cipher/.docs/instructions.md | 6 +- .../practice/space-age/.docs/instructions.md | 31 ++++---- .../practice/space-age/.docs/introduction.md | 20 ++++++ exercises/practice/strain/.meta/config.json | 4 +- .../practice/transpose/.meta/config.json | 2 +- .../practice/wordy/.docs/instructions.md | 2 +- .../Sources/Generator/generator-plugins.swift | 3 + 68 files changed, 699 insertions(+), 158 deletions(-) create mode 100644 exercises/practice/anagram/.docs/introduction.md create mode 100644 exercises/practice/armstrong-numbers/.docs/instructions.md create mode 100644 exercises/practice/armstrong-numbers/.meta/Sources/ArmstrongNumbers/ArmstrongNumbersExample.swift create mode 100644 exercises/practice/armstrong-numbers/.meta/config.json create mode 100644 exercises/practice/armstrong-numbers/.meta/template.swift create mode 100644 exercises/practice/armstrong-numbers/.meta/tests.toml create mode 100644 exercises/practice/armstrong-numbers/Package.swift create mode 100644 exercises/practice/armstrong-numbers/Sources/ArmstrongNumbers/ArmstrongNumbers.swift create mode 100644 exercises/practice/armstrong-numbers/Tests/ArmstrongNumbersTests/ArmstrongNumbersTests.swift create mode 100644 exercises/practice/darts/.docs/instructions.md create mode 100644 exercises/practice/darts/.meta/Sources/Darts/DartsExample.swift create mode 100644 exercises/practice/darts/.meta/config.json create mode 100644 exercises/practice/darts/.meta/template.swift create mode 100644 exercises/practice/darts/.meta/tests.toml create mode 100644 exercises/practice/darts/Package.swift create mode 100644 exercises/practice/darts/Sources/Darts/Darts.swift create mode 100644 exercises/practice/darts/Tests/DartsTests/DartsTests.swift create mode 100644 exercises/practice/matching-brackets/.docs/introduction.md create mode 100644 exercises/practice/pascals-triangle/.docs/introduction.md create mode 100644 exercises/practice/space-age/.docs/introduction.md diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 06d7d88ec..eb0214761 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -9,13 +9,12 @@ on: jobs: test: - runs-on: macos-13 + runs-on: macos-15 env: RUNALL: "true" steps: - name: Checkout code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 - + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Run tests run: swift test generator-tests: @@ -24,7 +23,7 @@ jobs: RUNALL: "true" steps: - name: Checkout code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Run tests run: swift test --package-path ./generator @@ -32,7 +31,7 @@ jobs: runs-on: macos-15 steps: - name: Checkout code - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 - name: Run tests run: ./bin/test_generator.sh diff --git a/Package.swift b/Package.swift index efb80e032..c566f2b74 100644 --- a/Package.swift +++ b/Package.swift @@ -49,11 +49,13 @@ let practiceExerciseTargets: [Target] = practiceExercises.flatMap { return [ .target( name:"\($0.pascalCased)", + dependencies: [.product(name: "Numerics", package: "swift-numerics")], path:"./exercises/practice/\($0)/.meta/Sources"), .testTarget( name:"\($0.pascalCased)Tests", dependencies: [ - .target(name:"\($0.pascalCased)") + .target(name:"\($0.pascalCased)"), + .product(name: "Numerics", package: "swift-numerics") ], path:"./exercises/practice/\($0)/Tests") ] @@ -68,5 +70,6 @@ let package = Package( name: "xswift", targets: allTargets.filter { $0.type == .regular }.map { $0.name }) ], + dependencies: [.package(url: "https://github.com/apple/swift-numerics", from: "1.0.2")], targets: allTargets ) diff --git a/concepts/dictionaries/about.md b/concepts/dictionaries/about.md index 3c7021abe..e2582151d 100644 --- a/concepts/dictionaries/about.md +++ b/concepts/dictionaries/about.md @@ -13,7 +13,7 @@ As [dictionaries][dictionaries] are one of Swift's three primary collection type ```swift var addresses: Dictionary = ["The Munsters": "1313 Mockingbird Lane", "The Simpsons": "742 Evergreen Terrace", "Buffy Summers": "1630 Revello Drive"] var sequences: [String: [Int]] = ["Euler's totient": [1, 1, 2, 2, 4, 2, 6, 4], "Lazy caterer": [1, 2, 4, 7, 11, 16, 22, 29, 37], "Carmichael": [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841]] -let constants: = ["pi": 3.14159, "e": 2.71828, "phi": 1.618033, "avogadro": 6.02214076e22] +let constants: = ["pi": 3.14159, "e": 2.71828, "phi": 1.618033, "avogadro": 6.02214076e23] ``` - Empty dictionaries can be written by following the type name of the dictionary by a pair of parenthesis, e.g. `[Int: String]()`, or, if the type can be determined from the context, as just a pair of square brackets surrounding a colon, `[:]`. diff --git a/concepts/dictionaries/introduction.md b/concepts/dictionaries/introduction.md index 738d6f0f8..e06a1cbb3 100644 --- a/concepts/dictionaries/introduction.md +++ b/concepts/dictionaries/introduction.md @@ -7,7 +7,7 @@ Dictionary literals are written as a series of `key: value` pairs, separated by ```swift var addresses: Dictionary = ["The Munsters": "1313 Mockingbird Lane", "The Simpsons": "742 Evergreen Terrace", "Buffy Summers": "1630 Revello Drive"] var sequences: [String: [Int]] = ["Euler's totient": [1, 1, 2, 2, 4, 2, 6, 4], "Lazy caterer": [1, 2, 4, 7, 11, 16, 22, 29, 37], "Carmichael": [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841]] -let constants = ["pi": 3.14159, "e": 2.71828, "phi": 1.618033, "avogadro": 6.02214076e22] +let constants = ["pi": 3.14159, "e": 2.71828, "phi": 1.618033, "avogadro": 6.02214076e23] var emptyDict1: [Int: Int] = [:] var emptyDict2 = [Character: String]() var emptyDict3 = Dictionary() diff --git a/concepts/enumerations/about.md b/concepts/enumerations/about.md index 394c7d77c..cb37a8007 100644 --- a/concepts/enumerations/about.md +++ b/concepts/enumerations/about.md @@ -37,7 +37,7 @@ enum NESButton { } ``` -This defines a new type named `NESButtons` with possible values `up`, `down`, `left`, `right`, `a`, `b`, `select`, and `start`. These values can be referred to by following the name of the type with a dot (`.`) and the value. In cases where the type name can be inferred, only the dot and value are needed. These values can then be used like any other values in Swift. +This defines a new type named `NESButton` with possible values `up`, `down`, `left`, `right`, `a`, `b`, `select`, and `start`. These values can be referred to by following the name of the type with a dot (`.`) and the value. In cases where the type name can be inferred, only the dot and value are needed. These values can then be used like any other values in Swift. ```swift var lastPressed = NESButton.up diff --git a/concepts/enumerations/introduction.md b/concepts/enumerations/introduction.md index b712d71a7..cd8107abf 100644 --- a/concepts/enumerations/introduction.md +++ b/concepts/enumerations/introduction.md @@ -27,7 +27,7 @@ enum NESButton { } ``` -This defines a new type named `NESButtons` with possible values `up`, `down`, `left`, `right`, `a`, `b`, `select`, and `start`. These values can be referred to by following the name of the type with a dot (`.`) and the value. In cases where the type name can be inferred, only the dot and value are needed. +This defines a new type named `NESButton` with possible values `up`, `down`, `left`, `right`, `a`, `b`, `select`, and `start`. These values can be referred to by following the name of the type with a dot (`.`) and the value. In cases where the type name can be inferred, only the dot and value are needed. ## Methods diff --git a/concepts/numbers/about.md b/concepts/numbers/about.md index d0536d872..8a9674424 100644 --- a/concepts/numbers/about.md +++ b/concepts/numbers/about.md @@ -23,7 +23,7 @@ let plancksConstant : Double = 6.62607015e-34 // plancksConstant is a Double ~~~~exercism/caution In Swift can't mix types in arithmetic operations, so you can't use any arithmetic operator on an `Int` with a `Double` or vice versa. -Thereby you have to do a type conversion first. +Therefore, you have to do a type conversion first. ~~~~ Swift does have a set of [arithmetic operators][arithmetic-operators] that can be used to perform basic mathematical operations. diff --git a/concepts/numbers/introduction.md b/concepts/numbers/introduction.md index d0536d872..8a9674424 100644 --- a/concepts/numbers/introduction.md +++ b/concepts/numbers/introduction.md @@ -23,7 +23,7 @@ let plancksConstant : Double = 6.62607015e-34 // plancksConstant is a Double ~~~~exercism/caution In Swift can't mix types in arithmetic operations, so you can't use any arithmetic operator on an `Int` with a `Double` or vice versa. -Thereby you have to do a type conversion first. +Therefore, you have to do a type conversion first. ~~~~ Swift does have a set of [arithmetic operators][arithmetic-operators] that can be used to perform basic mathematical operations. diff --git a/config.json b/config.json index d6f851cb2..0376ea85c 100644 --- a/config.json +++ b/config.json @@ -408,6 +408,14 @@ "transforming" ] }, + { + "slug": "darts", + "name": "Darts", + "uuid": "bdbc6f27-bc98-4edf-9f1d-93dbe49da361", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "bob", "name": "Bob", @@ -432,6 +440,14 @@ "transforming" ] }, + { + "slug": "armstrong-numbers", + "name": "Armstrong Numbers", + "uuid": "6bd76515-cc17-4238-bc08-7fbdfea14131", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "grade-school", "name": "Grade School", diff --git a/exercises/concept/freelancer-rates/.docs/introduction.md b/exercises/concept/freelancer-rates/.docs/introduction.md index d0536d872..8a9674424 100644 --- a/exercises/concept/freelancer-rates/.docs/introduction.md +++ b/exercises/concept/freelancer-rates/.docs/introduction.md @@ -23,7 +23,7 @@ let plancksConstant : Double = 6.62607015e-34 // plancksConstant is a Double ~~~~exercism/caution In Swift can't mix types in arithmetic operations, so you can't use any arithmetic operator on an `Int` with a `Double` or vice versa. -Thereby you have to do a type conversion first. +Therefore, you have to do a type conversion first. ~~~~ Swift does have a set of [arithmetic operators][arithmetic-operators] that can be used to perform basic mathematical operations. diff --git a/exercises/concept/high-score-board/.docs/introduction.md b/exercises/concept/high-score-board/.docs/introduction.md index c5e66c76e..244d9a2cc 100644 --- a/exercises/concept/high-score-board/.docs/introduction.md +++ b/exercises/concept/high-score-board/.docs/introduction.md @@ -7,7 +7,7 @@ Dictionary literals are written as a series of `key: value` pairs, separated by ```swift var addresses: Dictionary = ["The Munsters": "1313 Mockingbird Lane", "The Simpsons": "742 Evergreen Terrace", "Buffy Summers": "1630 Revello Drive"] var sequences: [String: [Int]] = ["Euler's totient": [1, 1, 2, 2, 4, 2, 6, 4], "Lazy caterer": [1, 2, 4, 7, 11, 16, 22, 29, 37], "Carmichael": [561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841]] -let constants = ["pi": 3.14159, "e": 2.71828, "phi": 1.618033, "avogadro": 6.02214076e22] +let constants = ["pi": 3.14159, "e": 2.71828, "phi": 1.618033, "avogadro": 6.02214076e23] var emptyDict1: [Int: Int] = [:] var emptyDict2 = [Character: String]() var emptyDict3 = Dictionary() diff --git a/exercises/concept/log-lines/.docs/introduction.md b/exercises/concept/log-lines/.docs/introduction.md index aa587dad0..54baf75e8 100644 --- a/exercises/concept/log-lines/.docs/introduction.md +++ b/exercises/concept/log-lines/.docs/introduction.md @@ -27,7 +27,7 @@ enum NESButton { } ``` -This defines a new type named `NESButtons` with possible values `up`, `down`, `left`, `right`, `a`, `b`, `select`, and `start`. These values can be referred to by following the name of the type with a dot (`.`) and the value. In cases where the type name can be inferred, only the dot and value are needed. +This defines a new type named `NESButton` with possible values `up`, `down`, `left`, `right`, `a`, `b`, `select`, and `start`. These values can be referred to by following the name of the type with a dot (`.`) and the value. In cases where the type name can be inferred, only the dot and value are needed. ## Methods diff --git a/exercises/practice/accumulate/.meta/config.json b/exercises/practice/accumulate/.meta/config.json index ec8e30056..a0c263257 100644 --- a/exercises/practice/accumulate/.meta/config.json +++ b/exercises/practice/accumulate/.meta/config.json @@ -26,5 +26,5 @@ }, "blurb": "Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.", "source": "Conversation with James Edward Gray II", - "source_url": "https://twitter.com/jeg2" + "source_url": "http://graysoftinc.com/" } diff --git a/exercises/practice/acronym/.docs/instructions.md b/exercises/practice/acronym/.docs/instructions.md index c62fc3e85..133bd2cbb 100644 --- a/exercises/practice/acronym/.docs/instructions.md +++ b/exercises/practice/acronym/.docs/instructions.md @@ -10,8 +10,8 @@ Punctuation is handled as follows: hyphens are word separators (like whitespace) For example: -|Input|Output| -|-|-| -|As Soon As Possible|ASAP| -|Liquid-crystal display|LCD| -|Thank George It's Friday!|TGIF| +| Input | Output | +| ------------------------- | ------ | +| As Soon As Possible | ASAP | +| Liquid-crystal display | LCD | +| Thank George It's Friday! | TGIF | diff --git a/exercises/practice/allergies/.docs/instructions.md b/exercises/practice/allergies/.docs/instructions.md index a13949209..daf8cfde2 100644 --- a/exercises/practice/allergies/.docs/instructions.md +++ b/exercises/practice/allergies/.docs/instructions.md @@ -22,6 +22,6 @@ Now, given just that score of 34, your program should be able to say: - Whether Tom is allergic to any one of those allergens listed above. - All the allergens Tom is allergic to. -Note: a given score may include allergens **not** listed above (i.e. allergens that score 256, 512, 1024, etc.). +Note: a given score may include allergens **not** listed above (i.e. allergens that score 256, 512, 1024, etc.). Your program should ignore those components of the score. For example, if the allergy score is 257, your program should only report the eggs (1) allergy. diff --git a/exercises/practice/anagram/.docs/instructions.md b/exercises/practice/anagram/.docs/instructions.md index 7d1c8283e..a7298485b 100644 --- a/exercises/practice/anagram/.docs/instructions.md +++ b/exercises/practice/anagram/.docs/instructions.md @@ -1,9 +1,9 @@ # Instructions -An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. -A word is not its own anagram: for example, `"stop"` is not an anagram of `"stop"`. +Your task is to, given a target word and a set of candidate words, to find the subset of the candidates that are anagrams of the target. -Given a target word and a set of candidate words, this exercise requests the anagram set: the subset of the candidates that are anagrams of the target. +An anagram is a rearrangement of letters to form a new word: for example `"owns"` is an anagram of `"snow"`. +A word is _not_ its own anagram: for example, `"stop"` is not an anagram of `"stop"`. The target and candidates are words of one or more ASCII alphabetic characters (`A`-`Z` and `a`-`z`). Lowercase and uppercase characters are equivalent: for example, `"PoTS"` is an anagram of `"sTOp"`, but `StoP` is not an anagram of `sTOp`. diff --git a/exercises/practice/anagram/.docs/introduction.md b/exercises/practice/anagram/.docs/introduction.md new file mode 100644 index 000000000..1acbdf00b --- /dev/null +++ b/exercises/practice/anagram/.docs/introduction.md @@ -0,0 +1,12 @@ +# Introduction + +At a garage sale, you find a lovely vintage typewriter at a bargain price! +Excitedly, you rush home, insert a sheet of paper, and start typing away. +However, your excitement wanes when you examine the output: all words are garbled! +For example, it prints "stop" instead of "post" and "least" instead of "stale." +Carefully, you try again, but now it prints "spot" and "slate." +After some experimentation, you find there is a random delay before each letter is printed, which messes up the order. +You now understand why they sold it for so little money! + +You realize this quirk allows you to generate anagrams, which are words formed by rearranging the letters of another word. +Pleased with your finding, you spend the rest of the day generating hundreds of anagrams. diff --git a/exercises/practice/armstrong-numbers/.docs/instructions.md b/exercises/practice/armstrong-numbers/.docs/instructions.md new file mode 100644 index 000000000..5e56bbe46 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.docs/instructions.md @@ -0,0 +1,14 @@ +# Instructions + +An [Armstrong number][armstrong-number] is a number that is the sum of its own digits each raised to the power of the number of digits. + +For example: + +- 9 is an Armstrong number, because `9 = 9^1 = 9` +- 10 is _not_ an Armstrong number, because `10 != 1^2 + 0^2 = 1` +- 153 is an Armstrong number, because: `153 = 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153` +- 154 is _not_ an Armstrong number, because: `154 != 1^3 + 5^3 + 4^3 = 1 + 125 + 64 = 190` + +Write some code to determine whether a number is an Armstrong number. + +[armstrong-number]: https://en.wikipedia.org/wiki/Narcissistic_number diff --git a/exercises/practice/armstrong-numbers/.meta/Sources/ArmstrongNumbers/ArmstrongNumbersExample.swift b/exercises/practice/armstrong-numbers/.meta/Sources/ArmstrongNumbers/ArmstrongNumbersExample.swift new file mode 100644 index 000000000..df0d8576a --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/Sources/ArmstrongNumbers/ArmstrongNumbersExample.swift @@ -0,0 +1,8 @@ +import Foundation + +func isArmstrongNumber(_ number: Int) -> Bool { + let stringNumber = String(number) + let numberLength = stringNumber.count + let sum = stringNumber.compactMap { Int(String($0)) }.reduce(0) { $0 + Int(pow(Double($1), Double(numberLength))) } + return sum == number +} diff --git a/exercises/practice/armstrong-numbers/.meta/config.json b/exercises/practice/armstrong-numbers/.meta/config.json new file mode 100644 index 000000000..8011bdcc1 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "meatball133" + ], + "files": { + "solution": [ + "Sources/ArmstrongNumbers/ArmstrongNumbers.swift" + ], + "test": [ + "Tests/ArmstrongNumbersTests/ArmstrongNumbersTests.swift" + ], + "example": [ + ".meta/Sources/ArmstrongNumbers/ArmstrongNumbersExample.swift" + ] + }, + "blurb": "Determine if a number is an Armstrong number.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Narcissistic_number" +} diff --git a/exercises/practice/armstrong-numbers/.meta/template.swift b/exercises/practice/armstrong-numbers/.meta/template.swift new file mode 100644 index 000000000..0ae784d07 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/template.swift @@ -0,0 +1,20 @@ +import XCTest +@testable import {{exercise|camelCase}} +class {{exercise|camelCase}}Tests: XCTestCase { + let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false + + {% for case in cases %} + {% if forloop.first -%} + func test{{case.description |camelCase }}() { + {% else -%} + func test{{case.description |camelCase }}() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + {% endif -%} + {%- if case.expected -%} + XCTAssertTrue(isArmstrongNumber({{case.input.number}})) + {%- else -%} + XCTAssertFalse(isArmstrongNumber({{case.input.number}})) + {%- endif %} + } + {% endfor -%} +} diff --git a/exercises/practice/armstrong-numbers/.meta/tests.toml b/exercises/practice/armstrong-numbers/.meta/tests.toml new file mode 100644 index 000000000..b956bdfd4 --- /dev/null +++ b/exercises/practice/armstrong-numbers/.meta/tests.toml @@ -0,0 +1,45 @@ +# 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. + +[c1ed103c-258d-45b2-be73-d8c6d9580c7b] +description = "Zero is an Armstrong number" + +[579e8f03-9659-4b85-a1a2-d64350f6b17a] +description = "Single-digit numbers are Armstrong numbers" + +[2d6db9dc-5bf8-4976-a90b-b2c2b9feba60] +description = "There are no two-digit Armstrong numbers" + +[509c087f-e327-4113-a7d2-26a4e9d18283] +description = "Three-digit number that is an Armstrong number" + +[7154547d-c2ce-468d-b214-4cb953b870cf] +description = "Three-digit number that is not an Armstrong number" + +[6bac5b7b-42e9-4ecb-a8b0-4832229aa103] +description = "Four-digit number that is an Armstrong number" + +[eed4b331-af80-45b5-a80b-19c9ea444b2e] +description = "Four-digit number that is not an Armstrong number" + +[f971ced7-8d68-4758-aea1-d4194900b864] +description = "Seven-digit number that is an Armstrong number" + +[7ee45d52-5d35-4fbd-b6f1-5c8cd8a67f18] +description = "Seven-digit number that is not an Armstrong number" + +[5ee2fdf8-334e-4a46-bb8d-e5c19c02c148] +description = "Armstrong number containing seven zeroes" +include = false + +[12ffbf10-307a-434e-b4ad-c925680e1dd4] +description = "The largest and last Armstrong number" +include = false diff --git a/exercises/practice/armstrong-numbers/Package.swift b/exercises/practice/armstrong-numbers/Package.swift new file mode 100644 index 000000000..9cc117728 --- /dev/null +++ b/exercises/practice/armstrong-numbers/Package.swift @@ -0,0 +1,21 @@ +// swift-tools-version:5.3 + +import PackageDescription + +let package = Package( + name: "ArmstrongNumbers", + products: [ + .library( + name: "ArmstrongNumbers", + targets: ["ArmstrongNumbers"]) + ], + dependencies: [], + targets: [ + .target( + name: "ArmstrongNumbers", + dependencies: []), + .testTarget( + name: "ArmstrongNumbersTests", + dependencies: ["ArmstrongNumbers"]), + ] +) diff --git a/exercises/practice/armstrong-numbers/Sources/ArmstrongNumbers/ArmstrongNumbers.swift b/exercises/practice/armstrong-numbers/Sources/ArmstrongNumbers/ArmstrongNumbers.swift new file mode 100644 index 000000000..63b122561 --- /dev/null +++ b/exercises/practice/armstrong-numbers/Sources/ArmstrongNumbers/ArmstrongNumbers.swift @@ -0,0 +1,3 @@ +func isArmstrongNumber(_ number: Int) -> Bool { + // Write your code for the 'Armstrong Numbers' exercise here. +} diff --git a/exercises/practice/armstrong-numbers/Tests/ArmstrongNumbersTests/ArmstrongNumbersTests.swift b/exercises/practice/armstrong-numbers/Tests/ArmstrongNumbersTests/ArmstrongNumbersTests.swift new file mode 100644 index 000000000..e99683b94 --- /dev/null +++ b/exercises/practice/armstrong-numbers/Tests/ArmstrongNumbersTests/ArmstrongNumbersTests.swift @@ -0,0 +1,51 @@ +import XCTest + +@testable import ArmstrongNumbers + +class ArmstrongNumbersTests: XCTestCase { + let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false + + func testZeroIsAnArmstrongNumber() { + XCTAssertTrue(isArmstrongNumber(0)) + } + + func testSingleDigitNumbersAreArmstrongNumbers() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertTrue(isArmstrongNumber(5)) + } + + func testThereAreNoTwoDigitArmstrongNumbers() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertFalse(isArmstrongNumber(10)) + } + + func testThreeDigitNumberThatIsAnArmstrongNumber() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertTrue(isArmstrongNumber(153)) + } + + func testThreeDigitNumberThatIsNotAnArmstrongNumber() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertFalse(isArmstrongNumber(100)) + } + + func testFourDigitNumberThatIsAnArmstrongNumber() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertTrue(isArmstrongNumber(9474)) + } + + func testFourDigitNumberThatIsNotAnArmstrongNumber() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertFalse(isArmstrongNumber(9475)) + } + + func testSevenDigitNumberThatIsAnArmstrongNumber() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertTrue(isArmstrongNumber(9_926_315)) + } + + func testSevenDigitNumberThatIsNotAnArmstrongNumber() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertFalse(isArmstrongNumber(9_926_314)) + } +} diff --git a/exercises/practice/binary-search-tree/.meta/config.json b/exercises/practice/binary-search-tree/.meta/config.json index 627751f4f..e05f518ea 100644 --- a/exercises/practice/binary-search-tree/.meta/config.json +++ b/exercises/practice/binary-search-tree/.meta/config.json @@ -20,6 +20,5 @@ ] }, "blurb": "Insert and search for numbers in a binary tree.", - "source": "Josh Cheek", - "source_url": "https://twitter.com/josh_cheek" + "source": "Josh Cheek" } diff --git a/exercises/practice/binary-search/.docs/instructions.md b/exercises/practice/binary-search/.docs/instructions.md index aa1946cfb..12f4358eb 100644 --- a/exercises/practice/binary-search/.docs/instructions.md +++ b/exercises/practice/binary-search/.docs/instructions.md @@ -11,7 +11,7 @@ Binary search only works when a list has been sorted. The algorithm looks like this: -- Find the middle element of a *sorted* list and compare it with the item we're looking for. +- Find the middle element of a _sorted_ list and compare it with the item we're looking for. - If the middle element is our item, then we're done! - If the middle element is greater than our item, we can eliminate that element and all the elements **after** it. - If the middle element is less than our item, we can eliminate that element and all the elements **before** it. diff --git a/exercises/practice/bowling/.docs/instructions.md b/exercises/practice/bowling/.docs/instructions.md index ddce7ee48..60ccad1b6 100644 --- a/exercises/practice/bowling/.docs/instructions.md +++ b/exercises/practice/bowling/.docs/instructions.md @@ -23,9 +23,9 @@ There are three cases for the tabulation of a frame. Here is a three frame example: -| Frame 1 | Frame 2 | Frame 3 | -| :-------------: |:-------------:| :---------------------:| -| X (strike) | 5/ (spare) | 9 0 (open frame) | +| Frame 1 | Frame 2 | Frame 3 | +| :--------: | :--------: | :--------------: | +| X (strike) | 5/ (spare) | 9 0 (open frame) | Frame 1 is (10 + 5 + 5) = 20 diff --git a/exercises/practice/circular-buffer/.docs/instructions.md b/exercises/practice/circular-buffer/.docs/instructions.md index 3487a0f61..2ba1fda2a 100644 --- a/exercises/practice/circular-buffer/.docs/instructions.md +++ b/exercises/practice/circular-buffer/.docs/instructions.md @@ -4,39 +4,55 @@ A circular buffer, cyclic buffer or ring buffer is a data structure that uses a A circular buffer first starts empty and of some predefined length. For example, this is a 7-element buffer: - - [ ][ ][ ][ ][ ][ ][ ] + +```text +[ ][ ][ ][ ][ ][ ][ ] +``` Assume that a 1 is written into the middle of the buffer (exact starting location does not matter in a circular buffer): - - [ ][ ][ ][1][ ][ ][ ] + +```text +[ ][ ][ ][1][ ][ ][ ] +``` Then assume that two more elements are added — 2 & 3 — which get appended after the 1: - - [ ][ ][ ][1][2][3][ ] + +```text +[ ][ ][ ][1][2][3][ ] +``` If two elements are then removed from the buffer, the oldest values inside the buffer are removed. The two elements removed, in this case, are 1 & 2, leaving the buffer with just a 3: - - [ ][ ][ ][ ][ ][3][ ] + +```text +[ ][ ][ ][ ][ ][3][ ] +``` If the buffer has 7 elements then it is completely full: - - [5][6][7][8][9][3][4] + +```text +[5][6][7][8][9][3][4] +``` When the buffer is full an error will be raised, alerting the client that further writes are blocked until a slot becomes free. When the buffer is full, the client can opt to overwrite the oldest data with a forced write. In this case, two more elements — A & B — are added and they overwrite the 3 & 4: - - [5][6][7][8][9][A][B] + +```text +[5][6][7][8][9][A][B] +``` 3 & 4 have been replaced by A & B making 5 now the oldest data in the buffer. Finally, if two elements are removed then what would be returned is 5 & 6 yielding the buffer: - - [ ][ ][7][8][9][A][B] + +```text +[ ][ ][7][8][9][A][B] +``` Because there is space available, if the client again uses overwrite to store C & D then the space where 5 & 6 were stored previously will be used not the location of 7 & 8. 7 is still the oldest element and the buffer is once again full. - - [C][D][7][8][9][A][B] + +```text +[C][D][7][8][9][A][B] +``` diff --git a/exercises/practice/clock/.meta/config.json b/exercises/practice/clock/.meta/config.json index 27512f701..5911a4d77 100644 --- a/exercises/practice/clock/.meta/config.json +++ b/exercises/practice/clock/.meta/config.json @@ -24,6 +24,5 @@ ] }, "blurb": "Implement a clock that handles times without dates.", - "source": "Pairing session with Erin Drummond", - "source_url": "https://twitter.com/ebdrummond" + "source": "Pairing session with Erin Drummond" } diff --git a/exercises/practice/darts/.docs/instructions.md b/exercises/practice/darts/.docs/instructions.md new file mode 100644 index 000000000..6518201c7 --- /dev/null +++ b/exercises/practice/darts/.docs/instructions.md @@ -0,0 +1,31 @@ +# Instructions + +Calculate the points scored in a single toss of a Darts game. + +[Darts][darts] is a game where players throw darts at a [target][darts-target]. + +In our particular instance of the game, the target rewards 4 different amounts of points, depending on where the dart lands: + +![Our dart scoreboard with values from a complete miss to a bullseye](https://assets.exercism.org/images/exercises/darts/darts-scoreboard.svg) + +- If the dart lands outside the target, player earns no points (0 points). +- If the dart lands in the outer circle of the target, player earns 1 point. +- If the dart lands in the middle circle of the target, player earns 5 points. +- If the dart lands in the inner circle of the target, player earns 10 points. + +The outer circle has a radius of 10 units (this is equivalent to the total radius for the entire target), the middle circle a radius of 5 units, and the inner circle a radius of 1. +Of course, they are all centered at the same point — that is, the circles are [concentric][] defined by the coordinates (0, 0). + +Given a point in the target (defined by its [Cartesian coordinates][cartesian-coordinates] `x` and `y`, where `x` and `y` are [real][real-numbers]), calculate the correct score earned by a dart landing at that point. + +## Credit + +The scoreboard image was created by [habere-et-dispertire][habere-et-dispertire] using [Inkscape][inkscape]. + +[darts]: https://en.wikipedia.org/wiki/Darts +[darts-target]: https://en.wikipedia.org/wiki/Darts#/media/File:Darts_in_a_dartboard.jpg +[concentric]: https://mathworld.wolfram.com/ConcentricCircles.html +[cartesian-coordinates]: https://www.mathsisfun.com/data/cartesian-coordinates.html +[real-numbers]: https://www.mathsisfun.com/numbers/real-numbers.html +[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire +[inkscape]: https://en.wikipedia.org/wiki/Inkscape diff --git a/exercises/practice/darts/.meta/Sources/Darts/DartsExample.swift b/exercises/practice/darts/.meta/Sources/Darts/DartsExample.swift new file mode 100644 index 000000000..5d602dc48 --- /dev/null +++ b/exercises/practice/darts/.meta/Sources/Darts/DartsExample.swift @@ -0,0 +1,15 @@ +import Foundation + +func dartScore(x: Double, y: Double) -> Int { + let distance = sqrt(x * x + y * y) + switch distance { + case 0...1: + return 10 + case 1...5: + return 5 + case 5...10: + return 1 + default: + return 0 + } +} diff --git a/exercises/practice/darts/.meta/config.json b/exercises/practice/darts/.meta/config.json new file mode 100644 index 000000000..d7184c4d9 --- /dev/null +++ b/exercises/practice/darts/.meta/config.json @@ -0,0 +1,18 @@ +{ + "authors": [ + "meatball133" + ], + "files": { + "solution": [ + "Sources/Darts/Darts.swift" + ], + "test": [ + "Tests/DartsTests/DartsTests.swift" + ], + "example": [ + ".meta/Sources/Darts/DartsExample.swift" + ] + }, + "blurb": "Calculate the points scored in a single toss of a Darts game.", + "source": "Inspired by an exercise created by a professor Della Paolera in Argentina" +} diff --git a/exercises/practice/darts/.meta/template.swift b/exercises/practice/darts/.meta/template.swift new file mode 100644 index 000000000..77fd528f3 --- /dev/null +++ b/exercises/practice/darts/.meta/template.swift @@ -0,0 +1,16 @@ +import XCTest +@testable import {{exercise|camelCase}} +class {{exercise|camelCase}}Tests: XCTestCase { + let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false + + {% for case in cases %} + {% if forloop.first -%} + func test{{case.description |camelCase }}() { + {% else -%} + func test{{case.description |camelCase }}() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + {% endif -%} + XCTAssertEqual(dartScore(x: {{case.input.x | round:1 }}, y: {{case.input.y | round:1}}), {{case.expected}}) + } + {% endfor -%} +} diff --git a/exercises/practice/darts/.meta/tests.toml b/exercises/practice/darts/.meta/tests.toml new file mode 100644 index 000000000..fbe2976d4 --- /dev/null +++ b/exercises/practice/darts/.meta/tests.toml @@ -0,0 +1,49 @@ +# 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. + +[9033f731-0a3a-4d9c-b1c0-34a1c8362afb] +description = "Missed target" + +[4c9f6ff4-c489-45fd-be8a-1fcb08b4d0ba] +description = "On the outer circle" + +[14378687-ee58-4c9b-a323-b089d5274be8] +description = "On the middle circle" + +[849e2e63-85bd-4fed-bc3b-781ae962e2c9] +description = "On the inner circle" + +[1c5ffd9f-ea66-462f-9f06-a1303de5a226] +description = "Exactly on center" + +[b65abce3-a679-4550-8115-4b74bda06088] +description = "Near the center" + +[66c29c1d-44f5-40cf-9927-e09a1305b399] +description = "Just within the inner circle" + +[d1012f63-c97c-4394-b944-7beb3d0b141a] +description = "Just outside the inner circle" + +[ab2b5666-b0b4-49c3-9b27-205e790ed945] +description = "Just within the middle circle" + +[70f1424e-d690-4860-8caf-9740a52c0161] +description = "Just outside the middle circle" + +[a7dbf8db-419c-4712-8a7f-67602b69b293] +description = "Just within the outer circle" + +[e0f39315-9f9a-4546-96e4-a9475b885aa7] +description = "Just outside the outer circle" + +[045d7d18-d863-4229-818e-b50828c75d19] +description = "Asymmetric position between the inner and middle circles" diff --git a/exercises/practice/darts/Package.swift b/exercises/practice/darts/Package.swift new file mode 100644 index 000000000..1dd8e0708 --- /dev/null +++ b/exercises/practice/darts/Package.swift @@ -0,0 +1,21 @@ +// swift-tools-version:5.3 + +import PackageDescription + +let package = Package( + name: "Darts", + products: [ + .library( + name: "Darts", + targets: ["Darts"]) + ], + dependencies: [], + targets: [ + .target( + name: "Darts", + dependencies: []), + .testTarget( + name: "DartsTests", + dependencies: ["Darts"]), + ] +) diff --git a/exercises/practice/darts/Sources/Darts/Darts.swift b/exercises/practice/darts/Sources/Darts/Darts.swift new file mode 100644 index 000000000..cc86ce15e --- /dev/null +++ b/exercises/practice/darts/Sources/Darts/Darts.swift @@ -0,0 +1,3 @@ +func dartScore(x: Double, y: Double) -> Int { + // Write your code for the 'Darts' exercise here. +} diff --git a/exercises/practice/darts/Tests/DartsTests/DartsTests.swift b/exercises/practice/darts/Tests/DartsTests/DartsTests.swift new file mode 100644 index 000000000..45491ab35 --- /dev/null +++ b/exercises/practice/darts/Tests/DartsTests/DartsTests.swift @@ -0,0 +1,71 @@ +import XCTest + +@testable import Darts + +class DartsTests: XCTestCase { + let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false + + func testMissedTarget() { + XCTAssertEqual(dartScore(x: -9, y: 9), 0) + } + + func testOnTheOuterCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: 0, y: 10), 1) + } + + func testOnTheMiddleCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: -5, y: 0), 5) + } + + func testOnTheInnerCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: 0, y: -1), 10) + } + + func testExactlyOnCenter() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: 0, y: 0), 10) + } + + func testNearTheCenter() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: -0.1, y: -0.1), 10) + } + + func testJustWithinTheInnerCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: 0.7, y: 0.7), 10) + } + + func testJustOutsideTheInnerCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: 0.8, y: -0.8), 5) + } + + func testJustWithinTheMiddleCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: -3.5, y: 3.5), 5) + } + + func testJustOutsideTheMiddleCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: -3.6, y: -3.6), 1) + } + + func testJustWithinTheOuterCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: -7, y: 7), 1) + } + + func testJustOutsideTheOuterCircle() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: 7.1, y: -7.1), 0) + } + + func testAsymmetricPositionBetweenTheInnerAndMiddleCircles() throws { + try XCTSkipIf(true && !runAll) // change true to false to run this test + XCTAssertEqual(dartScore(x: 0.5, y: -4), 5) + } +} diff --git a/exercises/practice/flatten-array/.docs/instructions.md b/exercises/practice/flatten-array/.docs/instructions.md index 51bea6790..89dacfa32 100644 --- a/exercises/practice/flatten-array/.docs/instructions.md +++ b/exercises/practice/flatten-array/.docs/instructions.md @@ -2,7 +2,7 @@ Take a nested list and return a single flattened list with all values except nil/null. -The challenge is to write a function that accepts an arbitrarily-deep nested list-like structure and returns a flattened structure without any nil/null values. +The challenge is to take an arbitrarily-deep nested list-like structure and produce a flattened structure without any nil/null values. For example: diff --git a/exercises/practice/hamming/.docs/instructions.md b/exercises/practice/hamming/.docs/instructions.md index 020fdd02d..b9ae6efc5 100644 --- a/exercises/practice/hamming/.docs/instructions.md +++ b/exercises/practice/hamming/.docs/instructions.md @@ -1,6 +1,6 @@ # Instructions -Calculate the Hamming Distance between two DNA strands. +Calculate the Hamming distance between two DNA strands. Your body is made up of cells that contain DNA. Those cells regularly wear out and need replacing, which they achieve by dividing into daughter cells. @@ -9,18 +9,18 @@ In fact, the average human body experiences about 10 quadrillion cell divisions When cells divide, their DNA replicates too. Sometimes during this process mistakes happen and single pieces of DNA get encoded with the incorrect information. If we compare two strands of DNA and count the differences between them we can see how many mistakes occurred. -This is known as the "Hamming Distance". +This is known as the "Hamming distance". -We read DNA using the letters C,A,G and T. +We read DNA using the letters C, A, G and T. Two strands might look like this: GAGCCTACTAACGGGAT CATCGTAATGACGGCCT ^ ^ ^ ^ ^ ^^ -They have 7 differences, and therefore the Hamming Distance is 7. +They have 7 differences, and therefore the Hamming distance is 7. -The Hamming Distance is useful for lots of things in science, not just biology, so it's a nice phrase to be familiar with :) +The Hamming distance is useful for lots of things in science, not just biology, so it's a nice phrase to be familiar with :) ## Implementation notes diff --git a/exercises/practice/hello-world/.meta/config.json b/exercises/practice/hello-world/.meta/config.json index 20938d569..1fecc872d 100644 --- a/exercises/practice/hello-world/.meta/config.json +++ b/exercises/practice/hello-world/.meta/config.json @@ -23,7 +23,7 @@ ".meta/Sources/HelloWorld/HelloWorldExample.swift" ] }, - "blurb": "The classical introductory exercise. Just say \"Hello, World!\".", + "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".", "source": "This is an exercise to introduce users to using Exercism", "source_url": "https://en.wikipedia.org/wiki/%22Hello,_world!%22_program" } diff --git a/exercises/practice/isogram/.docs/instructions.md b/exercises/practice/isogram/.docs/instructions.md index 5e4884476..2e8df851a 100644 --- a/exercises/practice/isogram/.docs/instructions.md +++ b/exercises/practice/isogram/.docs/instructions.md @@ -11,4 +11,4 @@ Examples of isograms: - downstream - six-year-old -The word *isograms*, however, is not an isogram, because the s repeats. +The word _isograms_, however, is not an isogram, because the s repeats. diff --git a/exercises/practice/list-ops/.docs/instructions.md b/exercises/practice/list-ops/.docs/instructions.md index d34533387..ebc5dffed 100644 --- a/exercises/practice/list-ops/.docs/instructions.md +++ b/exercises/practice/list-ops/.docs/instructions.md @@ -7,11 +7,13 @@ Implement a series of basic list operations, without using existing functions. The precise number and names of the operations to be implemented will be track dependent to avoid conflicts with existing names, but the general operations you will implement include: -- `append` (*given two lists, add all items in the second list to the end of the first list*); -- `concatenate` (*given a series of lists, combine all items in all lists into one flattened list*); -- `filter` (*given a predicate and a list, return the list of all items for which `predicate(item)` is True*); -- `length` (*given a list, return the total number of items within it*); -- `map` (*given a function and a list, return the list of the results of applying `function(item)` on all items*); -- `foldl` (*given a function, a list, and initial accumulator, fold (reduce) each item into the accumulator from the left using `function(accumulator, item)`*); -- `foldr` (*given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right using `function(item, accumulator)`*); -- `reverse` (*given a list, return a list with all the original items, but in reversed order*); +- `append` (_given two lists, add all items in the second list to the end of the first list_); +- `concatenate` (_given a series of lists, combine all items in all lists into one flattened list_); +- `filter` (_given a predicate and a list, return the list of all items for which `predicate(item)` is True_); +- `length` (_given a list, return the total number of items within it_); +- `map` (_given a function and a list, return the list of the results of applying `function(item)` on all items_); +- `foldl` (_given a function, a list, and initial accumulator, fold (reduce) each item into the accumulator from the left_); +- `foldr` (_given a function, a list, and an initial accumulator, fold (reduce) each item into the accumulator from the right_); +- `reverse` (_given a list, return a list with all the original items, but in reversed order_). + +Note, the ordering in which arguments are passed to the fold functions (`foldl`, `foldr`) is significant. diff --git a/exercises/practice/luhn/.docs/instructions.md b/exercises/practice/luhn/.docs/instructions.md index 8cbe791fc..49934c106 100644 --- a/exercises/practice/luhn/.docs/instructions.md +++ b/exercises/practice/luhn/.docs/instructions.md @@ -22,7 +22,8 @@ The first step of the Luhn algorithm is to double every second digit, starting f We will be doubling ```text -4_3_ 3_9_ 0_4_ 6_6_ +4539 3195 0343 6467 +↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ (double these) ``` If doubling the number results in a number greater than 9 then subtract 9 from the product. diff --git a/exercises/practice/matching-brackets/.docs/instructions.md b/exercises/practice/matching-brackets/.docs/instructions.md index 544daa968..ea1708423 100644 --- a/exercises/practice/matching-brackets/.docs/instructions.md +++ b/exercises/practice/matching-brackets/.docs/instructions.md @@ -1,4 +1,5 @@ # Instructions Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly. -The string may also contain other characters, which for the purposes of this exercise should be ignored. +Any other characters should be ignored. +For example, `"{what is (42)}?"` is balanced and `"[text}"` is not. diff --git a/exercises/practice/matching-brackets/.docs/introduction.md b/exercises/practice/matching-brackets/.docs/introduction.md new file mode 100644 index 000000000..0618221b2 --- /dev/null +++ b/exercises/practice/matching-brackets/.docs/introduction.md @@ -0,0 +1,8 @@ +# Introduction + +You're given the opportunity to write software for the Bracketeer™, an ancient but powerful mainframe. +The software that runs on it is written in a proprietary language. +Much of its syntax is familiar, but you notice _lots_ of brackets, braces and parentheses. +Despite the Bracketeer™ being powerful, it lacks flexibility. +If the source code has any unbalanced brackets, braces or parentheses, the Bracketeer™ crashes and must be rebooted. +To avoid such a scenario, you start writing code that can verify that brackets, braces, and parentheses are balanced before attempting to run it on the Bracketeer™. diff --git a/exercises/practice/pascals-triangle/.docs/instructions.md b/exercises/practice/pascals-triangle/.docs/instructions.md index f55678593..0f58f0069 100644 --- a/exercises/practice/pascals-triangle/.docs/instructions.md +++ b/exercises/practice/pascals-triangle/.docs/instructions.md @@ -1,8 +1,20 @@ # Instructions -Compute Pascal's triangle up to a given number of rows. +Your task is to output the first N rows of Pascal's triangle. -In Pascal's Triangle each number is computed by adding the numbers to the right and left of the current position in the previous row. +[Pascal's triangle][wikipedia] is a triangular array of positive integers. + +In Pascal's triangle, the number of values in a row is equal to its row number (which starts at one). +Therefore, the first row has one value, the second row has two values, and so on. + +The first (topmost) row has a single value: `1`. +Subsequent rows' values are computed by adding the numbers directly to the right and left of the current position in the previous row. + +If the previous row does _not_ have a value to the left or right of the current position (which only happens for the leftmost and rightmost positions), treat that position's value as zero (effectively "ignoring" it in the summation). + +## Example + +Let's look at the first 5 rows of Pascal's Triangle: ```text 1 @@ -10,5 +22,14 @@ In Pascal's Triangle each number is computed by adding the numbers to the right 1 2 1 1 3 3 1 1 4 6 4 1 -# ... etc ``` + +The topmost row has one value, which is `1`. + +The leftmost and rightmost values have only one preceding position to consider, which is the position to its right respectively to its left. +With the topmost value being `1`, it follows from this that all the leftmost and rightmost values are also `1`. + +The other values all have two positions to consider. +For example, the fifth row's (`1 4 6 4 1`) middle value is `6`, as the values to its left and right in the preceding row are `3` and `3`: + +[wikipedia]: https://en.wikipedia.org/wiki/Pascal%27s_triangle diff --git a/exercises/practice/pascals-triangle/.docs/introduction.md b/exercises/practice/pascals-triangle/.docs/introduction.md new file mode 100644 index 000000000..60b8ec30d --- /dev/null +++ b/exercises/practice/pascals-triangle/.docs/introduction.md @@ -0,0 +1,22 @@ +# Introduction + +With the weather being great, you're not looking forward to spending an hour in a classroom. +Annoyed, you enter the class room, where you notice a strangely satisfying triangle shape on the blackboard. +Whilst waiting for your math teacher to arrive, you can't help but notice some patterns in the triangle: the outer values are all ones, each subsequent row has one more value than its previous row and the triangle is symmetrical. +Weird! + +Not long after you sit down, your teacher enters the room and explains that this triangle is the famous [Pascal's triangle][wikipedia]. + +Over the next hour, your teacher reveals some amazing things hidden in this triangle: + +- It can be used to compute how many ways you can pick K elements from N values. +- It contains the Fibonacci sequence. +- If you color odd and even numbers differently, you get a beautiful pattern called the [Sierpiński triangle][wikipedia-sierpinski-triangle]. + +The teacher implores you and your classmates to lookup other uses, and assures you that there are lots more! +At that moment, the school bell rings. +You realize that for the past hour, you were completely absorbed in learning about Pascal's triangle. +You quickly grab your laptop from your bag and go outside, ready to enjoy both the sunshine _and_ the wonders of Pascal's triangle. + +[wikipedia]: https://en.wikipedia.org/wiki/Pascal%27s_triangle +[wikipedia-sierpinski-triangle]: https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle diff --git a/exercises/practice/perfect-numbers/.docs/instructions.md b/exercises/practice/perfect-numbers/.docs/instructions.md index 0dae8867f..b2bc82ca3 100644 --- a/exercises/practice/perfect-numbers/.docs/instructions.md +++ b/exercises/practice/perfect-numbers/.docs/instructions.md @@ -1,24 +1,39 @@ # Instructions -Determine if a number is perfect, abundant, or deficient based on -Nicomachus' (60 - 120 CE) classification scheme for positive integers. - -The Greek mathematician [Nicomachus][nicomachus] devised a classification scheme for positive integers, identifying each as belonging uniquely to the categories of **perfect**, **abundant**, or **deficient** based on their [aliquot sum][aliquot-sum]. -The aliquot sum is defined as the sum of the factors of a number not including the number itself. -For example, the aliquot sum of 15 is (1 + 3 + 5) = 9 - -- **Perfect**: aliquot sum = number - - 6 is a perfect number because (1 + 2 + 3) = 6 - - 28 is a perfect number because (1 + 2 + 4 + 7 + 14) = 28 -- **Abundant**: aliquot sum > number - - 12 is an abundant number because (1 + 2 + 3 + 4 + 6) = 16 - - 24 is an abundant number because (1 + 2 + 3 + 4 + 6 + 8 + 12) = 36 -- **Deficient**: aliquot sum < number - - 8 is a deficient number because (1 + 2 + 4) = 7 - - Prime numbers are deficient - -Implement a way to determine whether a given number is **perfect**. -Depending on your language track, you may also need to implement a way to determine whether a given number is **abundant** or **deficient**. +Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers. + +The Greek mathematician [Nicomachus][nicomachus] devised a classification scheme for positive integers, identifying each as belonging uniquely to the categories of [perfect](#perfect), [abundant](#abundant), or [deficient](#deficient) based on their [aliquot sum][aliquot-sum]. +The _aliquot sum_ is defined as the sum of the factors of a number not including the number itself. +For example, the aliquot sum of `15` is `1 + 3 + 5 = 9`. + +## Perfect + +A number is perfect when it equals its aliquot sum. +For example: + +- `6` is a perfect number because `1 + 2 + 3 = 6` +- `28` is a perfect number because `1 + 2 + 4 + 7 + 14 = 28` + +## Abundant + +A number is abundant when it is less than its aliquot sum. +For example: + +- `12` is an abundant number because `1 + 2 + 3 + 4 + 6 = 16` +- `24` is an abundant number because `1 + 2 + 3 + 4 + 6 + 8 + 12 = 36` + +## Deficient + +A number is deficient when it is greater than its aliquot sum. +For example: + +- `8` is a deficient number because `1 + 2 + 4 = 7` +- Prime numbers are deficient + +## Task + +Implement a way to determine whether a given number is [perfect](#perfect). +Depending on your language track, you may also need to implement a way to determine whether a given number is [abundant](#abundant) or [deficient](#deficient). [nicomachus]: https://en.wikipedia.org/wiki/Nicomachus [aliquot-sum]: https://en.wikipedia.org/wiki/Aliquot_sum diff --git a/exercises/practice/phone-number/.docs/instructions.md b/exercises/practice/phone-number/.docs/instructions.md index 6d3275cdf..62ba48e96 100644 --- a/exercises/practice/phone-number/.docs/instructions.md +++ b/exercises/practice/phone-number/.docs/instructions.md @@ -5,18 +5,20 @@ Clean up user-entered phone numbers so that they can be sent SMS messages. The **North American Numbering Plan (NANP)** is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: `1`. -NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as *area code*, followed by a seven-digit local number. -The first three digits of the local number represent the *exchange code*, followed by the unique four-digit number which is the *subscriber number*. +NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as _area code_, followed by a seven-digit local number. +The first three digits of the local number represent the _exchange code_, followed by the unique four-digit number which is the _subscriber number_. The format is usually represented as ```text -(NXX)-NXX-XXXX +NXX NXX-XXXX ``` where `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9. -Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code (1) if present. +Sometimes they also have the country code (represented as `1` or `+1`) prefixed. + +Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code if present. For example, the inputs diff --git a/exercises/practice/pig-latin/.docs/instructions.md b/exercises/practice/pig-latin/.docs/instructions.md index 6c843080d..a9645ac23 100644 --- a/exercises/practice/pig-latin/.docs/instructions.md +++ b/exercises/practice/pig-latin/.docs/instructions.md @@ -19,7 +19,7 @@ For example: ## Rule 2 -If a word begins with a one or more consonants, first move those consonants to the end of the word and then add an `"ay"` sound to the end of the word. +If a word begins with one or more consonants, first move those consonants to the end of the word and then add an `"ay"` sound to the end of the word. For example: @@ -33,7 +33,7 @@ If a word starts with zero or more consonants followed by `"qu"`, first move tho For example: -- `"quick"` -> `"ickqu"` -> `"ay"` (starts with `"qu"`, no preceding consonants) +- `"quick"` -> `"ickqu"` -> `"ickquay"` (starts with `"qu"`, no preceding consonants) - `"square"` -> `"aresqu"` -> `"aresquay"` (starts with one consonant followed by `"qu`") ## Rule 4 diff --git a/exercises/practice/poker/.docs/instructions.md b/exercises/practice/poker/.docs/instructions.md index 492fc4c9e..107cd49d6 100644 --- a/exercises/practice/poker/.docs/instructions.md +++ b/exercises/practice/poker/.docs/instructions.md @@ -2,6 +2,6 @@ Pick the best hand(s) from a list of poker hands. -See [wikipedia][poker-hands] for an overview of poker hands. +See [Wikipedia][poker-hands] for an overview of poker hands. [poker-hands]: https://en.wikipedia.org/wiki/List_of_poker_hands diff --git a/exercises/practice/poker/.meta/config.json b/exercises/practice/poker/.meta/config.json index 33b79fbcd..f1c68db36 100644 --- a/exercises/practice/poker/.meta/config.json +++ b/exercises/practice/poker/.meta/config.json @@ -24,5 +24,5 @@ }, "blurb": "Pick the best hand(s) from a list of poker hands.", "source": "Inspired by the training course from Udacity.", - "source_url": "https://www.udacity.com/course/viewer#!/c-cs212/" + "source_url": "https://www.udacity.com/course/design-of-computer-programs--cs212" } diff --git a/exercises/practice/protein-translation/.docs/instructions.md b/exercises/practice/protein-translation/.docs/instructions.md index d9b9054cf..7dc34d2ed 100644 --- a/exercises/practice/protein-translation/.docs/instructions.md +++ b/exercises/practice/protein-translation/.docs/instructions.md @@ -29,16 +29,16 @@ Note the stop codon `"UAA"` terminates the translation and the final methionine Below are the codons and resulting Amino Acids needed for the exercise. -Codon | Protein -:--- | :--- -AUG | Methionine -UUU, UUC | Phenylalanine -UUA, UUG | Leucine -UCU, UCC, UCA, UCG | Serine -UAU, UAC | Tyrosine -UGU, UGC | Cysteine -UGG | Tryptophan -UAA, UAG, UGA | STOP +| Codon | Protein | +| :----------------- | :------------ | +| AUG | Methionine | +| UUU, UUC | Phenylalanine | +| UUA, UUG | Leucine | +| UCU, UCC, UCA, UCG | Serine | +| UAU, UAC | Tyrosine | +| UGU, UGC | Cysteine | +| UGG | Tryptophan | +| UAA, UAG, UGA | STOP | Learn more about [protein translation on Wikipedia][protein-translation]. diff --git a/exercises/practice/pythagorean-triplet/.meta/config.json b/exercises/practice/pythagorean-triplet/.meta/config.json index 28c7f6cec..12e5ec945 100644 --- a/exercises/practice/pythagorean-triplet/.meta/config.json +++ b/exercises/practice/pythagorean-triplet/.meta/config.json @@ -24,7 +24,7 @@ ".meta/Sources/PythagoreanTriplet/PythagoreanTripletExample.swift" ] }, - "blurb": "There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the product a * b * c.", + "blurb": "There exists exactly one Pythagorean triplet for which a + b + c = 1000. Find the triplet.", "source": "Problem 9 at Project Euler", "source_url": "https://projecteuler.net/problem=9" } diff --git a/exercises/practice/queen-attack/.docs/instructions.md b/exercises/practice/queen-attack/.docs/instructions.md index ad7ea9547..97f22a0ae 100644 --- a/exercises/practice/queen-attack/.docs/instructions.md +++ b/exercises/practice/queen-attack/.docs/instructions.md @@ -8,18 +8,14 @@ A chessboard can be represented by an 8 by 8 array. So if you are told the white queen is at `c5` (zero-indexed at column 2, row 3) and the black queen at `f2` (zero-indexed at column 5, row 6), then you know that the set-up is like so: -```text - a b c d e f g h -8 _ _ _ _ _ _ _ _ 8 -7 _ _ _ _ _ _ _ _ 7 -6 _ _ _ _ _ _ _ _ 6 -5 _ _ W _ _ _ _ _ 5 -4 _ _ _ _ _ _ _ _ 4 -3 _ _ _ _ _ _ _ _ 3 -2 _ _ _ _ _ B _ _ 2 -1 _ _ _ _ _ _ _ _ 1 - a b c d e f g h -``` +![A chess board with two queens. Arrows emanating from the queen at c5 indicate possible directions of capture along file, rank and diagonal.](https://assets.exercism.org/images/exercises/queen-attack/queen-capture.svg) You are also able to answer whether the queens can attack each other. In this case, that answer would be yes, they can, because both pieces share a diagonal. + +## Credit + +The chessboard image was made by [habere-et-dispertire][habere-et-dispertire] using LaTeX and the [chessboard package][chessboard-package] by Ulrike Fischer. + +[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire +[chessboard-package]: https://github.com/u-fischer/chessboard diff --git a/exercises/practice/raindrops/.meta/config.json b/exercises/practice/raindrops/.meta/config.json index 6564b857d..ef430fdff 100644 --- a/exercises/practice/raindrops/.meta/config.json +++ b/exercises/practice/raindrops/.meta/config.json @@ -22,7 +22,7 @@ ".meta/Sources/Raindrops/RaindropsExample.swift" ] }, - "blurb": "Convert a number to a string, the content of which depends on the number's factors.", + "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.", "source": "A variation on FizzBuzz, a famous technical interview question that is intended to weed out potential candidates. That question is itself derived from Fizz Buzz, a popular children's game for teaching division.", "source_url": "https://en.wikipedia.org/wiki/Fizz_buzz" } diff --git a/exercises/practice/rotational-cipher/.docs/instructions.md b/exercises/practice/rotational-cipher/.docs/instructions.md index 4dee51b35..4bf64ca1d 100644 --- a/exercises/practice/rotational-cipher/.docs/instructions.md +++ b/exercises/practice/rotational-cipher/.docs/instructions.md @@ -22,8 +22,8 @@ Ciphertext is written out in the same formatting as the input including spaces a ## Examples -- ROT5 `omg` gives `trl` -- ROT0 `c` gives `c` +- ROT5 `omg` gives `trl` +- ROT0 `c` gives `c` - ROT26 `Cool` gives `Cool` - ROT13 `The quick brown fox jumps over the lazy dog.` gives `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` - ROT13 `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` gives `The quick brown fox jumps over the lazy dog.` diff --git a/exercises/practice/say/.docs/instructions.md b/exercises/practice/say/.docs/instructions.md index fb4a6dfb9..ad3d34778 100644 --- a/exercises/practice/say/.docs/instructions.md +++ b/exercises/practice/say/.docs/instructions.md @@ -30,8 +30,6 @@ Implement breaking a number up into chunks of thousands. So `1234567890` should yield a list like 1, 234, 567, and 890, while the far simpler `1000` should yield just 1 and 0. -The program must also report any values that are out of range. - ## Step 3 Now handle inserting the appropriate scale word between those chunks. diff --git a/exercises/practice/scale-generator/.docs/instructions.md b/exercises/practice/scale-generator/.docs/instructions.md index 23e06e1ab..ebb7debc7 100644 --- a/exercises/practice/scale-generator/.docs/instructions.md +++ b/exercises/practice/scale-generator/.docs/instructions.md @@ -56,13 +56,13 @@ Then, for each interval in the pattern, the next note is determined by starting For example, starting with G and using the seven intervals MMmMMMm, there would be the following eight notes: -Note | Reason ---|-- -G | Tonic -A | M indicates a whole step from G, skipping G♯ -B | M indicates a whole step from A, skipping A♯ -C | m indicates a half step from B, skipping nothing -D | M indicates a whole step from C, skipping C♯ -E | M indicates a whole step from D, skipping D♯ -F♯ | M indicates a whole step from E, skipping F -G | m indicates a half step from F♯, skipping nothing +| Note | Reason | +| ---- | ------------------------------------------------- | +| G | Tonic | +| A | M indicates a whole step from G, skipping G♯ | +| B | M indicates a whole step from A, skipping A♯ | +| C | m indicates a half step from B, skipping nothing | +| D | M indicates a whole step from C, skipping C♯ | +| E | M indicates a whole step from D, skipping D♯ | +| F♯ | M indicates a whole step from E, skipping F | +| G | m indicates a half step from F♯, skipping nothing | diff --git a/exercises/practice/series/.docs/instructions.md b/exercises/practice/series/.docs/instructions.md index e32cc38c6..fd97a6706 100644 --- a/exercises/practice/series/.docs/instructions.md +++ b/exercises/practice/series/.docs/instructions.md @@ -15,5 +15,5 @@ And the following 4-digit series: And if you ask for a 6-digit series from a 5-digit string, you deserve whatever you get. -Note that these series are only required to occupy *adjacent positions* in the input; -the digits need not be *numerically consecutive*. +Note that these series are only required to occupy _adjacent positions_ in the input; +the digits need not be _numerically consecutive_. diff --git a/exercises/practice/simple-cipher/.docs/instructions.md b/exercises/practice/simple-cipher/.docs/instructions.md index 9167a1d33..475af6182 100644 --- a/exercises/practice/simple-cipher/.docs/instructions.md +++ b/exercises/practice/simple-cipher/.docs/instructions.md @@ -9,7 +9,7 @@ If anyone wishes to decipher these, and get at their meaning, he must substitute —Suetonius, Life of Julius Caesar Ciphers are very straight-forward algorithms that allow us to render text less readable while still allowing easy deciphering. -They are vulnerable to many forms of cryptanalysis, but we are lucky that generally our little sisters are not cryptanalysts. +They are vulnerable to many forms of cryptanalysis, but Caesar was lucky that his enemies were not cryptanalysts. The Caesar Cipher was used for some messages from Julius Caesar that were sent afield. Now Caesar knew that the cipher wasn't very good, but he had one ally in that respect: almost nobody could read well. @@ -29,9 +29,9 @@ When "ldpdsdqgdehdu" is put into the decode function it would return the origina ## Step 2 -Shift ciphers are no fun though when your kid sister figures it out. +Shift ciphers quickly cease to be useful when the opposition commander figures them out. +So instead, let's try using a substitution cipher. Try amending the code to allow us to specify a key and use that for the shift distance. -This is called a substitution cipher. Here's an example: diff --git a/exercises/practice/space-age/.docs/instructions.md b/exercises/practice/space-age/.docs/instructions.md index fe938cc09..f23b5e2c1 100644 --- a/exercises/practice/space-age/.docs/instructions.md +++ b/exercises/practice/space-age/.docs/instructions.md @@ -1,25 +1,28 @@ # Instructions -Given an age in seconds, calculate how old someone would be on: +Given an age in seconds, calculate how old someone would be on a planet in our Solar System. -- Mercury: orbital period 0.2408467 Earth years -- Venus: orbital period 0.61519726 Earth years -- Earth: orbital period 1.0 Earth years, 365.25 Earth days, or 31557600 seconds -- Mars: orbital period 1.8808158 Earth years -- Jupiter: orbital period 11.862615 Earth years -- Saturn: orbital period 29.447498 Earth years -- Uranus: orbital period 84.016846 Earth years -- Neptune: orbital period 164.79132 Earth years +One Earth year equals 365.25 Earth days, or 31,557,600 seconds. +If you were told someone was 1,000,000,000 seconds old, their age would be 31.69 Earth-years. -So if you were told someone were 1,000,000,000 seconds old, you should -be able to say that they're 31.69 Earth-years old. +For the other planets, you have to account for their orbital period in Earth Years: -If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video]. +| Planet | Orbital period in Earth Years | +| ------- | ----------------------------- | +| Mercury | 0.2408467 | +| Venus | 0.61519726 | +| Earth | 1.0 | +| Mars | 1.8808158 | +| Jupiter | 11.862615 | +| Saturn | 29.447498 | +| Uranus | 84.016846 | +| Neptune | 164.79132 | -Note: The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year). +~~~~exercism/note +The actual length of one complete orbit of the Earth around the sun is closer to 365.256 days (1 sidereal year). The Gregorian calendar has, on average, 365.2425 days. While not entirely accurate, 365.25 is the value used in this exercise. See [Year on Wikipedia][year] for more ways to measure a year. -[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs [year]: https://en.wikipedia.org/wiki/Year#Summary +~~~~ diff --git a/exercises/practice/space-age/.docs/introduction.md b/exercises/practice/space-age/.docs/introduction.md new file mode 100644 index 000000000..014d78857 --- /dev/null +++ b/exercises/practice/space-age/.docs/introduction.md @@ -0,0 +1,20 @@ +# Introduction + +The year is 2525 and you've just embarked on a journey to visit all planets in the Solar System (Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus and Neptune). +The first stop is Mercury, where customs require you to fill out a form (bureaucracy is apparently _not_ Earth-specific). +As you hand over the form to the customs officer, they scrutinize it and frown. +"Do you _really_ expect me to believe you're just 50 years old? +You must be closer to 200 years old!" + +Amused, you wait for the customs officer to start laughing, but they appear to be dead serious. +You realize that you've entered your age in _Earth years_, but the officer expected it in _Mercury years_! +As Mercury's orbital period around the sun is significantly shorter than Earth, you're actually a lot older in Mercury years. +After some quick calculations, you're able to provide your age in Mercury Years. +The customs officer smiles, satisfied, and waves you through. +You make a mental note to pre-calculate your planet-specific age _before_ future customs checks, to avoid such mix-ups. + +~~~~exercism/note +If you're wondering why Pluto didn't make the cut, go watch [this YouTube video][pluto-video]. + +[pluto-video]: https://www.youtube.com/watch?v=Z_2gbGXzFbs +~~~~ diff --git a/exercises/practice/strain/.meta/config.json b/exercises/practice/strain/.meta/config.json index 970d7e60a..9901115fc 100644 --- a/exercises/practice/strain/.meta/config.json +++ b/exercises/practice/strain/.meta/config.json @@ -23,7 +23,7 @@ ".meta/Sources/Strain/StrainExample.swift" ] }, - "blurb": "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.", + "blurb": "Implement the `keep` and `discard` operation on collections.", "source": "Conversation with James Edward Gray II", - "source_url": "https://twitter.com/jeg2" + "source_url": "http://graysoftinc.com/" } diff --git a/exercises/practice/transpose/.meta/config.json b/exercises/practice/transpose/.meta/config.json index b1ebcc6e7..e8583330a 100644 --- a/exercises/practice/transpose/.meta/config.json +++ b/exercises/practice/transpose/.meta/config.json @@ -23,5 +23,5 @@ }, "blurb": "Take input text and output it transposed.", "source": "Reddit r/dailyprogrammer challenge #270 [Easy].", - "source_url": "https://www.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text" + "source_url": "https://web.archive.org/web/20230630051421/https://old.reddit.com/r/dailyprogrammer/comments/4msu2x/challenge_270_easy_transpose_the_input_text/" } diff --git a/exercises/practice/wordy/.docs/instructions.md b/exercises/practice/wordy/.docs/instructions.md index 0b9e67b6c..aafb9ee54 100644 --- a/exercises/practice/wordy/.docs/instructions.md +++ b/exercises/practice/wordy/.docs/instructions.md @@ -48,7 +48,7 @@ Since these are verbal word problems, evaluate the expression from left-to-right > What is 3 plus 2 multiplied by 3? -15 (i.e. not 9) +15 (i.e. not 9) ## Iteration 4 — Errors diff --git a/generator/Sources/Generator/generator-plugins.swift b/generator/Sources/Generator/generator-plugins.swift index e18be094b..353bd95bd 100644 --- a/generator/Sources/Generator/generator-plugins.swift +++ b/generator/Sources/Generator/generator-plugins.swift @@ -223,6 +223,9 @@ class GeneratorPlugins { } ext.registerFilter("round") { (value: Any?, args: [Any?]) in + if let inputNumber = value as? Int { + return inputNumber + } if let inputNumber = value as? Double { if let precision = args.first as? Int { let divisor = pow(10.0, Double(precision))