Skip to content

Commit 0ffd34b

Browse files
committed
Puzzle to Challenge
1 parent 23da53a commit 0ffd34b

File tree

19 files changed

+73
-73
lines changed

19 files changed

+73
-73
lines changed

.test/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ This subproject is designed to verify the root project. Checks are running with
44

55
## Consistency Checks
66

7-
Verify consistency across various challenges e.g. check puzzle naming and file structure.
7+
Verify consistency across various challenges e.g. check challenge naming and file structure.
88

99
## Solution Checks
1010

1111
Every coding challenge in this repo consists of a container (`challenge.kt` file) that has tests and
1212
empty placeholder for a user-coded solution. Since the placeholder is non-implemented method
1313
all tests in the root project will fail by design.
1414

15-
This subproject generates a test suite for each puzzle by combining puzzle container (`challenge.kt` file) with
16-
every puzzle solutions (`solution.kt` file).
15+
This subproject generates a test suite for each challenge by combining challenge container (`challenge.kt` file) with
16+
every challenge solutions (`solution.kt` file).
1717

1818
To generate tests run the `cd .test && ./gradlew generateTests && cd ..` command.
1919
Generated tests will be placed in the `src/test/kotlin/generated` directory.

.test/buildSrc/src/main/kotlin/com/igorwojda/challenge/utils/PuzzleFile.kt .test/buildSrc/src/main/kotlin/com/igorwojda/challenge/utils/ChallengeFile.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.igorwojda.challenge.utils
22

