Skip to content
Merged
2 changes: 0 additions & 2 deletions concepts/chars/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ The Java `char` type represents the smallest addressable components of text.
Multiple `char`s can comprise a string such as `"word"` or `char`s can be processed independently.
Their literals have single quotes e.g. `'A'`.

Java `char`s support Unicode encoding so in addition to the Latin character set pretty much all the writing systems in use worldwide can be represented, e.g. the Greek letter `'β'`.

There are many builtin library methods to inspect and manipulate `char`s.
These can be found as static methods of the `java.lang.Character` class.

Expand Down
18 changes: 7 additions & 11 deletions exercises/concept/squeaky-clean/.docs/hints.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,23 @@
- See [this method][iswhitespace] for detecting spaces. Remember it is a static method.
- `char` literals are enclosed in single quotes.

## 2. Replace control characters with the upper case string "CTRL"

- See [this method][iscontrol] to check if a character is a control character.

## 3. Convert kebab-case to camel-case
## 2. Convert kebab-case to camel-case

- See [this method][toupper] to convert a character to upper case.

## 4. Omit characters that are not letters
## 3. Convert leetspeak to normal text

- See [this method][isLetter] to check if a character is a letter.
- See [this method][isdigit] for detecting numbers.

## 5. Omit Greek lower case letters
## 4. Omit characters that are not letters

- `char`s support the default equality and comparison operators.
- See [this method][isletter] to check if a character is a letter.

