ЛКМ - Проверка, если a^2 + b^2 = c^2 в Сборке компьютера Маленького Человека эффективно

Моя программа должна принять 3 входа, а затем проверить, образуют ли они пифагорейскую тройку. Для этого я использую компьютер Little Man, и поэтому я использую сборку LMC. Если вы хотите получить больше информации о командах, которые можно использовать, или загрузить симулятор, который я использую, вот ссылка

Вот код, который я написал до сих пор.

#Valid mnemonics are:
# HLT, ADD, SUB, STO, LDA,
# BR, BRZ, BRP, IN, OUT, DAT
# The first part of the program will sort a,b and c, so that they will always be in order from
# a,b,c                                  



        IN      #get first input
        STO c   
        IN      #get second input   
        STO b
        IN      #get third input
        STO a

        SUB b   #Test if a>b
        BRP swapAB
        BR next1

swapAB  LDA b   #Swaps a and b
        STO temp
        LDA a
        STO b
        LDA temp
        STO a   #continues on to next1

next1   LDA b   #Test if b>c
        SUB c
        BRP swapBC
        BR end  #All sorted

swapBC  LDA c   #Swaps b an c
        STO temp
        LDA b
        STO c
        LDA temp
        STO b
        BR next2

next2   LDA a   #tests new a>b
        SUB b
        BRP swapAB  


end     LDA a   #begin the process of squaring a
        STO total
        SUB one
        STO count
loop1   LDA total
        ADD a
        STO total
        LDA count
        SUB one
        STO count
        BRZ endsq1
        BR loop1

endsq1  LDA total
        STO d   #stores a*a in d
        OUT #for testing. Outputs a*a
        SUB total
        STO total   

         LDA b  #Begins squaring b
         STO total
         SUB one
         STO count
loop2    LDA total
         ADD b
         STO total
         LDA count
         SUB one
         STO count
         BRZ endsq2
         BR loop2   #end of squaring b

endsq2   LDA total
         STO e  #stores b*b in e
         OUT
         SUB total
         STO total

         LDA c  #begin squaring c
         STO total
         SUB one
         STO count
 loop3   LDA total
         ADD c
         STO total
         LDA count
         SUB one
         STO count
         BRZ endsq3
         BR loop3   #end squaring c

         endsq3 LDA total
         STO f  #stores c*c in f
         OUT
         SUB total
         STO total

         LDA d  #begin check a^2 + b^2 = c^2
         ADD e
         SUB f
         BRZ true
         LDA count
         OUT    #FALSE output 000
         HLT
true     LDA one    
         OUT    #TRUE output 001
         HLT

a        DAT
b        DAT
c        DAT
d        DAT
e        DAT
f        DAT
temp     DAT
total    DAT 000
one      DAT 001
count    DAT 000

Программа выдаст 001, если a, b, c образуют пифагорейскую тройку, или 000, если нет. Однако он также должен выводить 002, если происходит переполнение, т.е. входы превышают 3-значный предел LMC.

Я знаю, что код работает для проверки, являются ли a, b, c тройками Пифагора. Однако мне нужен какой-то способ проверки на переполнение (LMC принимает только 3-значные значения). Чтобы сделать это сложнее, в используемой мной версии LMC нет флага переполнения. Я думаю, чтобы проверить, если c > 31, так как все, что выше 31 будет больше 1000 в квадрате, и как-то проверить, если a^2 + b^2 > 1000.

Чтобы еще больше усложнить это, у LMC есть только 99 адресов памяти для хранения данных и инструкций, и у меня осталось только 5-6. Можно ли как-нибудь упростить приведенный выше код, чтобы уменьшить объем памяти, занимаемый инструкциями программы? Первоначально я думал, что мог бы использовать один цикл для процесса возведения в квадрат, но я не уверен, каким образом я бы затем выполнял ответвление, чтобы каждый раз сохранять результат в другой переменной.

Любая помощь будет принята с благодарностью.

ОБНОВЛЕНИЕ: Вот код вставки сортировки lmc, который работает

inloop  IN # get a number
        STO tmp
        SUB range #check input < 31 
        BRP error
        LDA tmp
        SUB c # bigger than the biggest so far?
        BRP storeC
        LDA b
        BRZ storeB # if empty, use b
        LDA tmp    # must use a
        STO a
        BR minus
storeB  LDA tmp
        STO b
        BR minus
storeC  LDA b
        BRZ fillB # if empty, use b
        BR fillA  # otherwise, use a
fillB   LDA c    
        STO b
        LDA tmp
        STO c
        BR minus
fillA   LDA c 
        STO a
        LDA tmp
        STO c
        BR minus   
minus   LDA incount
        SUB one
        BRZ next
        STO incount
        BR inloop
next    LDA a
        OUT
        LDA b
        OUT
        LDA c
        OUT
        HLT
error   LDA overflow
        OUT
        HLT

range   DAT 031
a   DAT 000
b   DAT 000
c   DAT 000
tmp DAT
overflow DAT 002
incount DAT 003
one DAT 001

1 ответ

Решение

Как только вы узнаете, что отдельные квадраты действительны, вы можете изменить уравнение на c^2 - a^2 - b^2 = 0, Вы можете проверить это равенство, а также проверить отрицательный флаг, который сигнализирует о переполнении.

Чтобы сжать код, вы действительно можете создать цикл, который читает и возводит в квадрат число, а также помещает его на место. Так как вы все равно сортируете числа, вас не волнует порядок их ввода. Вы можете использовать алгоритм сортировки вставок, убедившись, что 3 местоположения данных инициализируются нулями.

Обновление: вот пример кода, показывающий грубую схему тела цикла:

        IN # get a number
        STO tmp
        # do range check here
        SUB c # bigger than the biggest so far?
        BRP storeC
store   LDA b
        BRZ storeB # if empty, use b
        LDA tmp    # must use a
        STO a
        BR next
storeB  LDA tmp
        STA b
        BR next
storeC  LDA c
        STO tmp2
        LDA tmp    # store new number
        STO c      # as biggest
        LDA tmp2   # insert previous biggest
        STO tmp
        BR store
next    # repeat until we got 3 numbers (use a counter)

Обратите внимание, что я оптимизировал его немного больше, так как нам нужно только знать, какое число является наибольшим (это относится к c) но отношение a а также b не имеет значения Я надеюсь, что это работает, я не проверял это.

Другие вопросы по тегам