I'm trying to code a bubble sort using the LMC, and well, it's not going too great.
First of all it just loops for all eternity, and I cannot figure out the cause, maybe a pair of fresh eyes would help?
I am unsure if I need to add a "sort 4" section or not either.
INP
STO NUM1
INP
STO NUM2
INP
STO NUM3
INP
STO NUM4
BEGIN LDA ZERO
STA INCRE
LDA NUM2
SUB NUM1
BRP SORT2
LDA ONE
STO INCRE
LDA NUM1
STO PLHOLDER
LDA NUM2
LDA PLHOLDER
STO NUM2
SORT2 LDA NUM3
SUB NUM2
BRP SORT3
LDA ONE
STO INCRE
LDA NUM2
STO PLHOLDER
LDA NUM3
STO NUM2
LDA PLHOLDER
STO NUM3
SORT3 LDA NUM4
SUB NUM3
BRP OUTPUT
LDA ONE
STO INCRE
LDA NUM2
STO PLHOLDER
LDA NUM4
STO NUM3
LDA PLHOLDER
STO NUM4
OUTPUT LDA INCRE
BRZ NOINCRE
BRA BEGIN
NOINCRE LDA NUM1
OUT
LDA NUM2
OUT
LDA NUM3
OUT
LDA NUM4
OUT
HLT
NUM1 DAT
NUM2 DAT
NUM3 DAT
NUM4 DAT
INCRE DAT
PLHOLDER DAT
ONE DAT 001
ZERO DAT 000
I am using the LMC for this.
The algorithm is fine, but you just have two little, unintended mistakes: the second one is the cause of the infinite loop (for some inputs).
See the comments in the correction below:
#input: 4 3 1 2
INP
STO NUM1
INP
STO NUM2
INP
STO NUM3
INP
STO NUM4
BEGIN LDA ZERO
STA INCRE
LDA NUM2
SUB NUM1
BRP SORT2
LDA ONE
STO INCRE
LDA NUM1
STO PLHOLDER
LDA NUM2
STO NUM1 -- was missing
LDA PLHOLDER
STO NUM2
SORT2 LDA NUM3
SUB NUM2
BRP SORT3
LDA ONE
STO INCRE
LDA NUM2
STO PLHOLDER
LDA NUM3
STO NUM2
LDA PLHOLDER
STO NUM3
SORT3 LDA NUM4
SUB NUM3
BRP OUTPUT
LDA ONE
STO INCRE
LDA NUM3 -- was wrong
STO PLHOLDER
LDA NUM4
STO NUM3
LDA PLHOLDER
STO NUM4
OUTPUT LDA INCRE
BRZ NOINCRE
BRA BEGIN
NOINCRE LDA NUM1
OUT
LDA NUM2
OUT
LDA NUM3
OUT
LDA NUM4
OUT
HLT
NUM1 DAT
NUM2 DAT
NUM3 DAT
NUM4 DAT
INCRE DAT
PLHOLDER DAT
ONE DAT 001
ZERO DAT 000
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc#v0.7/lmc.js"></script>
This also answers your second question:
I am unsure if I need to add a "sort 4" section or not either.
No, you don't need another such section. As each section compares two consecutive numbers, you only need 3 when you have an input of 4 numbers.
Generic solution
You have tackled the problem of sorting 4 values. But if you are looking for a solution where you can enter a variable number of values and get them sorted, have a look at these answers:
Buble Sort (with terminating zero)
Buble sort (first input is array size)
Related
How is it going guys ?
I've written a program that "draws" diamond in the command line (it's a part of my homework). For spaces inside the diamond I was given a formula "1 + 2(k-2) or 2k -3 , where k is line number", but I don't understand how this formula was created. Could anyone explain it ?
program diamond;
var
n, k, h, i: integer;
begin
repeat
write('Enter the diamond''s height (positive odd): ');
readln(h);
until (h > 0) and (h mod 2 = 1);
n := h div 2;
for k := 1 to n + 1 do
begin
for i := 1 to n + 1 - k do
write(' ');
write('*');
if k > 1 then
begin
for i := 1 to 2*k - 3 do
write(' ');
write('*')
end;
writeln
end;
for k := n downto 1 do
begin
for i := 1 to n + 1 - k do
write(' ');
write('*');
if k > 1 then
begin
for i := 1 to 2*k - 3 do
write(' ');
write('*')
end;
writeln
end
end.
I've already figured it out. It's a simple, but modified arithmetic progression An=A1-d(n-2). Usually we would use (n-1), but because we need to substract 2 stars from each line (starting from the second one, as this formula works for k>1), we use (n-2)
I need to multiply two boolean matrices in Julia.
Doing simply A*A or A^2 returns an Int64 Matrix.
Is there a way how to multiply efficiently boolean matrices?
Following Oscar's comment of adding two for loops around your code, but without the LoopVectorization improvement, although with not allocating the full array inside the any call (so that the any stops on the first occurrence), this is decently fast (edit: replaced standard AND & with short-circuit &&):
function bool_mul2(A, B)
mA, nA = size(A)
mB, nB = size(B)
nA ≠ mB && error()
AB = BitArray(undef, mA, nB)
for i in 1:mA, j in 1:nB
AB[i,j] = any(A[i,k] && B[k,j] for k in 1:nA)
end
AB
end
(Note I removed the [ and ] inside the any to not allocate there.
E.g., with A and B of size 1000×1000, I get
julia> #btime bool_mul2($A, $B) ;
16.128 ms (3 allocations: 122.25 KiB)
compared to
julia> #btime bool_mul($A, $B) ;
346.374 ms (12 allocations: 7.75 MiB)
EDIT: For squaring the matrix, maybe try
function bool_square(A)
m, n = size(A)
m ≠ n && error()
A² = BitArray(undef, n, n)
for i in 1:n, j in 1:n
A²[i,j] = any(A[i,k] && A[k,j] for k in 1:n)
end
A²
end
for which I get
julia> A = rand(Bool, 500, 500) ;
julia> #btime $A * $A .!= 0 ;
42.483 ms (12 allocations: 1.94 MiB)
julia> #btime bool_square($A) ;
4.653 ms (3 allocations: 30.69 KiB)
One very simple solution is
function bool_mul(A,B)
return A*B .!= 0
end
This won't be the most efficient since it will allocate a matrix for A*B, but might end up being one of the fastest solutions available.
How would I write the code to a six-sided dice are rolled and the two numbers showing are added to produce a sum between 2 and 12? Then plotting it
This code is for 10 observation. You can change it according to your criteria.
for i =1:1:10
first_no = randi([1 6],1);
second_no = randi([1 6],1);
if second_no == first_no
second_no = randi([1 6],1);
end
sum(i) = first_no + second_no
no(i) = 1
end
figure;
plot(no, sum)
You just need to define two variables that take the random values between 1-6. At the start, you can have the option of the number of observations. See the code below:
no_obs = 5;
for i=1:no_obs
num1 = randi([1 6],1);
num2 = randi([1 6],1);
sum(i) = num1 + num2;
end
display(sum);
figure;
plot(sum)
Here is what my data file looks like:
1
num num num
num num num
num num num
num num num
num num num
2
num num num
num num num
num num num
num num num
num num num
3
num num num
num num num
num num num
num num num
num num num
.
.
.
1000
num num num
num num num
num num num
num num num
num num num
'num' refers to a different float number, and 1,2,3,...,1000 are also part of the file, occupying one line each. What I want to do is, I need a loop from time step 1 to 1000, and during each step, I need to read the 3-column float number block below it as three column vectors. Then I proceed to the next time step, and read the block below, until I finish reading all.
How could I do this file reading with Matlab? In short, what I want to do is to read line 2 to line 6 as a matrix, then line 8 to line 12 as a matrix, then line 14 to 18 as a matrix, and so on...
Thanks!
You can read the text file as follows:
%Open text file
f = fopen('num.txt', 'r');
num_matrices = 1000;
%Initialize cell array - hold matrices.
C = cell(num_matrices, 1);
for i = 1:num_matrices
%Read index (to be ignored).
idx = fscanf(f, '%f', 1);
%Read 6x3 matrix into A
A = fscanf(f, '%f', [3, 6])';
%Store matrix in cell array C.
C{i} = A;
end
fclose(f);
Refer to https://www.mathworks.com/help/matlab/ref/fscanf.html for fscanf documentation.
LDA 2000h ; Store the no of byte that each number consists of in memory location 2000h.
MOV C A
MOV B A
LXI D 5000h
LXI H 2001h
STC
CMC
LOOP1: MOV A M
SHLD 7000h
LOOP: INX H
DCR C
JNZ LOOP
ADC M
STAX D
LHLD 7000h
LDA 2000h
MOV C A
INX D
INX H
DCR B
JNZ LOOP1
HLT
This is my code for the above mentioned problem. What would be more efficient algorithm to do so?