Skip to content

Commit 30f8e4c

Browse files
authored
[New Exercise]: Darts (#707)
* Add Darts exercise * Add author * Fix * Sync exercise to problem spec
1 parent 00c0ba8 commit 30f8e4c

File tree

10 files changed

+235
-0
lines changed

10 files changed

+235
-0
lines changed

config.json

+8
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,14 @@
408408
"transforming"
409409
]
410410
},
411+
{
412+
"slug": "darts",
413+
"name": "Darts",
414+
"uuid": "bdbc6f27-bc98-4edf-9f1d-93dbe49da361",
415+
"practices": [],
416+
"prerequisites": [],
417+
"difficulty": 2
418+
},
411419
{
412420
"slug": "bob",
413421
"name": "Bob",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Instructions
2+
3+
Calculate the points scored in a single toss of a Darts game.
4+
5+
[Darts][darts] is a game where players throw darts at a [target][darts-target].
6+
7+
In our particular instance of the game, the target rewards 4 different amounts of points, depending on where the dart lands:
8+
9+
![Our dart scoreboard with values from a complete miss to a bullseye](https://assets.exercism.org/images/exercises/darts/darts-scoreboard.svg)
10+
11+
- If the dart lands outside the target, player earns no points (0 points).
12+
- If the dart lands in the outer circle of the target, player earns 1 point.
13+
- If the dart lands in the middle circle of the target, player earns 5 points.
14+
- If the dart lands in the inner circle of the target, player earns 10 points.
15+
16+
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.
17+
Of course, they are all centered at the same point — that is, the circles are [concentric][] defined by the coordinates (0, 0).
18+
19+
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.
20+
21+
## Credit
22+
23+
The scoreboard image was created by [habere-et-dispertire][habere-et-dispertire] using [Inkscape][inkscape].
24+
25+
[darts]: https://en.wikipedia.org/wiki/Darts
26+
[darts-target]: https://en.wikipedia.org/wiki/Darts#/media/File:Darts_in_a_dartboard.jpg
27+
[concentric]: https://mathworld.wolfram.com/ConcentricCircles.html
28+
[cartesian-coordinates]: https://www.mathsisfun.com/data/cartesian-coordinates.html
29+
[real-numbers]: https://www.mathsisfun.com/numbers/real-numbers.html
30+
[habere-et-dispertire]: https://exercism.org/profiles/habere-et-dispertire
31+
[inkscape]: https://en.wikipedia.org/wiki/Inkscape
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import Foundation
2+
3+
func dartScore(x: Double, y: Double) -> Int {
4+
let distance = sqrt(x * x + y * y)
5+
switch distance {
6+
case 0...1:
7+
return 10
8+
case 1...5:
9+
return 5
10+
case 5...10:
11+
return 1
12+
default:
13+
return 0
14+
}
15+
}
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"authors": [
3+
"meatball133"
4+
],
5+
"files": {
6+
"solution": [
7+
"Sources/Darts/Darts.swift"
8+
],
9+
"test": [
10+
"Tests/DartsTests/DartsTests.swift"
11+
],
12+
"example": [
13+
".meta/Sources/Darts/DartsExample.swift"
14+
]
15+
},
16+
"blurb": "Calculate the points scored in a single toss of a Darts game.",
17+
"source": "Inspired by an exercise created by a professor Della Paolera in Argentina"
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import XCTest
2+
@testable import {{exercise|camelCase}}
3+
class {{exercise|camelCase}}Tests: XCTestCase {
4+
let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false
5+
6+
{% for case in cases %}
7+
{% if forloop.first -%}
8+
func test{{case.description |camelCase }}() {
9+
{% else -%}
10+
func test{{case.description |camelCase }}() throws {
11+
try XCTSkipIf(true && !runAll) // change true to false to run this test
12+
{% endif -%}
13+
XCTAssertEqual(dartScore(x: {{case.input.x | round:1 }}, y: {{case.input.y | round:1}}), {{case.expected}})
14+
}
15+
{% endfor -%}
16+
}
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[9033f731-0a3a-4d9c-b1c0-34a1c8362afb]
13+
description = "Missed target"
14+
15+
[4c9f6ff4-c489-45fd-be8a-1fcb08b4d0ba]
16+
description = "On the outer circle"
17+
18+
[14378687-ee58-4c9b-a323-b089d5274be8]
19+
description = "On the middle circle"
20+
21+
[849e2e63-85bd-4fed-bc3b-781ae962e2c9]
22+
description = "On the inner circle"
23+
24+
[1c5ffd9f-ea66-462f-9f06-a1303de5a226]
25+
description = "Exactly on center"
26+
27+
[b65abce3-a679-4550-8115-4b74bda06088]
28+
description = "Near the center"
29+
30+
[66c29c1d-44f5-40cf-9927-e09a1305b399]
31+
description = "Just within the inner circle"
32+
33+
[d1012f63-c97c-4394-b944-7beb3d0b141a]
34+
description = "Just outside the inner circle"
35+
36+
[ab2b5666-b0b4-49c3-9b27-205e790ed945]
37+
description = "Just within the middle circle"
38+
39+
[70f1424e-d690-4860-8caf-9740a52c0161]
40+
description = "Just outside the middle circle"
41+
42+
[a7dbf8db-419c-4712-8a7f-67602b69b293]
43+
description = "Just within the outer circle"
44+
45+
[e0f39315-9f9a-4546-96e4-a9475b885aa7]
46+
description = "Just outside the outer circle"
47+
48+
[045d7d18-d863-4229-818e-b50828c75d19]
49+
description = "Asymmetric position between the inner and middle circles"
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// swift-tools-version:5.3
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "Darts",
7+
products: [
8+
.library(
9+
name: "Darts",
10+
targets: ["Darts"])
11+
],
12+
dependencies: [],
13+
targets: [
14+
.target(
15+
name: "Darts",
16+
dependencies: []),
17+
.testTarget(
18+
name: "DartsTests",
19+
dependencies: ["Darts"]),
20+
]
21+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
func dartScore(x: Double, y: Double) -> Int {
2+
// Write your code for the 'Darts' exercise here.
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import XCTest
2+
3+
@testable import Darts
4+
5+
class DartsTests: XCTestCase {
6+
let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false
7+
8+
func testMissedTarget() {
9+
XCTAssertEqual(dartScore(x: -9, y: 9), 0)
10+
}
11+
12+
func testOnTheOuterCircle() throws {
13+
try XCTSkipIf(true && !runAll) // change true to false to run this test
14+
XCTAssertEqual(dartScore(x: 0, y: 10), 1)
15+
}
16+
17+
func testOnTheMiddleCircle() throws {
18+
try XCTSkipIf(true && !runAll) // change true to false to run this test
19+
XCTAssertEqual(dartScore(x: -5, y: 0), 5)
20+
}
21+
22+
func testOnTheInnerCircle() throws {
23+
try XCTSkipIf(true && !runAll) // change true to false to run this test
24+
XCTAssertEqual(dartScore(x: 0, y: -1), 10)
25+
}
26+
27+
func testExactlyOnCenter() throws {
28+
try XCTSkipIf(true && !runAll) // change true to false to run this test
29+
XCTAssertEqual(dartScore(x: 0, y: 0), 10)
30+
}
31+
32+
func testNearTheCenter() throws {
33+
try XCTSkipIf(true && !runAll) // change true to false to run this test
34+
XCTAssertEqual(dartScore(x: -0.1, y: -0.1), 10)
35+
}
36+
37+
func testJustWithinTheInnerCircle() throws {
38+
try XCTSkipIf(true && !runAll) // change true to false to run this test
39+
XCTAssertEqual(dartScore(x: 0.7, y: 0.7), 10)
40+
}
41+
42+
func testJustOutsideTheInnerCircle() throws {
43+
try XCTSkipIf(true && !runAll) // change true to false to run this test
44+
XCTAssertEqual(dartScore(x: 0.8, y: -0.8), 5)
45+
}
46+
47+
func testJustWithinTheMiddleCircle() throws {
48+
try XCTSkipIf(true && !runAll) // change true to false to run this test
49+
XCTAssertEqual(dartScore(x: -3.5, y: 3.5), 5)
50+
}
51+
52+
func testJustOutsideTheMiddleCircle() throws {
53+
try XCTSkipIf(true && !runAll) // change true to false to run this test
54+
XCTAssertEqual(dartScore(x: -3.6, y: -3.6), 1)
55+
}
56+
57+
func testJustWithinTheOuterCircle() throws {
58+
try XCTSkipIf(true && !runAll) // change true to false to run this test
59+
XCTAssertEqual(dartScore(x: -7, y: 7), 1)
60+
}
61+
62+
func testJustOutsideTheOuterCircle() throws {
63+
try XCTSkipIf(true && !runAll) // change true to false to run this test
64+
XCTAssertEqual(dartScore(x: 7.1, y: -7.1), 0)
65+
}
66+
67+
func testAsymmetricPositionBetweenTheInnerAndMiddleCircles() throws {
68+
try XCTSkipIf(true && !runAll) // change true to false to run this test
69+
XCTAssertEqual(dartScore(x: 0.5, y: -4), 5)
70+
}
71+
}

generator/Sources/Generator/generator-plugins.swift

+3
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ class GeneratorPlugins {
223223
}
224224

225225
ext.registerFilter("round") { (value: Any?, args: [Any?]) in
226+
if let inputNumber = value as? Int {
227+
return inputNumber
228+
}
226229
if let inputNumber = value as? Double {
227230
if let precision = args.first as? Int {
228231
let divisor = pow(10.0, Double(precision))

0 commit comments

Comments
 (0)