Homework 1: Putting the U in Utility
Assigned: Tuesday, September 15, 2026
Due: Thursday, October 1, 2026 @ 11:59 PM
Ready to get your feet wet with some good Java practice?
This assignment will make sure that you’re comfortable with the following topics:
- Java functional programming (this assignment requires you to craft only functions)
- Clean programming practices (including documentation).
- Writing your own unit tests to verify proper functionality.
- Being able to code independently from a group and ensure that you’re all caught up on the course’s technical content.
Your Task
Implement a hodge-podge of puzzle-like functions that fit into two main Utility files for both Financial and String processing.
Differences from Classwork
- You must work on this assignment individually
- Programming style will be graded
- I have only furnished some of the grading unit tests that will decide your correctness score; you must learn to adequately test your own code, and will gain practice adding to the skeleton provided!
Before You Start
Aside from just the functionality of your code, you will also be graded on style. Writing code that is clean, readable, and follows standard convention is important, as it both helps other programmers better collaborate with you (and iterate on your work when you’ve moved on to another job or project), and communicates to them that you are an attentive and precise programmer.
And thus I am tasked with imparting upon you an understanding of clean code! Before you get started on this assignment, take a moment and read the Java Style Guide. Keep a bookmark, as it’ll help to refer back to it as you complete your assignment:
Solution Skeleton
Solution Skeleton
Start with the solution skeleton in-hand! The following will also serve as your submission mechanism (see submission instructions below).
Included in the skeleton are:
FinanceUtils.javaandStringUtils.javacontaining the skeletons of all exercises you’ll need for the classwork. Read on for more specifications of what to do herein.FinanceUtilsTests.javaandStringUtilsTests.javato validate your solutions for the two files named above. REMEMBER: these are not all of the tests you’ll be graded on - it’s up to you to predict edge cases and test for yourself to ensure your code is airtight. Feel free to modify these files to add your own tests.
junit.jar, a file required to run your tests. Do not touch this!.gitignorea set of patterns for git to avoid committing. You may modify this file if your commit attempts to add any project files to the repo (i.e. IntelliJ.ideaproject files or Java.classfiles, which should not be submitted)
Finance Utilities Specifications
Finance Utilities
The
FinanceUtils.javafile contains a couple of methods that are vaguely related to finances and will give you practice primarily with Java numerical processing and lists.
In particular, you must implement the following two functions in this file:
Problem 1
Problem:
getEvenRedistributionImplement the
public static int[] getEvenRedistribution (int[] amounts)method that, given a list of Array representing some quantities of something, returns a new Array containing the sum of items inamountsevenly distributed between indexes.
Such a function might be used in, e.g., a game’s inventory management system, in which some splittable quantity of items is desired to be divided into some number of roughly even stacks to distribute.
Notes & Hints
- In the ideal case, the sum of items are evenly redistributable between the number of indexes:
getEvenRedistribution({1, 2, 3})should return the 3 item Array{2, 2, 2}because the input list had 3 indexes with a sum of 6 items, 2 of which then belong to each index in the output list. - In the event that there are a sum of items to evenly distribute that do not evenly divide into the number of indexes, the remainder of items should be given to the largest (aka last) indexes first (because the last shall be first or something like that, I dunno there’s some lesson here):
getEvenRedistribution({1, 2, 5})has 8 items to redistribute into 3 indexes, so the output should be{2, 3, 3}because the largest indexes receive the residuals. - Remember the rules of Java integer and floating point operations (especially regarding division) to help you out here.
- Exceptions Raised: this function must throw an
IllegalArgumentExceptionif it receives an input list with any elements that are less than 0 (equal to 0 is OK).
Test Examples
public void getEvenRedistribution_t0() {
assertArrayEquals(new int[] {2, 2, 2}, getEvenRedistribution(new int[] {3, 2, 1}));
assertArrayEquals(new int[] {2, 2, 2}, getEvenRedistribution(new int[] {2, 2, 2}));
assertArrayEquals(new int[] {2, 2, 2}, getEvenRedistribution(new int[] {1, 2, 3}));
}
@Test
public void getEvenRedistribution_t1() {
assertArrayEquals(new int[] {2, 2, 2, 3}, getEvenRedistribution(new int[] {3, 2, 1, 3}));
assertArrayEquals(new int[] {2, 2, 3, 3}, getEvenRedistribution(new int[] {3, 2, 2, 3}));
assertArrayEquals(new int[] {2, 3, 3, 3}, getEvenRedistribution(new int[] {4, 2, 2, 3}));
assertArrayEquals(new int[] {3, 3, 3, 3}, getEvenRedistribution(new int[] {4, 3, 2, 3}));
}
// TODO: Your additional unit tests to verify correct functionality!Problem 2
Problem:
greedyChangemakerImplement the
public static int[] greedyChangemaker (int amount)function that, given some amount of cents, returns the minimal number of pennies (1¢), nickels (5¢), dimes (10¢), and quarters (25¢) that would be needed to make the desired amount. Returned as a 4-element Array of ints indicating:[numPennies, numNickels, numDimes, numQuarters](note those are just placeholders and need not correspond to any variable names).
Why the “greedy” part of greedyChangemaker? It turns out that this implementation is a type of algorithmic paradigm that you’ll learn more about later known as a “greedy” approach, which is just coincidence that it pertains to money in this context (and why I like this problem).
In general, “greedy” approaches are characterized by choosing the largest / best / biggest option first before trying subsequent options. In our context, that means making change with the minimal number of coins starts first by trying to take as many quarters as possible, then trying to make the remainder with as many dimes, then nickels, etc.
Notes & Hints
- For example,
greedyChangemaker(6)asks “how many coins of each denomination are minimally required to make 6 cents in change?” The solution should be 1 penny and 1 nickel, which would be returned in array-format as:[1, 1, 0, 0](note the format above). - Consider making a constant array of the denomination amounts as they correspond to the indexes in the returned array.
- Similar to the first function, you’ll find the int operations of integer division and modulus to be useful here.
- Error Throws: this function must throw an
IllegalArgumentExceptionif it receives an input amount that is less than 0 (equal to 0 is OK).
Test Examples
@Test
public void greedyChangemaker_t0() {
assertArrayEquals(new int[] {1, 0, 0, 0}, greedyChangemaker(1));
assertArrayEquals(new int[] {0, 1, 0, 0}, greedyChangemaker(5));
assertArrayEquals(new int[] {0, 0, 1, 0}, greedyChangemaker(10));
assertArrayEquals(new int[] {0, 0, 0, 1}, greedyChangemaker(25));
}
@Test
public void greedyChangemaker_t1() {
assertArrayEquals(new int[] {3, 0, 0, 0}, greedyChangemaker(3));
assertArrayEquals(new int[] {0, 0, 2, 0}, greedyChangemaker(20));
}
// TODO: Your additional unit tests to verify correct functionality!String Utilities Specifications
Problem 3
Problem:
hasSequenceImplement the
public static boolean hasSequence (String corpus, String query)function, which returns true if the characters in the givenqueryString are found in-sequence in the givencorpusString, though possibly with other characters in between.
Sequences like those that this function will help with will also be covered in your Algorithms course, and are useful in a variety of contexts like computational biology, wherein parts of some genetic sequence of codons (G, T, A, C) may be of interest.
This function will be a less sophisticated version of the above, which we’ll expand on in the follow-on course to this one.
Notes & Hints
- As a simple example, consider that
hasSequence("XAXBXC", "ABC")will returntruebecause the query String, “ABC” appears with its letters in order (though with other letters, ‘X’, in between) in the corpus String, “XAXBXC”. Conversely,hasSequence("XCXBXA", "ABC")will returnfalsebecause the query’s characters are not found in the same sequence within the corpus. - Try using
toCharArray()to break yourcorpusstring up into individual characters to iterate through. - Don’t overthink this one; a single loop with a counter for the found letters in the query are all that’s required to solve successfully.
- For this function, exact matches of characters are required to be part of a sequence. For example,
hasSequence("ABC", "abc")would returnFalsebecause the cases of the characters in the query and corpus are different. - Empty strings are allowed for both parameters. As an edge case, the empty-query
query = ""should return true regardless of what’s in the corpus (even if the corpus is empty too). - This function throws no exceptions.
Test Examples
public void hasSequence_t0() {
assertTrue(hasSequence("GGGG", "GG"));
assertTrue(hasSequence("GTGTGTG", "GG"));
}
@Test
public void hasSequence_t1() {
assertFalse(hasSequence("GTC", "CGT"));
assertFalse(hasSequence("TTT", "TTTT"));
}
@Test
public void hasSequence_t2() {
assertTrue(hasSequence("CCCC", "CC"));
assertTrue(hasSequence("CGATTAGC", "CATTC"));
}
// TODO: Your additional unit tests to verify correct functionality!Problem 4
Problem:
sentCapImplement the
public static String sentCap (String sents)function, which takes a String of sentences (plural) as input, and returns a new String with the first letter of any word following a period.capitalized.
Let’s make some auto-correct function that applies all of that obnoxious auto-capitalization!
Notes & Hints
- For example,
sentCap("This. example. rocks.")would return the String"This. Example. Rocks." - You’ll find the following methods useful for your implementation: Strings’
toCharArray()and theCharacter.toUpperCase(). Google the Java documentation to see how to use these if you’re not sure! (you might use other methods too in your implementation, these are just the ones you might not have used or heard-of before). - Your implementation should still work even if there are multiple spaces between a period and the next word (see test
t2below). - You may assume that there will be no special or numerical characters in the input String; just good, old fashioned, letters, spaces, and periods.
- The empty String is permitted for the input sentence, as are sentences with only spaces.
- Only words that follow a period get capitalized. The first word of the String follows no period, so leave it exactly as you found it. For example,
sentCap("hello. world.")returns"hello. World."— “world” is capitalized because it follows a period, but “hello” is not, because nothing precedes it. - This function raises no errors.
Test Examples
@Test
public void sentCap_t0() {
assertEquals("Yo.", sentCap("Yo."));
}
@Test
public void sentCap_t1() {
assertEquals("Hello. My name is Java.", sentCap("Hello. my name is Java."));
}
@Test
public void sentCap_t2() {
assertEquals("I. Like. Spaces.", sentCap("I. like. spaces."));
}
// TODO: Your additional unit tests to verify correct functionality!Problem 5
Problem:
getNthMatchImplement the
public static String getNthMatch (String sent, String query, int n)function, which searches the givensentfor thenthmatch of the givenqueryword, independent of the capitalization of the matched word.
Think of this like a mini version of the CTRL+F or CMD+F “find” tools in many text processors, where you have the ability to scroll between / find any of n matches to a given query!
Notes & Hints
- For example,
getNthMatch("test Test tEsT", "test", n)will return"test"ifn=0(since it’s a first match of the query word),"Test"ifn=1(even though there is a case mis-match, it’s still the same word), and"tEsT"ifn=2. - If either the query word does not exist in the sent, or it does but the requested
nis beyond the number of matches (e.g.,n=3in the example above), then the function returns rovnull. - You might find a String’s
toLowerCase()method useful for normalizing the cases of compared Strings for matches. Note that both the givensentorqueryString may have cases of letters being unequal but still being considered a match. - Exceptions raised: this function must throw an
IllegalArgumentExceptionif either the inputqueryString is empty or the requestednis less than 0.
Test Examples
@Test
public void getNthMatch_t0() {
assertEquals("test", getNthMatch("test test test", "test", 0));
assertEquals("test", getNthMatch("test test test", "test", 1));
assertEquals("test", getNthMatch("test test test", "test", 2));
assertEquals(null, getNthMatch("test test test", "test", 3));
}
@Test
public void getNthMatch_t1() {
assertEquals("test", getNthMatch("test Test tEsT", "test", 0));
assertEquals("Test", getNthMatch("test Test tEsT", "test", 1));
assertEquals("tEsT", getNthMatch("test Test tEsT", "test", 2));
assertEquals(null, getNthMatch("test Test tEsT", "test", 3));
}
@Test
public void getNthMatch_t2() {
assertEquals(null, getNthMatch("test Test tEsT", "notest", 1));
}
// TODO: Your additional unit tests to verify correct functionality!Testing and Documentation
Problem 6
Write Your Own Tests
Although I won’t penalize you for not writing additional unit tests, you should almost certainly add some to the bare-bones skeleton that I provide to you to ensure that your code works as expected!
Disclaimer: the unit tests I provide to you in the skeleton are only a portion of the grading tests; this is a nontrivial assignment and there are lots of places and edge cases where things can go wrong, or where you may miss an aspect of the spec. As such, ensure that you test as many edge cases as possible to give yourself confidence of a higher grade, and more importantly, to gain the invaluable practice of writing good QA tests!
Pursuant to that, I’ve written up a detailed guide to how to write and design Unit Tests in Java:
Here are some good pieces of advice for writing effective unit tests:
- Test for the easy stuff first — e.g., on
greedyChangemaker, the first tests I gave you are those that verify the most efficient way to make each of the coin denominations is with a single coin. This will also give you a much needed boost of confidence, like making “Make TODO List” an item you get to check off from your TODO list. - If you find a bug, write a unit test that explicitly reveals that issue — as in, write it immediately before you’ve even solved the bug — this will help you to not forget it and ensures that, if you make later changes, it remains a test to make sure you don’t unsolve an issue.
- Use the “zero-one-infinity” principle to test with various values, which roughly means to make sure that you test for cases with empty inputs, a single input, and then multiple. E.g., on functions that accept Strings, validate that they work for empty Strings (or properly throw exceptions, where appropriate), Strings with a single character, and then Strings with multiple characters. Similar can apply to arrays, or numerical inputs with values of (literally) 0, 1, and then 2+.
- Identify “edge cases” where conditions may be needed to properly solve some input, and then write tests for these. E.g.,
sentCap’s 3rd test makes sure that it still works if there are multiple spaces following a period. - Test that every error is raised properly where expected, like in the CW1 tests.
- Ensure that all paths of control flow get tested, e.g., if you have an if-conditional that may only activate for certain inputs, make sure that you have a corresponding unit test testing for it. This is what’s called test coverage.
Additionally, you should provide function-level comments for each implemented function to receive full style credit.
All stylistic aspects of your submission will be graded (as these stylistic choices may influence job interviewers significantly in the “real world!”), and you can review the Java style guide for things to look out for here: Java Style Guide
Solution Restrictions
Submission Restrictions
Read the following list of submission restrictions carefully! Violating any restriction will net you a 0 on this homework!
- You may not import any Java packages/utils/etc. Most of all no Java Collections!
- Your source files must be named exactly as intimated above (as is in the Solution Skeleton), and you MUST submit your files under the same file structure as the one given (i.e., don’t touch the file structure of the skeleton).
- RECALL: As a homework assignment, you are free to discuss approaches at the high-level in groups so long as no code is shared between individuals. We use sophisticated similarity checking software to detect copying, so just do your own work!
- The same applies to using code written by ChatGPT or any other generative AI model!
Be Wary
Even sharing any code snippets will cause red flags — consider this fair warning, do not share any code! If you feel tempted to do so, contact me or a TA instead — we’re happy to help, so long as you give yourself enough time to work with us (so start early!).
Hints and Tips
The implementation of this assignment requires you to make some design decisions. However, here are some hints for how you might structure your own.
- Feeling unsteady in Java? There are some great resources here to learn Java and reference in case you forgot some syntax! I would specifically recommend the Java Language Basics section.
- Read the spec then re-read it — make sure you have a solid grasp on both the big and little picture before writing any code!
- Consider making helper methods — these can reduce complex code to more readable segments that better organize your thoughts, and can be used to keep your code DRY (in the case of behavior that is repeated or could benefit from the clarity of being labeled).
- Develop incrementally. I cannot impress this enough. Implement one method, ensure that it’s working with unit tests, make a commit, and then move on to the next… don’t code a bunch at once and then try to disentangle the errors after hours of work!
- Stuck on a bug? Draw things out, and remember that you can run individual unit tests to debug a particular case that’s haunting you.
- Do. Not. Wait. Give yourself ample time to complete this assignment — it may appear trivial but has some trickiness to it that may require you to spend lots of time debugging! As a veteran programmer, I cannot tell you how many bugs I’ve solved by just going to bed and waking up with a solution — however, this takes time before a deadline to be effective.
- Commit your code often! Saving your progress with well written commit messages will help you know where you left off when you pick the code back up later!
Submission
Info
You will be submitting your assignments through GitHub Classroom!
What
Complete the source files that accomplishes the specification above in the project structure given in the skeleton.
How
To clone this assignment (if you need a refresher), consult the guide here: GitHub Classroom Tutorial
To submit this assignment:
- Simply push your final, submission copy to the GitHub Classroom repository associated with your GitHub classroom account.
- Make sure that your name is commented as the author at the top of each submitted file AND in the accompanying
README.mdfile.