Hofstadter Q sequence: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(98 intermediate revisions by 39 users not shown)
Line 1:
{{task}}The [[wp:Hofstadter_sequence#Hofstadter_Q_sequence|Hofstadter Q sequence]] is defined as:
<big>
:<math>\begin{align}
:: <math>\begin{align}
Q(1)&=Q(2)=1, \\
Q(n)&=Q\big(n-Q(n-1)\big)+Q\big(n-Q(n-2)\big), \quad n>2.
\end{align}</math>
</big>
 
It is defined like the [[Fibonacci sequence]], but whereas the next term in the Fibonacci sequence is the sum of the previous two terms, in the Q sequence the previous two terms tell you how far to go back in the Q sequence to find the two numbers to sum to make the next term of the sequence.
 
 
;Task:
* Confirm and display that the first ten terms of the sequence are: 1, 1, 2, 3, 3, 4, 5, 5, 6, and 6
* Confirm and display that the 1000<sup>th</sup> term is: &nbsp; 502
 
 
;Optional extra credit
* Count and display how many times a member of the sequence is less than its preceding term for terms up to and including the 100,000'<sup>th</sup> term.
* Ensure that the extra credit solution &nbsp; ''safely'' &nbsp; handles being initially asked for an '''n'''<sup>th</sup> term where &nbsp; '''n''' &nbsp; is large.<br> (This point is to ensure that caching and/or recursion limits, if it is a concern, is correctly handled).
<br>(This point is to ensure that caching and/or recursion limits, if it is a concern, is correctly handled).
<br><br>
 
=={{header|11l}}==
{{trans|C}}
 
<syntaxhighlight lang="11l">V qseq = [0] * 100001
qseq[1] = 1
qseq[2] = 1
 
L(i) 3 .< qseq.len
qseq[i] = qseq[i - qseq[i-1]] + qseq[i - qseq[i-2]]
 
print(‘The first 10 terms are: ’qseq[1..10].map(q -> String(q)).join(‘, ’))
print(‘The 1000'th term is ’qseq[1000])
 
V less_than_preceding = 0
L(i) 2 .< qseq.len
I qseq[i] < qseq[i-1]
less_than_preceding++
print(‘Times a member of the sequence is less than its preceding term: ’less_than_preceding)</syntaxhighlight>
 
{{out}}
<pre>
The first 10 terms are: 1, 1, 2, 3, 3, 4, 5, 5, 6, 6
The 1000'th term is 502
Times a member of the sequence is less than its preceding term: 49798
</pre>
 
=={{header|360 Assembly}}==
{{trans|PL/I}}
<langsyntaxhighlight lang="360asm">* Hofstrader q sequence for any n - 18/10/2015
HOFSTRAD CSECT
USING HOFSTRAD,R15 set base register
Line 66 ⟶ 99:
Q DS 1000F array q(1000)
YREGS
END HOFSTRAD</langsyntaxhighlight>
{{out}}
<pre style="height:16ex">
Line 80 ⟶ 113:
n= 10, q= 6
n=1000, q= 502
</pre>
 
=={{header|8080 Assembly}}==
 
<syntaxhighlight lang="8080asm">puts: equ 9 ; CP/M call to print a string
org 100h
;;; Generate the first 1000 members of the Q sequence
lxi b,3 ; Start at 3rd element (1 and 2 already defined)
genq: dcx b ; BC = N-1
call q
mov e,m ; DE = Q(N-1)
inx h
mov d,m
inx b ; BC = (N-1)+1 = N
xchg ; HL = Q(N-1)
call neg ; HL = -Q(N-1)
dad b ; HL = N-Q(N-1)
push b ; Keep N
mov b,h ; BC = N-Q(N-1)
mov c,l
call q ; HL = *Q(N-Q(N-1))
mov e,m ; DE = Q(N-Q(N-1))
inx h
mov d,m
pop b ; Restore N
push d ; push Q(N-Q(N-1))
dcx b ; BC = N-2
dcx b
call q ; DE = Q(N-2)
mov e,m
inx h
mov d,m
inx b ; BC = (N-2)+2 = N
inx b
xchg ; HL = Q(N-2)
call neg ; HL = -Q(N-2)
dad b ; HL = N-Q(N-2)
push b ; Keep N
mov b,h ; BC = N-Q(N-2)
mov c,l
call q ; HL = *Q(N-Q(N-2))
mov a,m ; HL = Q(N-Q(N-2))
inx h
mov h,m
mov l,a
pop b ; Restore N
pop d ; pop Q(N-Q(N-1))
dad d ; HL = Q(N-Q(N-1))+Q(N-Q(N-2))
xchg ; DE = Q(N-Q(N-1))+Q(N-Q(N-2))
call q ; HL = *Q(N)
mov m,e ; Store Q(N)
inx h
mov m,d
inx b ; N = N+1
lxi h,-1001
dad b ; Are we there yet?
jnc genq
;;; Print first 10 terms
lxi d,m10
mvi c,puts
call 5
lxi b,1 ; Start at term 1
mvi d,10 ; 10 terms
p10: push b ; Save counters
push d
call prterm ; Print current term
pop d ; Restore counters
pop b
inx b ; Next term
dcr d ; Repeat 10 times
jnz p10
;;; Print 1000th term
lxi d,m1000
mvi c,puts
call 5
lxi b,1000 ; 1000th term
;;; Print Q(BC)
prterm: call q ; Load term into HL
mov a,m
inx h
mov h,m
mov l,a
lxi b,num ; Push pointer to end of number buffer
push b
lxi b,-10 ; Divisor
dgt: lxi d,-1 ; Quotient
divlp: inx d
dad b
jc divlp
mvi a,'0'+10
add l ; Make ASCII digit
pop h ; Get pointer
dcx h
mov m,a ; Store digit
push h
xchg ; HL = next quotient
mov a,h ; More digits?
ora l
jnz dgt
pop d ; Print string
mvi c,puts
jmp 5
;;; Set HL = -HL
neg: dcx h
mov a,h
cma
mov h,a
mov a,l
cma
mov l,a
ret
;;; Set HL to memory location of Q(BC)
q: push d ; Keep DE
mov h,b ; HL = 2*(BC-1)
mov l,c
dcx h
dad h
lxi d,qq ; Add to start of sequence
dad d
pop d
ret
m10: db 'The first 10 terms are: $'
m1000: db 13,10,'The 1000th term is: $'
db '*****' ; Placeholder for number
num: db ' $'
qq: dw 1,1 ; Q sequence stored here, starting with 1, 1</syntaxhighlight>
 
{{out}}
 
<pre>The first 10 terms are: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502</pre>
 
=={{header|8086 Assembly}}==
 
<syntaxhighlight lang="asm">puts: equ 9 ; MS-DOS syscall to print a string
cpu 8086
org 100h
section .text
;;; Generate first 1000 elements of Q sequence
mov dx,3 ; DX = N
mov di,Q+4 ; DI = place to store elements
mov cx,998 ; Generate 998 more terms
genq: mov si,dx ; SI = N
sub si,[di-2] ; SI -= Q[N-1]
mov bp,dx ; BP = N
sub bp,[di-4] ; BP -= Q[N-2]
dec si ; SI = 2*(SI-1) (0-indexed, 2 bytes/term)
shl si,1
dec bp ; Same for BP
shl bp,1
mov ax,[si+Q] ; Load Q[n-Q[n-1]]
add ax,[bp+Q] ; Add Q[n-Q[n-2]]
stosw ; Store as Q[n]
inc dx ; Increment N
loop genq
;;; Print first 10 elements
mov ah,puts
mov dx,m10
int 21h
mov cx,10
mov bx,1
p10: call prterm
inc bx
loop p10
;;; Print 1000th element
mov ah,puts
mov dx,m1000
int 21h
mov bx,1000
;;; Print the term in BX
prterm: push bx ; Save term
dec bx
shl bx,1
mov ax,[bx+Q] ; Load term into AX
mov bp,10 ; Divisor
mov bx,num ; Number buffer pointer
.dgt: xor dx,dx
div bp ; Divide number by 10
dec bx
add dl,'0' ; DX = remainder, add '0'
mov [bx],dl ; Stored digit
test ax,ax ; Done yet?
jnz .dgt ; If not, find next digit
mov dx,bx ; Print the number
mov ah,puts
int 21h
pop bx ; Restore term
ret
section .data
m10: db 'First 10 terms are: $'
m1000: db 13,10,'1000th term is: $'
db '*****' ; Number placeholder
num: db ' $'
Q: dw 1,1
</syntaxhighlight>
 
{{out}}
 
<pre>First 10 terms are: 1 1 2 3 3 4 5 5 6 6
1000th term is: 502</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">PROC Main()
DEFINE MAX="1000"
INT ARRAY q(MAX+1)
INT i
 
q(1)=1 q(2)=1
FOR i=3 TO MAX
DO
q(i)=q(i-q(i-1))+q(i-q(i-2))
OD
 
FOR i=1 TO 10
DO
PrintF("%I: %I%E",i,q(i))
OD
PrintF("%I: %I%E",MAX,q(MAX))
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Hofstadter_Q_sequence.png Screenshot from Atari 8-bit computer]
<pre>
1: 1
2: 1
3: 2
4: 3
5: 3
6: 4
7: 5
8: 5
9: 6
10: 6
1000: 502
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
 
procedure Hofstadter_Q_Sequence is
Line 141 ⟶ 407:
-- how many times a member of the sequence is less than its preceding term
-- for terms up to and including the 100,000'th term
end Hofstadter_Q_Sequence;</langsyntaxhighlight>
 
{{out}}
Line 154 ⟶ 420:
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
 
'''File: Hofstadter_Q_sequence.a68'''<langsyntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
 
INT n = 100000;
Line 177 ⟶ 443:
 
printf(($"flips: "g(0)l$, flip))
)</langsyntaxhighlight>
{{out}}
<pre>
Line 184 ⟶ 450:
flips: 49798
</pre>
 
=={{header|ALGOL-M}}==
<syntaxhighlight lang="algolm">begin
integer array Q[1:1000];
integer n;
 
Q[1] := Q[2] := 1;
for n := 3 step 1 until 1000 do
Q[n] := Q[n-Q[n-1]] + Q[n-Q[n-2]];
 
write("The first 10 terms are:");
write("");
for n := 1 step 1 until 10 do writeon(Q[n]);
 
write("The 1000th term is:", Q[1000]);
end</syntaxhighlight>
{{out}}
<pre>The first 10 terms are:
1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502</pre>
 
=={{header|ALGOL W}}==
<syntaxhighlight lang="algolw">begin % find elements of the Hofstader Q sequence Q(1) = Q(2) = 1 %
% Q(n) = Q( n - Q( n - 1 ) ) + Q( n - Q( n - 2 ) ) for n > 2 %
integer MAX_Q;
max_Q := 100000;
begin
integer array Q ( 1 :: MAX_Q );
integer array xQ ( 1 :: 10 );
integer ltCount;
logical valuesOk;
% expected values of the first 10 elements %
xQ( 1 ) := xQ( 2 ) := 1;
xQ( 3 ) := 2; xQ( 4 ) := xQ( 5 ) := 3; xQ( 6 ) := 4;
xQ( 7 ) := xQ( 8 ) := 5; xQ( 9 ) := xQ( 10 ) := 6;
% calculate the sequence and count how often Q( n ) < Q( n - 1 ) %
ltCount := 0;
Q( 1 ) := Q( 2 ) := 1;
for n := 3 until MAX_Q do begin
Q( n ) := Q( n - Q( n - 1 ) ) + Q( n - Q( n - 2 ) );
if Q( n ) < Q( n - 1 ) then ltCount := ltCount + 1
end for_n ;
valuesOk := true;
write( "The first 10 terms of the Hofstader Q sequence:" );
for i := 1 until 10 do begin
writeon( i_w := 1, s_w := 0, " ", Q( i ) );
if Q( i ) not = xQ( i ) then begin
writeon( i_w := 1, s_w := 0, "-EXPECTED-", xQ( i ) );
valuesOk := false
end if_Q_i_ne_xQ_i
end for_i ;
write( i_w := 1, s_w := 0, "The 1000th term is: ", Q( 1000 ) );
if Q( 1000 ) not = 502 then begin
writeon( "-EXPECTED-502" );
valuesOk := false
end if_Q_100_ne_502 ;
if valuesOk then write( " (Computed values are as expected)" )
else write( "Values NOT as expected" );
write( i_w := 1, s_w := 0, "Q(n) < Q(n-1) ", ltCount," times for n up to ", MAX_Q )
end
end.</syntaxhighlight>
{{out}}
<pre>
The first 10 terms of the Hofstader Q sequence: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502
(Computed values are as expected)
Q(n) < Q(n-1) 49798 times for n up to 100000
</pre>
 
=={{header|APL}}==
 
<syntaxhighlight lang="apl">∇ Q_sequence;seq;size
size←100000
seq←{⍵,+/⍵[(1+⍴⍵)-¯2↑⍵]}⍣(size-2)⊢1 1
 
⎕←'The first 10 terms are:', seq[⍳10]
⎕←'The 1000th term is:', seq[1000]
⎕←(+/ 2>/seq),'terms were preceded by a larger term.'
∇</syntaxhighlight>
 
{{out}}
 
<pre>
The first 10 terms are: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502
49798 terms were preceded by a larger term.
</pre>
 
=={{header|ARM Assembly}}==
<syntaxhighlight lang="text">.text
.global _start
_start: ldr r6,=qs @ R6 = base register for Q array
@@@ Write first 2 elements
mov r0,#1 @ Q(1) and Q(2) are 1
strh r0,[r6,#4]
strh r0,[r6,#8]
@@@ Generate 100 thousand elements
mov r1,#0x86A0
movt r1,#1 @ 0x186A0 = 100.000
mov r0,#3 @ Starting at element 3
1: sub r2,r0,#1 @ r2 = n-1
ldr r2,[r6,r2,lsl#2] @ r2 = Q[r2]
sub r2,r0,r2 @ r2 = n-Q[r2]
ldr r2,[r6,r2,lsl#2] @ r2 = Q[r2]
sub r3,r0,#2 @ r3 = n-2
ldr r3,[r6,r3,lsl#2] @ r3 = Q[r3]
sub r3,r0,r3 @ r3 = n-Q[r3]
ldr r3,[r6,r3,lsl#2] @ r3 = Q[r3]
add r2,r2,r3 @ r2 += r3
str r2,[r6,r0,lsl#2] @ Q[n] = r2
add r0,r0,#1 @ n++
cmp r0,r1
bls 1b @ If r0<=r1, generate next
@@@ Print first 10 elements
ldr r1,=f10m
bl pstr
mov r8,#1 @ Start at element 1
1: ldr r0,[r6,r8,lsl#2] @ Grab current element
bl pnum @ Print it
ldr r1,=space @ Print a space
bl pstr
add r8,r8,#1
cmp r8,#10 @ Keep going until 10 elements printed
bls 1b
ldr r1,=nl @ Print newline
bl pstr
@@@ Print 1000th element
ldr r1,=f1000m
bl pstr
mov r8,#1000 @ Grab 1000th element
ldr r0,[r6,r8,lsl#2]
bl pnum
ldr r1,=nl @ Print newline
bl pstr
@@@ Find how many times a member is less than its preceding term
mov r0,#0 @ counter
mov r1,#0x86A0 @ max element
movt r1,#1
mov r2,#1 @ value of previous element
mov r3,#2 @ number of current element
2: ldr r4,[r6,r3,lsl#2] @ get value of current element
cmp r2,r4 @ if previous more than current
addhi r0,r0,#1 @ then increment counter
mov r2,r4 @ current el is now prevous el
add r3,r3,#1 @ increment element index
cmp r3,r1 @ are we there yet?
bls 2b @ if not, keep going
bl pnum @ otherwise, print the number
ldr r1,=ltermm @ and the corresponding message
bl pstr
mov r0,#0 @ and then exit
mov r7,#1
swi #0
@@@ Print a length-prefixed string (in r1)
pstr: push {r7,lr} @ Save syscall and link registers
mov r0,#1 @ 1 = stdout
ldrb r2,[r1],#1 @ Get length and advance r1
mov r7,#4 @ Write
swi #0
pop {r7,pc}
@@@ Print unsigned number in r0 using Linux
pnum: push {r7,lr} @ Save syscall and link registers
ldr r7,=qs @ May as well use R7 as buffer pointer
1: mov r1,#10 @ Div-mod by 10
bl divmod
add r1,r1,#'0 @ This makes an ASCII digit
strb r1,[r7,#-1]! @ Store it in the buffer
tst r0,r0 @ Are there more digits?
bne 1b @ If so, calculate them
mov r0,#1 @ 1 = stdout
mov r1,r7 @ Start of number in R1
ldr r2,=qs @ Calculate length
sub r2,r2,r1
mov r7,#4 @ 4 = write
swi #0
pop {r7,pc}
@@@ Division routine: r0=r0/r1, r1=r0%r1
divmod: mov r2,#0 @ R2 = counter
1: cmp r1,r0 @ Double R1 until R1>R0
lslls r1,r1,#1
addls r2,r2,#1
bls 1b
mov r3,#0
2: lsl r3,r3,#1
subs r0,r0,r1 @ Trial subtraction
addhs r3,r3,#1 @ If it worked, mark
addlo r0,r0,r1 @ If it didn't, undo
lsr r1,r1,#1 @ Halve R1
subs r2,r2,#1 @ Decrement counter
bhs 2b @ Keep going until zero
mov r1,r0 @ R1 = modulus
mov r0,r3 @ R0 = quotient
bx lr
.data
space: .ascii "\x1 "
nl: .ascii "\x1\n"
f10m: .ascii "\x18The first 10 terms are: "
f1000m: .ascii "\x14The 1000th term is: "
ltermm: .ascii "' terms were preceded by a larger term.\n"
.bss
.align 4
.space 8 @ Buffer for number output
qs: .space 4 * 100001 @ One word per term</syntaxhighlight>
 
{{out}}
 
<pre>The first 10 terms are: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502
49798 terms were preceded by a larger term.</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">q: new [1 1]
n: 2
while [n<1001][
'q ++ (get q n-q\[n-1]) + get q n-q\[n-2]
n: n+1
]
 
print ["First ten items:" first.n: 10 q]
print ["1000th item:" q\[999]]</syntaxhighlight>
 
{{out}}
 
<pre>First ten items: [1 1 2 3 3 4 5 5 6 6]
1000th item: 502</pre>
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">SetBatchLines, -1
Q := HofsQSeq(100000)
 
Line 205 ⟶ 697:
}
return Q
}</langsyntaxhighlight>
{{out}}
<pre>First ten: 1, 1, 2, 3, 3, 4, 5, 5, 6, 6,
Line 212 ⟶ 704:
 
=={{header|AWK}}==
<langsyntaxhighlight lang="awk">#!/usr/bin/awk -f
BEGIN {
N = 100000
Line 233 ⟶ 725:
}
return seq
} </langsyntaxhighlight>
 
<pre>Q-sequence(1..10) : 1 1 2 3 3 4 5 5 6 6
Line 239 ⟶ 731:
number of Q(n)<Q(n+1) for n<=100000 : 49798</pre>
 
=={{header|BBC BASIC}}==
==={{header|BASIC256}}===
<lang bbcbasic> PRINT "First 10 terms of Q = " ;
{{trans|FreeBASIC}}
<syntaxhighlight lang="basic256">
limite = 100000
dim Q[limite+1]
cont = 0
Q[1] = 1
Q[2] = 1
for i = 3 to limite
Q[i] = Q[i-Q[i-1]] + Q[i-Q[i-2]]
if Q[i] < Q[i-1] then cont += 1
next i
 
print "Primeros 10 términos: ";
for i = 1 to 10
print Q[i] + " ";
next i
 
print "Término número 1000: "; Q[1000]
print "Términos menores que los anteriores: "; cont
</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
 
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> PRINT "First 10 terms of Q = " ;
FOR i% = 1 TO 10 : PRINT ;FNq(i%, c%) " "; : NEXT : PRINT
PRINT "1000th term = " ; FNq(1000, c%)
Line 257 ⟶ 776:
IF q%(i%) < q%(i%-1) THEN c% += 1
NEXT
= q%(n%)</langsyntaxhighlight>
{{out}}
<pre>
Line 265 ⟶ 784:
Term is less than preceding term 49798 times
</pre>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
<syntaxhighlight lang="qbasic">CONST limite = 10000
DIM Q(limite)
Q(1) = 1
Q(2) = 1
 
cont = 0
FOR i = 3 TO limite
Q(i) = Q(i - Q(i - 1)) + Q(i - Q(i - 2))
IF Q(i) < Q(i-1) THEN cont = cont + 1
NEXT i
 
PRINT "First 10 terms: ";
FOR i = 1 TO 10
PRINT Q(i); " ";
NEXT i
 
PRINT
PRINT "Term 1000: "; Q(1000)
PRINT "Terms less than preceding in first 100k: "; cont</syntaxhighlight>
 
==={{header|True BASIC}}===
<syntaxhighlight lang="qbasic">LET limite = 100000
 
DIM q(0)
MAT REDIM q(limite)
LET q(1) = 1
LET q(2) = 1
 
LET count = 0
FOR i = 3 TO limite
LET q(i) = q(i-q(i-1))+q(i-q(i-2))
IF q(i) < q(i-1) THEN
LET count = count + 1
END IF
NEXT i
 
PRINT "First 10 terms: ";
FOR i = 1 TO 10
PRINT q(i);
NEXT i
 
PRINT
PRINT "Term 1000: "; q(1000)
PRINT "Terms less than preceding in first 100k: "; count
END</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|XBasic}}===
{{works with|Windows XBasic}}
<syntaxhighlight lang="qbasic">PROGRAM "Hofstadter Q sequence"
VERSION "0.0000"
 
DECLARE FUNCTION Entry ()
 
FUNCTION Entry ()
limite = 1e5
DIM q[limite]
q[1] = 1
q[2] = 1
count = 0
FOR i = 3 TO limite
q[i] = q[i-q[i-1]] + q[i-q[i-2]]
IF q[i] < q[i-1] THEN
INC count
END IF
NEXT i
PRINT "First 10 terms: ";
FOR i = 1 TO 10
PRINT q[i];
NEXT i
PRINT "\nTerm 1000: "; q[1000]
PRINT "Terms less than preceding in first 100k: "; count
END FUNCTION
END PROGRAM
</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
==={{header|Yabasic}}===
<syntaxhighlight lang="basic">limite = 1e5
dim q(limite)
q(1) = 1
q(2) = 1
 
count = 0
for i = 3 to limite
q(i) = q(i-q(i-1)) + q(i-q(i-2))
if q(i) < q(i-1) count = count + 1
next i
 
print "First 10 terms: ";
 
for i = 1 to 10
print q(i), " ";
next i
 
print "\nTerm 1000: ", q(1000)
print "Terms less than preceding in first 100k: ", count
end</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">( 0:?memocells
& tbl$(memo,!memocells+1) { allocate array }
& ( Q
Line 298 ⟶ 926:
)
& out$!lessThan
);</langsyntaxhighlight>
Output:
<pre>1 1 2 3 3 4 5 5 6 6
502
49798</pre>
 
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
 
let start() be
$( let Q = vec 1000
Q!1 := 1
Q!2 := 1
for n = 3 to 1000 do
Q!n := Q!(n-Q!(n-1)) + Q!(n-Q!(n-2))
writes("The first 10 terms are:")
for n = 1 to 10 do writef(" %N", Q!n)
writef("*NThe 1000th term is: %N*N", Q!1000)
$)</syntaxhighlight>
{{out}}
<pre>The first 10 terms are: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502</pre>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 328 ⟶ 976:
printf("flips: %d\n", flip);
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>1 1 2 3 3 4 5 5 6 6
Line 334 ⟶ 982:
flips: 49798
</pre>
 
=={{header|C++}}==
solution modeled after Perl solution
 
<lang Cpp>#include <iostream>
int main() {
const int size = 100000;
int hofstadters[size] = { 1, 1 };
for (int i = 3 ; i < size; i++)
hofstadters[ i - 1 ] = hofstadters[ i - 1 - hofstadters[ i - 1 - 1 ]] +
hofstadters[ i - 1 - hofstadters[ i - 2 - 1 ]];
std::cout << "The first 10 numbers are: ";
for (int i = 0; i < 10; i++)
std::cout << hofstadters[ i ] << ' ';
std::cout << std::endl << "The 1000'th term is " << hofstadters[ 999 ] << " !" << std::endl;
int less_than_preceding = 0;
for (int i = 0; i < size - 1; i++)
if (hofstadters[ i + 1 ] < hofstadters[ i ])
less_than_preceding++;
std::cout << "In array of size: " << size << ", ";
std::cout << less_than_preceding << " times a number was preceded by a greater number!" << std::endl;
return 0;
}</lang>
{{out}}
<pre>The first 10 numbers are: 1 1 2 3 3 4 5 5 6 6
The 1000'th term is 502 !
In array of size: 100000, 49798 times a number was preceded by a greater number!</pre>
 
=={{header|C sharp}}==
 
<langsyntaxhighlight Clang="c sharp">using System;
using System.Collections.Generic;
 
Line 428 ⟶ 1,048:
}
}
}</langsyntaxhighlight>
 
{{out}}
Line 443 ⟶ 1,063:
Q(1000) = 502
Number of times a member of the sequence was less than its preceding term: 49798.</pre>
 
=={{header|C++}}==
solution modeled after Perl solution
 
<syntaxhighlight lang="cpp">#include <iostream>
int main() {
const int size = 100000;
int hofstadters[size] = { 1, 1 };
for (int i = 3 ; i < size; i++)
hofstadters[ i - 1 ] = hofstadters[ i - 1 - hofstadters[ i - 1 - 1 ]] +
hofstadters[ i - 1 - hofstadters[ i - 2 - 1 ]];
std::cout << "The first 10 numbers are: ";
for (int i = 0; i < 10; i++)
std::cout << hofstadters[ i ] << ' ';
std::cout << std::endl << "The 1000'th term is " << hofstadters[ 999 ] << " !" << std::endl;
int less_than_preceding = 0;
for (int i = 0; i < size - 1; i++)
if (hofstadters[ i + 1 ] < hofstadters[ i ])
less_than_preceding++;
std::cout << "In array of size: " << size << ", ";
std::cout << less_than_preceding << " times a number was preceded by a greater number!" << std::endl;
return 0;
}</syntaxhighlight>
{{out}}
<pre>The first 10 numbers are: 1 1 2 3 3 4 5 5 6 6
The 1000'th term is 502 !
In array of size: 100000, 49798 times a number was preceded by a greater number!</pre>
 
=={{header|Clojure}}==
Line 448 ⟶ 1,096:
The subsequences are vectors for efficient indexing.
''qfirst'' iterates ''qs'' so the nth iteration is Q{1..n].
<langsyntaxhighlight lang="clojure">(defn qs [q]
(let [n (count q)]
(condp = n
Line 460 ⟶ 1,108:
(println "first 10:" (qfirst 10))
(println "1000th:" (last (qfirst 1000)))
(println "extra credit:" (->> (qfirst 100000) (partition 2 1) (filter #(apply > %)) count))</langsyntaxhighlight>
{{out}}
<syntaxhighlight lang="text">first 10: [1 1 2 3 3 4 5 5 6 6]
1000th: 502
extra credit: 49798</langsyntaxhighlight>
 
=={{header|CLU}}==
<syntaxhighlight lang="clu">q_seq = proc (n: int) returns (sequence[int])
q: array[int] := array[int]$[1,1]
for i: int in int$from_to(3,n) do
array[int]$addh(q, q[i-q[i-1]] + q[i-q[i-2]])
end
return(sequence[int]$a2s(q))
end q_seq
 
start_up = proc ()
po: stream := stream$primary_output()
q: sequence[int] := q_seq(100000)
stream$puts(po, "First 10 terms:")
for i: int in int$from_to(1,10) do
stream$puts(po, " " || int$unparse(q[i]))
end
stream$puts(po, "\n1000th term: " || int$unparse(q[1000]))
flips: int := 0
for i: int in int$from_to(2, sequence[int]$size(q)) do
if q[i-1]>q[i] then flips := flips + 1 end
end
stream$putl(po, "\nflips: " || int$unparse(flips))
end start_up</syntaxhighlight>
{{out}}
<pre>First 10 terms: 1 1 2 3 3 4 5 5 6 6
1000th term: 502
flips: 49798</pre>
 
=={{header|CoffeeScript}}==
{{trans|JavaScript}}
<langsyntaxhighlight lang="coffeescript">hofstadterQ = do ->
memo = [ 1 ,1, 1]
Q = (n) ->
Line 478 ⟶ 1,158:
# some results:
console.log 'Q(' + i + ') = ' + hofstadterQ(i) for i in [1..10]
console.log 'Q(1000) = ' + hofstadterQ(1000)</langsyntaxhighlight>
{{out}}
<pre>Q(1) = 1
Line 490 ⟶ 1,170:
Q(9) = 6
Q(10) = 6
Q(1000) = 502</pre>
 
=={{header|COBOL}}==
<syntaxhighlight lang="cobol"> IDENTIFICATION DIVISION.
PROGRAM-ID. Q-SEQ.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 SEQ.
02 Q PIC 9(3) OCCURS 1000 TIMES.
02 Q-TMP1 PIC 9(3).
02 Q-TMP2 PIC 9(3).
02 N PIC 9(4).
01 DISPLAYING.
02 ITEM PIC Z(3).
02 IX PIC Z(4).
PROCEDURE DIVISION.
MAIN-PROGRAM.
PERFORM GENERATE-SEQUENCE.
PERFORM SHOW-ITEM
VARYING N FROM 1 BY 1
UNTIL N IS GREATER THAN 10.
SET N TO 1000.
PERFORM SHOW-ITEM.
STOP RUN.
GENERATE-SEQUENCE.
SET Q(1) TO 1.
SET Q(2) TO 1.
PERFORM GENERATE-ITEM
VARYING N FROM 3 BY 1
UNTIL N IS GREATER THAN 1000.
GENERATE-ITEM.
COMPUTE Q-TMP1 = N - Q(N - 1).
COMPUTE Q-TMP2 = N - Q(N - 2).
COMPUTE Q(N) = Q(Q-TMP1) + Q(Q-TMP2).
SHOW-ITEM.
MOVE N TO IX.
MOVE Q(N) TO ITEM.
DISPLAY 'Q(' IX ') = ' ITEM.</syntaxhighlight>
{{out}}
<pre>Q( 1) = 1
Q( 2) = 1
Q( 3) = 2
Q( 4) = 3
Q( 5) = 3
Q( 6) = 4
Q( 7) = 5
Q( 8) = 5
Q( 9) = 6
Q( 10) = 6
Q(1000) = 502</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defparameter *mm* (make-hash-table :test #'equal))
 
;;; generic memoization macro
Line 519 ⟶ 1,253:
(if (< next-q last-q) (incf c))
(setf last-q next-q))
finally (return c)))</langsyntaxhighlight>
{{out}}
<pre>First of Q: (1 1 2 3 3 4 5 5 6 6)
Line 525 ⟶ 1,259:
Bumps up to 100000: 49798</pre>
 
Although the above definition of <code>q</code> is more general, for this specific problem the following is faster:<langsyntaxhighlight lang="lisp">(let ((cc (make-array 3 :element-type 'integer
:initial-element 1
:adjustable t
Line 536 ⟶ 1,270:
(aref cc (- n (aref cc (- n 2)))))
cc))
(aref cc n)))</langsyntaxhighlight>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
# Generate 1000 terms of the Q sequence
var Q: uint16[1001];
Q[1] := 1;
Q[2] := 1;
 
var n: @indexof Q := 3;
while n <= 1000 loop
Q[n] := Q[n-Q[n-1]] + Q[n-Q[n-2]];
n := n + 1;
end loop;
 
# Print first 10 terms
print("The first 10 terms are: ");
n := 1;
while n <= 10 loop
print_i16(Q[n]);
print_char(' ');
n := n + 1;
end loop;
print_nl();
 
# Print 1000th term
print("The 1000th term is: ");
print_i16(Q[1000]);
print_nl();</syntaxhighlight>
 
{{out}}
<pre>The first 10 terms are: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502</pre>
 
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.functional, std.range;
 
int Q(in int n) nothrow
Line 557 ⟶ 1,325:
writefln("Q(i) is less than Q(i-1) for i [2..100_000] %d times.",
iota(2, 100_001).count!(i => Q(i) < Q(i - 1)));
}
}</lang>
</syntaxhighlight>
{{out}}
<pre>Q(n) for n = [1..10] is: [1, 1, 2, 3, 3, 4, 5, 5, 6, 6]
Q(1000) = 502
Q(i) is less than Q(i-1) for i [2..100_000] 49798 times.</pre>
</pre>
 
===Faster Version===
{{trans|Python}}
Same output.
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.array;
 
uint Q(in int n) nothrow
Line 584 ⟶ 1,354:
writefln("Q(i) is less than Q(i-1) for i [2..100_000] %d times.",
iota(2, 100_001).count!(i => Q(i) < Q(i - 1)));
}
}</lang>
</syntaxhighlight>
 
===Even Faster Version===
This code is here to show that you don't have to use all fancy features of D. Straightforward simple code is often clearer, and faster.
 
<syntaxhighlight lang="d">
<lang d>
import std.stdio;
 
Line 621 ⟶ 1,392:
writefln("Q(i) is less than Q(i-1) for i [2..100_000] %d times.", lt);
}
</syntaxhighlight>
</lang>
 
=={{header|Dart}}==
Naive version using only recursion (Q(1000) fails due to browser script runtime restrictions)
<langsyntaxhighlight lang="dart">int Q(int n) => n>2 ? Q(n-Q(n-1))+Q(n-Q(n-2)) : 1;
 
main() {
Line 632 ⟶ 1,403:
}
print("Q(1000)=${Q(1000)}");
}</langsyntaxhighlight>
 
