diff --git a/README.md b/README.md
index a6c3309aa..01d0d7940 100644
--- a/README.md
+++ b/README.md
@@ -383,7 +383,7 @@ If you would like to have collaborator permissions on the repo to merge your own
[1423 - Maximum Points You Can Obtain From Cards](https://leetcode.com/problems/maximum-points-you-can-obtain-from-cards/) | ❌
| ❌
| [✔️](csharp%2F1423-Maximum-Points-You-Can-Obtain-from-Cards.cs)
| ❌
| ❌
| ❌
| ❌
| [✔️](kotlin%2F1423-maximum-points-you-can-obtain-from-cards.kt)
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[1899 - Merge Triplets to Form Target Triplet](https://leetcode.com/problems/merge-triplets-to-form-target-triplet/) | ❌
| [✔️](cpp%2F1899-merge-triplets-to-form-target-triplet.cpp)
| [✔️](csharp%2F1899-Merge-Triplets-to-Form-Target-Triplet.cs)
| ❌
| ❌
| [✔️](java%2F1899-merge-triplets-to-form-target-triplet.java)
| [✔️](javascript%2F1899-merge-triplets-to-form-target-triplet.js)
| [✔️](kotlin%2F1899-merge-triplets-to-form-target-triplet.kt)
| [✔️](python%2F1899-merge-triplets-to-form-target-triplet.py)
| [✔️](ruby%2F1899-merge-triplets-to-form-target-triplet.rb)
| ❌
| ❌
| [✔️](swift%2F1899-Merge-Triplets-To-Form-Target-Triplet.swift)
| [✔️](typescript%2F1899-Merge-Triplets-to-Form-Target-Triplet.ts)
[0763 - Partition Labels](https://leetcode.com/problems/partition-labels/) | ❌
| [✔️](cpp%2F0763-partition-labels.cpp)
| [✔️](csharp%2F0763-partition-labels.cs)
| ❌
| [✔️](go%2F0763-partition-labels.go)
| [✔️](java%2F0763-partition-labels.java)
| [✔️](javascript%2F0763-partition-labels.js)
| [✔️](kotlin%2F0763-partition-labels.kt)
| [✔️](python%2F0763-partition-labels.py)
| [✔️](ruby%2F0763-partition-labels.rb)
| ❌
| ❌
| ❌
| ❌
-[0678 - Valid Parenthesis String](https://leetcode.com/problems/valid-parenthesis-string/) | [✔️](c%2F0678-valid-parenthesis-string.c)
| [✔️](cpp%2F0678-valid-parenthesis-string.cpp)
| [✔️](csharp%2F0678-valid-parenthesis-string.cs)
| ❌
| ❌
| [✔️](java%2F0678-valid-parenthesis-string.java)
| [✔️](javascript%2F0678-valid-parenthesis-string.js)
| ❌
| [✔️](python%2F0678-valid-parenthesis-string.py)
| ❌
| ❌
| ❌
| ❌
| [✔️](typescript%2F0678-valid-parenthesis-string.ts)
+[0678 - Valid Parenthesis String](https://leetcode.com/problems/valid-parenthesis-string/) | [✔️](c%2F0678-valid-parenthesis-string.c)
| [✔️](cpp%2F0678-valid-parenthesis-string.cpp)
| [✔️](csharp%2F0678-valid-parenthesis-string.cs)
| ❌
| ❌
| [✔️](java%2F0678-valid-parenthesis-string.java)
| [✔️](javascript%2F0678-valid-parenthesis-string.js)
| [✔️](kotlin%2F0678-valid-parenthesis-string.kt)
| [✔️](python%2F0678-valid-parenthesis-string.py)
| ❌
| ❌
| ❌
| ❌
| [✔️](typescript%2F0678-valid-parenthesis-string.ts)
[1921 - Eliminate Maximum Number of Monsters](https://leetcode.com/problems/eliminate-maximum-number-of-monsters/) | ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
| ❌
[1029 - Two City Scheduling](https://leetcode.com/problems/two-city-scheduling/) | ❌
| ❌
| ❌
| ❌
| [✔️](go%2F1029-two-city-scheduling.go)
| [✔️](java%2F1029-two-city-scheduling.java)
| [✔️](javascript%2F1029-two-city-scheduling.js)
| ❌
| [✔️](python%2F1029-two-city-scheduling.py)
| ❌
| [✔️](rust%2F1029-two-city-scheduling.rs)
| ❌
| ❌
| [✔️](typescript%2F1029-two-city-scheduling.ts)
diff --git a/kotlin/0678-valid-parenthesis-string.kt b/kotlin/0678-valid-parenthesis-string.kt
new file mode 100644
index 000000000..ee51cf772
--- /dev/null
+++ b/kotlin/0678-valid-parenthesis-string.kt
@@ -0,0 +1,57 @@
+class Solution {
+
+ fun checkValidString(s: String): Boolean {
+ // number of opening parenthesis when '*' is taken as '('
+ var noOfOpenParenthesisWhenStarIsAnOpeningParenthesis = 0
+ // number of opening parenthesis when '*' is taken as ')'
+ var noOfOpenParenthesisWhenStarIsAClosingParenthesis = 0
+ // number of opening parenthesis when '*' is taken as ' '
+ var noOfOpenParenthesisWhenStarIsAnEmptyString = 0
+
+ for (char in s) {
+ if (char == '(') {
+ noOfOpenParenthesisWhenStarIsAnOpeningParenthesis++
+ noOfOpenParenthesisWhenStarIsAClosingParenthesis++
+ noOfOpenParenthesisWhenStarIsAnEmptyString++
+
+ }
+ if (char == '*') {
+ noOfOpenParenthesisWhenStarIsAnOpeningParenthesis++
+ noOfOpenParenthesisWhenStarIsAClosingParenthesis--
+ }
+
+ if (char == ')') {
+ noOfOpenParenthesisWhenStarIsAnOpeningParenthesis--
+ noOfOpenParenthesisWhenStarIsAClosingParenthesis--
+ noOfOpenParenthesisWhenStarIsAnEmptyString--
+ }
+ // A negative value indicates an excess of closing parenthesis.
+ // Eg: -1 indicates that there are no opening parenthesis and 1 closing parenthesis.
+ // If at least one of our possibilities is a positive value, then it indicates
+ // that the string is possibly valid.
+ // If all of our possibilities have a negative value, it indicates that none of the
+ // possibilities lead to a valid string. Hence, return false.
+ if (
+ noOfOpenParenthesisWhenStarIsAnOpeningParenthesis < 0 &&
+ noOfOpenParenthesisWhenStarIsAClosingParenthesis < 0 &&
+ noOfOpenParenthesisWhenStarIsAnEmptyString < 0
+ ) return false
+
+ // Ensure that the variables are always positive. A negative value doesn't make sense
+ // because there cannot be a negative number of opening parenthesis.
+ noOfOpenParenthesisWhenStarIsAnOpeningParenthesis =
+ noOfOpenParenthesisWhenStarIsAnOpeningParenthesis.coerceAtLeast(0)
+
+ noOfOpenParenthesisWhenStarIsAClosingParenthesis =
+ noOfOpenParenthesisWhenStarIsAClosingParenthesis.coerceAtLeast(0)
+
+ noOfOpenParenthesisWhenStarIsAnEmptyString =
+ noOfOpenParenthesisWhenStarIsAnEmptyString.coerceAtLeast(0)
+
+ }
+
+ return noOfOpenParenthesisWhenStarIsAnOpeningParenthesis == 0 ||
+ noOfOpenParenthesisWhenStarIsAClosingParenthesis == 0 ||
+ noOfOpenParenthesisWhenStarIsAnEmptyString == 0
+ }
+}
\ No newline at end of file