Created
February 23, 2012 00:35
-
-
Save ihercowitz/1888724 to your computer and use it in GitHub Desktop.
The 3n + 1 Problem
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The 3n + 1 Problem | |
*Consider the following algorithm to generate a sequence of numbers. Start with an | |
*integer n. If n is even, divide by 2. If n is odd, multiply by 3 and add 1. Repeat this | |
*process with the new value of n, terminating when n = 1. For example, the following | |
*sequence of numbers will be generated for n = 22: | |
*22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 | |
*It is conjectured (but not yet proven) that this algorithm will terminate at n = 1 for | |
*every integer n. Still, the conjecture holds for all integers up to at least 1, 000, 000. | |
*For an input n, the cycle-length of n is the number of numbers generated up to and | |
*including the 1. In the example above, the cycle length of 22 is 16. Given any two | |
*numbers i and j, you are to determine the maximum cycle length over all numbers | |
*between i and j, including both endpoints. | |
* | |
*Input | |
*The input will consist of a series of pairs of integers i and j, one pair of integers per | |
*line. All integers will be less than 1,000,000 and greater than 0. | |
* | |
*Output | |
*For each pair of input integers i and j, output i, j in the same order in which they | |
*appeared in the input and then the maximum cycle length for integers between and | |
*including i and j. These three numbers should be separated by one space, with all three | |
*numbers on one line and with one line of output for each line of input. | |
* | |
* Sample Input Sample Output | |
* 1 10 1 10 20 | |
* 100 200 100 200 125 | |
* 201 210 201 210 89 | |
* 900 1000 900 1000 174 | |
*/ | |
function solve(number, step) { | |
if (number === 1) return step; | |
var tmp; | |
if (number % 2 === 0) { | |
tmp = number /2; | |
} else { | |
tmp = (number * 3) + 1; | |
} | |
return solve(tmp, ++step); | |
} | |
function maximum_cycle_in(start, end) { | |
var max_cycle = 0; | |
for (var i=start; i <= end; i++) { | |
var tmp = solve(i, 1); | |
if (tmp > max_cycle) | |
max_cycle = tmp; | |
} | |
return max_cycle; | |
} | |
var start = 1 | |
var end = 1000000 | |
print(start+" "+end+" "+maximum_cycle_in(start, end)); |
Not OP, but I'll try my best to help.
/**
* Main solver function.
* This uses recursion to count the number of steps required for solving the following algorithm:
*
* `If n is even, divide by 2. If n is odd, multiply by 3 and add 1.`
*
* @param (number) number The current integer for evaluation
* @param (number) step An increment counter. The '++' prefix in the return function increments the value before assigning it.
*/
function solve(number, step) {
// Return step, which will be at it's highest level if number === 1.
// This also terminates the function.
if (number === 1) return step;
// Temporary variable for holding values of the original number
var tmp;
// First part of the algorithm: `If n is even, divide by 2.`
if (number % 2 === 0) {
tmp = number /2;
// Second part of the algorithm: `If n is odd, multiply by 3 and add 1.`
} else {
tmp = (number * 3) + 1;
}
// Call the function again with the updated number value
// and increment step before doing so.
return solve(tmp, ++step);
}
/**
* Driver function.
* This function runs the solve() function and evaluates each result against a local maximum number.
* The loop domain is from start to end, inclusive.
*
* @param (number) start The smaller number in a two-number set.
* @param (number) end The larger number in a two-number set.
*/
function maximum_cycle_in(start, end) {
// Variable to hold the latest maximum cycle from the solve() function
// if that result is greater than the current maximum value.
var max_cycle = 0;
// Standard looping procedure which includes the start and end variables.
for (var i=start; i <= end; i++) {
// Variable to hold cycle (step) count of each number.
var tmp = solve(i, 1);
// Evaluation of whether the latest cycle (step) count is greater than
// the current maximum count. If so, update the local variable.
if (tmp > max_cycle)
max_cycle = tmp;
}
// Outout the max cycle (step) count once the for-loop concludes
return max_cycle;
}
// Start and end variables
var start = 1
var end = 1000000
print(start+" "+end+" "+maximum_cycle_in(start, end));
// Alt method
// var start = 1
// var end = 1000000
// let og_start = start; // My addition. Stores original start value for output.
// let og_end = end; // My addition. Stores original end value for output.
// hotswap(start, end); // My addition. See below.
// print(og_start+" "+og_end+" "+maximum_cycle_in(start, end));
/**
* Function to set variables in proper order if entered incorrectly.
* Using start and end as parameters will update those values in-place.
*
* @param (number) low Lower valued variable of two variables used in this solution.
* @param (number) high Higher valued variable of two variables used in this solution.
*/
hotswap = function(low, high) {
// If `low` is actually a larger number than `high`
if (low > high) {
// Set `low` to a temporary variable
let tmp_low = low;
// Set `low` to the `high` value.
low = high;
// Set `high` to the `low` value.
high = tmp_low;
}
// Set our `start` and `end` variables to their new values.
// Note: If low is actually the lower value, having the variables
// update here is still okay.
start = low;
end = high;
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice solution!! But, can You please explain me your code?