Version featuring caching.
<langsyntaxhighlight lang="dart">class Q {
Map<int,int> _table;
 
Line 676 ⟶ 1,447:
}
print("value is smaller than previous $count times");
}</langsyntaxhighlight>
{{out}}
<pre>Q(1)=1
Line 692 ⟶ 1,463:
 
If the maximum number is known, filling an array is probably the fastest solution.
<langsyntaxhighlight lang="dart">main() {
List<int> q=new List<int>(100001);
q[1]=q[2]=1;
Line 708 ⟶ 1,479:
print("Q(1000)=${q[1000]}");
print("value is smaller than previous $count times");
}</langsyntaxhighlight>
 
=={{header|Draco}}==
<syntaxhighlight lang="draco">proc nonrec make_Q([*] word q) void:
word n;
q[1] := 1;
q[2] := 1;
for n from 3 upto dim(q,1)-1 do
q[n] := q[n-q[n-1]] + q[n-q[n-2]]
od
corp
 
proc nonrec main() void:
word MAX = 1000;
word i;
[MAX+1] word q;
make_Q(q);
write("The first 10 terms are:");
for i from 1 upto 10 do write(" ", q[i]) od;
writeln();
writeln("The 1000th term is: ", q[1000])
corp</syntaxhighlight>
{{out}}
<pre>The first 10 terms are: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502</pre>
 
