2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,19 +1,27 @@
|
|||
These two sequences of positive integers are defined as:
|
||||
:<math>\begin{align}
|
||||
:::: <big><math>\begin{align}
|
||||
R(1)&=1\ ;\ S(1)=2 \\
|
||||
R(n)&=R(n-1)+S(n-1), \quad n>1.
|
||||
\end{align}</math>
|
||||
:The sequence <math>S(n)</math> is further defined as the sequence of positive integers ''not'' present in <math>R(n)</math>.
|
||||
Sequence R starts: 1, 3, 7, 12, 18, ...<br>
|
||||
Sequence S starts: 2, 4, 5, 6, 8, ...
|
||||
\end{align}</math></big>
|
||||
|
||||
<br>
|
||||
The sequence <big><math>S(n)</math></big> is further defined as the sequence of positive integers '''''not''''' present in <big><math>R(n)</math></big>.
|
||||
|
||||
Sequence <big><math>R</math></big> starts:
|
||||
1, 3, 7, 12, 18, ...
|
||||
Sequence <big><math>S</math></big> starts:
|
||||
2, 4, 5, 6, 8, ...
|
||||
|
||||
|
||||
;Task:
|
||||
# Create two functions named '''ffr''' and '''ffs''' that when given '''n''' return '''R(n)''' or '''S(n)''' respectively.<br>(Note that R(1) = 1 and S(1) = 2 to avoid off-by-one errors).
|
||||
# No maximum value for '''n''' should be assumed.
|
||||
# Calculate and show that the first ten values of '''R''' are:<br> 1, 3, 7, 12, 18, 26, 35, 45, 56, and 69
|
||||
# Calculate and show that the first 40 values of '''ffr''' plus the first 960 values of '''ffs''' include all the integers from 1 to 1000 exactly once.
|
||||
|
||||
Task:
|
||||
# Create two functions named ffr and ffs that when given n return R(n) or S(n) respectively.<br><small>(Note that R(1) = 1 and S(1) = 2 to avoid off-by-one errors).</small>
|
||||
# No maximum value for n should be assumed.
|
||||
# Calculate and show that the first ten values of R are: 1, 3, 7, 12, 18, 26, 35, 45, 56, and 69
|
||||
# Calculate and show that the first 40 values of ffr plus the first 960 values of ffs include all the integers from 1 to 1000 exactly once.
|
||||
|
||||
;References:
|
||||
* Sloane's [http://oeis.org/A005228 A005228] and [http://oeis.org/A030124 A030124].
|
||||
* [http://mathworld.wolfram.com/HofstadterFigure-FigureSequence.html Wolfram Mathworld]
|
||||
* [http://mathworld.wolfram.com/HofstadterFigure-FigureSequence.html Wolfram MathWorld]
|
||||
* Wikipedia: [[wp:Hofstadter_sequence#Hofstadter_Figure-Figure_sequences|Hofstadter Figure-Figure sequences]].
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
unsigned hofstadter(unsigned rlistSize, unsigned slistSize)
|
||||
{
|
||||
auto n = rlistSize > slistSize ? rlistSize : slistSize;
|
||||
auto rlist = new vector<unsigned> { 1, 3, 7 };
|
||||
auto slist = new vector<unsigned> { 2, 4, 5, 6 };
|
||||
auto list = rlistSize > 0 ? rlist : slist;
|
||||
auto target_size = rlistSize > 0 ? rlistSize : slistSize;
|
||||
|
||||
while (list->size() > target_size) list->pop_back();
|
||||
|
||||
while (list->size() < target_size)
|
||||
{
|
||||
auto lastIndex = rlist->size() - 1;
|
||||
auto lastr = (*rlist)[lastIndex];
|
||||
auto r = lastr + (*slist)[lastIndex];
|
||||
rlist->push_back(r);
|
||||
for (auto s = lastr + 1; s < r && list->size() < target_size;)
|
||||
slist->push_back(s++);
|
||||
}
|
||||
|
||||
auto v = (*list)[n - 1];
|
||||
delete rlist;
|
||||
delete slist;
|
||||
return v;
|
||||
}
|
||||
|
||||
ostream& operator<<(ostream& os, const set<unsigned>& s)
|
||||
{
|
||||
cout << '(' << s.size() << "):";
|
||||
auto i = 0;
|
||||
for (auto c = s.begin(); c != s.end();)
|
||||
{
|
||||
if (i++ % 20 == 0) os << endl;
|
||||
os << setw(5) << *c++;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
const auto v1 = atoi(argv[1]);
|
||||
const auto v2 = atoi(argv[2]);
|
||||
set<unsigned> r, s;
|
||||
for (auto n = 1; n <= v2; n++)
|
||||
{
|
||||
if (n <= v1)
|
||||
r.insert(hofstadter(n, 0));
|
||||
s.insert(hofstadter(0, n));
|
||||
}
|
||||
cout << "R" << r << endl;
|
||||
cout << "S" << s << endl;
|
||||
|
||||
int m = max(*r.rbegin(), *s.rbegin());
|
||||
for (auto n = 1; n <= m; n++)
|
||||
if (r.count(n) == s.count(n))
|
||||
clog << "integer " << n << " either in both or neither set" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
% ./hofstadter 40 100 2> /dev/null
|
||||
R(40):
|
||||
1 3 7 12 18 26 35 45 56 69 83 98 114 131 150 170 191 213 236 260
|
||||
285 312 340 369 399 430 462 495 529 565 602 640 679 719 760 802 845 889 935 982
|
||||
S(100):
|
||||
2 4 5 6 8 9 10 11 13 14 15 16 17 19 20 21 22 23 24 25
|
||||
27 28 29 30 31 32 33 34 36 37 38 39 40 41 42 43 44 46 47 48
|
||||
49 50 51 52 53 54 55 57 58 59 60 61 62 63 64 65 66 67 68 70
|
||||
71 72 73 74 75 76 77 78 79 80 81 82 84 85 86 87 88 89 90 91
|
||||
92 93 94 95 96 97 99 100 101 102 103 104 105 106 107 108 109 110 111 112
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
R = [ null, 1 ]
|
||||
S = [ null, 2 ]
|
||||
|
||||
extend_sequences = (n) ->
|
||||
current = Math.max(R[R.length - 1], S[S.length - 1])
|
||||
i = undefined
|
||||
while R.length <= n or S.length <= n
|
||||
i = Math.min(R.length, S.length) - 1
|
||||
current += 1
|
||||
if current == R[i] + S[i]
|
||||
R.push current
|
||||
else
|
||||
S.push current
|
||||
|
||||
ff = (X, n) ->
|
||||
extend_sequences n
|
||||
X[n]
|
||||
|
||||
console.log 'R(' + i + ') = ' + ff(R, i) for i in [1..10]
|
||||
int_array = ([1..40].map (i) -> ff(R, i)).concat [1..960].map (i) -> ff(S, i)
|
||||
int_array.sort (a, b) -> a - b
|
||||
|
||||
for i in [1..1000]
|
||||
if int_array[i - 1] != i
|
||||
throw 'Something\'s wrong!'
|
||||
console.log '1000 integer check ok.'
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
;;; equally doable with a list
|
||||
(flet ((seq (i) (make-array 1 :element-type 'integer
|
||||
:initial-element i
|
||||
:fill-pointer 1
|
||||
:adjustable t)))
|
||||
(let ((rr (seq 1)) (ss (seq 2)))
|
||||
(labels ((extend-r ()
|
||||
(let* ((l (1- (length rr)))
|
||||
(r (+ (aref rr l) (aref ss l)))
|
||||
(s (elt ss (1- (length ss)))))
|
||||
(vector-push-extend r rr)
|
||||
(loop while (<= s r) do
|
||||
(if (/= (incf s) r)
|
||||
(vector-push-extend s ss))))))
|
||||
(defun seq-r (n)
|
||||
(loop while (> n (length rr)) do (extend-r))
|
||||
(elt rr (1- n)))
|
||||
|
||||
(defun seq-s (n)
|
||||
(loop while (> n (length ss)) do (extend-r))
|
||||
(elt ss (1- n))))))
|
||||
|
||||
(defun take (f n)
|
||||
(loop for x from 1 to n collect (funcall f x)))
|
||||
|
||||
(format t "First of R: ~a~%" (take #'seq-r 10))
|
||||
|
||||
(mapl (lambda (l) (if (and (cdr l)
|
||||
(/= (1+ (car l)) (cadr l)))
|
||||
(error "not in sequence")))
|
||||
(sort (append (take #'seq-r 40)
|
||||
(take #'seq-s 960))
|
||||
#'<))
|
||||
(princ "Ok")
|
||||
|
|
@ -1,43 +1,43 @@
|
|||
/*REXX program calculates and verifies the Hofstadter Figure─Figure sequences.*/
|
||||
parse arg x top bot . /*obtain optional arguments from the CL*/
|
||||
if x=='' | x==',' then x= 10 /*Not specified? Then use the default.*/
|
||||
if top=='' | top==',' then top=1000 /* " " " " " " */
|
||||
if bot=='' | bot==',' then bot= 40 /* " " " " " " */
|
||||
low=1; if x<0 then low=abs(x) /*only display a single │X│ value? */
|
||||
r.=0; r.1=1; rr.=r.; rr.1=1; s.=r.; s.1=2 /*initialize the R RR S arrays.*/
|
||||
errs=0; $.=0
|
||||
do i=low to abs(x) /*display the 1st X values of R & S.*/
|
||||
say right('R('i") =", 20) right(ffr(i), 7),
|
||||
right('S('i") =", 20) right(ffs(i), 7)
|
||||
end /*i*/
|
||||
if x<1 then exit
|
||||
do m=1 for bot; r=ffr(m); $.r=1
|
||||
end /*m*/ /* [↑] calculate the 1st 40 R values.*/
|
||||
|
||||
do n=1 for top-bot; s=ffs(n)
|
||||
if $.s then call ser 'duplicate number in R and S lists:' s; $.s=1
|
||||
end /*n*/ /* [↑] calculate the 1st 960 S values.*/
|
||||
|
||||
do v=1 for top
|
||||
if \$.v then call ser 'missing R │ S:' v
|
||||
end /*v*/ /* [↑] are all 1≤ numbers ≤1k present?*/
|
||||
/*REXX program calculates and verifies the Hofstadter Figure─Figure sequences. */
|
||||
parse arg x top bot . /*obtain optional arguments from the CL*/
|
||||
if x=='' | x=="," then x= 10 /*Not specified? Then use the default.*/
|
||||
if top=='' | top=="," then top=1000 /* " " " " " " */
|
||||
if bot=='' | bot=="," then bot= 40 /* " " " " " " */
|
||||
low=1; if x<0 then low=abs(x) /*only display a single │X│ value? */
|
||||
r.=0; r.1=1; rr.=r.; rr.1=1; s.=r.; s.1=2 /*initialize the R, RR, and S arrays.*/
|
||||
errs=0 /*the number of errors found (so far).*/
|
||||
do i=low to abs(x) /*display the 1st X values of R & S.*/
|
||||
say right('R('i") =",20) right(FFR(i),7) right('S('i") =",20) right(FFS(i),7)
|
||||
end /*i*/
|
||||
/* [↑] list the 1st X Fig─Fig numbers.*/
|
||||
if x<1 then exit /*if X isn't positive, then we're done.*/
|
||||
$.=0 /*initialize the memoization ($) array.*/
|
||||
do m=1 for bot; r=FFR(m); $.r=1 /*calculate the first forty R values.*/
|
||||
end /*m*/ /* [↑] ($.) is used for memoization. */
|
||||
/* [↓] check for duplicate #s in R & S*/
|
||||
do n=1 for top-bot; s=FFS(n) /*calculate the value of FFS(n). */
|
||||
if $.s then call ser 'duplicate number in R and S lists:' s; $.s=1
|
||||
end /*n*/ /* [↑] calculate the 1st 960 S values.*/
|
||||
/* [↓] check for missing values in R│S*/
|
||||
do v=1 for top; if \$.v then call ser 'missing R │ S:' v
|
||||
end /*v*/ /* [↑] are all 1≤ numbers ≤1k present?*/
|
||||
say
|
||||
if errs==0 then say 'verification completed for all numbers from 1 ──►' top " [inclusive]."
|
||||
else say 'verification failed with' errs "errors."
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
ffr: procedure expose r. s. rr.; parse arg n /*obtain the number from the arg.*/
|
||||
if r.n\==0 then return r.n /*Defined? Then return the value.*/
|
||||
_=ffr(n-1) + ffs(n-1) /*calculate the FFR & FFS values.*/
|
||||
r.n=_; rr._=1; return _ /*assign value to R & RR; return.*/
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
ffs: procedure expose r. s. rr.; parse arg n /*search for ¬null R or S number.*/
|
||||
if s.n==0 then do k=1 for n /* [↓] 1st IF is a SHORT CIRCUIT*/
|
||||
if s.k\==0 then if r.k\==0 then iterate
|
||||
call ffr k /*define R.k via FFR subroutine*/
|
||||
km=k-1; _=s.km+1 /*the next S number, possibly.*/
|
||||
_=_+rr._; s.k=_ /*define an element of S array.*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
FFR: procedure expose r. rr. s.; parse arg n /*obtain the number from the arguments.*/
|
||||
if r.n\==0 then return r.n /*R.n defined? Then return the value.*/
|
||||
_=FFR(n-1) + FFS(n-1) /*calculate the FFR and FFS values.*/
|
||||
r.n=_; rr._=1; return _ /*assign the value to R & RR; return.*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
FFS: procedure expose r. s. rr.; parse arg n /*search for not null R or S number. */
|
||||
if s.n==0 then do k=1 for n /* [↓] 1st IF is a SHORT CIRCUIT. */
|
||||
if s.k\==0 then if r.k\==0 then iterate /*are both defined?*/
|
||||
call FFR k /*define R.k via the FFR subroutine*/
|
||||
km=k-1; _=s.km+1 /*calc. the next S number, possibly.*/
|
||||
_=_+rr._; s.k=_ /*define an element of the S array. */
|
||||
end /*k*/
|
||||
return s.n /*return S.n value to the invoker*/
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
ser: errs=errs+1; say '***error***!' arg(1); return
|
||||
return s.n /*return S.n value to the invoker. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
ser: errs=errs+1; say '***error***' arg(1); return
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue