Darts Problem – Haskell [Problem Solved]

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

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:

  1. Calculate the Distance: Use the distance formula sqrt(x^2 + y^2) to determine how far the dart landed from the origin.
  2. 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 two Double arguments (x and y coordinates) and returns an Int representing the points earned.
  • Guards:
    • If distance > 10, it returns 0 points.
    • If distance > 5 and within 10, it returns 1 point.
    • If distance > 1 and within 5, it returns 5 points.
    • Otherwise, the distance is within the inner circle, so it returns 10 points.
  • where Clause: distance is calculated as sqrt(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.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *