Skip to content

Commit

Permalink
feat: Add PermutationOfPatternInString algorithm fixes #31
Browse files Browse the repository at this point in the history
  • Loading branch information
mohshin-shah authored and Mohshinsha Shahmadar committed Sep 9, 2024
1 parent 52e0abc commit 6e3d845
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 2 deletions.
76 changes: 76 additions & 0 deletions Sources/SlidingWindow/MinimumWindowMatchingPattern.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//
// PermutationOfPatternInString.swift
//
//
// Created by Mohshinsha Shahmadar on 2024-09-09.
//

import Foundation
/**
Problem Statement
Given a string and a pattern, find out if the string contains any permutation of the pattern.

Example 1:

Input: str="oidbcaf", pattern="abc"
Output: true
Explanation: The string contains "bca" which is a permutation of the given pattern.
Example 2:

Input: str="odicf", pattern="dc"
Output: false
Explanation: No permutation of the pattern is present in the given string as a substring.
Example 3:

Input: str="bcdxabcdy", pattern="bcdyabcdx"
Output: true
Explanation: Both the string and the pattern are a permutation of each other.
Example 4:

Input: str="aaacb", pattern="abc"
Output: true
Explanation: The string contains "acb" which is a permutation of the given pattern.
*/
func findPermutationOfPatternInString(
string: String,
pattern p: String
) -> Bool {
var windowStart = 0
let array = Array(string)
let pattern = Array(p)

let patternMap: [Character: Int] = pattern.reduce(into: [:]) { map, char in
map[char, default: 0] += 1
}

var matchCount = 0
var windowMap = [Character: Int]()

for (windowEnd, char) in string.enumerated() {
windowMap.increment(char)

// Check if the frequency of the current character matches that in the patternMap
if let patternFreq = patternMap[char], patternFreq == windowMap[char] {
matchCount += 1
}

if windowEnd >= pattern.count {
let windowStartChar = array[windowStart]

if let pC = patternMap[windowStartChar],
let wC = windowMap[windowStartChar],
pC == wC {
matchCount -= 1
}

windowMap.decrement(windowStartChar)
windowStart += 1
}

if matchCount == patternMap.count {
return true
}
}

return false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// PermutationOfPatternInStringTests.swift
//
//
// Created by Mohshinsha Shahmadar on 2024-09-09.
//

import Foundation
import XCTest
@testable import SwiftyAlgorithms

final class PermutationOfPatternInStringTests: XCTestCase {
func testPermutationOfPatternInString() {

let testCases: [AlgorithmTestCase] = [
.init((string: "oidbcaf", pattern: "abc"), true),
.init((string: "odicf", pattern: "dc"), false),
.init((string: "bcdxabcdy", pattern: "bcdyabcdx"), true),
.init((string: "aaacb", pattern: "abc"), true),
]

testAlgorithm(
name: "PermutationOfPatternInStringTests",
with: testCases
) { input in
findPermutationOfPatternInString(string: input.string, pattern: input.pattern)
}
}
}
4 changes: 2 additions & 2 deletions Tests/SwiftyAlgorithmsTests/TestEngine/AlgorithTestCase.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Foundation
import XCTest

/// Represents a generic test case for an algorithm with multiple inputs.
struct AlgorithmTestCase<Input, Output: Comparable> {
struct AlgorithmTestCase<Input, Output: Equatable> {
let input: Input
let expected: Output
let description: String?
Expand All @@ -29,7 +29,7 @@ extension XCTestCase {
/// - algorithmName: A human-readable name for the algorithm being tested.
/// - testCases: A list of test cases containing inputs (as tuples or structs) and expected outputs.
/// - algorithm: A closure that runs the algorithm with the given input.
func testAlgorithm<Input, Output: Comparable>(
func testAlgorithm<Input, Output: Equatable>(
name: String,
with testCases: [AlgorithmTestCase<Input, Output>],
algorithm: (Input) -> Output
Expand Down

0 comments on commit 6e3d845

Please sign in to comment.