=={{header|EasyLang}}==
{{trans|Lua}}
<syntaxhighlight>
proc hofstadter limit . q[] .
q[] = [ 1 1 ]
for n = 3 to limit
q[] &= q[n - q[n - 1]] + q[n - q[n - 2]]
.
.
proc count . q[] cnt .
for i = 2 to len q[]
if q[i] < q[i - 1]
cnt += 1
.
.
.
hofstadter 100000 hofq[]
for i = 1 to 10
write hofq[i] & " "
.
print ""
print hofq[1000]
count hofq[] cnt
print cnt
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
(define RECURSE_BUMP 500) ;; minimum of chrome:500 safari:1000 firefox:2000
 
Line 735 ⟶ 1,557:
(Q 1000) → 502
(flips 100000) → 49798
</syntaxhighlight>
</lang>
 
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
<lang Eiffel>
class
APPLICATION
Line 801 ⟶ 1,622:
end
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 810 ⟶ 1,631:
Number of Flips:
49798
</pre>
 
=={{header|Elixir}}==
{{trans|Erlang}}
changed collection (Erlang array => Map)
<syntaxhighlight lang="elixir">defmodule Hofstadter do
defp flip(v2, v1) when v1 > v2, do: 1
defp flip(_v2, _v1), do: 0
defp list_terms(max, n, acc), do: Enum.map_join(n..max, ", ", &acc[&1])
defp hofstadter(n, n, acc, flips) do
IO.puts "The first ten terms are: #{list_terms(10, 1, acc)}"
IO.puts "The 1000'th term is #{acc[1000]}"
IO.puts "Number of flips: #{flips}"
end
defp hofstadter(max, n, acc, flips) do
qn1 = acc[n-1]
qn = acc[n - qn1] + acc[n - acc[n-2]]
hofstadter(max, n+1, Map.put(acc, n, qn), flips + flip(qn, qn1))
end
def main(max \\ 100_000) do
acc = %{1 => 1, 2 => 1}
hofstadter(max+1, 3, acc, 0)
end
end
 
Hofstadter.main</syntaxhighlight>
 
{{out}}
<pre>
The first ten terms are: 1, 1, 2, 3, 3, 4, 5, 5, 6, 6
The 1000'th term is 502
Number of flips: 49798
</pre>
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">%% @author Jan Willem Luiten <jwl@secondmove.com>
%% Hofstadter Q Sequence for Rosetta Code
 
Line 843 ⟶ 1,699:
Acc = array:set(1, 1, Tmp),
hofstadter(?MAX, 2, Acc, 0).
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 853 ⟶ 1,709:
=={{header|ERRE}}==
{{output|ERRE}}
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM HOFSTADER_Q
 
Line 889 ⟶ 1,745:
PRINT("Number of Q(n)<Q(n+1) for n<=10000 : ";NN)
END PROGRAM
</syntaxhighlight>
</lang>
Note: The extra credit was limited to 10000 because memory addressable range is limited to 64K.
If you want to implement extra credit for 100,000 you must use external file for array Q%[].
 
