Increasing gaps between consecutive Niven numbers: Difference between revisions

Add x86-64 Assembly
(Add Fortran)
(Add x86-64 Assembly)
Line 1,696:
150 61,074,615 989,888,823
</pre>
 
=={{header|x86 64 Assembly}}==
This program runs under Linux.
 
<lang asm> bits 64
section .data
;;; Header
header: db 'Gap no Gap Niven index Niven number',10
db '------ --- ------------- --------------',10
.len: equ $-header
;;; Placeholder for line output
line: db 'XXXXXX'
.gapno: db ' XXX'
.gap: db ' XXXXXXXXXXXXX'
.nivno: db ' XXXXXXXXXXXXXX'
.niv: db 10
.len: equ $-line
section .text
global _start
_start: xor r8,r8 ; Keep a 10 in R8 to divide by
mov r8b,10
mov rsi,header ; Write header
mov rdx,header.len
call write
xor r15,r15 ; Let R15 be the previous number
inc r15
xor r14,r14 ; Let R14 be the gap
xor r13,r13 ; Let R13 be the digit sum
xor r12,r12 ; Let R12 be the index
mov r11,r15 ; Let R11 be the gap index
xor r10,r10 ; And let R10 be the Niven number
jmp niven ; Jump over end of loop
next: mov r15,r10 ; Previous number is now current number
inc r12 ; Increment index
niven: inc r10 ; Check next Niven number
inc r13 ; Calculate next digit sum
mov rax,r10 ; rax = n/10
xor rdx,rdx ; rdx = n%10
digsum: div r8
sub r13,9 ; sum -= 9
test rdx,rdx ; was it divisible by 10?
jnz check ; if not, we're done
test rax,rax ; otherwise, have we reached 0?
jnz digsum ; if not, keep going
check: add r13,9 ; add 9 back
test r13b,1 ; sum divisible by 2?
jnz chdiv ; if not try division
test r10b,1 ; number divisible by 2?
jnz niven
chdiv: mov rax,r10 ; number divisible by sum?
xor rdx,rdx
div r13
test rdx,rdx
jnz niven ; if not, try next number
mov rax,r10 ; calculate gap size
sub rax,r15
cmp rax,r14 ; bigger than previous gap?
jbe next ; If not, count but don't display
mov r14,rax ; If so, store new gap size
mov rbx,line.niv ; Format Niven number
mov rax,r15
mov cl,14
call format
dec rbx
dec rbx
mov rax,r12 ; Niven index
mov cl,13
call format
dec rbx
dec rbx
mov rax,r14 ; Gap
mov cl,3
call format
dec rbx
dec rbx
mov rax,r11 ; Gap index
mov cl,6
call format
mov rsi,rbx ; Write line
mov rdx,line.len
call write
inc r11 ; Increment gap index
cmp r11b,32 ; Done?
jbe next ; If not, next number
mov rax,60
xor rdi,rdi ; Otherwise, exit
syscall
;;; Write RDX chars to STDOUT starting at RSI
write: xor rax,rax ; Write syscall is 1
inc rax
mov rdi,rax ; STDOUT is also 1
push r11 ; R11 is clobbered, keep it
syscall
pop r11
ret
;;; Format number in RAX as ASCII, with thousand
;;; separators; storing at RBX going leftward,
;;; padding with spaces for length CL.
format: mov ch,3 ; Thousands counter
.loop: xor rdx,rdx ; Divide
div r8
add dl,'0' ; ASCII zero
dec rbx ; Store value
mov [rbx],dl
dec cl ; One fewer char left
jz .out ; Stop if field full
test rax,rax ; Done whole number?
jz .ndone
dec ch ; Time for separator?
jnz .loop ; If not, continue;
mov ch,3 ; If so, reset counter,
dec rbx ; Add separator,
mov [rbx],byte ','
dec cl ; One fewer char left
jmp .loop
.ndone: mov al,' ' ; Pad with spaces
test cl,cl ; Done yet?
jz .out
.pad: dec rbx ; If not, add space
mov [rbx],al
dec cl
jnz .pad
.out: ret</lang>
 
{{out}}
 
<pre>Gap no Gap Niven index Niven number
------ --- ------------- --------------
1 1 1 1
2 2 10 10
3 6 11 12
4 7 26 63
5 8 28 72
6 10 32 90
7 12 83 288
8 14 102 378
9 18 143 558
10 23 561 2,889
11 32 716 3,784
12 36 1,118 6,480
13 44 2,948 19,872
14 45 4,194 28,971
15 54 5,439 38,772
16 60 33,494 297,864
17 66 51,544 478,764
18 72 61,588 589,860
19 88 94,748 989,867
20 90 265,336 2,879,865
21 99 800,054 9,898,956
22 108 3,750,017 49,989,744
23 126 6,292,149 88,996,914
24 135 44,194,186 689,988,915
25 144 55,065,654 879,987,906
26 150 61,074,615 989,888,823
27 153 179,838,772 2,998,895,823
28 192 399,977,785 6,998,899,824
29 201 497,993,710 8,889,999,624
30 234 502,602,764 8,988,988,866
31 258 547,594,831 9,879,997,824
32 276 1,039,028,518 18,879,988,824</pre>
 
=={{header|zkl}}==
2,114

edits