Skip to content

Commit

Permalink
Add reverse-string exercise (#204)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode authored Jan 9, 2024
1 parent ea62568 commit c54c03a
Show file tree
Hide file tree
Showing 9 changed files with 242 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@
"prerequisites": [],
"difficulty": 2
},
{
"slug": "reverse-string",
"name": "Reverse String",
"uuid": "0e03cb80-b443-45ba-9bd7-e74690fb5faf",
"practices": [],
"prerequisites": [],
"difficulty": 2
},
{
"slug": "triangle",
"name": "Triangle",
Expand Down
6 changes: 6 additions & 0 deletions exercises/practice/reverse-string/.docs/hints.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Hints

## General

- The `$t0-9` registers can be used to temporarily store values
- The instructions specify which registers are used as input and output
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Instructions append

## Registers

| Register | Usage | Type | Description |
| -------- | ------------ | ------- | ----------------------------- |
| `$a0` | input | address | null-terminated input string |
| `$a1` | input/output | address | null-terminated output string |
| `$t0-9` | temporary | any | used for temporary storage |
7 changes: 7 additions & 0 deletions exercises/practice/reverse-string/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Instructions

Reverse a string

For example:
input: "cool"
output: "looc"
19 changes: 19 additions & 0 deletions exercises/practice/reverse-string/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"impl.mips"
],
"test": [
"runner.mips"
],
"example": [
".meta/example.mips"
]
},
"blurb": "Reverse a string.",
"source": "Introductory challenge to reverse an input string",
"source_url": "https://medium.freecodecamp.org/how-to-reverse-a-string-in-javascript-in-3-different-ways-75e4763c68cb"
}
33 changes: 33 additions & 0 deletions exercises/practice/reverse-string/.meta/example.mips
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Reverse a string
#
# $a0 - input, pointer to null-terminated input string
# $a1 - input, pointer to null-terminated output string
# $t0 - pointer into input string
# $t1 - pointer into output string
# $t2 - input byte

.globl reverse

reverse:
move $t0, $a0 # copy input address
move $t1, $a1 # copy output address
j end_check

scan:
addi $t0, $t0, 1 # increment input address

end_check:
lb $t2, 0($t0) # load next input byte
bne $t2, $zero, scan # repeat until end of string
j begin_check

copy:
subi $t0, $t0, 1 # decrement input address
lb $t2, 0($t0) # load next input byte
sb $t2, 0($t1) # store byte
addi $t1, $t1, 1 # increment output address

begin_check:
bne $t0, $a0, copy
sb $zero, 0($t1) # write null terminator
jr $ra
28 changes: 28 additions & 0 deletions exercises/practice/reverse-string/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[c3b7d806-dced-49ee-8543-933fd1719b1c]
description = "an empty string"

[01ebf55b-bebb-414e-9dec-06f7bb0bee3c]
description = "a word"

[0f7c07e4-efd1-4aaa-a07a-90b49ce0b746]
description = "a capitalized word"

[71854b9c-f200-4469-9f5c-1e8e5eff5614]
description = "a sentence with punctuation"

[1f8ed2f3-56f3-459b-8f3e-6d8d654a1f6c]
description = "a palindrome"

[b9e7dec1-c6df-40bd-9fa3-cd7ded010c4c]
description = "an even-sized word"
10 changes: 10 additions & 0 deletions exercises/practice/reverse-string/impl.mips
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# | Register | Usage | Type | Description |
# | -------- | ------------ | ------- | ----------------------------- |
# | `$a0` | input | address | null-terminated input string |
# | `$a1` | input/output | address | null-terminated output string |
# | `$t0-9` | temporary | any | used for temporary storage |

.globl reverse

reverse:
jr $ra
122 changes: 122 additions & 0 deletions exercises/practice/reverse-string/runner.mips
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#
# Test reverse with some examples
#
# a0 - input string, for callee
# a1 - pointer to output string, for callee
# s0 - num of tests left to run
# s1 - address of input string
# s2 - address of expected output string
# s3 - char byte of input
# s4 - char byte of output
# s5 - copy of output location

.data

# number of test cases
n: .word 6
# input values (null terminated)
ins: .asciiz
"",
"robot",
"Ramen",
"I'm hungry!",
"racecar",
"drawer"
# expected output values (null terminated)
outs: .asciiz
"",
"tobor",
"nemaR",
"!yrgnuh m'I",
"racecar",
"reward"

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

li $v0, 9 # code for allocating heap memory
li $a0, 12 # specify 12 bytes - length of longest expected output
syscall
move $s5, $v0 # location of allocated memory is where callee writes result

run_test:
jal clear_output # zero out output location
move $a0, $s1 # load input value into a0
move $a1, $s5 # load destination address into a1
jal reverse # call subroutine under test
move $a1, $s5
move $s6, $s5 # take copy of output value
move $s7, $s2

scan:
lb $s3, 0($s2) # load one byte of the expectation
lb $s4, 0($a1) # load one byte of the actual
bne $s3, $s4, exit_fail # if the two differ, the test has failed
addi $s2, $s2, 1 # point to next expectation byte
addi $a1, $a1, 1 # point to next actual byte
bne $s3, $zero, scan # if one char (and therefore the other) was not null, loop

input_scan:
lb $s3, 0($s1)
addi $s1, $s1, 1
bne $s3, $zero, input_scan

done_scan:
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, $s6 # print actual that failed on
li $v0, 4
syscall

la $a0, tobemsg
li $v0, 4
syscall

move $a0, $s7 # print expected value that failed on
li $v0, 4
syscall

li $a0, 1 # set error code to 1
li $v0, 17 # 17 is exit with error
syscall

clear_output:
sw $zero, 0($s5) # zero out output by storing 3 words (12 bytes) of zeros
sw $zero, 4($s5)
sw $zero, 8($s5)
jr $ra

# # Include your implementation here if you wish to run this from the MARS GUI.
# .include "impl.mips"

0 comments on commit c54c03a

Please sign in to comment.