3-
enum class PuzzleFile(val fileName: String) {
3+
enum class ChallengeFile(val fileName: String) {
44
SOLUTIONS_KT("solution.kt"),
55
DESC_MD("desc.md"),
66
CHALLENGE_KT("challenge.kt"),

.test/buildSrc/src/main/kotlin/com/igorwojda/challenge/utils/KotlinGeneratorUtils.kt

+12-10
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,22 @@ import org.jetbrains.kotlin.psi.KtObjectDeclaration
88
import java.io.File
99

1010
object KotlinGeneratorUtils {
11-
fun getTestFiles(puzzleDirectoryPath: File): List<TestFile> {
12-
val challengeKtFile = KotlinParserUtils.getPuzzleKtFile(puzzleDirectoryPath, PuzzleFile.CHALLENGE_KT)
13-
val solutionKtFile = KotlinParserUtils.getPuzzleKtFile(puzzleDirectoryPath, PuzzleFile.SOLUTIONS_KT)
14-
val puzzleName = getPuzzleName(challengeKtFile)
11+
fun getTestFiles(challengeDirectoryPath: File): List<TestFile> {
12+
val challengeKtFile =
13+
KotlinParserUtils.getChallengeKtFile(challengeDirectoryPath, ChallengeFile.CHALLENGE_KT)
14+
val solutionKtFile =
15+
KotlinParserUtils.getChallengeKtFile(challengeDirectoryPath, ChallengeFile.SOLUTIONS_KT)
16+
val challengeName = getChallengeName(challengeKtFile)
1517

1618
val solutions = getSolutions(solutionKtFile)
1719

1820
return solutions.map {
19-
getTestFile(puzzleName, challengeKtFile, solutionKtFile, it)
21+
getTestFile(challengeName, challengeKtFile, solutionKtFile, it)
2022
}
2123
}
2224

2325
private fun getTestFile(
24-
puzzleName: String,
26+
challengeName: String,
2527
challengeKtFile: KtFile,
2628
solutionKtFile: KtFile,
2729
solution: KtObjectDeclaration,
@@ -43,13 +45,13 @@ object KotlinGeneratorUtils {
4345
tests
4446
).flatten()
4547

46-
val testrSolutionFileName = getFileName(solution, puzzleName)
48+
val testrSolutionFileName = getFileName(solution, challengeName)
4749
val relativePath = solutionName.toLowerCase()
4850

4951
return TestFile(testrSolutionFileName, relativePath, lines)
5052
}
5153

52-
private fun getPuzzleName(challengeKtFile: KtFile) =
54+
private fun getChallengeName(challengeKtFile: KtFile) =
5355
challengeKtFile
5456
.packageFqName
5557
.toString()
@@ -81,9 +83,9 @@ object KotlinGeneratorUtils {
8183
private fun getPackage(ktFile: KtFile, solutionName: String) =
8284
"package generated.${ktFile.packageFqName}.$solutionName".toLowerCase()
8385

84-
private fun getFileName(solution: KtObjectDeclaration, puzzleName: String): String {
86+
private fun getFileName(solution: KtObjectDeclaration, challengeName: String): String {
8587
val solutionName = checkNotNull(solution.name) { "Solution name is null" }
86-
return "Test_${puzzleName}_$solutionName.kt"
88+
return "Test_${challengeName}_$solutionName.kt"
8789
}
8890

8991
private fun getSolutions(ktFile: KtFile) = ktFile

.test/buildSrc/src/main/kotlin/com/igorwojda/challenge/utils/KotlinParserUtils.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,18 @@ object KotlinParserUtils {
1919
).project
2020
}
2121

22-
fun getPuzzleFile(puzzleDirectoryPath: File, puzzleFile: PuzzleFile): File {
23-
val path = "${puzzleDirectoryPath.path}/${puzzleFile.fileName}"
22+
fun getChallengeFile(challengeDirectoryPath: File, ChallengeFile: ChallengeFile): File {
23+
val path = "${challengeDirectoryPath.path}/${ChallengeFile.fileName}"
2424
return File(path)
2525
}
2626

27-
fun getPuzzleKtFile(puzzleDirectoryPath: File, puzzleFile: PuzzleFile): KtFile {
28-
val file = getPuzzleFile(puzzleDirectoryPath, puzzleFile)
29-
val fullFileName = "${puzzleDirectoryPath.path}/${puzzleFile.fileName}"
30-
return getPuzzleKtFile(file.readText(), fullFileName)
27+
fun getChallengeKtFile(challengeDirectoryPath: File, ChallengeFile: ChallengeFile): KtFile {
28+
val file = getChallengeFile(challengeDirectoryPath, ChallengeFile)
29+
val fullFileName = "${challengeDirectoryPath.path}/${ChallengeFile.fileName}"
30+
return getChallengeKtFile(file.readText(), fullFileName)
3131
}
3232

33-
private fun getPuzzleKtFile(codeString: String, fileName: String) =
33+
private fun getChallengeKtFile(codeString: String, fileName: String) =
3434
PsiManager.getInstance(project)
3535
.findFile(
3636
LightVirtualFile(fileName, KotlinFileType.INSTANCE, codeString)

.test/buildSrc/src/main/kotlin/com/igorwojda/challenge/utils/TestUtils.kt

+12-12
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@ import java.io.File
66
object TestUtils {
77

88
fun generateTestFiles(project: Project) {
9-
getPuzzleDirectories(project).forEach {
9+
getChallengeDirectories(project).forEach {
1010
generateTestFiles(it)
1111
}
1212
}
1313

1414
/**
15-
* Generate test files for a given puzzle by combining challenge file with available solutions
15+
* Generate test files for a given challenge by combining challenge file with available solutions
1616
*/
17-
private fun generateTestFiles(puzzleDirectoryPath: File) {
18-
val generatedPuzzleDirecotryPath = puzzleDirectoryPath
17+
private fun generateTestFiles(challengeDirectoryPath: File) {
18+
val generatedChallengeDirecotryPath = challengeDirectoryPath
1919
.path
2020
.replace("kotlin/com/igorwojda/", "kotlin/generated/com/igorwojda/")
2121

2222
// May be already pre-cached by CI
23-
deleteDirectory(File(generatedPuzzleDirecotryPath))
23+
deleteDirectory(File(generatedChallengeDirecotryPath))
2424

25-
val testFiles = KotlinGeneratorUtils.getTestFiles(puzzleDirectoryPath)
25+
val testFiles = KotlinGeneratorUtils.getTestFiles(challengeDirectoryPath)
2626

2727
testFiles
2828
.forEach {
29-
createTestFile(generatedPuzzleDirecotryPath, it)
29+
createTestFile(generatedChallengeDirecotryPath, it)
3030
}
3131
}
3232

@@ -47,10 +47,10 @@ object TestUtils {
4747
}
4848

4949
/**
50-
* Create a test files for a given puzzle
50+
* Create a test files for a given challenge
5151
*/
52-
private fun createTestFile(generatedPuzzleDirecotryPath: String, testFile: TestFile) {
53-
val testDirectory = File("$generatedPuzzleDirecotryPath/${testFile.relativePath}/")
52+
private fun createTestFile(generatedChallengeDirecotryPath: String, testFile: TestFile) {
53+
val testDirectory = File("$generatedChallengeDirecotryPath/${testFile.relativePath}/")
5454
testDirectory.mkdirs()
5555

5656
val targetChallengeFile = File("${testDirectory.path}/${testFile.fileName}")
@@ -60,7 +60,7 @@ object TestUtils {
6060
/**
6161
* Return list of project names
6262
*/
63-
private fun getPuzzleDirectories(project: Project): List<File> {
63+
private fun getChallengeDirectories(project: Project): List<File> {
6464
val path = "${project.rootDir.path}/../src/test/kotlin/com/igorwojda"
6565
val directory = File(path)
6666
val miscDirectoryName = "misc"
@@ -74,7 +74,7 @@ object TestUtils {
7474
}
7575

7676
/**
77-
* Checks whatever or not directory is high level directory (puzzle grouping directory)
77+
* Checks whatever or not directory is high level directory (challenge grouping directory)
7878
*/
7979
private val File.isHighLevelDirectory get() = this.isDirectory && this.listFiles().none { it.isDirectory }
8080
}

.test/src/test/kotlin/com/igorwojda/challenge/ProjectConsistencyTest.kt

+12-13
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.igorwojda.challenge
22

33
import com.igorwojda.challenge.utils.KotlinParserUtils
4-
import com.igorwojda.challenge.utils.PuzzleFile
54
import com.igorwojda.challenge.utils.TestUtils
65
import org.amshove.kluent.shouldBeEqualTo
76
import org.amshove.kluent.shouldBeGreaterOrEqualTo
@@ -17,10 +16,10 @@ import kotlin.io.path.Path
1716

1817
class ProjectConsistencyTest {
1918

20-
@ParameterizedTest(name = "Puzzle file exists: {0}")
21-
@MethodSource("getPuzzleRequiredFilePaths")
22-
fun `Puzzle file exists`(puzzleFilePath: String) {
23-
val path = Path(puzzleFilePath)
19+
@ParameterizedTest(name = "chalenge file exists: {0}")
20+
@MethodSource("getChallengeRequiredFilePaths")
21+
fun `chalenge file exists`(challengeFilePath: String) {
22+
val path = Path(challengeFilePath)
2423
require(Files.exists(path)) { "Missing file $path" }
2524
}
2625

@@ -69,21 +68,21 @@ class ProjectConsistencyTest {
6968
companion object {
7069
@JvmStatic
7170
fun getSolutionFiles() = TestUtils
72-
.getPuzzleDirectories()
73-
.map { KotlinParserUtils.getPuzzleKtFile(it, PuzzleFile.SOLUTIONS_KT) }
71+
.getChallengeDirectories()
72+
.map { KotlinParserUtils.getChallengeKtFile(it, ChallengeFile.SOLUTIONS_KT) }
7473

7574
@JvmStatic
7675
fun getChallenge() = TestUtils
77-
.getPuzzleDirectories()
78-
.map { KotlinParserUtils.getPuzzleKtFile(it, PuzzleFile.CHALLENGE_KT) }
76+
.getChallengeDirectories()
77+
.map { KotlinParserUtils.getChallengeKtFile(it, ChallengeFile.CHALLENGE_KT) }
7978

8079
@JvmStatic
81-
fun getPuzzleRequiredFilePaths() = TestUtils
82-
.getPuzzleDirectories()
80+
fun getChallengeRequiredFilePaths() = TestUtils
81+
.getChallengeDirectories()
8382
.flatMap { getProjectRequiredFiles(it) }
8483

85-
private fun getProjectRequiredFiles(puzzleDirectory: File) = PuzzleFile
84+
private fun getProjectRequiredFiles(challengeDirectory: File) = ChallengeFile
8685
.values()
87-
.map { "${puzzleDirectory.path}/${it.fileName}" }
86+
.map { "${challengeDirectory.path}/${it.fileName}" }
8887
}
8988
}

.test/src/test/kotlin/com/igorwojda/challenge/utils/PuzzleFile.kt .test/src/test/kotlin/com/igorwojda/challenge/utils/ChallengeFile.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.igorwojda.challenge.utils
22

3-
enum class PuzzleFile(val fileName: String) {
3+
enum class ChallengeFile(val fileName: String) {
44
SOLUTIONS_KT("solution.kt"),
55
DESC_MD("desc.md"),
66
CHALLENGE_KT("challenge.kt"),

.test/src/test/kotlin/com/igorwojda/challenge/utils/KotlinParserUtils.kt

+7-7
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ object KotlinParserUtils {
2020
).project
2121
}
2222

23-
private fun getPuzzleFile(puzzleDirectoryPath: File, puzzleFile: PuzzleFile): File {
24-
val path = "${puzzleDirectoryPath.path}/${puzzleFile.fileName}"
23+
private fun getChallengeFile(challengeDirectoryPath: File, chalengeFile: ChallengeFile): File {
24+
val path = "${challengeDirectoryPath.path}/${chalengeFile.fileName}"
2525
return File(path)
2626
}
2727

28-
fun getPuzzleKtFile(puzzleDirectoryPath: File, puzzleFile: PuzzleFile): KtFile {
29-
val file = getPuzzleFile(puzzleDirectoryPath, puzzleFile)
30-
val fullFileName = "${puzzleDirectoryPath.path}/${puzzleFile.fileName}"
31-
return getPuzzleKtFile(file.readText(), fullFileName)
28+
fun getChallengeKtFile(pchallengeDirectoryPath: File, ChallengeFile: ChallengeFile): KtFile {
29+
val file = getChallengeFile(pchallengeDirectoryPath, ChallengeFile)
30+
val fullFileName = "${pchallengeDirectoryPath.path}/${ChallengeFile.fileName}"
31+
return getChallengeKtFile(file.readText(), fullFileName)
3232
}
3333

34-
private fun getPuzzleKtFile(codeString: String, fileName: String) =
34+
private fun getChallengeKtFile(codeString: String, fileName: String) =
3535
PsiManager.getInstance(project)
3636
.findFile(
3737
LightVirtualFile(fileName, KotlinFileType.INSTANCE, codeString)

.test/src/test/kotlin/com/igorwojda/challenge/utils/TestUtils.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object TestUtils {
1515
/**
1616
* Return list of project names
1717
*/
18-
fun getPuzzleDirectories(): List<File> {
18+
fun getChellengeDirectories(): List<File> {
1919
val path = "${repoRootDirectoryFile.path}/src/test/kotlin/com/igorwojda"
2020
val directory = File(path)
2121
val miscDirectoryName = "misc"
@@ -29,7 +29,7 @@ object TestUtils {
2929
}
3030

3131
/**
32-
* Checks whatever or not directory is high level directory (puzzle grouping directory)
32+
* Checks whatever or not directory is high level directory (challenge grouping directory)
3333
*/
3434
private val File.isHighLevelDirectory get() = this.isDirectory && this.listFiles().none { it.isDirectory }
3535
}

README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ determine space/time complexity and we look at code readability.
3636
# Let's solve some challenges
3737

3838
Challenges below are segregated by different difficulties. The repository also contains challenges grouped by
39-
[problem type](misc/PuzzleGroups.md).
39+
[problem type](misc/ChallengeGroups.md).
4040

4141
Some challenges may contain a reference to other challenges that should be solved before to have a better understanding
4242
of the problem. Check the
@@ -199,8 +199,8 @@ multiple times and be persistent over time.
199199

200200
# Contribute
201201

202-
Feedback and new contributions are welcome whether it's through bug reports or new PRs. To add new coding puzzle just
203-
follow this [guide](https://github.com/igorwojda/kotlin-coding-challenges/wiki/Adding-a-new-puzzle) and open PR.
202+
Feedback and new contributions are welcome whether it's through bug reports or new PRs. To add new coding challenge just
203+
follow this [guide](https://github.com/igorwojda/kotlin-coding-challenges/wiki/Adding-a-new-challenge) and open PR.
204204

205205
# Author
206206

misc/PuzzleGroups.md misc/ChallengeGroups.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Problems groups
22

3-
This section contains **subset** of puzzles that are grouped by type of solution (recursive, double pointer etc.) or
4-
type of problem (searching, sorting etc.). One puzzle may fit int outfile groups.
3+
This section contains **subset** of challenges that are grouped by type of solution (recursive, double pointer etc.) or
4+
type of problem (searching, sorting etc.). One challenge may fit int outfile groups.
55

66
## Recursion
77

@@ -81,7 +81,7 @@ We use sliding window instead of nested loops which decreases complexity from `O
8181
- [Quick sort](../src/test/kotlin/com/igorwojda/list/sort/quicksort/desc.md)
8282
- [Radix sort](../src/test/kotlin/com/igorwojda/list/sort/radixsort/desc.md)
8383

84-
### Other list puzzles
84+
### Other list challenges
8585

8686
- [Capitalize First](../src/test/kotlin/com/igorwojda/list/capitalizeFirst/desc.md)
8787
- [Flatten](../src/test/kotlin/com/igorwojda/list/flatten/desc.md)

misc/template/challenge/challenge.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.igorwojda.puzzle
1+
package com.igorwojda.challenge
22

33
import org.amshove.kluent.shouldBeEqualTo
44
import org.junit.jupiter.api.Test

misc/template/challenge/desc.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Puzzle name
1+
# Challenge name
22

33
## Nice to solve before
44

misc/template/challenge/solution.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.igorwojda.puzzle
1+
package com.igorwojda.challenge
22

33
// Time complexity:
44
// ???

src/test/kotlin/com/igorwojda/linkedlist/doubly/base/desc.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66

77
### Instructions
88

9-
Implement [doubly linked list](https://en.wikipedia.org/wiki/Doubly_linked_list) data structure. This is quite big puzzle, so
10-
we will split it into multiple multiple methods and properties that we will implement one my one.
9+
Implement [doubly linked list](https://en.wikipedia.org/wiki/Doubly_linked_list) data structure. This is quite big
10+
challenge, so we will split it into multiple multiple methods and properties that we will implement one my one.
1111

1212
We also want to handle various edge cases, because we are assuming that developer using our class many do certain
1313
mistakes. That's why each step has one or more tests associated with it. Tests are commented out default, so before

src/test/kotlin/com/igorwojda/linkedlist/singly/base/desc.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
### Instructions
44

5-
Implement [singly linked list](https://en.wikipedia.org/wiki/Linked_list) data structure. This is quite big puzzle, so
6-
we will split it into multiple multiple methods and properties that we will implement one my one.
5+
Implement [singly linked list](https://en.wikipedia.org/wiki/Linked_list) data structure. This is quite big
6+
challenge, so we will split it into multiple multiple methods and properties that we will implement one my one.
77

88
We also want to handle various edge cases, because we are assuming that developer using our class many do certain
99
mistakes. That's why each step has one or more tests associated with it. Tests are commented out default, so before

src/test/kotlin/com/igorwojda/string/ispalindrome/tolerant/solution.kt

+1-2
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ private object Solution2 {
4343
return true
4444
}
4545

46-
println(str)
4746
val removeLeftResult = isTolerantPalindrome(
4847
str.substring(2 until str.lastIndex),
4948
true
@@ -78,4 +77,4 @@ private object Solution3 {
7877
isTolerantPalindrome(reducedRevStr, true)
7978
}
8079
}
81-
}
80+
}

src/test/kotlin/com/igorwojda/tree/classic/traversal/challenge.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ private data class BinaryNode<E : Comparable<E>>(
9999

100100
/*
101101
We can use queue as helper class to implement breath first traversal. This is not most optimal queue implementation,
102-
however it's enough for this task. Check "Queue puzzle" solution for more details and more efficient queue
102+
however it's enough for this task. Check "Queue challenge" solution for more details and more efficient queue
103103
implementation.
104104
*/
105105
private class Queue<E> {

src/test/kotlin/com/igorwojda/tree/classic/traversal/solution.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ private object Solution1 {
163163

164164
/*
165165
We can use queue as helper class to implement breath first traversal. This is not most optimal queue implementation,
166-
however it's enough for this task. Check "Queue puzzle" solution for more details and more efficient queue
166+
however it's enough for this task. Check "Queue challenge" solution for more details and more efficient queue
167167
implementation.
168168
*/
169169
private class Queue<E> {

0 commit comments

Comments
 (0)