ЛКМ - Проверка, если 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
не имеет значения Я надеюсь, что это работает, я не проверял это.