-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #8 from exercism/more-exercises
Add isogram and triangle
- Loading branch information
Showing
5 changed files
with
309 additions
and
1 deletion.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,9 @@ | |
"trinary", | ||
"hexadecimal", | ||
"leap", | ||
"hamming" | ||
"hamming", | ||
"isogram", | ||
"triangle" | ||
], | ||
"deprecated": [ | ||
|
||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
# Determine if the given string is an isogram, meaning that the same character | ||
# does not appear more than once. | ||
# | ||
# Strategy: use the bits of a single word to represent set of encountered letters | ||
# | ||
# $a0 - input, pointer to null-terminated string of chars 0-7 | ||
# $v0 - output, boolean representing is or is not isogram | ||
# $t0 - set of bits | ||
# $t1 - an encountered character | ||
|
||
.globl is_isogram | ||
|
||
is_isogram: | ||
li $t0, 0 # Reset set to 0. | ||
|
||
loop: | ||
lb $t1, 0($a0) # Load a character, | ||
beq $t1, $zero, true # if end of string, return true. | ||
|
||
addi $t2, $t1, -65 # If less than 'A'... | ||
blt $t2, $zero, increment # continue to next letter. | ||
|
||
addi $t1, $t1, -97 # Find offset from 'a'. | ||
blt $t1, $zero, downcase # If negative, presume upper case, so downcase | ||
|
||
consider_seen: | ||
li $t3, 1 | ||
sllv $t3, $t3, $t1 # Create bit mask | ||
and $t4, $t0, $t3 # Apply to set. | ||
bgt $t4, $zero, false # If char has been seen, return false. | ||
|
||
or $t0, $t0, $t3 # Otherwise flip bit for char | ||
|
||
increment: | ||
addi $a0, $a0, 1 # Finally, increment the pointer | ||
j loop # and loop. | ||
|
||
downcase: | ||
addi $t1, $t1, 32 # Upper -> lower ascii value | ||
j consider_seen | ||
|
||
false: | ||
li $v0, 0 | ||
jr $ra | ||
|
||
true: | ||
li $v0, 1 | ||
jr $ra |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# | ||
# Test is_isogram with some examples | ||
# | ||
# s0 - num of tests left to run | ||
# s1 - address of input word | ||
# s2 - address of expected output word | ||
# s3 - char byte | ||
# s4 - output word | ||
# | ||
# is_isogram must: | ||
# - be named is_isogram and declared as global | ||
# - read input address of string from a0 | ||
# - follow the convention of using the t0-9 registers for temporary storage | ||
# - (if it uses s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning) | ||
# - write boolean result to v0 | ||
|
||
.data | ||
|
||
# number of test cases | ||
n: .word 8 | ||
# input values (null terminated) & expected output values (word sized ints) | ||
ins: .asciiz "duplicates", "eleven", "subdermatoglyphic", "Alphabet", "thumbscrew-japingly", "Hjelmqvist-Gryb-Zock-Pfund-Wax", "the quick brown fox", "Emily Jung Schwartzkopf" | ||
outs: .word 1, 0, 1, 0, 1, 1, 0, 1 | ||
|
||
failmsg: .asciiz "failed for test input: " | ||
expectedmsg: .asciiz ". expected " | ||
tobemsg: .asciiz " to be " | ||
okmsg: .asciiz "all tests passed" | ||
|
||
|
||
.text | ||
|
||
runner: | ||
lw $s0, n | ||
la $s1, ins | ||
la $s2, outs | ||
|
||
run_test: | ||
move $a0, $s1 # move address of input str to a0 | ||
jal is_isogram # call subroutine under test | ||
move $v1, $v0 # move return value in v0 to v1 because we need v0 for syscall | ||
|
||
lw $s4, 0($s2) # read expected output from memory | ||
bne $v1, $s4, exit_fail # if expected doesn't match actual, jump to fail | ||
|
||
scan: | ||
addi $s1, $s1, 1 # move input address on byte forward | ||
lb $s3, 0($s1) # load byte | ||
beq $s3, $zero, done_scan # if char null, break loop | ||
j scan # loop | ||
|
||
done_scan: | ||
addi $s1, $s1, 1 # move input address on byte past null | ||
|
||
addi $s2, $s2, 4 # move to next word in output | ||
sub $s0, $s0, 1 # decrement num of tests left to run | ||
bgt $s0, $zero, run_test # if more than zero tests to run, jump to run_test | ||
|
||
exit_ok: | ||
la $a0, okmsg # put address of okmsg into a0 | ||
li $v0, 4 # 4 is print string | ||
syscall | ||
|
||
li $v0, 10 # 10 is exit with zero status (clean exit) | ||
syscall | ||
|
||
exit_fail: | ||
la $a0, failmsg # put address of failmsg into a0 | ||
li $v0, 4 # 4 is print string | ||
syscall | ||
|
||
move $a0, $s1 # print input that failed on | ||
li $v0, 4 | ||
syscall | ||
|
||
la $a0, expectedmsg | ||
li $v0, 4 | ||
syscall | ||
|
||
move $a0, $v1 # print actual that failed on | ||
li $v0, 1 # 1 is print integer | ||
syscall | ||
|
||
la $a0, tobemsg | ||
li $v0, 4 | ||
syscall | ||
|
||
move $a0, $s4 # print expected value that failed on | ||
li $v0, 1 # 1 is print integer | ||
syscall | ||
|
||
li $a0, 1 # set error code to 1 | ||
li $v0, 17 # 17 is exit with error | ||
syscall | ||
|
||
# # Include your implementation here if you wish to run this from the MARS GUI. | ||
# .include "impl.mips" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
# | ||
# Determine if triangle with given sides is invalid, equilateral, isoceles or scalene. | ||
# | ||
# Variables: | ||
# | ||
# $a0 - side a (int) | ||
# $a1 - side b (int) | ||
# $a2 - side c (int) | ||
# $v0 - enum 0: scalene, 1: isoceles, 2: equilateral, 3: invalid | ||
# $t0 - a == b | ||
# $t1 - b == c | ||
# $t5 - a == b && b == c (equilateral) | ||
# $t6 - a == b || b == c (isoceles, if not above) | ||
|
||
.globl triangle | ||
|
||
|
||
triangle: | ||
bgt $a0, $a1, swap_ab | ||
bgt $a1, $a2, swap_bc | ||
j solve | ||
|
||
swap_ab: | ||
move $t0, $a1 | ||
move $a1, $a0 | ||
move $a0, $t0 | ||
j triangle | ||
|
||
swap_bc: | ||
move $t0, $a2 | ||
move $a2, $a1 | ||
move $a1, $t0 | ||
j triangle | ||
|
||
solve: | ||
addu $t0, $a0, $a1 | ||
bge $a2, $t0, invalid # invalid if violate triangle inequality | ||
|
||
seq $t0, $a0, $a1 # a == b | ||
seq $t1, $a1, $a2 # b == c | ||
|
||
and $t5, $t0, $t1 | ||
or $t6, $t0, $t1 | ||
|
||
bne $t5, $zero, equilateral | ||
bne $t6, $zero, isoceles | ||
|
||
li $v0, 0 | ||
jr $ra | ||
|
||
equilateral: | ||
li $v0, 2 | ||
jr $ra | ||
|
||
isoceles: | ||
li $v0, 1 | ||
jr $ra | ||
|
||
invalid: | ||
li $v0, 3 | ||
jr $ra |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
# | ||
# Test triange with some examples | ||
# | ||
# s0 - num of tests left to run | ||
# s1 - address of side 1 | ||
# s2 - address of side 2 | ||
# s3 - address of side 3 | ||
# s4 - address of expected output | ||
# s5 - value of expected output | ||
# | ||
# triangle must: | ||
# - be named triangle and declared as global | ||
# - read input integers from a0, a1 and a2 | ||
# - follow the convention of using the t0-9 registers for temporary storage | ||
# - (if it wants to use s0-7 then it is responsible for pushing existing values to the stack then popping them back off before returning) | ||
# - write result to v0 as: | ||
# 0 - scalene | ||
# 1 - isoceles | ||
# 2 - equilateral | ||
# 3 - invalid triangle | ||
|
||
.data | ||
|
||
n: .word 11 | ||
as: .word 2, 10, 3, 4, 4, 3, 10, 5, 7, 1, 0 | ||
bs: .word 2, 10, 4, 3, 7, 4, 11, 4, 3, 1, 0 | ||
cs: .word 2, 10, 4, 4, 4, 5, 12, 2, 2, 3, 0 | ||
outs: .word 2, 2, 1, 1, 1, 0, 0, 0, 3, 3, 3 | ||
|
||
failmsg: .asciiz "failed for test input: " | ||
okmsg: .asciiz "all tests passed" | ||
comma: .asciiz ", " | ||
|
||
.text | ||
|
||
runner: | ||
lw $s0, n | ||
la $s1, as | ||
la $s2, bs | ||
la $s3, cs | ||
la $s4, outs | ||
|
||
run_test: | ||
lw $a0, 0($s1) # load inputs into argument registers | ||
lw $a1, 0($s2) | ||
lw $a2, 0($s3) | ||
|
||
jal triangle # call subroutine under test | ||
move $v1, $v0 # move return value in v0 to v1 because we need v0 for syscall | ||
|
||
lw $s5, 0($s4) # read expected output from memory | ||
bne $v1, $s5, exit_fail # if expected doesn't match actual, jump to fail | ||
|
||
addi $s1, $s1, 4 # move to next word in as | ||
addi $s2, $s2, 4 # move to next word in bs | ||
addi $s3, $s3, 4 # move to next word in cs | ||
addi $s4, $s4, 4 # move to next word in output | ||
|
||
sub $s0, $s0, 1 # decrement num of tests left to run | ||
bgt $s0, $zero, run_test # if more than zero tests to run, jump to run_test | ||
|
||
exit_ok: | ||
la $a0, okmsg # put address of okmsg into a0 | ||
li $v0, 4 # 4 is print string | ||
syscall | ||
|
||
li $v0, 10 # 10 is exit with zero status (clean exit) | ||
syscall | ||
|
||
exit_fail: | ||
la $a0, failmsg # put address of failmsg into a0 | ||
li $v0, 4 # 4 is print string | ||
syscall | ||
|
||
lw $a0, 0($s1) # set arg of syscall to input that failed the test | ||
li $v0, 1 # 1 is print int | ||
syscall | ||
|
||
la $a0, comma # put address of failmsg into a0 | ||
li $v0, 4 # 4 is print string | ||
syscall | ||
|
||
lw $a0, 0($s2) # set arg of syscall to input that failed the test | ||
li $v0, 1 # 1 is print int | ||
syscall | ||
|
||
la $a0, comma # put address of failmsg into a0 | ||
li $v0, 4 # 4 is print string | ||
syscall | ||
|
||
lw $a0, 0($s3) # set arg of syscall to input that failed the test | ||
li $v0, 1 # 1 is print int | ||
syscall | ||
|
||
li $a0, 1 # set exit code to 1 | ||
li $v0, 17 # terminate with the exit code in $a0 | ||
syscall | ||
|
||
# # Include your implementation here if you wish to run this from the MARS GUI. | ||
# .include "impl.mips" |