-
-
Notifications
You must be signed in to change notification settings - Fork 229
feat: add pig-latin exercise #812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# Instructions | ||
|
||
Implement a program that translates from English to Pig Latin. | ||
|
||
Pig Latin is a made-up children's language that's intended to be confusing. | ||
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. | ||
|
||
- **Rule 1**: If a word begins with a vowel sound, add an "ay" sound to the end of the word. | ||
Please note that "xr" and "yt" at the beginning of a word make vowel sounds (e.g. "xray" -> "xrayay", "yttria" -> "yttriaay"). | ||
- **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. | ||
Consonant sounds can be made up of multiple consonants, such as the "ch" in "chair" or "st" in "stand" (e.g. "chair" -> "airchay"). | ||
- **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"). | ||
- **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"). | ||
|
||
There are a few more rules for edge cases, and there are regional variants too. | ||
Check the tests for all the details. | ||
|
||
Read more about [Pig Latin on Wikipedia][pig-latin]. | ||
|
||
[pig-latin]: https://en.wikipedia.org/wiki/Pig_latin |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{ | ||
"authors": [ | ||
"vaeng" | ||
], | ||
"files": { | ||
"solution": [ | ||
"pig_latin.cpp", | ||
"pig_latin.h" | ||
], | ||
"test": [ | ||
"pig_latin_test.cpp" | ||
], | ||
"example": [ | ||
".meta/example.cpp", | ||
".meta/example.h" | ||
] | ||
}, | ||
"blurb": "Implement a program that translates from English to Pig Latin.", | ||
"source": "The Pig Latin exercise at Test First Teaching by Ultrasaurus", | ||
"source_url": "https://github.com/ultrasaurus/test-first-teaching/blob/master/learn_ruby/pig_latin/" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#include "pig_latin.h" | ||
|
||
namespace pig_latin { | ||
std::string translate_word(std::string word) { | ||
for (std::string start : {"a", "e", "i", "o", "u", "yt", "xr"}) { | ||
vaeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (word.substr(0, start.size()) == start) return word + "ay"; | ||
} | ||
for (std::string start : {"thr", "sch", "squ", "ch", "qu", "th", "rh"}) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While this list of consonant clusters is sufficient to pass the tests, those cover only a fraction of the possibilities. Words for which the current implementation would not give the correct pig latin version include "friend", "splash", "smile", "string". That's why I said in some other comment that my implementation is more generic. Instead of explicitly listing consonant clusters, it moves characters to the back until it finds a vowel. Only There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would vote to move that discussion and possible solutions to an article for the exercise. |
||
if (word.substr(0, start.size()) == start) | ||
return word.substr(start.size()) + start + "ay"; | ||
} | ||
return word.substr(1) + word.front() + "ay"; | ||
} | ||
|
||
std::string translate(std::string_view phrase) { | ||
size_t start = 0; | ||
std::string translation{}; | ||
for (size_t found = phrase.find(' '); found != std::string::npos; | ||
found = phrase.find(' ', start)) { | ||
translation += translate_word(std::string(phrase.begin() + start, | ||
phrase.begin() + found)) + | ||
vaeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
" "; | ||
start = found + 1; | ||
} | ||
if (start != phrase.size()) | ||
translation += | ||
translate_word(std::string(phrase.begin() + start, phrase.end())); | ||
vaeng marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
return translation; | ||
} | ||
} // namespace pig_latin |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
#include <string_view> | ||
|
||
namespace pig_latin { | ||
std::string translate(std::string_view phrase); | ||
|
||
} // namespace pig_latin |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# 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. | ||
|
||
[11567f84-e8c6-4918-aedb-435f0b73db57] | ||
description = "ay is added to words that start with vowels -> word beginning with a" | ||
|
||
[f623f581-bc59-4f45-9032-90c3ca9d2d90] | ||
description = "ay is added to words that start with vowels -> word beginning with e" | ||
|
||
[7dcb08b3-23a6-4e8a-b9aa-d4e859450d58] | ||
description = "ay is added to words that start with vowels -> word beginning with i" | ||
|
||
[0e5c3bff-266d-41c8-909f-364e4d16e09c] | ||
description = "ay is added to words that start with vowels -> word beginning with o" | ||
|
||
[614ba363-ca3c-4e96-ab09-c7320799723c] | ||
description = "ay is added to words that start with vowels -> word beginning with u" | ||
|
||
[bf2538c6-69eb-4fa7-a494-5a3fec911326] | ||
description = "ay is added to words that start with vowels -> word beginning with a vowel and followed by a qu" | ||
|
||
[e5be8a01-2d8a-45eb-abb4-3fcc9582a303] | ||
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with p" | ||
|
||
[d36d1e13-a7ed-464d-a282-8820cb2261ce] | ||
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with k" | ||
|
||
[d838b56f-0a89-4c90-b326-f16ff4e1dddc] | ||
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with x" | ||
|
||
[bce94a7a-a94e-4e2b-80f4-b2bb02e40f71] | ||
description = "first letter and ay are moved to the end of words that start with consonants -> word beginning with q without a following u" | ||
|
||
[c01e049a-e3e2-451c-bf8e-e2abb7e438b8] | ||
description = "some letter clusters are treated like a single consonant -> word beginning with ch" | ||
|
||
[9ba1669e-c43f-4b93-837a-cfc731fd1425] | ||
description = "some letter clusters are treated like a single consonant -> word beginning with qu" | ||
|
||
[92e82277-d5e4-43d7-8dd3-3a3b316c41f7] | ||
description = "some letter clusters are treated like a single consonant -> word beginning with qu and a preceding consonant" | ||
|
||
[79ae4248-3499-4d5b-af46-5cb05fa073ac] | ||
description = "some letter clusters are treated like a single consonant -> word beginning with th" | ||
|
||
[e0b3ae65-f508-4de3-8999-19c2f8e243e1] | ||
description = "some letter clusters are treated like a single consonant -> word beginning with thr" | ||
|
||
[20bc19f9-5a35-4341-9d69-1627d6ee6b43] | ||
description = "some letter clusters are treated like a single consonant -> word beginning with sch" | ||
|
||
[54b796cb-613d-4509-8c82-8fbf8fc0af9e] | ||
description = "some letter clusters are treated like a single vowel -> word beginning with yt" | ||
|
||
[8c37c5e1-872e-4630-ba6e-d20a959b67f6] | ||
description = "some letter clusters are treated like a single vowel -> word beginning with xr" | ||
|
||
[a4a36d33-96f3-422c-a233-d4021460ff00] | ||
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" | ||
|
||
[adc90017-1a12-4100-b595-e346105042c7] | ||
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" | ||
|
||
[29b4ca3d-efe5-4a95-9a54-8467f2e5e59a] | ||
description = "position of y in a word determines if it is a consonant or a vowel -> y as second letter in two letter word" | ||
|
||
[44616581-5ce3-4a81-82d0-40c7ab13d2cf] | ||
description = "phrases are translated -> a whole phrase" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Get the exercise name from the current directory | ||
get_filename_component(exercise ${CMAKE_CURRENT_SOURCE_DIR} NAME) | ||
|
||
# Basic CMake project | ||
cmake_minimum_required(VERSION 3.5.1) | ||
|
||
# Name the project after the exercise | ||
project(${exercise} CXX) | ||
|
||
# Get a source filename from the exercise name by replacing -'s with _'s | ||
string(REPLACE "-" "_" file ${exercise}) | ||
|
||
# Implementation could be only a header | ||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.cpp) | ||
set(exercise_cpp ${file}.cpp) | ||
else() | ||
set(exercise_cpp "") | ||
endif() | ||
|
||
# Use the common Catch library? | ||
if(EXERCISM_COMMON_CATCH) | ||
# For Exercism track development only | ||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h $<TARGET_OBJECTS:catchlib>) | ||
elseif(EXERCISM_TEST_SUITE) | ||
# The Exercism test suite is being run, the Docker image already | ||
# includes a pre-built version of Catch. | ||
find_package(Catch2 REQUIRED) | ||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h) | ||
target_link_libraries(${exercise} PRIVATE Catch2::Catch2WithMain) | ||
# When Catch is installed system wide we need to include a different | ||
# header, we need this define to use the correct one. | ||
target_compile_definitions(${exercise} PRIVATE EXERCISM_TEST_SUITE) | ||
else() | ||
# Build executable from sources and headers | ||
add_executable(${exercise} ${file}_test.cpp ${exercise_cpp} ${file}.h test/tests-main.cpp) | ||
endif() | ||
|
||
set_target_properties(${exercise} PROPERTIES | ||
CXX_STANDARD 17 | ||
CXX_STANDARD_REQUIRED OFF | ||
CXX_EXTENSIONS OFF | ||
) | ||
|
||
set(CMAKE_BUILD_TYPE Debug) | ||
|
||
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(GNU|Clang)") | ||
set_target_properties(${exercise} PROPERTIES | ||
COMPILE_FLAGS "-Wall -Wextra -Wpedantic -Werror" | ||
) | ||
endif() | ||
|
||
# Configure to run all the tests? | ||
if(${EXERCISM_RUN_ALL_TESTS}) | ||
target_compile_definitions(${exercise} PRIVATE EXERCISM_RUN_ALL_TESTS) | ||
endif() | ||
|
||
# Tell MSVC not to warn us about unchecked iterators in debug builds | ||
if(${MSVC}) | ||
set_target_properties(${exercise} PROPERTIES | ||
COMPILE_DEFINITIONS_DEBUG _SCL_SECURE_NO_WARNINGS) | ||
endif() | ||
|
||
# Run the tests on every build | ||
add_custom_target(test_${exercise} ALL DEPENDS ${exercise} COMMAND ${exercise}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#include "pig_latin.h" | ||
|
||
namespace pig_latin { | ||
|
||
} // namespace pig_latin |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
#pragma once | ||
|
||
namespace pig_latin { | ||
|
||
} // namespace pig_latin |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#include "pig_latin.h" | ||
#ifdef EXERCISM_TEST_SUITE | ||
#include <catch2/catch.hpp> | ||
#else | ||
#include "test/catch.hpp" | ||
#endif | ||
|
||
|
||
TEST_CASE("word beginning with a", "[11567f84-e8c6-4918-aedb-435f0b73db57]") { | ||
REQUIRE("appleay" == pig_latin::translate("apple")); | ||
} | ||
|
||
#if defined(EXERCISM_RUN_ALL_TESTS) | ||
|
||
TEST_CASE("word beginning with e", "[f623f581-bc59-4f45-9032-90c3ca9d2d90]") { | ||
REQUIRE("earay" == pig_latin::translate("ear")); | ||
} | ||
|
||
TEST_CASE("word beginning with i", "[7dcb08b3-23a6-4e8a-b9aa-d4e859450d58]") { | ||
REQUIRE("iglooay" == pig_latin::translate("igloo")); | ||
} | ||
|
||
TEST_CASE("word beginning with o", "[0e5c3bff-266d-41c8-909f-364e4d16e09c]") { | ||
REQUIRE("objectay" == pig_latin::translate("object")); | ||
} | ||
|
||
TEST_CASE("word beginning with u", "[614ba363-ca3c-4e96-ab09-c7320799723c]") { | ||
REQUIRE("underay" == pig_latin::translate("under")); | ||
} | ||
|
||
TEST_CASE("word beginning with a vowel and followed by a qu", "[bf2538c6-69eb-4fa7-a494-5a3fec911326]") { | ||
REQUIRE("equalay" == pig_latin::translate("equal")); | ||
} | ||
|
||
TEST_CASE("word beginning with p", "[e5be8a01-2d8a-45eb-abb4-3fcc9582a303]") { | ||
REQUIRE("igpay" == pig_latin::translate("pig")); | ||
} | ||
|
||
TEST_CASE("word beginning with k", "[d36d1e13-a7ed-464d-a282-8820cb2261ce]") { | ||
REQUIRE("oalakay" == pig_latin::translate("koala")); | ||
} | ||
|
||
TEST_CASE("word beginning with x", "[d838b56f-0a89-4c90-b326-f16ff4e1dddc]") { | ||
REQUIRE("enonxay" == pig_latin::translate("xenon")); | ||
} | ||
|
||
TEST_CASE("word beginning with q without a following u", "[bce94a7a-a94e-4e2b-80f4-b2bb02e40f71]") { | ||
REQUIRE("atqay" == pig_latin::translate("qat")); | ||
} | ||
|
||
TEST_CASE("word beginning with ch", "[c01e049a-e3e2-451c-bf8e-e2abb7e438b8]") { | ||
REQUIRE("airchay" == pig_latin::translate("chair")); | ||
} | ||
|
||
TEST_CASE("word beginning with qu", "[9ba1669e-c43f-4b93-837a-cfc731fd1425]") { | ||
REQUIRE("eenquay" == pig_latin::translate("queen")); | ||
} | ||
|
||
TEST_CASE("word beginning with qu and a preceding consonant", "[92e82277-d5e4-43d7-8dd3-3a3b316c41f7]") { | ||
REQUIRE("aresquay" == pig_latin::translate("square")); | ||
} | ||
|
||
TEST_CASE("word beginning with th", "[79ae4248-3499-4d5b-af46-5cb05fa073ac]") { | ||
REQUIRE("erapythay" == pig_latin::translate("therapy")); | ||
} | ||
|
||
TEST_CASE("word beginning with thr", "[e0b3ae65-f508-4de3-8999-19c2f8e243e1]") { | ||
REQUIRE("ushthray" == pig_latin::translate("thrush")); | ||
} | ||
|
||
TEST_CASE("word beginning with sch", "[20bc19f9-5a35-4341-9d69-1627d6ee6b43]") { | ||
REQUIRE("oolschay" == pig_latin::translate("school")); | ||
} | ||
|
||
TEST_CASE("word beginning with yt", "[54b796cb-613d-4509-8c82-8fbf8fc0af9e]") { | ||
REQUIRE("yttriaay" == pig_latin::translate("yttria")); | ||
} | ||
|
||
TEST_CASE("word beginning with xr", "[8c37c5e1-872e-4630-ba6e-d20a959b67f6]") { | ||
REQUIRE("xrayay" == pig_latin::translate("xray")); | ||
} | ||
|
||
TEST_CASE("y is treated like a consonant at the beginning of a word", "[a4a36d33-96f3-422c-a233-d4021460ff00]") { | ||
REQUIRE("ellowyay" == pig_latin::translate("yellow")); | ||
} | ||
|
||
TEST_CASE("y is treated like a vowel at the end of a consonant cluster", "[adc90017-1a12-4100-b595-e346105042c7]") { | ||
REQUIRE("ythmrhay" == pig_latin::translate("rhythm")); | ||
} | ||
|
||
TEST_CASE("y as second letter in two letter word", "[29b4ca3d-efe5-4a95-9a54-8467f2e5e59a]") { | ||
REQUIRE("ymay" == pig_latin::translate("my")); | ||
} | ||
|
||
TEST_CASE("a whole phrase", "[44616581-5ce3-4a81-82d0-40c7ab13d2cf]") { | ||
REQUIRE("ickquay astfay unray" == pig_latin::translate("quick fast run")); | ||
} | ||
|
||
#endif |
Uh oh!
There was an error while loading. Please reload this page.