Last active
February 24, 2019 12:03
-
-
Save neuro-sys/afc6b33fe98ac0dd72af7000bd99f270 to your computer and use it in GitHub Desktop.
Project Euler #1
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; If we list all the natural numbers below 10 that | |
; are multiples of 3 or 5, we get 3, 5, 6 and | |
; 9. The sum of these multiples is 23. Find the | |
; sum of all the multiples of 3 or 5 below 1000. | |
ORG &8000 | |
RUN &8000,break | |
DI | |
LD DE, 999 ; COUNT INTEGERS BELOW 1000 | |
LD BC, 3 | |
CALL DIV16_2 ; P = TARGET / N | |
EX DE, HL | |
LD DE, 3 | |
CALL SUMDIVBYN | |
PUSH HL | |
EXX | |
PUSH HL | |
EXX ; SAVE SUMDIVBY(3) | |
LD DE, 999 | |
LD BC, 5 | |
CALL DIV16_2 ; P = TARGET / N | |
EX DE, HL | |
LD DE, 5 | |
CALL SUMDIVBYN | |
EXX | |
POP DE | |
EXX | |
POP DE | |
CALL ADD32 ; HL'HL = SUMDIVBY(3) + SUMDIVBY(5) | |
PUSH HL | |
EXX | |
PUSH HL | |
EXX ; SAVE HL'HL | |
LD DE, 999 | |
LD BC, 15 | |
CALL DIV16_2 | |
EX DE, HL | |
LD DE, 15 | |
CALL SUMDIVBYN ; HL'HL = SUMDIVBY(15) | |
CALL NEG32 | |
EXX | |
POP DE | |
EXX | |
POP DE | |
CALL ADD32 ; HL'HL IS THE RESULT | |
.break | |
JP $ | |
; p = target / n | |
; sum = n * (p * (p + 1)) / 2 | |
; HL = P | |
; DE = N | |
; HL'HL is result | |
SUMDIVBYN: LD C, L | |
LD B, H ; BC = P | |
INC BC ; BC = P + 1 | |
PUSH DE ; SAVE N | |
EX DE, HL ; DE = P | |
EXX | |
LD DE, 0 | |
LD BC, 0 | |
EXX | |
CALL MUL32_2 ; P * (P + 1) | |
POP BC ; BC = N | |
EX DE, HL ; DE = PREVIOUS RESULT | |
EXX | |
EX DE, HL | |
LD BC, 0 | |
EXX | |
CALL MUL32_2 ; N * (P * (P + 1)) | |
EXX | |
SRL H | |
RR L | |
EXX | |
RR H | |
RR L ; HL'HL / 2 | |
RET | |
NEG32: | |
LD A, H | |
CPL | |
LD H, A | |
LD A, L | |
CPL | |
LD L, A | |
EXX | |
LD A, H | |
CPL | |
LD H, A | |
LD A, L | |
CPL | |
LD L, A ; ONE'S COMPLEMENT HL'HL | |
EXX | |
LD DE, &01 | |
EXX | |
LD DE, 0 | |
EXX | |
CALL ADD32 ; ADD 1 | |
RET | |
; HL'HL = HL'HL + DE'DE | |
ADD32: ADD HL, DE | |
EXX | |
ADC HL, DE | |
EXX | |
RET | |
; DE is dividend | |
; BC is divisor | |
; out DE is quotient | |
; out HL is remainder | |
DIV16_2: LD HL, 0 ; SET ACCUMULATOR TO ZERO | |
EX AF, AF' | |
LD A, 16 | |
.DIV16_2_L1 EX AF, AF' | |
LD A, H | |
OR A | |
JP M, DIV16_2_L2 ; A < 0 | |
SLA E | |
RL D ; LEFT SHIFT DIVIDEND | |
RL L | |
RL H ; LEFT SHIFT ACCUMULATOR | |
OR A | |
SBC HL, BC ; A = A - M | |
JP DIV16_2_L3 | |
.DIV16_2_L2 SLA E | |
RL D ; LEFT SHIFT DIVIDEND | |
RL L | |
RL H ; LEFT SHIFT ACCUMULATOR | |
ADD HL, BC ; A = A + M | |
.DIV16_2_L3 LD A, H | |
OR A | |
JP M, DIV16_2_L4 ; A < 0 | |
SET 0, E ; Q(0) = 1 | |
JP DIV16_2_L5 | |
.DIV16_2_L4 RES 0, E ; Q(0) = 0 | |
.DIV16_2_L5 EX AF, AF' | |
DEC A | |
JP NZ, DIV16_2_L1 | |
LD A, H | |
OR A | |
JP P, DIV16_2_L6 ; A < 0 | |
ADD HL, BC ; YES, A = A + M | |
.DIV16_2_L6 RET | |
; DE'DE is multiplicand | |
; BC'BC is multiplier | |
; HL'HL is result | |
MUL32_2: LD A, 32 ; COUNTER SET TO 32 | |
LD HL, 0 | |
EXX | |
LD HL, 0 | |
EXX ; RESET RESULT | |
.MUL32_2_L2 BIT 0, C ; Q(0) = 1? | |
JP Z, MUL32_2_L1 | |
CALL ADD32 ; A = A + M | |
.MUL32_2_L1 SLA E | |
RL D | |
EXX | |
RL E | |
RL D ; LEFT SHIFT DE'DE | |
SRA B | |
RR C | |
EXX | |
RR B | |
RR C ; RIGHT SHIFT BC'BC | |
DEC A ; DECREMENT COUNTER | |
JP NZ, MUL32_2_L2 | |
RET |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment