Skip to content

Commit dc44239

Browse files
authored
feat: add pig-latin exercise (#812)
1 parent 378cfac commit dc44239

File tree

12 files changed

+18274
-0
lines changed

12 files changed

+18274
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1168,6 +1168,14 @@
11681168
"practices": [],
11691169
"prerequisites": [],
11701170
"difficulty": 5
1171+
},
1172+
{
1173+
"slug": "pig-latin",
1174+
"name": "Pig Latin",
1175+
"uuid": "e4242a6e-3611-4f49-890b-368f1ebbdc94",
1176+
"practices": [],
1177+
"prerequisites": [],
1178+
"difficulty": 4
11711179
}
11721180
],
11731181
"foregone": [
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Instructions
2+
3+
Implement a program that translates from English to Pig Latin.
4+
5+
Pig Latin is a made-up children's language that's intended to be confusing.
6+
It obeys a few simple rules (below), but when it's spoken quickly it's really difficult for non-children (and non-native speakers) to understand.
7+
8+
- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to the end of the word.
9+
Please note that "xr" and "yt" at the beginning of a word make vowel sounds (e.g. "xray" -> "xrayay", "yttria" -> "yttriaay").
10+
- **Rule 2**: If a word begins with a consonant sound, move it to the end of the word and then add an "ay" sound to the end of the word.
11+
Consonant sounds can be made up of multiple consonants, such as the "ch" in "chair" or "st" in "stand" (e.g. "chair" -> "airchay").
12+
- **Rule 3**: If a word starts with a consonant sound followed by "qu", move it to the end of the word, and then add an "ay" sound to the end of the word (e.g. "square" -> "aresquay").
13+
- **Rule 4**: If a word contains a "y" after a consonant cluster or as the second letter in a two letter word it makes a vowel sound (e.g. "rhythm" -> "ythmrhay", "my" -> "ymay").
14+
15+
There are a few more rules for edge cases, and there are regional variants too.
16+
Check the tests for all the details.
17+
18+
Read more about [Pig Latin on Wikipedia][pig-latin].
19+
20+
[pig-latin]: https://en.wikipedia.org/wiki/Pig_latin
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"authors": [
3+
"vaeng"
4+
],
5+
"files": {
6+
"solution": [
7+
"pig_latin.cpp",
8+
"pig_latin.h"
9+
],
10+
"test": [
11+
"pig_latin_test.cpp"
12+
],
13+
"example": [
14+
".meta/example.cpp",
15+
".meta/example.h"
16+
]
17+
},
18+
"blurb": "Implement a program that translates from English to Pig Latin.",
19+
"source": "The Pig Latin exercise at Test First Teaching by Ultrasaurus",
20+
"source_url": "https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/"
21+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include "pig_latin.h"
2+
3+
namespace pig_latin {
4+
std::string translate_word(const std::string& word) {
5+
for (const std::string start : {"a", "e", "i", "o", "u", "yt", "xr"}) {
6+
if (word.substr(0, start.size()) == start) return word + "ay";
7+
}
8+
for (const std::string start : {"thr", "sch", "squ", "ch", "qu", "th", "rh"}) {
9+
if (word.substr(0, start.size()) == start)
10+
return word.substr(start.size()) + start + "ay";
11+
}
12+
return word.substr(1) + word.front() + "ay";
13+
}
14+
15+
std::string translate(const std::string& phrase) {
16+
size_t start = 0;
17+
std::string translation{};
18+
for (size_t found = phrase.find(' '); found != std::string::npos;
19+
found = phrase.find(' ', start)) {
20+
translation += translate_word(phrase.substr(start, found - start)) + " ";
21+
start = found + 1;
22+
}
23+
if (start != phrase.size())
24+
translation += translate_word(phrase.substr(start));
25+
26+
return translation;
27+
}
28+
} // namespace pig_latin
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include <string>
4+
#include <string_view>
5+
6+
namespace pig_latin {
7+
std::string translate(const std::string& phrase);
8+
9+
} // namespace pig_latin
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[11567f84-e8c6-4918-aedb-435f0b73db57]
13+
description = "ay is added to words that start with vowels -> word beginning with a"
14+
15+
[f623f581-bc59-4f45-9032-90c3ca9d2d90]
16+
description = "ay is added to words that start with vowels -> word beginning with e"
17+
18+
[7dcb08b3-23a6-4e8a-b9aa-d4e859450d58]
19+
description = "ay is added to words that start with vowels -> word beginning with i"
20+
21+
[0e5c3bff-266d-41c8-909f-364e4d16e09c]
22+
description = "ay is added to words that start with vowels -> word beginning with o"
23+
24+
[614ba363-ca3c-4e96-ab09-c7320799723c]
25+
description = "ay is added to words that start with vowels -> word beginning with u"
26+
27+
[bf2538c6-69eb-4fa7-a494-5a3fec911326]
28+
description = "ay is added to words that start with vowels -> word beginning with a vowel and followed by a qu"
29+
30+
[e5be8a01-2d8a-45eb-abb4-3fcc9582a303]
31+
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with p"
32+
33+
[d36d1e13-a7ed-464d-a282-8820cb2261ce]
34+
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with k"
35+
36+
[d838b56f-0a89-4c90-b326-f16ff4e1dddc]
37+
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with x"
38+
39+
[bce94a7a-a94e-4e2b-80f4-b2bb02e40f71]
40+
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with q without a following u"
41+
42+
[c01e049a-e3e2-451c-bf8e-e2abb7e438b8]
43+
description = "some letter clusters are treated like a single consonant -> word beginning with ch"
44+
45+
[9ba1669e-c43f-4b93-837a-cfc731fd1425]
46+
description = "some letter clusters are treated like a single consonant -> word beginning with qu"
47+
48+
[92e82277-d5e4-43d7-8dd3-3a3b316c41f7]
49+
description = "some letter clusters are treated like a single consonant -> word beginning with qu and a preceding consonant"
50+
51+
[79ae4248-3499-4d5b-af46-5cb05fa073ac]
52+
description = "some letter clusters are treated like a single consonant -> word beginning with th"
53+
54+
[e0b3ae65-f508-4de3-8999-19c2f8e243e1]
55+
description = "some letter clusters are treated like a single consonant -> word beginning with thr"
56+
57+
[20bc19f9-5a35-4341-9d69-1627d6ee6b43]
58+
description = "some letter clusters are treated like a single consonant -> word beginning with sch"
59+
60+
[54b796cb-613d-4509-8c82-8fbf8fc0af9e]
61+
description = "some letter clusters are treated like a single vowel -> word beginning with yt"
62+
63+
[8c37c5e1-872e-4630-ba6e-d20a959b67f6]
64+
description = "some letter clusters are treated like a single vowel -> word beginning with xr"
65+
66+
[a4a36d33-96f3-422c-a233-d4021460ff00]
67+
description = "position of y in a word determines if it is a consonant or a vowel -> y is treated like a consonant at the beginning of a word"
68+
69+
[adc90017-1a12-4100-b595-e346105042c7]
70+
description = "position of y in a word determines if it is a consonant or a vowel -> y is treated like a vowel at the end of a consonant cluster"
71+
72+
[29b4ca3d-efe5-4a95-9a54-8467f2e5e59a]
73+
description = "position of y in a word determines if it is a consonant or a vowel -> y as second letter in two letter word"
74+
75+
[44616581-5ce3-4a81-82d0-40c7ab13d2cf]
76+
description = "phrases are translated -> a whole phrase"
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Get the exercise name from the current directory
2+
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME)
3+
4+
# Basic CMake project
5+
cmake_minimum_required(VERSION 3.5.1)
6+
7+
# Name the project after the exercise
8+
project(${exercise} CXX)
9+
10+
# Get a source filename from the exercise name by replacing -'s with _'s
11+
string(REPLACE "-" "_" file ${exercise})
12+
13+
# Implementation could be only a header
14+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp)
15+
set(exercise_cpp ${file}.cpp)
16+
else()
17+
set(exercise_cpp "")
18+
endif()
19+
20+
# Use the common Catch library?
21+
if(EXERCISM_COMMON_CATCH)
22+
# For Exercism track development only
23+
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $<TARGET_OBJECTS:catchlib>)
24+
elseif(EXERCISM_TEST_SUITE)
25+
# The Exercism test suite is being run, the Docker image already
26+
# includes a pre-built version of Catch.
27+
find_package(Catch2 REQUIRED)
28+
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h)
29+
target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain)
30+
# When Catch is installed system wide we need to include a different
31+
# header, we need this define to use the correct one.
32+
target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE)
33+
else()
34+
# Build executable from sources and headers
35+
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp)
36+
endif()
37+
38+
set_target_properties(${exercise} PROPERTIES
39+
CXX_STANDARD 17
40+
CXX_STANDARD_REQUIRED OFF
41+
CXX_EXTENSIONS OFF
42+
)
43+
44+
set(CMAKE_BUILD_TYPE Debug)
45+
46+
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)")
47+
set_target_properties(${exercise} PROPERTIES
48+
COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror"
49+
)
50+
endif()
51+
52+
# Configure to run all the tests?
53+
if(${EXERCISM_RUN_ALL_TESTS})
54+
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS)
55+
endif()
56+
57+
# Tell MSVC not to warn us about unchecked iterators in debug builds
58+
if(${MSVC})
59+
set_target_properties(${exercise} PROPERTIES
60+
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS)
61+
endif()
62+
63+
# Run the tests on every build
64+
add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise})
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#include "pig_latin.h"
2+
3+
namespace pig_latin {
4+
5+
} // namespace pig_latin
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#pragma once
2+
3+
namespace pig_latin {
4+
5+
} // namespace pig_latin
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include "pig_latin.h"
2+
#ifdef EXERCISM_TEST_SUITE
3+
#include <catch2/catch.hpp>
4+
#else
5+
#include "test/catch.hpp"
6+
#endif
7+
8+
9+
TEST_CASE("word beginning with a", "[11567f84-e8c6-4918-aedb-435f0b73db57]") {
10+
REQUIRE("appleay" == pig_latin::translate("apple"));
11+
}
12+
13+
#if defined(EXERCISM_RUN_ALL_TESTS)
14+
15+
TEST_CASE("word beginning with e", "[f623f581-bc59-4f45-9032-90c3ca9d2d90]") {
16+
REQUIRE("earay" == pig_latin::translate("ear"));
17+
}
18+
19+
TEST_CASE("word beginning with i", "[7dcb08b3-23a6-4e8a-b9aa-d4e859450d58]") {
20+
REQUIRE("iglooay" == pig_latin::translate("igloo"));
21+
}
22+
23+
TEST_CASE("word beginning with o", "[0e5c3bff-266d-41c8-909f-364e4d16e09c]") {
24+
REQUIRE("objectay" == pig_latin::translate("object"));
25+
}
26+
27+
TEST_CASE("word beginning with u", "[614ba363-ca3c-4e96-ab09-c7320799723c]") {
28+
REQUIRE("underay" == pig_latin::translate("under"));
29+
}
30+
31+
TEST_CASE("word beginning with a vowel and followed by a qu", "[bf2538c6-69eb-4fa7-a494-5a3fec911326]") {
32+
REQUIRE("equalay" == pig_latin::translate("equal"));
33+
}
34+
35+
TEST_CASE("word beginning with p", "[e5be8a01-2d8a-45eb-abb4-3fcc9582a303]") {
36+
REQUIRE("igpay" == pig_latin::translate("pig"));
37+
}
38+
39+
TEST_CASE("word beginning with k", "[d36d1e13-a7ed-464d-a282-8820cb2261ce]") {
40+
REQUIRE("oalakay" == pig_latin::translate("koala"));
41+
}
42+
43+
TEST_CASE("word beginning with x", "[d838b56f-0a89-4c90-b326-f16ff4e1dddc]") {
44+
REQUIRE("enonxay" == pig_latin::translate("xenon"));
45+
}
46+
47+
TEST_CASE("word beginning with q without a following u", "[bce94a7a-a94e-4e2b-80f4-b2bb02e40f71]") {
48+
REQUIRE("atqay" == pig_latin::translate("qat"));
49+
}
50+
51+
TEST_CASE("word beginning with ch", "[c01e049a-e3e2-451c-bf8e-e2abb7e438b8]") {
52+
REQUIRE("airchay" == pig_latin::translate("chair"));
53+
}
54+
55+
TEST_CASE("word beginning with qu", "[9ba1669e-c43f-4b93-837a-cfc731fd1425]") {
56+
REQUIRE("eenquay" == pig_latin::translate("queen"));
57+
}
58+
59+
TEST_CASE("word beginning with qu and a preceding consonant", "[92e82277-d5e4-43d7-8dd3-3a3b316c41f7]") {
60+
REQUIRE("aresquay" == pig_latin::translate("square"));
61+
}
62+
63+
TEST_CASE("word beginning with th", "[79ae4248-3499-4d5b-af46-5cb05fa073ac]") {
64+
REQUIRE("erapythay" == pig_latin::translate("therapy"));
65+
}
66+
67+
TEST_CASE("word beginning with thr", "[e0b3ae65-f508-4de3-8999-19c2f8e243e1]") {
68+
REQUIRE("ushthray" == pig_latin::translate("thrush"));
69+
}
70+
71+
TEST_CASE("word beginning with sch", "[20bc19f9-5a35-4341-9d69-1627d6ee6b43]") {
72+
REQUIRE("oolschay" == pig_latin::translate("school"));
73+
}
74+
75+
TEST_CASE("word beginning with yt", "[54b796cb-613d-4509-8c82-8fbf8fc0af9e]") {
76+
REQUIRE("yttriaay" == pig_latin::translate("yttria"));
77+
}
78+
79+
TEST_CASE("word beginning with xr", "[8c37c5e1-872e-4630-ba6e-d20a959b67f6]") {
80+
REQUIRE("xrayay" == pig_latin::translate("xray"));
81+
}
82+
83+
TEST_CASE("y is treated like a consonant at the beginning of a word", "[a4a36d33-96f3-422c-a233-d4021460ff00]") {
84+
REQUIRE("ellowyay" == pig_latin::translate("yellow"));
85+
}
86+
87+
TEST_CASE("y is treated like a vowel at the end of a consonant cluster", "[adc90017-1a12-4100-b595-e346105042c7]") {
88+
REQUIRE("ythmrhay" == pig_latin::translate("rhythm"));
89+
}
90+
91+
TEST_CASE("y as second letter in two letter word", "[29b4ca3d-efe5-4a95-9a54-8467f2e5e59a]") {
92+
REQUIRE("ymay" == pig_latin::translate("my"));
93+
}
94+
95+
TEST_CASE("a whole phrase", "[44616581-5ce3-4a81-82d0-40c7ab13d2cf]") {
96+
REQUIRE("ickquay astfay unray" == pig_latin::translate("quick fast run"));
97+
}
98+
99+
#endif

0 commit comments

Comments
 (0)