=={{header|F_Sharp|F#Delphi}}==
{{works with|Delphi|6.0}}
<lang fsharp>let memoize f =
{{libheader|SysUtils,StdCtrls}}
let cache = System.Collections.Generic.Dictionary<_,_>()
fun x ->
match cache.TryGetValue(x) with
| (true, v) -> v
| (_, _) ->
let v = f x
cache.[x] <- v
v
 
let rec q = memoize (fun i ->
if i < 3I then 1I
else q (i - q (i - 1I)) + q (i - q(i - 2I)))
 
<syntaxhighlight lang="Delphi">
printf "q(1 .. 10) ="; List.iter (q >> (printf " %A")) [1I .. 10I]
type TIntArray = array of integer;
printfn ""
 
printfn "q(1000) = %A" (q 1000I)
procedure FillHofstadterArray(var HA: TIntArray);
printfn "descents(100000) = %A" (Seq.sum (Seq.init 100000 (fun i -> if q(bigint(i)) > q(bigint(i+1)) then 1 else 0)))</lang>
{Fill array with Hofstader numbers}
{Preset array size to the number of terms you want}
var I: integer;
begin
{Starting condition}
HA[1]:=1; HA[2]:=1;
{Fill array up to last item}
for I:=3 to High(HA) do HA[I]:=HA[I-HA[I-1]]+HA[I-HA[I-2]];
end;
 
 
procedure ShowHofstadterNumbers(Memo: TMemo);
{Fill array with a }
var I, LessCount: integer;
var QArray: TIntArray;
begin
{Select the number of items we want}
SetLength(QArray,100000);
{Fill array}
FillHofstadterArray(QArray);
{Display first 10}
for I:=1 to 10 do Memo.Lines.Add(Format('%4d: %4d',[I,QArray[I]]));
Memo.Lines.Add(Format('%4d: %4d',[1000,QArray[1000]]));
{Count number the number of times Q(n)<Q(n-1)}
LessCount:=0;
for I:=1 to High(QArray) do
if QArray[I]>QArray[I-1] then Inc(LessCount);
Memo.Lines.Add('Count of Q(n)<Q(n-1) = '+IntToStr(LessCount));
end;
 
</syntaxhighlight>
{{out}}
<pre>
<pre>q(1 .. 10) = 1 1 2 3 3 4 5 5 6 6
1: 1
q(1000) = 502
2: 1
descents(100000) = 49798</pre>
3: 2
4: 3
5: 3
6: 4
7: 5
8: 5
9: 6
10: 6
1000: 502
Count of Q(n)<Q(n-1) = 49997
</pre>
 
 
=={{header|F_Sharp|F#}}==
===The function===
<syntaxhighlight lang="fsharp">
// Populate an array with values of Hofstadter Q sequence. Nigel Galloway: August 26th., 2020
let fQ N=let g=Array.length N in N.[0]<-1; N.[1]<-1;(for g in 2..g-1 do N.[g]<-N.[g-N.[g-1]]+N.[g-N.[g-2]])
</syntaxhighlight>
===The Tasks===
<syntaxhighlight lang="fsharp">
let Q=Array.zeroCreate<int>10 in fQ Q; printfn "%A" Q
let Q=Array.zeroCreate<int>1000 in fQ Q; printfn "%d" (Array.last Q)
</syntaxhighlight>
{{out}}
<pre>
[|1; 1; 2; 3; 3; 4; 5; 5; 6; 6|]
502
</pre>
===Extra Credit===
<syntaxhighlight lang="fsharp">
let Q=Array.zeroCreate<int>100000 in fQ Q; printfn "%d" (Q|>Seq.pairwise|>Seq.sumBy(fun(n,g)->if n>g then 1 else 0))
</syntaxhighlight>
{{out}}
<pre>
49798
</pre>
 
;What is a large number?
<syntaxhighlight lang="fsharp">
let Q=Array.zeroCreate<int>2500000000 in fQ Q; printfn "%d" (Array.last Q)
let Q=Array.zeroCreate<int>5000000000 in fQ Q; printfn "%d" (Array.last Q)
</syntaxhighlight>
{{out}}
<pre>
121648520 (in 0m14.347s)
247777817 (in 0m37.757s)
</pre>
 
=={{header|Factor}}==
We define a method next that takes a sequence of the first n Q values and appends the next one to it. Then we perform it 1000 times on <code>{ 1 1 }</code> and show the first 10 and 999th (because the list is zero-indexed) elements.
<langsyntaxhighlight lang="factor">( scratchpad ) : next ( seq -- newseq )
dup 2 tail* over length [ swap - ] curry map
[ dupd swap nth ] map 0 [ + ] reduce suffix ;
Line 925 ⟶ 1,850:
( scratchpad ) { 1 1 } 1000 [ next ] times dup 10 head . 999 swap nth .
{ 1 1 2 3 3 4 5 5 6 6 }
502</langsyntaxhighlight>
 
=={{header|Fermat}}==
<syntaxhighlight lang="text">Func Hq(n) = if n<2 then 1 else
Array qq[n+1];
qq[1] := 1;
qq[2] := 1;
for i = 3, n do
qq[i]:=qq[i-qq[i-1]]+qq[i-qq[i-2]]
od;
Return(qq[n]);
fi;
.
 
for i=1 to 10 do !Hq(i);!' ' od;
Hq(1000)</syntaxhighlight>
{{out}}<pre>
1 1 2 3 3 4 5 5 6 6
502</pre>
 
=={{header|Forth}}==
{{trans|C}}
<syntaxhighlight lang="forth">100000 constant N
 
: q ( n -- addr ) cells here + ;
 
: qinit
1 0 q !
1 1 q !
N 2 do
i i 1- q @ - q @
i i 2 - q @ - q @
+ i q !
loop ;
 
: flips
." flips: "
0 N 1 do
i q @ i 1- q @ < if 1+ then
loop . cr ;
 
: qprint ( n -- )
0 do i q @ . loop cr ;
 
qinit
10 qprint
999 q @ . cr
flips
bye</syntaxhighlight>
 
{{out}}
<pre>
1 1 2 3 3 4 5 5 6 6
502
flips: 49798
</pre>
 
=={{header|Fortran}}==
The latter-day function COUNT(''logical expression'') could easily be replaced by a simple test-and-count in the DO-loop preparing the array. One hopes that the compiler produces sensible code rather than creating an auxiliary array of boolean results then counting the ''true'' values. Rather more clunky is the need to employ odd structure for the input loop so as to handle possible bad input (text, rather than a valid number, for example) and who knows, end-of-file might happen also.
 
<syntaxhighlight lang="fortran">
<lang Fortran>
Calculate the Hofstadter Q-sequence, using a big array rather than recursion.
INTEGER ENUFF
Line 961 ⟶ 1,941:
999 WRITE (6,*) "Bye."
END
</syntaxhighlight>
</lang>
 
Output:
Line 973 ⟶ 1,953:
Bye.
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
Const limite = 100000
 
Dim As Long Q(limite), i, cont = 0
 
Q(1) = 1
Q(2) = 1
For i = 3 To limite
Q(i) = Q(i-Q(i-1)) + Q(i-Q(i-2))
If Q(i) < Q(i-1) Then cont += 1
Next i
 
Print "Primeros 10 terminos: ";
For i = 1 To 10
Print Q(i) &" ";
Next i
Print
 
Print "Termino numero 1000: "; Q(1000)
 
Print "Terminos menores que los anteriores: " &cont
End
</syntaxhighlight>
{{out}}
<pre>
Primeros 10 terminos: 1 1 2 3 3 4 5 5 6 6
Termino numero 1000: 502
Terminos menores que los anteriores: 49798
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Hofstadter_Q_sequence}}
 
'''Solution'''
 
The following function calculate the given number of terms of the Hofstadter Q sequence:
 
[[File:Fōrmulæ - Hofstadter Q sequence 01.png]]
 
'''Case 1''' First 10 terms
 
[[File:Fōrmulæ - Hofstadter Q sequence 02.png]]
 
[[File:Fōrmulæ - Hofstadter Q sequence 03.png]]
 
'''Case 2''' Confirm and display that the 1000th term is 502
 
[[File:Fōrmulæ - Hofstadter Q sequence 04.png]]
 
[[File:Fōrmulæ - Hofstadter Q sequence 05.png]]
 
'''Case 3''' Count and display how many times a member of the sequence is less than its preceding term for terms up to and including the 100,000th term.
 
[[File:Fōrmulæ - Hofstadter Q sequence 06.png]]
 
[[File:Fōrmulæ - Hofstadter Q sequence 07.png]]
 
=={{header|Go}}==
Sure there are ways that run faster or handle larger numbers; for the task though, maps and recursion work just fine.
<langsyntaxhighlight lang="go">package main
 
import "fmt"
Line 1,021 ⟶ 2,060:
func showQ(n int) {
fmt.Printf("Q(%d) = %d\n", n, q(n))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,038 ⟶ 2,077:
Q(1000000) = 512066
</pre>
 
=={{header|GW-BASIC}}==
<syntaxhighlight lang="gwbasic">10 DIM Q!(1000)
20 Q(1) = 1: Q(2) = 1
30 FOR N = 3 TO 1000
40 Q(N) = Q(N - Q(N - 1)) + Q(N - Q(N - 2))
50 NEXT N
60 FOR N = 1 TO 10
70 PRINT Q(N)
80 NEXT N
90 PRINT Q(1000)</syntaxhighlight>
 
=={{header|Haskell}}==
Line 1,043 ⟶ 2,093:
The basic task:
 
<langsyntaxhighlight Haskelllang="haskell">qSequence = tail qq where
qq = 0 : 1 : 1 : map g [3..]
g n = qq !! (n - qq !! (n-1)) + qq !! (n - qq !! (n-2))
Line 1,050 ⟶ 2,100:
*Main> (take 10 qSequence, qSequence !! (1000-1))
([1,1,2,3,3,4,5,5,6,6],502)
(0.00 secs, 525044 bytes)</langsyntaxhighlight>
 
Extra credit task:
 
<langsyntaxhighlight Haskelllang="haskell">import Data.Array
 
qSequence n = arr
Line 1,074 ⟶ 2,124:
. _S (zipWith (-)) tail . take n . elems $ arr )
 
_S f g x = f x (g x)</langsyntaxhighlight>
 
{{out}}
<langsyntaxhighlight Haskelllang="haskell">Prelude Main> qSeqTest 1000 100000 -- reversals in 100,000
([1,1,2,3,3,4,5,5,6,6],502,49798)
(0.09 secs, 18879708 bytes)
Line 1,083 ⟶ 2,133:
Prelude Main> qSeqTest 1000000 100000 -- 1,000,000-th item
([1,1,2,3,3,4,5,5,6,6],512066,49798)
(2.80 secs, 87559640 bytes)</langsyntaxhighlight>
 
Using a list (more or less) seemlessly backed up by a double resizing array:
<syntaxhighlight lang="haskell">q = qq (listArray (1,2) [1,1]) 1 where
<lang haskell>import Data.Array
qq ar n = (arr!n) : qq arr (n+1) where
 
l = snd (bounds ar)
q = qq (listArray (1,2) [1,1]) 1 where
qq ar step n = (=arr!(n) :- qq(fromIntegral (arr !(n+ - 1)))) where+
arr!(n - (fromIntegral (arr!(n - 2))))
l = snd (bounds ar)
arr :: Array Int Integer
step n =arr!(n - (fromIntegral (arr!(n - 1)))) +
arr | n <= l = ar
arr!(n - (fromIntegral (arr!(n - 2))))
| otherwise = listArray (1, l*2)$
arr :: Array Int Integer
([ar!i | i <- [1..l]] ++
arr | n <= l = ar
[step i | i <- [l+1..l*2]])
| otherwise = listArray (1, l*2)$
([ar!i | i <- [1..l]] ++
[step i | i <- [l+1..l*2]])
 
main = do
putStr("first 10: "); print (take 10 q)
putStr("1000-th: "); print (q !! 999)
putStr("flips: ")
print $ length $ filter id $ take 100000 (zipWith (>) q (tail q))</langsyntaxhighlight>
{{out}}
<pre>
Line 1,112 ⟶ 2,160:
 
List backed up by a list of arrays, with nominal constant lookup time. ''Somehow'' faster than the previous method.
<langsyntaxhighlight lang="haskell">import Data.Array
import Data.Int (Int64)
 
q = qq [listArray (1,2) [1,1]] 1 where
qq a n = seek aa n : qq aa (1 + n) where
aa | n <= l = a
| otherwise = listArray (l+1,l*2) (take l $ drop 2 lst):a
where
l = snd (bounds $ head a)
lst = seek a (l-1):seek a l:(ext lst (l+1))
ext (q1:q2:qs) i = (g (i-q2) + g (i-q1)):ext (q2:qs) (1+i)
g = seek aa
seek (ar:ars) n
| n >= fst (bounds ar) = ar ! n
| otherwise = seek ars n
 
-- Only a perf test. Task can be done exactly the same as above
main = print $ sum qqq
where
where qqq :: [Int64]
qqq :: [Int64]
qqq = map fromIntegral $ take 3000000 q</lang>
qqq = map fromIntegral $ take 3000000 q</syntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
<langsyntaxhighlight Iconlang="icon">link printf
 
procedure main()
Line 1,172 ⟶ 2,221:
runerr(500,n)
}
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 1,190 ⟶ 2,239:
There were 49798 inversions in Q up to 100000</pre>
 
=={{header|IS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "QSequen.bas"
110 LET LIMIT=1000
120 NUMERIC Q(1 TO LIMIT)
130 LET Q(1),Q(2)=1
140 FOR I=3 TO LIMIT
150 LET Q(I)=Q(I-Q(I-1))+Q(I-Q(I-2))
160 NEXT
170 PRINT "First 10 terms:"
180 FOR I=1 TO 10
190 PRINT Q(I);
200 NEXT
210 PRINT :PRINT "Term 1000:";Q(1000)</syntaxhighlight>
 
=={{header|J}}==
'''Solution''' (''bottom-up''):<langsyntaxhighlight lang="j"> Qs=:0 1 1
Q=: verb define
n=. >./,y
Line 1,199 ⟶ 2,261:
end.
y{Qs
)</langsyntaxhighlight>
 
'''Solution''' (''top-down''):<langsyntaxhighlight lang="j"> Q=: 1:`(+&$:/@:- $:@-& 1 2)@.(>&2)"0 M.</langsyntaxhighlight>
 
'''Example''':<langsyntaxhighlight lang="j"> Q 1+i.10
1 1 2 3 3 4 5 5 6 6
Q 1000
502
+/2>/\ Q 1+i.100000
49798</langsyntaxhighlight>
 
'''Note''': The bottom-up solution uses iteration and doesn't risk failure due to recursion limits or cache overflows. The top-down solution uses recursion, and likely hews closer to the spirit of the task. While this latter uses memoization/caching, at some point it will still hit a recursion limit (depends on the environment; in mine, it barfs at N=4402). We use the bottom up version for the extra credit part of this task (the expression which compares adjacent numbers and gave us the result 49798).
Line 1,219 ⟶ 2,281:
[[Category:Memoization]]{{works with|Java|1.5+}}
This example also counts the number of times each n is used as an argument up to 100000 and reports the one that was used the most.
<langsyntaxhighlight lang="java5">import java.util.HashMap;
import java.util.Map;
 
Line 1,264 ⟶ 2,326:
System.out.println("Q(" + maxN + ") was called the most with " + maxUses + " calls");
}
}</langsyntaxhighlight>
{{out}}
<pre>Q(1) = 1
Line 1,281 ⟶ 2,343:
 
=={{header|JavaScript}}==
===ES5===
Based on memoization example from 'JavaScript: The Good Parts'.
<langsyntaxhighlight JavaScriptlang="javascript">var hofstadterQ = function() {
var memo = [1,1,1];
var Q = function (n) {
Line 1,300 ⟶ 2,363:
 
console.log('Q(1000) = ' + hofstadterQ(1000));
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,314 ⟶ 2,377:
Q(10) = 6
Q(1000) = 502</pre>
 
 
===ES6===
Memoising with the accumulator of a fold
<syntaxhighlight lang="javascript">(() => {
'use strict';
 
// hofQSeq :: Int -> [Int]
const hofQSeq = x =>
x > 2 ? tail(foldl((Q, n) =>
n < 3 ? Q : Q.concat(
Q[n - Q[n - 1]] + Q[n - Q[n - 2]]
), [0, 1, 1],
range(1, x))) : (x > 0 ? take(x, [1, 1]) : undefined);
 
 
// GENERIC FUNCTIONS -------------------------------------------
 
// foldl :: (b -> a -> b) -> b -> [a] -> b
const foldl = (f, a, xs) => xs.reduce(f, a),
 
// range :: Int -> Int -> [Int]
range = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i),
 
// tail :: [a] -> [a]
tail = xs => xs.length ? xs.slice(1) : undefined,
 
// last :: [a] -> a
last = xs => xs.length ? xs.slice(-1)[0] : undefined,
 
// Int -> [a] -> [a]
take = (n, xs) => xs.slice(0, n);
 
// TEST --------------------------------------------------------
return {
firstTen: hofQSeq(10),
thousandth: last(hofQSeq(1000)),
'Q<Q-1UpTo10E5': hofQSeq(100000)
.reduce((a, x, i, xs) => x < xs[i - 1] ? a + 1 : a, 0)
};
})();</syntaxhighlight>
 
{{Out}}
<syntaxhighlight lang="javascript">{"firstTen":[1, 1, 2, 3, 3, 4, 5, 5, 6, 6],
"thousandth":502,
"Q<Q-1UpTo10E5":49798}</syntaxhighlight>
 
=={{header|jq}}==
Line 1,321 ⟶ 2,433:
formula also holds for n == 2, and so that we can cache Q(n) at the
n-th position of an array with index origin 0.
<syntaxhighlight lang="jq">
<lang jq>
# For n>=2, Q(n) = Q(n - Q(n-1)) + Q(n - Q(n-2))
def Q:
Line 1,349 ⟶ 2,461:
((range(0;11), 1000) | "Q(\(.)) = \( . | Q)"),
 
(100000 | "flips(\(.)) = \(flips(.))")</langsyntaxhighlight>
===Transcript===
<langsyntaxhighlight lang="bash">
$ uname -a
Darwin Mac-mini 13.3.0 Darwin Kernel Version 13.3.0: Tue Jun 3 21:27:35 PDT 2014; root:xnu-2422.110.17~1/RELEASE_X86_64 x86_64
Line 1,371 ⟶ 2,483:
real 0m0.562s
user 0m0.541s
sys 0m0.011s</langsyntaxhighlight>
 
=={{header|Julia}}==
The following implementation accepts an argument that is a single integer, an array of integers, or a range:
<langsyntaxhighlight lang="julia">function QhofstQseq(n, typerst::Type=Int)
N nmax = maximum(n)
q r = ArrayVector{typerst}(Int, Nnmax)
q r[1], q[2] = 1, 1
if nmax ≥ 2 r[2] = 1 end
for i = 3:N
for i in 3:nmax
q[i] = q[i - q[i-1]] + q[i - q[i-2]]
r[i] = r[i - r[i - 1]] + r[i - r[i - 2]]
end
return q[n] end
return r[n]
end</lang>
end
 
println("First ten elements of sequence: ", join(hofstQseq(1:10), ", "))
println("1000-th element: ", hofstQseq(1000))
</syntaxhighlight>
 
{{out}}
<pre>First ten elements of sequence: 1, 1, 2, 3, 3, 4, 5, 5, 6, 6
<lang julia>julia> Q(1:10)
1000-th element: 502</pre>
10-element Array{Int64,1}:
1
1
2
3
3
4
5
5
6
6
 
julia> Q(1000)
502</lang>
And we can also count the number of times a value is less than its predecessor by, for example:
<syntaxhighlight lang julia>="julia">seq sum(diff(Q= hofstQseq(1:10^5)) .< 0100_000)
cnt = count(diff(seq) .< 0)
49798</lang>
println("$cnt elements are less than the preceding one.")</syntaxhighlight>
 
{{out}}
<pre>49798 elements are less than the preceding one.</pre>
 
Since the implementation is non-recursive, there is no issue with recursion limits.
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.4
 
fun main(args: Array<String>) {
val q = IntArray(100_001)
q[1] = 1
q[2] = 1
for (n in 3..100_000) q[n] = q[n - q[n - 1]] + q[n - q[n - 2]]
print("The first 10 terms are : ")
for (i in 1..10) print("${q[i]} ")
println("\n\nThe 1000th term is : ${q[1000]}")
val flips = (2..100_000).count { q[it] < q[it - 1] }
println("\nThe number of flips for the first 100,000 terms is : $flips")
}</syntaxhighlight>
 
{{out}}
<pre>
The first 10 terms are : 1 1 2 3 3 4 5 5 6 6
 
The 1000th term is : 502
 
The number of flips for the first 100,000 terms is : 49798
</pre>
 
=={{header|Lua}}==
Here, the whole sequence up to the 100,000th term is generated for the first task, so this is where we risk hitting the recursion limit. As it happens, we do not. The function is called using 'pcall' so that any error would be caught. By increasing the argument on line 19 from 1e5 to 1e8, we can cause LuaJIT to run out of memory, but that is not necessary for this task.
<syntaxhighlight lang="lua">function hofstadter (limit)
local Q = {1, 1}
for n = 3, limit do
Q[n] = Q[n - Q[n - 1]] + Q[n - Q[n - 2]]
end
return Q
end
 
function countDescents (t)
local count = 0
for i = 2, #t do
if t[i] < t[i - 1] then
count = count + 1
end
end
return count
end
 
local noError, hofSeq = pcall(hofstadter, 1e5)
if noError == false then
print("The sequence could not be calculated up to the specified limit.")
os.exit()
end
for i = 1, 10 do
io.write(hofSeq[i] .. " ")
end
print("\n" .. hofSeq[1000])
print(countDescents(hofSeq))</syntaxhighlight>
{{out}}
<pre>1 1 2 3 3 4 5 5 6 6
502
49798</pre>
=={{header|MAD}}==
 
<syntaxhighlight lang="mad"> NORMAL MODE IS INTEGER
VECTOR VALUES FMT = $2HQ(,I4,3H) =,I4*$
DIMENSION Q(1000)
Q(1) = 1
Q(2) = 1
THROUGH FILL, FOR N=3, 1, N.G.1000
FILL Q(N) = Q(N-Q(N-1)) + Q(N-Q(N-2))
 
THROUGH SHOW, FOR N=1, 1, N.G.10
SHOW PRINT FORMAT FMT, N, Q(N)
PRINT FORMAT FMT, 1000, Q(1000)
END OF PROGRAM</syntaxhighlight>
 
{{out}}
 
<pre>Q( 1) = 1
Q( 2) = 1
Q( 3) = 2
Q( 4) = 3
Q( 5) = 3
Q( 6) = 4
Q( 7) = 5
Q( 8) = 5
Q( 9) = 6
Q( 10) = 6
Q(1000) = 502</pre>
 
 
 
=={{header|Maple}}==
We use automatic memoisation ("option remember") in the following. The use of "option system" assures that memoised values can be garbage collected.
<langsyntaxhighlight Maplelang="maple">Q := proc( n )
option remember, system;
if n = 1 or n = 2 then
Line 1,415 ⟶ 2,617:
thisproc( n - thisproc( n - 1 ) ) + thisproc( n - thisproc( n - 2 ) )
end if
end proc:</langsyntaxhighlight>
From this we get:
<langsyntaxhighlight Maplelang="maple">> seq( Q( i ), i = 1 .. 10 );
1, 1, 2, 3, 3, 4, 5, 5, 6, 6
 
> Q( 1000 );
502</langsyntaxhighlight>
To determine the number of "flips", we proceed as follows.
<langsyntaxhighlight Maplelang="maple">> flips := 0:
> for i from 2 to 100000 do
> if L[ i ] < L[ i - 1 ] then
Line 1,430 ⟶ 2,632:
> end do:
> flips;
49798</langsyntaxhighlight>
Alternatively, we can build the sequence in an array.
<langsyntaxhighlight Maplelang="maple">Qflips := proc( n )
local a := Array( 1 .. n );
a[ 1 ] := 1;
Line 1,446 ⟶ 2,648:
end do;
flips
end proc:</langsyntaxhighlight>
This gives the same result.
<langsyntaxhighlight Maplelang="maple">> Qflips( 10^5 );
49798</langsyntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">Hofstadter[1] = Hofstadter[2] = 1;
Hofstadter[n_Integer?Positive] := Hofstadter[n] = Block[{$RecursionLimit = Infinity},
Hofstadter[n - Hofstadter[n - 1]] + Hofstadter[n - Hofstadter[n - 2]]
]</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight Mathematicalang="mathematica">Hofstadter /@ Range[10]
{1,1,2,3,3,4,5,5,6,6}
Hofstadter[1000]
502
Count[Differences[Hofstadter /@ Range[100000]], _?Negative]
49798</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
This solution pre-allocates memory and is an iterative solution, so caching or recursion limits do not apply.
<langsyntaxhighlight MATLABlang="matlab">function Q = Qsequence(N)
%% zeros are used to pre-allocate memory, this is not strictly necessary but can significantly improve performance for large N
Q = [1,1,zeros(1,N-2)];
Line 1,472 ⟶ 2,674:
Q(n) = Q(n-Q(n-1))+Q(n-Q(n-2));
end;
end; </langsyntaxhighlight>
Confirm and display that the first ten terms of the sequence are: 1, 1, 2, 3, 3, 4, 5, 5, 6, and 6
<pre>>> Qsequence(10)
Line 1,486 ⟶ 2,688:
ans = 49798
</pre>
 
=={{header|Maxima}}==
<syntaxhighlight lang="maxima">
/* Function that return the terms of the Hofstadter Q sequence */
hofstadter(n):=block(
if member(n,[1,2]) then L[n]:1 else L[n]:L[n-L[n-1]]+L[n-L[n-2]],
L[n])$
 
/* Test cases */
/* First ten terms */
makelist(hofstadter(i),i,1,10);
 
/* 1000th term */
last(makelist(hofstadter(i),i,1,1000));
</syntaxhighlight>
{{out}}
<pre>
[1,1,2,3,3,4,5,5,6,6]
 
502
</pre>
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE QSequence;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
 
VAR n: CARDINAL;
Q: ARRAY [1..1000] OF CARDINAL;
BEGIN
Q[1] := 1;
Q[2] := 1;
FOR n := 3 TO 1000 DO
Q[n] := Q[n-Q[n-1]] + Q[n-Q[n-2]];
END;
WriteString("The first 10 terms are:");
FOR n := 1 TO 10 DO
WriteCard(Q[n],2);
END;
WriteLn();
WriteString("The 1000th term is:");
WriteCard(Q[1000],4);
WriteLn();
END QSequence.</syntaxhighlight>
{{out}}
<pre>The first 10 terms are: 1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502</pre>
 
=={{header|MiniScript}}==
<syntaxhighlight lang="miniscript">cache = {1:1, 2:1}
 
Q = function(n)
if not cache.hasIndex(n) then
q = Q(n - Q(n-1)) + Q(n - Q(n-2))
cache[n] = q
end if
return cache[n]
end function
 
for i in range(1,10)
print "Q(" + i + ") = " + Q(i)
end for
print "Q(1000) = " + Q(1000)</syntaxhighlight>
{{out}}
<pre>Q(1) = 1
Q(2) = 1
Q(3) = 2
Q(4) = 3
Q(5) = 3
Q(6) = 4
Q(7) = 5
Q(8) = 5
Q(9) = 6
Q(10) = 6
Q(1000) = 502</pre>
 
=={{header|Miranda}}==
<syntaxhighlight lang="miranda">main :: [sys_message]
main = [Stdout (lay (map showq ([1..10] ++ [1000])))]
where showq n = "q!" ++ show n ++ " = " ++ show (q!n)
 
q :: [num]
q = 0 : 1 : 1 : map f [3..] where f n = q!(n - q!(n-1)) + q!(n - q!(n-2))</syntaxhighlight>
{{out}}
<pre>q!1 = 1
q!2 = 1
q!3 = 2
q!4 = 3
q!5 = 3
q!6 = 4
q!7 = 5
q!8 = 5
q!9 = 6
q!10 = 6
q!1000 = 502</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">var q = @[1, 1]
for n in 2 .. < 100_000: q.add q[n-q[n-1]] + q[n-q[n-2]]
 
echo q[0..9]
Line 1,498 ⟶ 2,797:
 
var lessCount = 0
for n in 1 .. < 100_000:
if q[n] < q[n-1]:
inc lessCount
echo lessCount</langsyntaxhighlight>
{{out}}
<pre>@[1, 1, 2, 3, 3, 4, 5, 5, 6, 6]
Line 1,509 ⟶ 2,808:
=={{header|Oberon-2}}==
Works with oo2c version 2
<langsyntaxhighlight lang="oberon2">
MODULE Hofstadter;
IMPORT
Line 1,546 ⟶ 2,845:
Out.String("terms less than the previous: ");Out.LongInt(count,4);Out.Ln
END Hofstadter.
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,563 ⟶ 2,862:
</pre>
 
=={{header|OforthOCaml}}==
<syntaxhighlight lang="ocaml">(* valid results for n in 0..119628 *)
let seq_hofstadter_q n =
let a = Bigarray.(Array1.create int16_unsigned c_layout n) in
let () =
for i = 0 to pred n do
a.{i} <- if i < 2 then 1 else a.{i - a.{pred i}} + a.{i - a.{i - 2}}
done
in
Seq.init n (Bigarray.Array1.get a)
 
let () =
<lang Oforth>func: QSeqTask
let count_backflip (a, c) b = b, if b < a then succ c else c
{
and hq = seq_hofstadter_q 100_000 in
let () = Seq.(hq |> take 10 |> iter (Printf.printf " %u")) in
let () = Seq.(hq |> drop 999 |> take 1 |> iter (Printf.printf "\n%u\n")) in
hq |> Seq.fold_left count_backflip (0, 0) |> snd |> Printf.printf "%u\n"</syntaxhighlight>
{{out}}
<pre>
1 1 2 3 3 4 5 5 6 6
502
49798
</pre>
 
=={{header|Oforth}}==
<syntaxhighlight lang="oforth">: QSeqTask
| q i |
ListBuffer newSize(100000) dup add(1) dup add(1) ->q
0 3 100000 for: i [
q add(q at(i q at(i 1 -) -) q at(i q at(i 2 -) -) +)
q at(i) q at(i 1 -) < ifTrue: [ 1 + ]
]
q left(10) println q at(1000) println println ; </syntaxhighlight>
q at(1000) println
println
} </lang>
 
{{out}}
Line 1,587 ⟶ 2,905:
=={{header|PARI/GP}}==
Straightforward, unoptimized version; about 1 ms.
<langsyntaxhighlight lang="parigp">Q=vector(1000);Q[1]=Q[2]=1;for(n=3,#Q,Q[n]=Q[n-Q[n-1]]+Q[n-Q[n-2]]);
Q1=vecextract(Q,"1..10");
print("First 10 terms: "Q1,if(Q1==[1, 1, 2, 3, 3, 4, 5, 5, 6, 6]," (as expected)"," (in error)"));
print("1000-th term: "Q[1000],if(Q[1000]==502," (as expected)"," (in error)"));</langsyntaxhighlight>
 
{{out}}
Line 1,597 ⟶ 2,915:
 
=={{header|Pascal}}==
<langsyntaxhighlight lang="pascal">Program HofstadterQSequence (output);
 
const
Line 1,620 ⟶ 2,938:
inc(flips);
writeln('Flips: ', flips);
end.</langsyntaxhighlight>
{{out}}
<pre>:> ./HofstadterQSequence
Line 1,630 ⟶ 2,948:
=={{header|Perl}}==
 
<langsyntaxhighlight Perllang="perl">my @Q = (0,1,1);
push @Q, $Q[-$Q[-1]] + $Q[-$Q[-2]] for 1..100_000;
say "First 10 terms: [@Q[1..10]]";
say "Term 1000: $Q[1000]";
say "Terms less than preceding in first 100k: ",scalar(grep { $Q[$_] < $Q[$_-1] } 2..100000);</langsyntaxhighlight>
{{out}}
<pre>First 10 terms: [1 1 2 3 3 4 5 5 6 6]
Line 1,641 ⟶ 2,959:
 
A more verbose and less idiomatic solution:
<langsyntaxhighlight Perllang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 1,662 ⟶ 2,980:
print "Up to and including the 100000'th term, $less_than_preceding terms are less " .
"than their preceding terms!\n";
</syntaxhighlight>
</lang>
{{out}}
<pre>1
Line 1,682 ⟶ 3,000:
I could have chosen to do recursion instead of iteration, as perl has no limit on how deeply one may recurse, but did not see the benefit of doing so.
 
<langsyntaxhighlight Perllang="perl">#!perl
use strict;
use warnings;
Line 1,717 ⟶ 3,035:
}
print "Extra credit: $count\n";
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,725 ⟶ 3,043:
</pre>
 
=={{header|Perl 6Phix}}==
Just to be flash, I also (on the desktop only) calculated the 100 millionth term - the only limiting factor here is the length of Q
===OO solution===
(theoretically 402,653,177 on 32 bit).
{{works with|Rakudo/JVM|2013-10-19}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">Q</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">l</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">Q</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">-</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]]+</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">-</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">l</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (or collect one by one)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"First ten terms: %v\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">10</span><span style="color: #0000FF;">]})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"1000th: %d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"100,000th: %,d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">q</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100_000</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100_000</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]<</span><span style="color: #000000;">Q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Flips up to 100,000: %,d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"100,000,000th: %,d (%3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">q</span><span style="color: #0000FF;">(</span><span style="color: #000000;">100_000_000</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
First ten terms: {1,1,2,3,3,4,5,5,6,6}
1000th: 502
100,000th: 48,157
Flips up to 100,000: 49,798
100,000,000th: 50,166,508 (8.52s)
</pre>
The last line shows fine under pwa/p2js, but would take about 20s.
 
=={{header|Picat}}==
Similar concept as the perl5 solution, except that the cache is only filled on demand.
<syntaxhighlight lang="picat">go =>
println([q(I) : I in 1..10]),
println(q1000=q(1000)),
Q = {q(I) : I in 1..100_000},
println(flips=sum({1 : I in 2..100_000, Q[I-1] > Q[I]})),
nl.
 
table
<lang perl6>class Hofstadter {
has @!cq(1) = 1,1;.
q(2) = 1.
method at_pos ($me: Int $i) {
q(N) = q(N-q(N-1)) + q(N-q(N-2)).</syntaxhighlight>
@!c.push($me[@!c.elems-$me[@!c.elems-1]] +
$me[@!c.elems-$me[@!c.elems-2]]) until @!c[$i]:exists;
return @!c[$i];
}
}</lang>
Testing:
<lang perl6>my Hofstadter $Q .= new();
 
say "first ten: $Q[^10]";
say "1000th: $Q[999]";
 
my $count = 0;
$count++ if $Q[$_ +1 ] < $Q[$_] for ^99_999;
say "In the first 100_000 terms, $count terms are less than their preceding terms";</lang>
{{out}}
<pre>first ten: [1 ,1 ,2 ,3 ,3 ,4 ,5 ,5 ,6 ,6]
1000th:q1000 = 502
flips = 49798</pre>
In the first 100_000 terms, 49798 terms are less than their preceding terms</pre>
 
===Idiomatic solution===
{{Works with|rakudo|2015-11-22}}
With a lazily generated array, we automatically get caching.
<lang perl6>my @Q = 1, 1, -> $a, $b {
(state $n = 1)++;
@Q[$n - $a] + @Q[$n - $b]
} ... *;</lang>
Testing:
<lang perl6>say "first ten: ", @Q[^10];
say "1000th: ", @Q[999];
say "In the first 100_000 terms, ",
[+](@Q[1..100000] Z< @Q[0..99999]),
" terms are less than their preceding terms";</lang>
(Same output.)
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de q (N)
(cache '(NIL) N
(if (>= 2 N)
Line 1,775 ⟶ 3,108:
(+
(q (- N (q (dec N))))
(q (- N (q (- N 2)))) ) ) ) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">: (mapcar q (range 1 10))
-> (1 1 2 3 3 4 5 5 6 6)
 
Line 1,785 ⟶ 3,118:
: (let L (mapcar q (range 1 100000))
(cnt < (cdr L) L) )
-> 49798</langsyntaxhighlight>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
/* Hofstrader Q sequence for any "n". */
 
Line 1,809 ⟶ 3,142:
end;
end H;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,841 ⟶ 3,174:
</pre>
Bonus to produce the count of unordered values:
<syntaxhighlight lang="text">
declare tally fixed binary (31) initial (0);
 
Line 1,848 ⟶ 3,181:
end;
put skip data (tally);
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,854 ⟶ 3,187:
TALLY= 49798;
</pre>
 
=={{header|PL/M}}==
<syntaxhighlight lang="plm">100H:
BDOS: PROCEDURE (FN, ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; CALL BDOS(0,0); END EXIT;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9,S); END PRINT;
 
PRINT$NUMBER: PROCEDURE (N);
DECLARE S (7) BYTE INITIAL ('..... $');
DECLARE (N, P) ADDRESS, C BASED P BYTE;
P = .S(5);
DIGIT:
P = P - 1;
C = N MOD 10 + '0';
N = N / 10;
IF N > 0 THEN GO TO DIGIT;
CALL PRINT(P);
END PRINT$NUMBER;
 
DECLARE Q (1001) ADDRESS;
DECLARE N ADDRESS;
 
Q(1)=1;
Q(2)=1;
DO N=3 TO LAST(Q);
Q(N) = Q(N-Q(N-1)) + Q(N-Q(N-2));
END;
 
CALL PRINT(.'THE FIRST 10 TERMS ARE: $');
DO N=1 TO 10;
CALL PRINT$NUMBER(Q(N));
END;
 
CALL PRINT(.(13,10,'THE 1000TH TERM IS: $'));
CALL PRINT$NUMBER(Q(1000));
CALL EXIT;
EOF</syntaxhighlight>
{{out}}
<pre>THE FIRST 10 TERMS ARE: 1 1 2 3 3 4 5 5 6 6
THE 1000TH TERM IS: 502</pre>
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">If Not OpenConsole("Hofstadter Q sequence")
End 1
EndIf
 
#N = 100000
Define i.i, flip.i = 0
Dim q.i(#N)
q(1) = 1
q(2) = 1
For i = 3 To #N
q(i) = q(i - q(i - 1)) + q(i - q(i - 2))
Next
For i = 1 To #N - 1
flip + Bool(q(i) > q(i + 1))
Next
 
Print(~"First ten:\t")
For i = 1 To 10 : Print(LSet(Str(q(i)), 3)) : Next
PrintN(~"\n1000th:\t\t" + Str(q(1000)))
PrintN(~"Flips:\t\t" + Str(flip))
Input()
End</syntaxhighlight>
{{out}}
<pre>First ten: 1 1 2 3 3 4 5 5 6 6
1000th: 502
Flips: 49798</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">def q(n):
if n < 1 or type(n) != int: raise ValueError("n must be an int >= 1")
try:
Line 1,871 ⟶ 3,272:
print("Q(n) for n = [1..10] is:", ', '.join(str(i) for i in first10))
assert q(1000) == 502, "Q(1000) value error"
print("Q(1000) =", q(1000))</langsyntaxhighlight>
 
;Extra credit:
Line 1,879 ⟶ 3,280:
 
The following code is to be concatenated to the code above:
<langsyntaxhighlight lang="python">from sys import getrecursionlimit
 
def q1(n):
Line 1,897 ⟶ 3,298:
tmp = q1(100000)
print("Q(i+1) < Q(i) for i [1..100000] is true %i times." %
sum(k1 < k0 for k0, k1 in zip(q.seq[1:], q.seq[2:])))</langsyntaxhighlight>
 
{{out|Combined output}}
Line 1,905 ⟶ 3,306:
 
===Alternative===
<langsyntaxhighlight lang="python">def q(n):
l = len(q.seq)
while l <= n:
Line 1,917 ⟶ 3,318:
q(100000)
print("Q(i+1) < Q(i) for i [1..100000] is true %i times." %
sum([q.seq[i] > q.seq[i + 1] for i in range(1, 100000)]))</langsyntaxhighlight>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery">[ 2dup swap size dup negate swap within
not if
[ drop size 1+ number$
$ "Term " swap join
$ " of the Q sequence is not defined."
join message put bail ]
peek ] is qpeek ( [ n --> x )
 
[ dup dup -1 qpeek negate qpeek
dip [ dup dup -2 qpeek negate qpeek ]
+ join ] is next-q ( [ --> [ )
 
[ dup size 2 < iff
[ drop 0 ] done
0 swap behead swap
witheach
[ tuck > if [ dip 1+ ] ]
drop ] is drops ( [ --> n )
 
0 backup
[ ' [ 1 1 ]
998 times next-q
dup
-1 split swap 10 split drop
witheach [ echo sp ]
say "... "
0 peek echo cr
99000 times next-q
drops echo
say " decreasing terms" ]
bailed if
[ message take cr echo$ cr ]</syntaxhighlight>
 
{{out}}
 
<pre>1 1 2 3 3 4 5 5 6 6 ... 502
49798 decreasing terms</pre>
 
=={{header|R}}==
<syntaxhighlight lang="rsplus">
cache <- vector("integer", 0)
cache[1] <- 1
cache[2] <- 1
 
Q <- function(n) {
if (is.na(cache[n])) {
value <- Q(n-Q(n-1)) + Q(n-Q(n-2))
cache[n] <<- value
}
cache[n]
}
 
for (i in 1:1e5) {
Q(i)
}
 
for (i in 1:10) {
cat(Q(i)," ",sep = "")
}
cat("\n")
cat(Q(1000),"\n")
 
count <- 0
for (i in 2:1e5) {
if (Q(i) < Q(i-1)) count <- count + 1
}
cat(count,"terms is less than its preceding term\n")
</syntaxhighlight>
{{out}}
<pre>
1 1 2 3 3 4 5 5 6 6
502
49798 terms is less than its preceding term
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 1,937 ⟶ 3,415:
;; extra credit
(for/sum ([i 100000]) (if (< (Q (add1 i)) (Q i)) 1 0))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,945 ⟶ 3,423:
49798
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
===OO solution===
{{Works with|rakudo|2016.03}}
 
Similar concept as the perl5 solution, except that the cache is only filled on demand.
 
<syntaxhighlight lang="raku" line>class Hofstadter {
has @!c = 1,1;
method AT-POS ($me: Int $i) {
@!c.push($me[@!c.elems-$me[@!c.elems-1]] +
$me[@!c.elems-$me[@!c.elems-2]]) until @!c[$i]:exists;
return @!c[$i];
}
}
 
# Testing:
 
my Hofstadter $Q .= new();
 
say "first ten: $Q[^10]";
say "1000th: $Q[999]";
 
my $count = 0;
$count++ if $Q[$_ +1 ] < $Q[$_] for ^99_999;
say "In the first 100_000 terms, $count terms are less than their preceding terms";</syntaxhighlight>
{{out}}
<pre>first ten: 1 1 2 3 3 4 5 5 6 6
1000th: 502
In the first 100_000 terms, 49798 terms are less than their preceding terms</pre>
 
===Idiomatic solution===
{{Works with|rakudo|2015-11-22}}
With a lazily generated array, we automatically get caching.
<syntaxhighlight lang="raku" line>my @Q = 1, 1, -> $a, $b {
(state $n = 1)++;
@Q[$n - $a] + @Q[$n - $b]
} ... *;
 
# Testing:
 
say "first ten: ", @Q[^10];
say "1000th: ", @Q[999];
say "In the first 100_000 terms, ",
[+](@Q[1..100000] Z< @Q[0..99999]),
" terms are less than their preceding terms";</syntaxhighlight>
(Same output.)
 
=={{header|REXX}}==
===non-recursive===
The REXX language doesn't allow expressions for stemmed array indices, so a temporary variable must be used.
<langsyntaxhighlight lang="rexx">/*REXX program generates the Hofstadter Q sequence for any specified N. */
parse arg a b c d . /*getobtain optional valuesarguments from the CL*/
if \datatype(a,=='W') | a=="," then a= 10 /*A notNot specified? Then use Usethe default.*/
if \datatype(b,=='W') | b=="," then b= -1000 /*B " " " " " " */
if \datatype(c,=='W') | c=="," then c= -100000 /*C " " " " " " */
if \datatype(d,=='W') | d=="," then d= -1000000 /*D " " " " " " */
q@.= 1; ac= abs(c) /* [↑] negnegative #'s don't show values.*/
call HofstadterQ a; say
call HofstadterQ b; say; 'HofstadterQ say' commas(abs(b))th(b) " 'valueterm is:' " commas(result; say)
call HofstadterQ c; say
downs= 0; do j=2 for ac-1; jm= j - 1
downs= downs + (q@.j<q@.jm)
end /*j*/
 
say commas(downs) ' HofstatdterQ terms are less then the previous term,' ac||th(ac) 'term is:' q.ac,
call HofstadterQ d; ' ad=absHofstatdterQ(d'commas(ac); || th(ac)") term is: " saycommas(@.ac)
call HofstadterQ d; ad= abs(d); say
say 'The' ad || th(ad) 'term is' q.ad
say 'The ' commas(ad) || th(ad) ' HofstatdterQ term is: ' commas(@.ad)
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────HofstadterQ subroutine──────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
HofstadterQ: procedure expose q.; parse arg x 1 ox /*get # to gen thru.*/
HofstadterQ: procedure expose @.; parse arg x 1 ox /*get number to generate through.*/
/* [↑] OX is the same as X.*/
x=abs(x) /*use the[↑] absolute value forOX is the same as X. */
wx=length abs(x); w= length( commas(x) ) /*use forabsolute rightvalue; justifiedget outputlength.*/
do j=1 for x /* [↓] use short-circuitshort─circuit IF test*/
if j>2 then if q@.j==1 then do; jm1= j - 1; jm2= j - 2
_1one= j -q @.jm1; _2 two= j -q @.jm2
q @.j=q @._1one +q @._2two
end
if ox>0 then say 'HofstadterQ('right(j, w)"): " right(q@.j,max(w,length(@.j))) /*show if OX>0*/
end /*j*/
return q@.x /*return the │X│th term to caller*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────TH subroutine───────────────────────────────────────────────*/
commas: parse arg _; do ?=length(_)-3 to 1 by -3; _=insert(',', _, ?); end; return _
th: procedure; parse arg x; x=abs(x); return word('th st nd rd',1+x//10*(x//100%10\==1)*(x//10<4))</lang>
th: procedure; #=abs(arg(1)); return word('th st nd rd',1+#//10*(#//100%10\==1)*(#//10<4))</syntaxhighlight>
{{out}}
{{out|output|text=&nbsp; when using the internal default inputs:}}
<pre>
HofstadterQ( 1): 1
1 1
HofstadterQ( 2): 1
2 1
HofstadterQ( 3): 2
3 2
HofstadterQ( 4): 3
4 3
HofstadterQ( 5): 3
5 3
HofstadterQ( 6): 4
6 4
HofstadterQ( 7): 5
7 5
HofstadterQ( 8): 5
8 5
HofstadterQ( 9): 6
9 6
HofstadterQ(10): 6
 
1000thHofstadterQ value 1,000th term is: 502
 
4979849,798 HofstatdterQ terms are less then the previous term, 100000th HofstatdterQ(100,000th) term is: 48157 48,157
 
The 1000000th 1,000,000th HofstatdterQ term is: 512066512,066
</pre>
 
Line 2,005 ⟶ 3,532:
This REXX example is identical to the first version
except that it uses a function to retrieve array elements which may have index expressions.
<langsyntaxhighlight lang="rexx">/*REXX program generates the Hofstadter Q sequence for any specified N. */
parse arg a b c d . /*getobtain optional valuesarguments from the CL*/
if \datatype(a,=='W') | a=="," then a= 10 /*A notNot specified? Then use Usethe default.*/
if \datatype(b,=='W') | b=="," then b= -1000 /*B " " " " " " */
if \datatype(c,=='W') | c=="," then c= -100000 /*C " " " " " " */
if \datatype(d,=='W') | d=="," then d= -1000000 /*D " " " " " " */
q@.= 1; ac= abs(c) /* [↑] negnegative #'s don't show values.*/
call HofstadterQ a; say
call HofstadterQ b; say; 'HofstadterQ say' commas(abs(b))th(b) " 'valueterm is:' " commas(result; say)
call HofstadterQ c; say
downs= 0; do j=2 for ac-1; downs jm=downs+(q.j<q( j - 1))
end /* downs= downs + (@.j*/<@.jm)
end /*j*/
 
say commas(downs) ' HofstatdterQ terms are less then the previous term,' ac||th(ac) 'term is:' q.ac,
call HofstadterQ d; ' ad=absHofstatdterQ(d'commas(ac); || th(ac)") term is: " saycommas(@.ac)
call HofstadterQ d; ad= abs(d); say
say 'The' ad || th(ad) 'term is' q.ad
say 'The ' commas(ad) || th(ad) ' HofstatdterQ term is: ' commas(@.ad)
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────HofstadterQ subroutine──────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
HofstadterQ: procedure expose q.; parse arg x 1 ox /*get # to gen thru.*/
HofstadterQ: procedure expose @.; parse arg x 1 ox /*get number to generate through.*/
/* [↑] OX is the same as X.*/
x=abs(x) /*use the[↑] absolute value forOX is the same as X. */
wx=length abs(x); w= length( commas(x) ) /*use forabsolute rightvalue; justifiedget outputlength.*/
do j=1 for x
if j>2 then if q@.j==1 then q@.j=q @(j -q @(j-1)) + q @(j -q @(j-2))
if ox>0 then say 'HofstadterQ('right(j, w)"): " right(q@.j,max(w) /*if X>0, tell*/length(@.j)))
end /*j*/
return q@.x /*return the │X│th term to caller*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────Q subroutine────────────────────────*/
q@: parse arg ?; return q@.? /*return value of Q@.? to invoker.*/
th: procedure; #=abs(arg(1)); return word('th st nd rd',1+#//10*(#//100%10\==1)*(#//10<4))
/*──────────────────────────────────TH subroutine───────────────────────────────────────────────*/
commas: parse arg _; do ?=length(_)-3 to 1 by -3; _=insert(',', _, ?); end; return _</syntaxhighlight>
th: procedure; parse arg x; x=abs(x); return word('th st nd rd',1+x//10*(x//100%10\==1)*(x//10<4))</lang>
'''{{out|output'''|text=&nbsp; is identical to the first1<sup>st</sup> REXX version.}}
 
Because of the additional subroutine (function) invokes, this REXX version is about half as fast as the 1<sup>st</sup> REXX version.
 
===recursive===
<langsyntaxhighlight lang="rexx">/*REXX pgmprogram generates the Hofstadter Q sequence (using recursion) sequence for any specified N. */
parse arg a b c d . /*getobtain optional valuesarguments from the CL*/
if \datatype(a,=='W') | a=="," then a= 10 /*A notNot specified? Then use Usethe default.*/
if \datatype(b,=='W') | b=="," then b= -1000 /*B " " " " " " */
if \datatype(c,=='W') | c=="," then c= -100000 /*C " " " " " " */
if \datatype(d,=='W') | d=="," then d= -1000000 /*D " " " " " " */
q@.= 0; q @.1= 1; q @.2= 1; ac= abs(c) /* [↑] negnegative #'s don't show values.*/
call HofstadterQ a; say
call HofstadterQ b; say; 'HofstadterQ say' commas(abs(b))th(b) " 'valueterm is:' " commas(result; say)
call HofstadterQ c; say
downs= 0; do j=2 for ac-1; jm= j - 1
downs= downs + (q@.j<q@.jm)
end /*j*/
 
say commas(downs) ' HofstatdterQ terms are less then the previous term,' ac||th(ac) 'term is:' q.ac,
call HofstadterQ d; ' ad=absHofstatdterQ(d'commas(ac); || th(ac)") term is: " saycommas(@.ac)
call HofstadterQ d; ad= abs(d); say
say 'The' ad || th(ad) 'term is' q.ad
say 'The ' commas(ad) || th(ad) ' HofstatdterQ term is: ' commas(@.ad)
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────HofstadterQ subroutine──────────────*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
HofstadterQ: procedure expose q.; parse arg x 1 ox /*get # to gen thru.*/
HofstadterQ: procedure expose @.; parse arg x 1 ox /*get number to generate through.*/
/* [↑] OX is the same as X.*/
x=abs(x) /*use the[↑] absolute value forOX is the same as X. */
wx=length abs(x); w= length( commas(x) ) /*use forabsolute rightvalue; justifiedget outputlength.*/
do j=1 for x
if q@.j==0 then q@.j= QR(j) /*Not defined? Then define it.*/
if ox>0 then say 'HofstadterQ('right(j, w)"): " right(q@.j,max(w,length(@.j))) /*show if OX>0*/
end /*j*/
return q@.x /*return the Xth│X│th term to caller.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────QR subroutine───────────────────────*/
QR: procedure expose q@.; parse arg n /*this QR function is recursive. */
if q@.n==0 then q@.n= QR(n-QR(n-1)) + QR(n-QR(n-2)) /*¬Not defined? Define Then define it.*/
return q@.n /*return with the value. to the invoker*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────TH subroutine───────────────────────────────────────────────*/
th: procedure; parse arg x; x#=abs(xarg(1)); return word('th st nd rd',1+x#//10*(x#//100%10\==1)*(x#//10<4))</lang>
commas: parse arg _; do ?=length(_)-3 to 1 by -3; _=insert(',', _, ?); end; return _</syntaxhighlight>
'''output''' is identical to the first version. <br><br>
The recursive version{{out|output|text=&nbsp; is almostidentical ten times slower thanto the (1<sup>st</sup>) non-recursiveREXX version.<br>}}
 
The recursive version is almost ten times slower than the (1<sup>st</sup>) non-recursive version.<br><br>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
n = 20
aList = list(n)
aList[1] = 1
aList[2] = 1
for i = 1 to n
if i >= 3 aList[i] = ( aList[i - aList[i-1]] + aList[i - aList[i-2]] ) ok
if i <= 20 see "n = " + string(i) + " : "+ aList[i] + nl ok
next
</syntaxhighlight>
 
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
{ 1 1 } 3
WHILE '''DUP''' 4 PICK ≤ '''REPEAT'''
DUP2 2 - GETI ROT ROT GET → n q2 q1
≪ DUP n q1 - GET
OVER n q2 - GET + +
n 1 + SWAP
'''END''' DROP
≫ ''''HOFST'''' STO
|
'''HOFST''' ''( m -- { Q(1)..Q(m) } ) ''
initialize stack with Q1, Q2 and loop index n
loop
store n, Q(n-2) and Q(n-1)
get Q(n-Q(n-1))
add Q(n-Q(n-2)) and add result to list
put back n+1 in stack
|}
{{in}}
<pre>
10 HOFST
1000 HOSFT DUP SIZE GET
</pre>
{{out}}
<pre>
2: { 1 1 2 3 3 4 5 5 6 6 }
1: 502
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">@cache = []
def Q(n)
if @cache[n].nil?
Line 2,100 ⟶ 3,682:
prev = q
end
puts "number of times in the first 100,000 terms where Q(i)<Q(i-1): #{count}"</langsyntaxhighlight>
{{out}}
<pre>first 10 numbers in the sequence: [1, 1, 2, 3, 3, 4, 5, 5, 6, 6]
Line 2,107 ⟶ 3,689:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight Runbasiclang="runbasic">input "How many values do you want? :";n
dim Q(n)
Q(1) = 1
Line 2,117 ⟶ 3,699:
if i > 20 then print "n=";using("####",i);using("####",Q(i))
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,148 ⟶ 3,730:
Rust doesn't allow static Vec's (but there's lazy_static crate), thus memoization storage is allocated in <code>main</code>.
 
<langsyntaxhighlight lang="rust">fn hofq(q: &mut Vec<u32>, x : u32) -> u32 {
let cur_len=q.len()-1;
let i=x as usize;
Line 2,174 ⟶ 3,756:
println!("Term is less than preceding term {} times", nless);
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,196 ⟶ 3,778:
Naive but elegant version using only recursion doesn't work
because runtime is excessive increasing ...
<langsyntaxhighlight lang="scala">object HofstadterQseq extends App {
val Q: Int => Int = n => {
if (n <= 2) 1
Line 2,203 ⟶ 3,785:
(1 to 10).map(i=>(i,Q(i))).foreach(t=>println("Q("+t._1+") = "+t._2))
println("Q("+1000+") = "+Q(1000))
}</langsyntaxhighlight>
 
 
Line 2,210 ⟶ 3,792:
Thus we are forced to use a caching featured version.
 
<langsyntaxhighlight lang="scala">object HofstadterQseq extends App {
 
val HofQ = scala.collection.mutable.Map((1->1),(2->1))
Line 2,228 ⟶ 3,810:
println("Q("+1000+") = "+Q(1000))
println((3 to 100000).filter(i=>Q(i)<Q(i-1)).size)
}</langsyntaxhighlight>
{{out}}
<pre>Q(1) = 1
Line 2,247 ⟶ 3,829:
or to resize arrays, or to do formated output--anything to make the code
less silly looking while still run under more than one interpreter.
<langsyntaxhighlight lang="lisp">(define qc '#(0 1 1))
(define filled 3)
(define len 3)
Line 2,293 ⟶ 3,875:
(if (>= i 100000) s
(loop (+ s (if (> (q i) (q (+ 1 i))) 1 0)) (+ 1 i)))))
(newline)</langsyntaxhighlight>
{{out}}
<pre>Q(1 .. 10): 1 1 2 3 3 4 5 5 6 6
Line 2,300 ⟶ 3,882:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const type: intHash is hash [integer] integer;
Line 2,337 ⟶ 3,919:
end for;
writeln("q(n) < q(n-1) for n = 2 .. 100000: " <& less_than_preceding);
end func;</langsyntaxhighlight>
 
{{out}}
Line 2,346 ⟶ 3,928:
q(n) < q(n-1) for n = 2 .. 100000: 49798
</pre>
 
=={{header|SETL}}==
<syntaxhighlight lang="setl">program hofstadter_q;
q := [1,1];
loop for n in [3..100000] do
q(n) := q(n-q(n-1)) + q(n-q(n-2));
end loop;
 
print("First 10 terms: " + q(1..10));
print("1000th term: " + q(1000));
print("q(x) < q(x-1): " + #[x : x in [2..#q] | q(x) < q(x-1)]);
end program;</syntaxhighlight>
{{out}}
<pre>First 10 terms: [1 1 2 3 3 4 5 5 6 6]
1000th term: 502
q(x) < q(x-1): 49798</pre>
 
=={{header|Sidef}}==
Using a memoized function:
<langsyntaxhighlight lang="ruby">func Q(n) is cached {
n <= 2  ? 1
 : Q(n - Q(n-1))+Q(n-Q(n-2))
}
 
 
say "First 10 terms: #{10.of {|n| Q(n) }.dumpmap(1..10) }"
say "Term 1000: #{Q(1000)}"
say "Terms less than preceding in first 100k: #{2..100000->count{|i|Q(i)<Q(i-1)}}"</langsyntaxhighlight>
 
Using an array:
<langsyntaxhighlight lang="ruby">var Q = [0, 1, 1];
100_000.times {
Q << (Q[-Q[-1]] + Q[-Q[-2]])
}
 
say "First 10 terms: #{Q.ftslice(1, 10).dumpfirst(10)}"
say "Term 1000: #{Q[1000]}"
say "Terms less than preceding in first 100k: #{2..100000->count{|i|Q[i]<Q[i-1]}}"</langsyntaxhighlight>
 
{{out}}
<pre>
Line 2,373 ⟶ 3,970:
Term 1000: 502
Terms less than preceding in first 100k: 49798
</pre>
 
=={{header|Swift}}==
{{trans|C}}
<syntaxhighlight lang="swift">let n = 100000
 
var q = Array(repeating: 0, count: n)
q[0] = 1
q[1] = 1
 
for i in 2..<n {
q[i] = q[i - q[i - 1]] + q[i - q[i - 2]]
}
 
print("First 10 elements of the sequence: \(q[0..<10])")
print("1000th element of the sequence: \(q[999])")
 
var count = 0
for i in 1..<n {
if q[i] < q[i - 1] {
count += 1
}
}
print("Number of times a member of the sequence is less than the preceding term for terms up to and including the 100,000th term: \(count)")</syntaxhighlight>
 
{{out}}
<pre>
First 10 elements of the sequence: [1, 1, 2, 3, 3, 4, 5, 5, 6, 6]
1000th element of the sequence: 502
Number of times a member of the sequence is less than the preceding term for terms up to and including the 100,000th term: 49798
</pre>
 
=={{header|Tailspin}}==
<syntaxhighlight lang="tailspin">
templates q
def outputFrom: $(1);
def until: $(2);
@: [1,1];
1..$until -> #
when <$@::length~..> do
..|@: $@($ - $@($ - 1)) + $@($ - $@($ - 2));
$ -> #
when <$outputFrom..> do
$@($) !
end q
 
[1,10] -> q -> '$; ' -> !OUT::write
'
' -> !OUT::write
 
[1000,1000] -> q -> '$;
' -> !OUT::write
 
templates countDownSteps
@: 0;
def qs: $;
2..$qs::length -> #
$@ !
when <?($qs($) <..~$qs($-1)>)> do @: $@ + 1;
end countDownSteps
 
[[1, 100000] -> q] -> countDownSteps -> 'Less than previous $; times' -> !OUT::write
</syntaxhighlight>
{{out}}
<pre>
1 1 2 3 3 4 5 5 6 6
502
Less than previous 49798 times
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
# Index 0 is not used, but putting it in makes the code a bit shorter
Line 2,399 ⟶ 4,064:
incr count [expr {$q > [set q [expr {Q($i)}]]}]
}
puts "Q(i)<Q(i-1) for i \[2..100000\] is true $count times"</langsyntaxhighlight>
{{out}}
<pre>
Line 2,415 ⟶ 4,080:
Q(i)<Q(i-1) for i [2..100000] is true 49798 times
</pre>
 
=={{header|uBasic/4tH}}==
{{trans|BBC BASIC}}
uBasic/4tH simply lacks the memory to make it through to the 1000th term. 256 is the best it can do.
<syntaxhighlight lang="text">Print "First 10 terms of Q = " ;
For i = 1 To 10 : Print FUNC(_q(i));" "; : Next : Print
Print "256th term = ";FUNC(_q(256))
 
End
 
_q Param(1)
Local(2)
 
If a@ < 3 Then Return (1)
If a@ = 3 Then Return (2)
 
@(0) = 1 : @(1) = 1 : @(2) = 2
c@ = 0
 
For b@ = 3 To a@-1
@(b@) = @(b@ - @(b@-1)) + @(b@ - @(b@-2))
If @(b@) < @(b@-1) Then c@ = c@ + 1
Next
 
Return (@(a@-1))</syntaxhighlight>
{{out}}
<pre>First 10 terms of Q = 1 1 2 3 3 4 5 5 6 6
256th term = 123
 
0 OK, 0:320</pre>
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">Public Q(100000) As Long
Public Sub HofstadterQ()
Dim n As Long, smaller As Long
Q(1) = 1
Q(2) = 1
For n = 3 To 100000
Q(n) = Q(n - Q(n - 1)) + Q(n - Q(n - 2))
If Q(n) < Q(n - 1) Then smaller = smaller + 1
Next n
Debug.Print "First ten terms:"
For i = 1 To 10
Debug.Print Q(i);
Next i
Debug.print
Debug.Print "The 1000th term is:"; Q(1000)
Debug.Print "Number of times smaller:"; smaller
End Sub</syntaxhighlight>{{out}}
<pre>First ten terms:
1 1 2 3 3 4 5 5 6 6
The 1000th term is: 502
Number of times smaller: 49798 </pre>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
<lang vb>
Sub q_sequence(n)
Dim Q()
Line 2,445 ⟶ 4,163:
 
q_sequence(100000)
</syntaxhighlight>
</lang>
 
{{Out}}
Line 2,453 ⟶ 4,171:
Number of times the member of the sequence is less than its preceding term: 49798
</pre>
 
=={{header|uBasic/4tH}}==
{{trans|BBC BASIC}}
uBasic/4tH simply lacks the memory to make it through to the 1000th term. 256 is the best it can do.
<lang>Print "First 10 terms of Q = " ;
For i = 1 To 10 : Print FUNC(_q(i));" "; : Next : Print
Print "256th term = ";FUNC(_q(256))
 
End
 
_q Param(1)
Local(2)
 
If a@ < 3 Then Return (1)
If a@ = 3 Then Return (2)
 
@(0) = 1 : @(1) = 1 : @(2) = 2
c@ = 0
 
For b@ = 3 To a@-1
@(b@) = @(b@ - @(b@-1)) + @(b@ - @(b@-2))
If @(b@) < @(b@-1) Then c@ = c@ + 1
Next
 
Return (@(a@-1))</lang>
{{out}}
<pre>First 10 terms of Q = 1 1 2 3 3 4 5 5 6 6
256th term = 123
 
0 OK, 0:320</pre>
 
=={{header|Visual FoxPro}}==
<langsyntaxhighlight lang="vfp">
LOCAL p As Integer, i As Integer
CLEAR
Line 2,514 ⟶ 4,202:
RETURN aq[n]
ENDFUNC
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,522 ⟶ 4,210:
100000th term: 48157
Number of terms less than the preceding term: 49798
</pre>
 
=={{header|Wren}}==
<syntaxhighlight lang="wren">var N = 1e5
var q = List.filled(N + 1, 0)
q[1] = 1
q[2] = 1
for (n in 3..N) q[n] = q[n - q[n-1]] + q[n - q[n-2]]
 
System.print("The first ten terms of the Hofstadter Q sequence are:")
System.print(q[1..10])
System.print("\nThe thousandth term is %(q[1000]).")
var flips = 0
for (n in 2..N) {
if (q[n] < q[n-1]) flips = flips + 1
}
System.print("\nThere are %(flips) flips in the first %(N) terms.")</syntaxhighlight>
 
{{out}}
<pre>
The first ten terms of the Hofstadter Q sequence are:
[1, 1, 2, 3, 3, 4, 5, 5, 6, 6]
 
The thousandth term is 502.
 
There are 49798 flips in the first 100000 terms.
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code ChOut=8, CrLf=9, IntOut=11;
int N, C, Q(100_001);
[Q(1):= 1; Q(2):= 1; C:= 0;
Line 2,537 ⟶ 4,251:
IntOut(0, Q(1000)); CrLf(0);
IntOut(0, C); CrLf(0);
]</langsyntaxhighlight>
 
{{out}}
Line 2,545 ⟶ 4,259:
49798
</pre>
 
 
=={{header|zkl}}==
{{trans|ALGOL 68}}
<langsyntaxhighlight lang="zkl">const n = 0d100_000;
q:=(n+1).pump(List.createLong(n+1).write); // (0,1,2,...,n) base 1
q[1] = q[2] = 1;
Line 2,560 ⟶ 4,273:
flip := 0;
foreach i in (n){ flip += (q[i] > q[i + 1]) }
println("flips: ",flip);</langsyntaxhighlight>
{{out}}
<pre>
Line 2,567 ⟶ 4,280:
flips: 49798
</pre>
 
=={{header|ZX Spectrum Basic}}==
{{trans|BBC_BASIC}}
Extra credit 100000 is not implemented because of memory limitations.
<syntaxhighlight lang="zxbasic">10 PRINT "First 10 terms of Q = "
20 FOR i=1 TO 10: GO SUB 1000: PRINT s;" ";: NEXT i: PRINT
30 LET i=1000
40 PRINT "1000th term = ";: GO SUB 1000: PRINT s
50 PRINT "Term is less than preceding term ";c;" times"
100 STOP
1000 REM Qsequence subroutine
1010 IF i<3 THEN LET s=1: RETURN
1020 IF i=3 THEN LET s=2: RETURN
1030 DIM q(i)
1040 LET q(1)=1: LET q(2)=1: LET q(3)=2
1050 LET c=0
1060 FOR j=3 TO i
1070 LET q(j)=q(j-q(j-1))+q(j-q(j-2))
1080 IF q(j)<q(j-1) THEN LET c=c+1
1090 NEXT j
1100 LET s=q(i)
1110 RETURN</syntaxhighlight>
9,485

edits