assemblylittle-man-computer

Output all the factors of the input


I'm trying to output every number that evenly divides the input (so there is no remainder).

For example: if 60 is input, then the output should be:

1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30, 60

I have programmed code that outputs 10 in this example: 50 / 5. But I cannot figure out how to modify this, so that I get every factor. I would appreciate some help!

       IN
       STO DIVID
       IN
       STO DIVIS
LOOP1  LDA count
       ADD one
       STO count
       LDA DIVID
       SUB DIVIS
       STO DIVID
       OUT DIVID
       BRP LOOP1
       
       HLT

DIVID  DAT 000
DIVIS  DAT 000
one    DAT 001
count  DAT 000

Solution

  • You'll need an extra, outer loop to manage the value of DIVIS, increasing it from 1 to DIVID.

    Here is how that could look in a runnable snippet:

    #input:60
              LDA ONE
              STO divisor
              IN
              BRZ invalid
              STO dividend
    
    next      LDA dividend
    loop      BRZ output
              STO remainder
              LDA remainder 
              SUB divisor
              BRP loop
              BRA inc     
         
    output    LDA divisor
              OUT
    
    inc       LDA divisor
              SUB dividend
              BRP done
    
              LDA divisor
              ADD ONE
              STO divisor
              BRA next
    
    invalid   OUT ; zero
    done      HLT
    
    ONE       DAT 1 ; constant
    divisor   DAT
    dividend  DAT 
    remainder DAT
    
    <script src="https://cdn.jsdelivr.net/gh/trincot/lmc@v0.74/lmc.js"></script>

    In case the input is 0 this program will consider it as "invalid" and output 0 and halt.

    This is a quite basic algorithm, and not optimised for efficiency. Several optimisations are possible, which would make the code longer. For instance, every number has divisor 1, so you could output it immediately, and start the main loop with divisor=2 instead of 1. Similarly, once the divisor becomes greater than half of the dividend, you could exit the loop and output the dividend itself, as there are no other divisors to be found between dividend/2 and dividend.

    More efficiency is achieved by implementing the long division algorithm.