A grassy field is in the shape of a circle of radius 100m and is enclosed by a circular fence.

A goat is attached by a rope to a hook at a fixed point on the fence.

To stop the goat getting too fat, the farmer wants to make sure that the goat can only reach half the grass in the field.

How long should the rope be?

Today in our math class, us student teachers were given a puzzle and had to decide what year level it would be appropriate for. After a minute or so of working, it became clear that the solution could only be found numerically. I started by working out the math involved in finding the area and then searched for someone elses solution which I found here. I made that solution in JavaScript which you can play with here.

Circular Field Radius (value > 0):
Fraction of Original Area Wanted (0 < value < 1):
Answer Decimal Precision (1 < value < 20):


The code that runs when “Calculate!” is pressed is below.

function calculateRadius() {

  // Get the input variables 
  var originalRadius = document.forms["goat"]["originalRadius"].value;
  var answerPrecisionDecimals = document.forms["goat"]["precision"].value;
  var howMuchOfOriginalArea = document.forms["goat"]["newAreaPercentage"].value;

  // Check validity
  if (isNaN(originalRadius) || isNaN(answerPrecisionDecimals) || isNaN(howMuchOfOriginalArea)) {
  	document.getElementById("goatResult").innerHTML = "ERROR: input values are not numbers.";
  	return;
  }

  if (originalRadius <= 0) {
  	document.getElementById("goatResult").innerHTML = "ERROR: Circular Field Radius < 0.";
  	return;
  }

  if (howMuchOfOriginalArea <= 0 || howMuchOfOriginalArea >= 1) {
  	document.getElementById("goatResult").innerHTML = "ERROR: Fraction of original area is out of range. If it goes out of bounds, the solution wont be found by the program.";
  	return;
  }

  if (answerPrecisionDecimals >=20 || answerPrecisionDecimals < 1) {
  	document.getElementById("goatResult").innerHTML = "ERROR: Answer precision out of range. Floating point numbers can do strange thing if you ask for too much precision.";
  	return;
  }


  // Calculate areas from the input
  var originalArea = Math.PI * Math.pow(originalRadius, 2);
  var errorAllowed = 1.0/Math.pow(10,answerPrecisionDecimals);
  var newArea = howMuchOfOriginalArea * originalArea;


  // From our starting variables, define the edges of our solution search
  var upperRadius = 2 * originalRadius; 
  var lowerRadius = 0.0;
  var midRadius = lowerRadius + (upperRadius - lowerRadius)/2;
  var prevMidRadius = 0;
  var calculatedArea = 0;
  var iterations = 0;

  // Binary search for solution
	var output = "------------------------------------------------------------------\n" + "Area of the field = " + originalArea.toFixed(answerPrecisionDecimals).toString() + "\nArea that the goat can eat (" + howMuchOfOriginalArea.toString() + " of the field) = " + newArea.toFixed(answerPrecisionDecimals).toString() +"\n" + "------------------------------------------------------------------\n";

	while (Math.abs(midRadius - prevMidRadius) > errorAllowed) {
	  // Assume the midRadius is the right radius and calculate the area
	  calculatedArea = Math.pow(midRadius, 2) * Math.acos(midRadius/(2 * originalRadius)) + Math.pow(originalRadius, 2) * Math.acos((2 * Math.pow(originalRadius, 2) - Math.pow(midRadius, 2))/(2 * Math.pow(originalRadius, 2))) - 0.5 * midRadius * Math.sqrt((4 * Math.pow(originalRadius, 2) - Math.pow(midRadius, 2)));

	  if (calculatedArea > newArea) {
	    // The mid radius is too big, so change the upper bounds
	    upperRadius = midRadius;
	  } else {
	    // The mid radius is too small, so change the lower bounds
	    lowerRadius = midRadius;
	  }

	  // Update our previous mid radius, mid radius, counter and output string
	  prevMidRadius = midRadius;
	  midRadius = lowerRadius + (upperRadius - lowerRadius)/2;
	  iterations++;
	  output += "Step " + iterations.toString() + ": Radius = " + midRadius.toFixed(answerPrecisionDecimals).toString() + ", Area = " + calculatedArea.toFixed(answerPrecisionDecimals).toString() + "\n";
	}

	output += "------------------------------------------------------------------\nThe goat's rope needs to be " + midRadius.toFixed(answerPrecisionDecimals).toString() + " long.";
	// Solution has been found. Lets display it
	document.getElementById("goatResult").innerHTML = output;
}