[chars-docs]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Character.html
[chars-tutorial]: https://docs.oracle.com/javase/tutorial/java/data/characters.html
[char-at]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/String.html#charAt(int)
[string-builder]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/StringBuilder.html
[iswhitespace]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Character.html#isWhitespace(char)
[iscontrol]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Character.html#isISOControl(char)
[toupper]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Character.html#toUpperCase(char)
[isLetter]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Character.html#isLetter(char)
[isletter]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Character.html#isLetter(char)
[isdigit]: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/lang/Character.html#isDigit(char)
28 changes: 11 additions & 17 deletions exercises/concept/squeaky-clean/.docs/instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,38 +17,32 @@ SqueakyClean.clean("my Id");
// => "my___Id"
```

## 2. Replace control characters with the upper case string "CTRL"
## 2. Convert kebab-case to camelCase

Modify the (_static_) `SqueakyClean.clean()` method to replace control characters with the upper case string `"CTRL"`.
Modify the (_static_) `SqueakyClean.clean()` method to convert kebab-case to camelCase.

```java
SqueakyClean.clean("my\0Id");
// => "myCTRLId",
SqueakyClean.clean("a-bc");
// => "aBc"
```

## 3. Convert kebab-case to camelCase
## 3. Convert leetspeak to normal text

Modify the (_static_) `SqueakyClean.clean()` method to convert kebab-case to camelCase.
Modify the (_static_) `SqueakyClean.clean()` method to convert [leetspeak][leet-speak] to normal text.
For simplicity we will only be using `4`, `3`, `0`, `1` and `7` from the table.

```java
SqueakyClean.clean("à-ḃç");
// => "àḂç"
SqueakyClean.clean("H3ll0 W0rld");
// => "Hello_World"
```

## 4. Omit characters that are not letters

Modify the (_static_) `SqueakyClean.clean()` method to omit any characters that are not letters.

```java
SqueakyClean.clean("a1😀2😀3😀b");
SqueakyClean.clean("a$#.b");
// => "ab"
```

## 5. Omit Greek lower case letters

Modify the (_static_) `SqueakyClean.clean()` method to omit any Greek letters in the range 'α' to 'ω'.

```java
SqueakyClean.clean("MyΟβιεγτFinder");
// => "MyΟFinder"
```
[leet-speak]: https://en.wikipedia.org/wiki/Leet
2 changes: 0 additions & 2 deletions exercises/concept/squeaky-clean/.docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ The Java `char` type represents the smallest addressable components of text.
Multiple `char`s can comprise a string such as `"word"` or `char`s can be processed independently.
Their literals have single quotes e.g. `'A'`.

Java `char`s support Unicode encoding so in addition to the Latin character set pretty much all the writing systems in use worldwide can be represented, e.g. the Greek letter `'β'`.

There are many builtin library methods to inspect and manipulate `char`s.
These can be found as static methods of the `java.lang.Character` class.

Expand Down
4 changes: 4 additions & 0 deletions exercises/concept/squeaky-clean/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
"authors": [
"ystromm"
],
"contributors": [
"sanderploegsma",
"manumafe98"
],
"files": {
"solution": [
"src/main/java/SqueakyClean.java"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
class SqueakyClean {

private static char replaceDigit(char digit) {
if (digit == '3') {
return 'e';
}

if (digit == '4') {
return 'a';
}

if (digit == '0') {
return 'o';
}

if (digit == '1') {
return 'l';
}
return 't';
}

static String clean(String identifier) {
final StringBuilder cleanIdentifier = new StringBuilder();
boolean kebab = false;
for (int i = 0; i < identifier.length(); i++) {
final char ch = identifier.charAt(i);
if (Character.isSpaceChar(ch)) {
cleanIdentifier.append("_");
} else if (Character.isISOControl(ch)) {
cleanIdentifier.append("CTRL");
} else if (Character.isDigit(ch)) {
cleanIdentifier.append(SqueakyClean.replaceDigit(ch));
} else if (ch == '-') {
kebab = true;
} else if (isLetter(ch)) {
} else if (Character.isLetter(ch)) {
cleanIdentifier.append(
kebab ? Character.toUpperCase(ch) : ch
);
Expand All @@ -19,7 +39,4 @@ static String clean(String identifier) {
}
return cleanIdentifier.toString();
}
private static boolean isLetter(char ch) {
return Character.isLetter(ch) && !(ch >= 'α' && ch <= 'ω');
}
}
54 changes: 27 additions & 27 deletions exercises/concept/squeaky-clean/src/test/java/SqueakyCleanTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void single_letter() {
@Tag("task:1")
@DisplayName("The clean method returns the same string when invoked on a string of three letters")
public void string() {
assertThat(SqueakyClean.clean("àḃç")).isEqualTo("àḃç");
assertThat(SqueakyClean.clean("abc")).isEqualTo("abc");
}

@Test
Expand All @@ -43,50 +43,50 @@ public void leading_and_trailing_spaces() {

@Test
@Tag("task:2")
@DisplayName("The clean method replaces control characters with CTRL")
public void ctrl() {
assertThat(SqueakyClean.clean("my\0\r\u007FId")).isEqualTo("myCTRLCTRLCTRLId");
@DisplayName("The clean method converts kebab to camel case after removing a dash")
public void kebab_to_camel_case() {
assertThat(SqueakyClean.clean("a-bc")).isEqualTo("aBc");
}

@Test
@Tag("task:4")
@DisplayName("The clean method returns an empty string when invoked on a string with no letters")
public void string_with_no_letters() {
assertThat(SqueakyClean.clean("\uD83D\uDE00\uD83D\uDE00\uD83D\uDE00")).isEmpty();
@Tag("task:2")
@DisplayName("The clean method returns a string in camel case after removing a dash and replaces a whitespace")
public void kebab_to_camel_case_and_number() {
assertThat(SqueakyClean.clean("a-C ")).isEqualTo("aC_");
}

@Test
@Tag("task:3")
@DisplayName("The clean method converts kebab to camel case after removing a dash")
public void kebab_to_camel_case() {
assertThat(SqueakyClean.clean("à-ḃç")).isEqualTo("àḂç");
@Tag("task:2")
@DisplayName("The clean method returns a string in camel case and replaces leading and trailing whitespaces")
public void kebab_to_camel_case_and_spaces() {
assertThat(SqueakyClean.clean(" hello-world ")).isEqualTo("_helloWorld_");
}

@Test
@Tag("task:3")
@DisplayName("The clean method returns a string in camel case after removing a dash and a number")
public void kebab_to_camel_case_no_letter() {
assertThat(SqueakyClean.clean("a-1C")).isEqualTo("aC");
@DisplayName("The clean method converts leetspeak to normal text after replacing numbers with chars")
public void leetspeak_to_normal_text() {
assertThat(SqueakyClean.clean("H3ll0 W0rld")).isEqualTo("Hello_World");
}

@Test
@Tag("task:4")
@DisplayName("The clean method removes all characters that are not letters")
public void keep_only_letters() {
assertThat(SqueakyClean.clean("a1\uD83D\uDE002\uD83D\uDE003\uD83D\uDE00b")).isEqualTo("ab");
@Tag("task:3")
@DisplayName("The clean method converts leetspeak to normal text with spaces and special characters")
public void leetspeak_to_normal_text_with_spaces_and_special_characters() {
assertThat(SqueakyClean.clean("¡1337sp34k is fun!")).isEqualTo("leetspeak_is_fun");
}

@Test
@Tag("task:5")
@DisplayName("The clean method removes all lowercase greek letters")
public void omit_lower_case_greek_letters() {
assertThat(SqueakyClean.clean("MyΟβιεγτFinder")).isEqualTo("MyΟFinder");
@Tag("task:4")
@DisplayName("The clean method removes all characters that are not letters")
public void special_characters() {
assertThat(SqueakyClean.clean("a$#.b")).isEqualTo("ab");
}

@Test
@Tag("task:5")
@DisplayName("The clean method returns the correct result after performing a few cleaning operations")
public void combine_conversions() {
assertThat(SqueakyClean.clean("9 -abcĐ\uD83D\uDE00ω\0")).isEqualTo("_AbcĐCTRL");
@Tag("task:4")
@DisplayName("The clean method removes all characters that are not letters and replaces spaces")
public void special_characters_and_spaces() {
assertThat(SqueakyClean.clean("¡hello world!. ")).isEqualTo("hello_world_");
}
}