diff --git a/.idea/misc.xml b/.idea/misc.xml
index d2b5d0f..50bd5c9 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -8,7 +8,5 @@
-
-
-
+
\ No newline at end of file
diff --git a/src/main/java/BonusExercises.java b/src/main/java/BonusExercises.java
index d02a746..6773b30 100644
--- a/src/main/java/BonusExercises.java
+++ b/src/main/java/BonusExercises.java
@@ -19,14 +19,31 @@ public class BonusExercises {
- Can't have underscores
- Each segment (between dots) must follow same hyphen rules
*/
+
public boolean validateEmail(String email) {
- String regex = ""; // todo
+ // Regex توضیح:
+ // ^ : شروع رشته
+ // [^.] : نباید با نقطه شروع شود
+ // [^@.]+ : کاراکترهای مجاز در local-part (به جز نقطه و @)
+ // (?:\\.[^@.]+)* : صفر یا بیشتر گروه (نقطه + کاراکترهای مجاز) - برای نقاط میانی
+ // [^.] : نباید با نقطه تمام شود
+ // @ : باید دقیقاً یک @ باشد
+ // [^@.]+ : کاراکترهای مجاز در دامنه (به جز نقطه و @)
+ // (?:\\.[^@.]+)* : صفر یا بیشتر گروه (نقطه + کاراکترهای مجاز) - برای نقاط میانی
+ // [^@.-]+ : بخش آخر دامنه (بدون نقطه، @، یا خط تیره)
+ // $ : پایان رشته
+
+
+ String regex = "^[^.][^@.]*(?:\\.[^@.]+)*@[^@.]+\\.[^@.]+$";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(email);
return matcher.matches();
}
+
+
+
/*
This method should find and return the first date in a string.
@@ -39,8 +56,29 @@ public class BonusExercises {
If no match for a date is found in the string, return null.
*/
public String findDate(String string) {
- // todo
- return null;
+ // Regex توضیح:
+ // (?: ... ) : گروه غیر حافظ (non-capturing group)
+ // \d{1,2} : یک یا دو رقم (برای روز و ماه)
+ // \d{4} : چهار رقم (برای سال)
+ // [/.-] : کاراکتر جداکننده میتواند / یا . یا - باشد
+ //
+ // تاریخهای MM/DD/YYYY یا DD/MM/YYYY:
+ // (\d{1,2}[/.-]\d{1,2}[/.-]\d{4})
+ //
+ // تاریخهای YYYY-MM-DD یا YYYY/MM/DD:
+ // (\d{4}[/.-]\d{1,2}[/.-]\d{1,2})
+ // اولویت با فرمت YYYY داده شده تا اگر YYYY/MM/DD هم داشتیم، آن را اول پیدا کند.
+
+ String regex = "(\\d{4}[/.-]\\d{1,2}[/.-]\\d{1,2})|(\\d{1,2}[/.-]\\d{1,2}[/.-]\\d{4})";
+ Pattern pattern = Pattern.compile(regex);
+ Matcher matcher = pattern.matcher(string);
+
+ if (matcher.find())
+ {
+ return matcher.group(0); // گروه 0 کل متن مطابق با regex است
+ } else {
+ return null;
+ }
}
/*
@@ -53,24 +91,103 @@ public class BonusExercises {
- at least one number and at least a special char "!@#$%^&*"
- has no white-space in it
*/
+
public int findValidPasswords(String string) {
- // todo
- return -1;
+ // Regex توضیح:
+ // ^ : شروع رشته
+ // (?=.*[a-z]) : پیششرط: حداقل یک حرف کوچک (lookahead)
+ // (?=.*[A-Z]) : پیششرط: حداقل یک حرف بزرگ (lookahead)
+ // (?=.*\\d) : پیششرط: حداقل یک عدد (lookahead)
+ // (?=.*[!@#$%^&*]) : پیششرط: حداقل یک کاراکتر خاص (lookahead)
+ // [^\\s]{8,} : کاراکترهای غیر از فاصله، حداقل 8 بار تکرار شود
+ // $ : پایان رشته
+
+ String regex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*])[^\\s]{8,}$";
+ Pattern pattern = Pattern.compile(regex);
+ Matcher matcher = pattern.matcher(string);
+
+ int count = 0;
+ // matcher.find() را در حلقه استفاده میکنیم تا تمام پسوردهای معتبر در رشته را پیدا کنیم
+
+ String passwordRegex = "[^\\s]+";
+ Pattern passwordPattern = Pattern.compile(passwordRegex);
+ Matcher passwordMatcher = passwordPattern.matcher(string);
+
+ while(passwordMatcher.find()) {
+ String potentialPassword = passwordMatcher.group(0);
+ if (pattern.matcher(potentialPassword).matches())
+ { // چک میکنیم که آیا این پسورد کاندید، معتبر است یا نه
+ count++;
+ }
+ }
+ return count;
}
+
/*
you should return a list of *words* which are palindromic
by word we mean at least 3 letters with no whitespace in it
note: your implementation should be case-insensitive, e.g. Aba -> is palindrome
*/
- public List findPalindromes(String string) {
+
+ public List findPalindromes(String string)
+ {
List list = new ArrayList<>();
- // todo
+ String[] words = string.split("\\W+");
+
+ for (String word : words)
+ {
+ // شرط اول: کلمه حداقل 3 حرف داشته باشد
+ if (word.length() >= 3) {
+ // شرط دوم: case-insensitive بودن
+ String lowerCaseWord = word.toLowerCase();
+ String reversedWord = new StringBuilder(lowerCaseWord).reverse().toString();
+
+ // چک میکنیم که آیا کلمه معکوس شده با کلمه اصلی (بدون در نظر گرفتن case) برابر است
+ if (lowerCaseWord.equals(reversedWord))
+ {
+ list.add(word); // اگر پالیندروم بود، کلمه اصلی را به لیست اضافه کن
+ }
+ }
+ }
return list;
}
- public static void main(String[] args) {
- // you can test your code here
+ public static void main(String[] args)
+ {
+ BonusExercises be = new BonusExercises();
+
+ // تست validateEmail
+ System.out.println("Email Validation:");
+ System.out.println("test@example.com: " + be.validateEmail("test@example.com")); // true
+ System.out.println("test.user@domain.co.uk: " + be.validateEmail("test.user@domain.co.uk")); // true (بسته به regex)
+ System.out.println("invalid-email: " + be.validateEmail("invalid-email")); // false
+ System.out.println("@domain.com: " + be.validateEmail("@domain.com")); // false
+ System.out.println("test@.com: " + be.validateEmail("test@.com")); // false
+
+ System.out.println("\nFind Date:");
+ // تست findDate
+ System.out.println("12/09/2023: " + be.findDate("The date is 12/09/2023.")); // 12/09/2023
+ System.out.println("2024-07-15: " + be.findDate("Meeting scheduled for 2024-07-15.")); // 2024-07-15
+ System.out.println("2025/01/01: " + be.findDate("New year starts 2025/01/01.")); // 2025/01/01
+ System.out.println("No date here: " + be.findDate("Just some text.")); // null
+
+ System.out.println("\nFind Valid Passwords:");
+ // تست findValidPasswords
+ System.out.println("Password123!: " + be.findValidPasswords("Password123!")); // 1
+ System.out.println("password123!: " + be.findValidPasswords("password123!")); // 0 (no uppercase)
+ System.out.println("PASSWORD123!: " + be.findValidPasswords("PASSWORD123!")); // 0 (no lowercase)
+ System.out.println("PasswordAbc!: " + be.findValidPasswords("PasswordAbc!")); // 0 (no number)
+ System.out.println("Password123: " + be.findValidPasswords("Password123")); // 0 (no special char)
+ System.out.println("Pass 123!: " + be.findValidPasswords("Pass 123!")); // 0 (whitespace)
+ System.out.println("ComplexP@sswOrd123 A-stronger-password_too99#: " + be.findValidPasswords("ComplexP@sswOrd123 A-stronger-password_too99#")); // 2
+
+ System.out.println("\nFind Palindromes:");
+ // تست findPalindromes
+ System.out.println("madam racecar level: " + be.findPalindromes("madam racecar level"));
+ System.out.println("Aba, Civic, Noon: " + be.findPalindromes("Aba, Civic, Noon"));
+ System.out.println("hello world: " + be.findPalindromes("hello world"));
}
+
}
diff --git a/src/main/java/MainExercises.java b/src/main/java/MainExercises.java
index 21581ea..e2f4de4 100644
--- a/src/main/java/MainExercises.java
+++ b/src/main/java/MainExercises.java
@@ -1,3 +1,6 @@
+import java.util.List;
+import java.util.ArrayList;
+
public class MainExercises
{
/*
@@ -18,15 +21,27 @@ public class MainExercises
the output has to be a two-dimensional array of characters, so don't just print the triangle!
*/
- public char[][] generateTriangle(int n) {
+ public char[][] generateTriangle(int n)
+ {
- // todo
- return null;
+ char[][] triangle = new char[n][];
+ for (int i = 0; i < n; i++)
+ {
+ triangle[i] = new char[i + 1];
+
+ for (int j = 0; j <= i; j++)
+ {
+ if (i == n - 1 || j == 0 || j == i)
+ triangle[i][j] = '*';
+ else
+ triangle[i][j] = ' ';
+ }
+ }
+
+ return triangle;
}
-
-
/*
SPIRAL TRAVERSAL OF A RECTANGULAR MATRIX
@@ -57,11 +72,58 @@ public class MainExercises
- Number of rows: matrix.length
- Number of columns: matrix[0].length (if rectangular)
*/
- public int[] spiralTraversal(int[][] matrix) {
- // todo
- return null;
+ public int[] spiralTraversal(int[][] matrix)
+ {
+
+ int rows = matrix.length;
+ int cols = matrix[0].length;
+
+ int[] result = new int[rows * cols];
+ int index = 0;
+
+ int top = 0;
+ int bottom = rows - 1;
+ int left = 0;
+ int right = cols - 1;
+
+ while (top <= bottom && left <= right)
+ {
+
+ for (int i = left; i <= right; i++)
+ {
+ result[index++] = matrix[top][i];
+ }
+ top++;
+
+ for (int i = top; i <= bottom; i++)
+ {
+ result[index++] = matrix[i][right];
+ }
+ right--;
+
+ if (top <= bottom)
+ {
+ for (int i = right; i >= left; i--)
+ {
+ result[index++] = matrix[bottom][i];
+ }
+ bottom--;
+ }
+
+ if (left <= right)
+ {
+ for (int i = bottom; i >= top; i--)
+ {
+ result[index++] = matrix[i][left];
+ }
+ left++;
+ }
+ }
+
+ return result;
}
+
/*
integer partitioning is a combinatorics problem in discreet maths
the problem is to generate sum numbers which their summation is the input number
@@ -90,11 +152,32 @@ public class MainExercises
body to use them instead of arrays.
*/
- public int[][] intPartitions(int n) {
- // todo
- return null;
+
+ public int[][] intPartitions(int n)
+ {
+ List result = new ArrayList<>();
+ build(n, n, new ArrayList<>(), result);
+
+ return result.toArray(new int[0][]);
}
+ private void build(int remain, int max, List curr, List out)
+ {
+ if (remain == 0)
+ {
+ int[] arr = new int[curr.size()];
+ for (int i = 0; i < arr.length; i++) arr[i] = curr.get(i);
+ out.add(arr);
+ return;
+ }
+
+ for (int i = Math.min(remain, max); i >= 1; i--)
+ {
+ curr.add(i);
+ build(remain - i, i, curr, out);
+ curr.remove(curr.size() - 1);
+ }
+ }
public static void main()
{