upto(n) = {m = Map(); mapput(m, 1, 0); endOfChain = 1; for(i = 2, n, \\print(maptovec()); c = findsum(i); if(c == -1, setNewEndOfChain(i) , insertAt(c) ) ); known(n) } findsum(n) = { my(key = endOfChain); my(val = mapget(m, key)); while(key != 1, \\ the beginning of the chain is always 0. If beginning is non-constant, you might want to use mapisdefined. if(val + key == n, return(key); ); key = val; val = mapget(m, key); ); return(-1) } insertAt(key) = { my(val = mapget(m, key), s = val + key); mapput(m, key, s); mapput(m, s, val); } setNewEndOfChain(i) = { mapput(m, i, endOfChain); endOfChain = i; } maptovec() = {my(res = List(), c = endOfChain); while(c != 0, listput(res, c); c = mapget(m, c); ); listput(res, 0); Vecrev(Vec(res)) } known(n) = {my(i = 1); v = maptovec(); while(i < #v, if(v[i] + v[i+1] > n, return(vector(i, j, v[j])) ); i++ ); return(v) }