For a sequence of cycle numbers (1,1,2,2,3,3, etc.)

I looked through it and this Hofstadter Female sequence template . Equations

M (n) = nF (M (n-1))

F (n) = nM (F (n-1))

but I'm not sure how to do this in code.

So far, I:

while () {
    _p++
    _r++
    if (_p % 2 === 0) {
        _r = _p - 1;
    }
}

Any help?

+4
source share
4 answers

Without memoization :

function F(n)
{
    return 0 < n ? n - M(F(n-1)) : 1
}

function M(n)
{
    return 0 < n ? n - F(M(n-1)) : 0
}

var N = 10;
var f = [];
var m = [];
for (var i = 0; i <= N; ++i) {
    f.push(F(i));
    m.push(M(i));
}

console.log('F: ' + f.join(','))
console.log('M: ' + m.join(','))

Output:

F: 1,1,2,2,3,3,4,5,5,6,6
M: 0,0,1,2,2,3,4,4,5,6,6

http://jsfiddle.net/KtGBg/1/

+5
source

Recursion should be avoided if possible, so you can cache the already calculated values ​​for F (n) and M (n) :

var f = new Array();
var m = new Array();

function F(n){
    if(f[n] != undefined) {
        return f[n];
    }
    if (n==0) { 
       value = 1;
    } else {
       value = n - M(F(n-1));
    }
    f[n] = value;
    return value;
}

function M(n){
    if(m[n] != undefined) {
        return m[n];
    }
    if (n==0) { 
       value = 0;
    } else {
       value = n - F(M(n-1));
    }
    m[n] = value;
    return value;
}

( 10000)

+3

:

function F(n){
    if (n==0) return 1
    else return n - M(F(n-1))
}

function M(n){
    if (n==0) return 0
    else return n - F(M(n-1))
}

var str = ""
for(var i=0; i<=10; i++) str += F(i) + ", "
console.log(str.substr(0,str.length-2))
+2

Like GaborSch's answer , you can use the Doug Crockford memoizer function, which can be found in Chapter 4 of Javascript: The Good Parts . Using memoization took the time to compute the first 150 members of the male and female Hofstadter sequences up to 256 ms, compared to almost 8 seconds without memoization.

var memoizer = function (memo, formula) {
  var recur = function (n) {
    var result = memo[n];
    if (typeof result !== 'number') {
      result = formula(recur, n);
      memo[n] = result;
    }
    return result;
  };
  return recur;
};

var maleHofstadter = memoizer([0], function (recur, n) {
  return n - femaleHofstadter(recur(n-1));
});

var femaleHofstadter = memoizer([1], function (recur, n) {
  return n - maleHofstadter(recur(n-1));
});

var N = 150;
var f = [];
var m = [];
for (var i = 0; i <= N; ++i) {
  f.push(femaleHofstadter(i));
  m.push(maleHofstadter(i));
}

console.log('F: ' + f.join(','));
console.log('M: ' + m.join(','));
+2
source

Source: https://habr.com/ru/post/1525669/


All Articles