Skip to content

Commit

Permalink
Add pangram exercise (#201)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode authored Jan 9, 2024
1 parent e4e96c7 commit 8225fb8
Show file tree
Hide file tree
Showing 10 changed files with 267 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,14 @@
"difficulty": 3,
"topics": []
},
{
"slug": "pangram",
"name": "Pangram",
"uuid": "4a772784-2896-4c70-a2b0-71d45f302261",
"practices": [],
"prerequisites": [],
"difficulty": 3
},
{
"slug": "nucleotide-count",
"name": "Nucleotide Count",
Expand Down
6 changes: 6 additions & 0 deletions exercises/practice/pangram/.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
9 changes: 9 additions & 0 deletions exercises/practice/pangram/.docs/instructions.append.md
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 |
| `$v0` | output | boolean | input is a pangram (`0` = `false`, `1` = `true`) |
| `$t0-9` | temporary | any | used for temporary storage |
8 changes: 8 additions & 0 deletions exercises/practice/pangram/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Instructions

Your task is to figure out if a sentence is a pangram.

A pangram is a sentence using every letter of the alphabet at least once.
It is case insensitive, so it doesn't matter if a letter is lower-case (e.g. `k`) or upper-case (e.g. `K`).

For this exercise, a sentence is a pangram if it contains each of the 26 letters in the English alphabet.
16 changes: 16 additions & 0 deletions exercises/practice/pangram/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Introduction

You work for a company that sells fonts through their website.
They'd like to show a different sentence each time someone views a font on their website.
To give a comprehensive sense of the font, the random sentences should use **all** the letters in the English alphabet.

They're running a competition to get suggestions for sentences that they can use.
You're in charge of checking the submissions to see if they are valid.

~~~~exercism/note
Pangram comes from Greek, παν γράμμα, pan gramma, which means "every letter".
The best known English pangram is:
> The quick brown fox jumps over the lazy dog.
~~~~
19 changes: 19 additions & 0 deletions exercises/practice/pangram/.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": "Determine if a sentence is a pangram.",
"source": "Wikipedia",
"source_url": "https://en.wikipedia.org/wiki/Pangram"
}
39 changes: 39 additions & 0 deletions exercises/practice/pangram/.meta/example.mips
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Determine if the given string is an pangram, meaning that every letter appears at least once.
#
# Strategy: use the bits of a single word to represent set of encountered letters
#
# $a0 - input, pointer to null-terminated string
# $v0 - output, boolean representing is or is not pangram
# $t0 - set of bits
# $t1 - 1
# $t2 - an encountered character
# $t3 - 'a'
# $t4 - 'z'

.globl is_pangram

is_pangram:
move $t0, $zero # Reset set to 0.
li $t1, 1
li $t3, 'a'
li $t4, 'z'
j load

loop:
ori $t2, 32 # downcase
blt $t2, $t3, increment # If less than 'a', continue to next letter.
bgt $t2, $t4, increment # If greater than 'z', continue to next letter.
sub $t2, $t2, $t3 # Calculate letter's position in alphabet.
sllv $t2, $t1, $t2 # Create bit mask
or $t0, $t0, $t2 # Apply to set.

increment:
addi $a0, $a0, 1 # Finally, increment the pointer

load:
lb $t2, 0($a0) # Load a character,
bne $t2, $zero, loop # if not end of string, continue.

li $t2, 0x3ffffff # (2 ** 26) - 1
seq $v0, $t0, $t2 # Does $t0 have all 26 letter bits set?
jr $ra
45 changes: 45 additions & 0 deletions exercises/practice/pangram/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# 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.

[64f61791-508e-4f5c-83ab-05de042b0149]
description = "empty sentence"

[74858f80-4a4d-478b-8a5e-c6477e4e4e84]
description = "perfect lower case"

[61288860-35ca-4abe-ba08-f5df76ecbdcd]
description = "only lower case"

[6564267d-8ac5-4d29-baf2-e7d2e304a743]
description = "missing the letter 'x'"

[c79af1be-d715-4cdb-a5f2-b2fa3e7e0de0]
description = "missing the letter 'h'"

[d835ec38-bc8f-48e4-9e36-eb232427b1df]
description = "with underscores"

[8cc1e080-a178-4494-b4b3-06982c9be2a8]
description = "with numbers"

[bed96b1c-ff95-45b8-9731-fdbdcb6ede9a]
description = "missing letters replaced by numbers"

[938bd5d8-ade5-40e2-a2d9-55a338a01030]
description = "mixed case and punctuation"

[2577bf54-83c8-402d-a64b-a2c0f7bb213a]
description = "case insensitive"
include = false

[7138e389-83e4-4c6e-8413-1e40a0076951]
description = "a-m and A-M are 26 different characters but not a pangram"
reimplements = "2577bf54-83c8-402d-a64b-a2c0f7bb213a"
10 changes: 10 additions & 0 deletions exercises/practice/pangram/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 |
# | `$v0` | output | boolean | input is a pangram (`0` = `false`, `1` = `true`) |
# | `$t0-9` | temporary | any | used for temporary storage |

.globl is_pangram

is_pangram:
jr $ra
107 changes: 107 additions & 0 deletions exercises/practice/pangram/runner.mips
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#
# Test is_pangram with some examples
#
# s0 - num of tests left to run
# s1 - address of input string
# s2 - address of expected output word
# s3 - char byte
# s4 - expected output word

.data

# number of test cases
n: .word 10
# input values (null terminated)
ins: .asciiz
"",
"abcdefghijklmnopqrstuvwxyz",
"the quick brown fox jumps over the lazy dog",
"a quick movement of the enemy will jeopardize five gunboats",
"five boxing wizards jump quickly at it",
"the_quick_brown_fox_jumps_over_the_lazy_dog",
"the 1 quick brown fox jumps over the 2 lazy dogs",
"7h3 qu1ck brown fox jumps ov3r 7h3 lazy dog",
"\"Five quacking Zephyrs jolt my wax bed.\"",
"abcdefghijklm ABCDEFGHIJKLM"
# expected output values (word sized ints)
outs: .word
0,
1,
1,
0,
0,
1,
1,
0,
1,
0

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_pangram # 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:
lb $s3, 0($s1) # load byte
addi $s1, $s1, 1 # move input address on byte forward
bne $s3, $zero, scan # if char not null, continue loop

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"

0 comments on commit 8225fb8

Please sign in to comment.