Background
This problem comes courtesy of the great folks over at Exercism. I highly recommend jumping on their Haskell track to apply your knowledge of Haskell.
The Problem
Write a function that returns the earned points in a single toss of a Darts game. Darts is a game where players throw darts at a target.
In our particular instance of the game, the target rewards 4 different amounts of points, depending on where the dart lands:
- 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).
Write a function that given a point in the target (defined by its Cartesian coordinates x and y, where x and y are real), returns the correct amount earned by a dart landing at that point.
Knowledge You Need to Solve This Problem
- Basic Functions and How to Write Them
- The ‘sqrt’ Arithmetic Operator
- Guards or if-else statements
- Pattern Matching
- Basic understanding of how coordinates (x, x) work
The Solution
To solve this problem in Haskell, we can write a function that takes the x
and y
coordinates of the dart’s landing point, calculates the distance of that point from the origin (0, 0)
, and determines the score based on this distance.
Steps to Implement the Function:
- Calculate the Distance: Use the distance formula
sqrt(x^2 + y^2)
to determine how far the dart landed from the origin. - Score Based on Distance: Compare the distance to the radii of the circles:
- If the distance is greater than 10, the dart lands outside the target (0 points).
- If the distance is within 10 but greater than 5, the dart lands in the outer circle (1 point).
- If the distance is within 5 but greater than 1, the dart lands in the middle circle (5 points).
- If the distance is within 1, the dart lands in the inner circle (10 points).
Haskell Code:
dartScore :: Double -> Double -> Int
dartScore x y
| distance > 10 = 0 -- Outside the target
| distance > 5 = 1 -- Outer circle
| distance > 1 = 5 -- Middle circle
| otherwise = 10 -- Inner circle
where
distance = sqrt (x^2 + y^2)
Explanation:
- Function Name:
dartScore
takes twoDouble
arguments (x
andy
coordinates) and returns anInt
representing the points earned. - Guards:
- If
distance > 10
, it returns0
points. - If
distance > 5
and within 10, it returns1
point. - If
distance > 1
and within 5, it returns5
points. - Otherwise, the distance is within the inner circle, so it returns
10
points.
- If
where
Clause:distance
is calculated assqrt(x^2 + y^2)
to avoid recalculating it multiple times.
Example Usage:
dartScore 0 0 -- Result: 10 (inner circle)
dartScore 2 2 -- Result: 5 (middle circle)
dartScore 8 8 -- Result: 1 (outer circle)
dartScore 11 0 -- Result: 0 (missed target)
dartScore -9 9 -- Result: 0 (missed target)
This function efficiently calculates the points earned based on where the dart lands relative to the target circles.
💡 Helpful References
Exercism - Darts
https://exercism.org/tracks/haskell/exercises/darts/
Leave a Reply