├── .travis.yml
├── CodeChallenge.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ ├── CodeChallengeTests.xcscheme
│ │ └── CodeChallenge.xcscheme
└── project.pbxproj
├── CodeChallengeTests
├── Challenges
│ ├── LetterCombinationsOfPhoneNumberTests.swift
│ ├── LongestSubstringWithoutRepeatingCharactersTests.swift
│ ├── ClockTests.swift
│ ├── TwoSumTests.swift
│ └── BulletMatchTests.swift
├── Base
│ ├── ExampleChallengeTests.swift
│ └── CodeChallengeTestCase.swift
└── Info.plist
├── .gitignore
├── CodeChallenge
├── Challenges
│ ├── TwoSum
│ │ ├── Entries
│ │ │ ├── IanKeen.swift
│ │ │ ├── Aryaxt.swift
│ │ │ ├── AlexPersian.swift
│ │ │ ├── Nuudles.swift
│ │ │ ├── Logan.swift
│ │ │ ├── BugKrusha.swift
│ │ │ ├── Mosab.swift
│ │ │ ├── Aranasaurus.swift
│ │ │ └── juliand665TwoSumEntry.swift
│ │ └── TwoSumChallenge.swift
│ ├── BulletMatch
│ │ ├── Entries
│ │ │ ├── CodesmanBulletMatchEntry.swift
│ │ │ ├── juliand665BulletMatchEntry.swift
│ │ │ ├── FlavioSilverioBulletMatchEntry.swift
│ │ │ ├── matthijsBulletMatchEntry.swift
│ │ │ └── BugKrushaBulletMatchEntry.swift
│ │ └── BulletMatch.swift
│ ├── Clock
│ │ ├── Entries
│ │ │ ├── matthijsClockEntry.swift
│ │ │ ├── juliand665ClockEntry.swift
│ │ │ ├── BugKrushaClockEntry.swift
│ │ │ ├── FlavioSilverioClockEntry.swift
│ │ │ ├── BrandonShegaClockEntry.swift
│ │ │ ├── EthanSchatzline-ClockEntry.swift
│ │ │ └── felixdumitClockEntry.swift
│ │ ├── Clock.swift
│ │ └── Clock_dataset.json
│ ├── LongestSubstringWithoutRepeatingCharacters
│ │ ├── Entries
│ │ │ └── juliand665LSWRCEntry.swift
│ │ └── LongestSubstringWithoutRepeatingCharactersChallenge.swift
│ └── LetterCombinationsOfPhoneNumber
│ │ ├── Entries
│ │ ├── juliand665LetterCombinationOfPhoneNumberEntry.swift
│ │ ├── LoganWrightEntry.swift
│ │ └── BugKrushaLetterCombinationsOfPhoneNumberEntry.swift
│ │ └── LetterCombinationsOfPhoneNumberChallenge.swift
├── Info.plist
└── Base
│ ├── ExampleCodeChallenge.swift
│ └── CodeChallengeType.swift
├── LICENSE
└── README.md
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode8.2
3 |
4 | script:
5 | - xcodebuild test -scheme CodeChallengeTests -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.1'
--------------------------------------------------------------------------------
/CodeChallenge.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Challenges/LetterCombinationsOfPhoneNumberTests.swift:
--------------------------------------------------------------------------------
1 |
2 | import XCTest
3 | @testable import CodeChallenge
4 |
5 | class LetterCombinationsOfPhoneNumberTests: CodeChallengeTestCase {
6 | func testLetterCombinationsOfPhoneNumberEntries() {
7 | runTestsForChallenge(LetterCombinationsOfPhoneNumberChallenge())
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Challenges/LongestSubstringWithoutRepeatingCharactersTests.swift:
--------------------------------------------------------------------------------
1 |
2 | import XCTest
3 | @testable import CodeChallenge
4 |
5 | class LongestSubstringWithoutRepeatingCharactersTests: CodeChallengeTestCase {
6 | func testLetterCombinationsOfPhoneNumberEntries() {
7 | runTestsForChallenge(LongestSubstringWithoutRepeatingCharactersChallenge())
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Challenges/ClockTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ClockTests.swift
3 | // CodeChallenge
4 | //
5 | // Created by Jon-Tait Beason on 12/13/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeChallenge
11 |
12 | class ClockTests: CodeChallengeTestCase {
13 | func testClockEntries() {
14 | runTestsForChallenge(ClockChallenge())
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Challenges/TwoSumTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TwoSumTests.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | @testable import CodeChallenge
12 |
13 | class TwoSumTests: CodeChallengeTestCase {
14 | func testTwoSumEntries() {
15 | runTestsForChallenge(TwoSumChallenge())
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Challenges/BulletMatchTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BulletMatchTests.swift
3 | // CodeChallenge
4 | //
5 | // Created by Jon-Tait Beason on 12/19/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeChallenge
11 |
12 | class BulletMatchTests: CodeChallengeTestCase {
13 | func testBulletMatch() {
14 | runTestsForChallenge(BulletChallenge())
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Base/ExampleChallengeTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleChallengeTests.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | @testable import CodeChallenge
12 |
13 | class ExampleChallengeTests: CodeChallengeTestCase {
14 | func testExampleEntries() {
15 | runTestsForChallenge(ExampleCodeChallenge())
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata
19 |
20 | ## Other
21 | *.xccheckout
22 | *.moved-aside
23 | *.xcuserstate
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 | .DS_Store
30 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/Entries/IanKeen.swift:
--------------------------------------------------------------------------------
1 | //
2 | // IanKeen.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 11/1/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let ianKeenTwoSumEntry = CodeChallengeEntry(name: "IanKeen") { input in
12 | for (index, digit) in input.numbers.enumerated() {
13 | if let other = input.numbers.index(of: input.target - digit) {
14 | return (index + 1, Int(other) + 1)
15 | }
16 | }
17 | return nil
18 | }
19 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/Entries/Aryaxt.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Aryaxt.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let aryaxtTwoSumEntry = CodeChallengeEntry(name: "Aryaxt") { input in
12 | for i in 0..(name: "AlexPersian") { input in
12 | for i in 0..(name: "Nuudles") { input in
12 | var numberToIndex: [Int: Int] = [:]
13 | for (index, number) in input.numbers.enumerated()
14 | {
15 | if let pairIndex = numberToIndex[input.target - number]
16 | {
17 | return (first: pairIndex + 1, second: index + 1) // Why not 0 index? Silly
18 | }
19 | numberToIndex[number] = index
20 | }
21 | return nil
22 | }
23 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/Entries/Logan.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Logan.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 11/1/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let loganTwoSumEntry = CodeChallengeEntry(name: "Logan") { input in
12 | let lastIdx = input.numbers.count - 1
13 | for firstIdx in 0..(name: "codesman") { input in
12 | let weapon = input.0
13 | var cartridge = input.1
14 |
15 | for _ in cartridge.characters {
16 | guard cartridge != weapon else { return true }
17 | // Rotate the cartridge one scratch and try again!
18 | cartridge.insert(cartridge.remove(at: cartridge.startIndex), at: cartridge.endIndex)
19 | }
20 | return false
21 | }
22 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/BulletMatch/Entries/juliand665BulletMatchEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // juliand665BulletMatchEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Julian Dunskus on 06.01.17.
6 | // Copyright © 2017 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let juliand665BulletMatchEntry = CodeChallengeEntry(name: "juliand665", block: compare)
12 |
13 | private func compare(bullet: String, gun: String) -> Bool {
14 | var bul = bullet
15 |
16 | for _ in 1 ... bul.characters.count {
17 | // equate
18 | if bul == gun {
19 | return true
20 | }
21 | // rotate
22 | bul.characters.append(bul.characters.popFirst()!)
23 | }
24 |
25 | return false
26 | }
27 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Entries/matthijsClockEntry.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | private extension Array {
4 | // Applies func[i] to self[i]
5 | func mapfuncs(_ funcs: [([Element]) -> Element]) -> [Element] {
6 | precondition(funcs.count == self.count)
7 | var result: [Element] = []
8 | for i in 0..(name: "matthijs") { input in
16 |
17 | let output = input.components(separatedBy: ":").map({ Int($0)! }).mapfuncs([
18 | { x in ((x[0]*60 + x[1])*60 + x[2]) / 120 },
19 | { x in (x[1]*60 + x[2]) / 10 },
20 | { x in x[2] * 6 },
21 | ])
22 |
23 | return (output[0], output[1], output[2])
24 | }
25 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/LongestSubstringWithoutRepeatingCharacters/Entries/juliand665LSWRCEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // juliand665LSWRCEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Julian Dunskus on 06.01.17.
6 | // Copyright © 2017 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let juliand665LSWRCEntry = CodeChallengeEntry(name: "juliand665", block: lswrc)
12 |
13 | private func lswrc(in input: String) -> Int {
14 | var chars: [Character] = []
15 | var longest = 0
16 |
17 | for char in input.characters {
18 | if chars.contains(char) {
19 | chars.removeFirst(chars.index(of: char)! + 1)
20 | }
21 | chars.append(char)
22 | longest = max(longest, chars.count)
23 | }
24 |
25 | return longest
26 | }
27 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/Entries/BugKrusha.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BugKrusha.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let bugkrushaTwoSumEntry = CodeChallengeEntry(name: "Jazbo") { input in
12 | for (index, num) in input.numbers.enumerated() {
13 | for i in index + 1 ..< input.numbers.count {
14 | if calculate(input.numbers[i], numTwo: num, calculation: +) == input.target {
15 | return (index + 1, i + 1)
16 | }
17 | }
18 | }
19 | return nil
20 | }
21 |
22 | private func calculate(_ numOne: Int, numTwo: Int, calculation: (_ a: Int, _ b: Int) -> Int) -> Int {
23 | return calculation(numOne, numTwo)
24 | }
25 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/CodeChallenge/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Entries/juliand665ClockEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // juliand665ClockEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Julian Dunskus on 06.01.17.
6 | // Copyright © 2017 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let juliand665ClockEntry = CodeChallengeEntry(name: "juliand665", block: anglesOfHands)
12 |
13 | private func anglesOfHands(at input: String) -> (Int, Int, Int) {
14 | var time = input.components(separatedBy: ":").map { Int($0)! }
15 |
16 | time[2] *= 6
17 | time[1] *= 6
18 | time[1] += time[2] / 60
19 | time[0] *= 30
20 | time[0] += time[1] / 12
21 |
22 | return (time[0], time[1], time[2])
23 | }
24 |
25 | private func anglesOfHandsNice(at input: String) -> (Int, Int, Int) {
26 | let secs = input.components(separatedBy: ":").flatMap { Int($0) }.reduce(0) { $0 * 60 + $1 } // @teevee's `scan` would be really nice here
27 |
28 | return (secs * 360 / 43200, (secs % 3600) * 360 / 3600, (secs % 60) * 360 / 60)
29 | }
30 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/Entries/Mosab.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Mosab.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 11/1/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let mosabTwoSumEntry = CodeChallengeEntry(name: "Mosab") { input in
12 | var numbers = input.numbers
13 | var dictionary : [Int : Int] = [:] //Dictionary to hold numbers and indices
14 |
15 | for (index, number) in numbers.enumerated() {
16 | dictionary[number] = index
17 | }
18 |
19 | return findIndices(&dictionary, numbers: &numbers, target: input.target)
20 | }
21 |
22 | private func findIndices(_ map : inout [Int:Int], numbers : inout [Int], target : Int) -> (Int, Int)?
23 | {
24 | for (index, number) in numbers.enumerated()
25 | {
26 | if let index2 = map[abs(number - target)]
27 | {
28 | return (index + 1, index2 + 1) //offset by 1 so we're not 0 based
29 | }
30 | }
31 |
32 | return nil
33 | }
34 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/Entries/Aranasaurus.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Aranasaurus.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let aranasaurusTwoSumEntry = CodeChallengeEntry(name: "Aranasaurus") { input in
12 |
13 | var max = Datum(0, 0)
14 | let mid = input.target / 2
15 |
16 | for (i, number) in input.numbers.enumerated() {
17 | guard number >= 0 && number <= input.target && number >= mid else { continue }
18 |
19 | if number > max.number {
20 | if let diffIndex = input.numbers.index(of: input.target - number) {
21 | return (diffIndex + 1, i + 1)
22 | }
23 | max = Datum(i, number)
24 | }
25 | }
26 |
27 | return .none
28 | }
29 |
30 | private struct Datum {
31 | let index: Int
32 | let number: Int
33 |
34 | init(_ index: Int, _ number: Int) {
35 | self.index = index
36 | self.number = number
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Entries/BugKrushaClockEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BugKrusha.swift
3 | // CodeChallenge
4 | //
5 | // Created by Jon-Tait Beason on 12/13/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let bugKrushaClockEntry = CodeChallengeEntry(name: "bugkrusha") { input in
12 | let timeBreakDown = input.components(separatedBy: ":")
13 |
14 | let oneRevolution = 360.0
15 | let numberOfIntervals = 60.0
16 | let degreePerHour = 30.0
17 | let degreePerInterval = oneRevolution / numberOfIntervals
18 |
19 | guard
20 | let seconds = Double(timeBreakDown[2]),
21 | let minutes = Double(timeBreakDown[1]),
22 | let hours = Double(timeBreakDown[0])
23 | else { fatalError() }
24 |
25 | let secondsAngle = seconds * degreePerInterval
26 | let minutesAngle = minutes * degreePerInterval + (seconds/numberOfIntervals * degreePerInterval)
27 | let hoursAngle = hours * degreePerHour + (minutes/numberOfIntervals * degreePerHour)
28 |
29 | return (Int(hoursAngle), Int(minutesAngle), Int(secondsAngle))
30 | }
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 iOS Developers
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/BulletMatch/Entries/FlavioSilverioBulletMatchEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FlavioSilverioBulletMatchEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Flávio Silvério on 31/01/17.
6 | // Copyright © 2017 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let FlavioSilverioBulletMatchEntry = CodeChallengeEntry(name: "flaviodsilverio") { input in
12 |
13 | let bulletMarkings = input.0
14 | var gunMarkings = input.1
15 |
16 | for _ in 0...bulletMarkings.characters.count - 1 {
17 |
18 | if bulletMarkings == gunMarkings {
19 | return true
20 | } else {
21 |
22 | gunMarkings.characters.append(gunMarkings.remove(at: gunMarkings.startIndex))
23 |
24 | //made this second one to try it, it's way slower than the previous one...
25 | // gunMarkings.insert(gunMarkings.remove(
26 | // at: gunMarkings.startIndex),
27 | // at: gunMarkings.endIndex)
28 | }
29 |
30 | }
31 |
32 | return false
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Entries/FlavioSilverioClockEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FlavioSilverioClockEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Flávio Silvério on 15/12/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let FlavioSilverioClockEntry = CodeChallengeEntry(name: "flaviodsilverio") { input in
12 |
13 | let formatter = DateFormatter()
14 | formatter.dateFormat = "hh:mm:ss"
15 |
16 | guard let date = formatter.date(from: input) else {
17 | return (Int(0), Int(0), Int(0))
18 | }
19 |
20 | let calendar = Calendar.current
21 |
22 | let seconds = calendar.component(.second, from: date)
23 | let minutesAsSeconds = calendar.component(.minute, from: date) * 60 + seconds
24 | let hoursAsSeconds = calendar.component(.hour, from: date) * 3600 + minutesAsSeconds
25 |
26 | let secondsAngle = Int(360 / 60 * seconds)
27 | let minutesAngle = Int((Double(minutesAsSeconds) / Double(3600)) * 360)
28 | let hoursAngle = Int((Double(hoursAsSeconds) / Double(3600 * 12)) * 360)
29 |
30 | return (hoursAngle, minutesAngle, secondsAngle)
31 | }
32 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Entries/BrandonShegaClockEntry.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | let brandonShegaClockEntry = CodeChallengeEntry(name: "brandonshega") { input in
4 | let clock = Clock(for: input)
5 | return clock.timeInAngles
6 | }
7 |
8 | fileprivate struct Clock {
9 | let hour: Double
10 | let minute: Double
11 | let second: Double
12 |
13 | init(for date: String) {
14 | let df = DateFormatter()
15 | df.dateFormat = "hh:mm:ss"
16 | guard let date = df.date(from: date) else { fatalError("Bad Time") }
17 | let dateComps = Calendar.current.dateComponents([.hour, .minute, .second], from: date)
18 | guard
19 | let hour = dateComps.hour,
20 | let minute = dateComps.minute,
21 | let second = dateComps.second else { fatalError("Bad Time") }
22 | self.hour = Double(hour)
23 | self.minute = Double(minute)
24 | self.second = Double(second)
25 | }
26 |
27 | var timeInAngles: (Int, Int, Int) {
28 | let hoursToAngle = Int(hour * 30 + (minute/60 * 30))
29 | let minutesToAngle = Int(minute * 6 + (second/60 * 6))
30 | let secondsToAngle = Int(second * 6)
31 | return (hoursToAngle, minutesToAngle, secondsToAngle)
32 | }
33 |
34 | }
35 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/LetterCombinationsOfPhoneNumber/Entries/juliand665LetterCombinationOfPhoneNumberEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // juliand665LetterCombinationOfPhoneNumberEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Julian Dunskus on 06.01.17.
6 | // Copyright © 2017 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let juliand665LetterCombinationOfPhoneNumberEntry = CodeChallengeEntry(name: "juliand665", block: combinations)
12 |
13 | private func combinations(of input: String) -> [String] {
14 | var combs: [String] = [""]
15 |
16 | let expanded = input.characters.flatMap { numbersToLetters[$0] }
17 |
18 | for letters in expanded {
19 | combs = combs.flatMap { prev in
20 | letters.map { prev.appending($0) }
21 | }
22 | }
23 |
24 | return combs
25 | }
26 |
27 | private let numbersToLetters: [Character: [String]] = [ // explicit declaration reduces compile time
28 | "0": [" "],
29 | "1": [""],
30 | "2": ["a", "b", "c"],
31 | "3": ["d", "e", "f"],
32 | "4": ["g", "h", "i"],
33 | "5": ["j", "k", "l"],
34 | "6": ["m", "n", "o"],
35 | "7": ["p", "q", "r", "s"],
36 | "8": ["t", "u", "v"],
37 | "9": ["w", "x", "y", "z"],
38 | ]
39 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/BulletMatch/Entries/matthijsBulletMatchEntry.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | /*
4 | This is perhaps a bit of a weird solution. :-)
5 |
6 | If gun is || ||| |||| |
7 |
8 | then we glue two of these together to get:
9 |
10 | || ||| |||| | || ||| |||| |
11 |
12 | and then we try to find bullet as a substring:
13 |
14 | | || ||| ||||
15 |
16 | This is a match, yay!
17 |
18 | However, this approach can produce false positives, as in this example:
19 |
20 | |||| || |||| ||
21 | | ||||
22 |
23 | There is a matching substring but it's not a valid solution. To deal with
24 | this situation, we remove the parts of the string that match:
25 |
26 | |||| | ||
27 |
28 | If this is not identical to the original gun string, then the bullet did
29 | not come from the gun.
30 |
31 | It may sound slow but it's actually a very fast solution!
32 | */
33 |
34 | let matthijsBulletMatchEntry = CodeChallengeEntry(name: "matthijs") { (bullet, gun) in
35 | let gungun = gun + gun
36 | if let range = gungun.range(of: bullet) {
37 | let leftover = gungun.substring(to: range.lowerBound) + gungun.substring(from: range.upperBound)
38 | return (leftover == gun)
39 | }
40 | return false
41 | }
42 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/BulletMatch/Entries/BugKrushaBulletMatchEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BugKrushaBulletMatchEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Jon-Tait Beason on 12/19/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let bugKrushaBulletMatchEntry = CodeChallengeEntry(name: "bugKrusha") { input in
12 | let count = input.0.characters.count
13 |
14 | guard
15 | count == input.1.characters.count
16 | else { return false }
17 |
18 | var resets = count
19 | var bulletIndex = 0
20 | var gunIndex = 0
21 | var matches = 0
22 |
23 | let bulletMarks = input.0.characters.flatMap { String($0) }
24 | var gunMarks = input.1.characters.flatMap { String($0) }
25 |
26 | while resets >= 0 && gunIndex < count {
27 | if bulletMarks[bulletIndex] == gunMarks[gunIndex] {
28 | gunIndex += 1
29 | matches += 1
30 | bulletIndex += 1
31 | } else {
32 | let last = gunMarks.removeLast()
33 | gunMarks = [last] + gunMarks
34 | gunIndex = 0
35 | bulletIndex = 0
36 | matches = 0
37 |
38 | resets -= 1
39 | }
40 |
41 | if matches == count { return true }
42 | }
43 | return false
44 | }
45 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/LetterCombinationsOfPhoneNumber/Entries/LoganWrightEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LoganWrightEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Logan Wright on 11/8/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // MARK: Entry
12 |
13 | typealias PhoneCombinationsTest = CodeChallengeEntry
14 | let LoganWrightLetterCombinationOfPhoneNumberEntry =
15 | PhoneCombinationsTest(name: "LoganWright") { possibleCombinationsForPhoneNumber(phoneNumber: $0) }
16 |
17 | // MARK: Solution
18 |
19 | private let phoneNumberMap: [String : [String]] = [
20 | "2" : ["a", "b", "c"],
21 | "3" : ["d", "e", "f"],
22 | "4" : ["g", "h", "i"],
23 | "5" : ["j", "k", "l"],
24 | "6" : ["m", "n", "o"],
25 | "7" : ["p", "q", "r", "s"],
26 | "8" : ["t", "u", "v"],
27 | "9" : ["w", "x", "y", "z"]
28 | ]
29 |
30 | func possibleCombinationsForPhoneNumber(phoneNumber: String) -> [String] {
31 | return phoneNumber
32 | .characters
33 | .map { String($0) }
34 | .flatMap { phoneNumberMap[$0] }
35 | .reduce([]) { combinations, nextSet in
36 | guard !combinations.isEmpty else { return nextSet }
37 | return nextSet.flatMap { letter in
38 | return combinations.map { $0 + letter }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/CodeChallenge/Base/ExampleCodeChallenge.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ExampleCodeChallenge.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // Challenge Definition
12 |
13 | struct ExampleCodeChallenge: CodeChallengeType {
14 | typealias InputType = Int
15 | typealias OutputType = String
16 |
17 | let title = "Example Challenge"
18 |
19 | var entries: [CodeChallengeEntry] = [
20 | // Participants must add their entry instance to this array
21 | noobExampleEntry,
22 | proExampleEntry
23 | ]
24 |
25 | func generateDataset() -> [Int] {
26 | return [Int](1...1000)
27 | }
28 |
29 | func verifyOutput(_ output: String, forInput input: Int) -> Bool {
30 | return output == "\(input)"
31 | }
32 | }
33 |
34 | // Challenge Entries
35 |
36 | let noobExampleEntry = CodeChallengeEntry(name: "Crash Override") { input -> String in
37 | for i in 1...10000 {
38 | // Wait for the Gibson to come online.
39 | }
40 |
41 | guard arc4random_uniform(100) > 20 else {
42 | // Sometimes you gotta stick it to the man, if you _really_ wanna win.
43 | return "\(input-1)"
44 | }
45 | return "\(input)"
46 | }
47 |
48 | let proExampleEntry = CodeChallengeEntry(name: "Acid Burn") { input -> String in
49 | // Just do it.
50 | return "\(input)"
51 | }
52 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Entries/EthanSchatzline-ClockEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EthanSchatzline-ClockEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ethan Schatzline on 12/15/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | private struct Constants {
12 |
13 | static let maxDegrees: Double = 360.0
14 | static let hourTenth: Double = 1.0 / 12.0
15 | static let hourDegrees: Double = 30.0
16 | static let secondMinuteTenth: Double = 1.0 / 60.0
17 | static let minuteDegrees: Double = 6.0
18 | }
19 |
20 | let ethanSchatzlineClockEntry = CodeChallengeEntry(name: "ethan.schatzline") { input in
21 |
22 | let components = input.components(separatedBy: ":")
23 |
24 | guard components.count == 3,
25 | let hour = Double(components[0]),
26 | let minute = Double(components[1]),
27 | let second = Double(components[2])
28 | else { fatalError("Bad input") }
29 |
30 | let secondPercentage = second * Constants.secondMinuteTenth
31 | let minutePercentage = minute * Constants.secondMinuteTenth
32 | let hourPercentage = hour * Constants.hourTenth
33 |
34 | let secondAngle = Int(secondPercentage * Constants.maxDegrees)
35 |
36 | let minuteDegree = minutePercentage * Constants.maxDegrees
37 | let minuteOffset = secondPercentage * Constants.minuteDegrees
38 | let minuteAngle = Int(minuteDegree + minuteOffset)
39 |
40 | let hourDegree = hourPercentage * Constants.maxDegrees
41 | let hourOffset = minutePercentage * Constants.hourDegrees
42 | let hourAngle = Int(hourDegree + hourOffset)
43 |
44 | return (hourAngle, minuteAngle, secondAngle)
45 | }
46 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/LongestSubstringWithoutRepeatingCharacters/LongestSubstringWithoutRepeatingCharactersChallenge.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LongestSubstringWithoutRepeatingCharactersChallenge.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 11/1/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /*
12 | https://leetcode.com/problems/longest-substring-without-repeating-characters/
13 | Longest Substring Without Repeating Characters
14 |
15 | Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.
16 |
17 | */
18 | struct LongestSubstringWithoutRepeatingCharactersChallenge: CodeChallengeType {
19 | typealias InputType = String
20 | typealias OutputType = Int
21 |
22 | let title = "Longest Substring Without Repeating Characters"
23 |
24 | let entries: [CodeChallengeEntry] = [
25 | juliand665LSWRCEntry
26 | ]
27 |
28 | func generateDataset() -> [InputType] {
29 | return [
30 | "abcabcbb",
31 | "bbbbb",
32 | "",
33 | "jdjekjaoefeij"
34 | ]
35 | }
36 |
37 | func verifyOutput(_ output: OutputType, forInput input: InputType) -> Bool {
38 | guard let expected = verificationDictionary[input] else { return false }
39 | return output == expected
40 | }
41 |
42 | fileprivate let verificationDictionary = [
43 | "abcabcbb": 3,
44 | "bbbbb": 1,
45 | "": 0,
46 | "jdjekjaoefeij": 6
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/LetterCombinationsOfPhoneNumber/LetterCombinationsOfPhoneNumberChallenge.swift:
--------------------------------------------------------------------------------
1 | //
2 | // LetterCombinationsOfPhoneNumberChallenge.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 11/1/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | https://leetcode.com/problems/letter-combinations-of-a-phone-number/
13 | Letter Combinations of a Phone Number
14 |
15 | Given a digit string, return all possible letter combinations that the number could represent.
16 |
17 | A mapping of digit to letters (just like on the telephone buttons) is given below.
18 |
19 | 
20 |
21 | Input:Digit string "23"
22 | Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
23 | */
24 | struct LetterCombinationsOfPhoneNumberChallenge: CodeChallengeType {
25 | typealias InputType = String
26 | typealias OutputType = [String]
27 |
28 | let title = "Letter Combinations of Phone Number"
29 |
30 | let entries: [CodeChallengeEntry] = [
31 | bugKrushaLetterCombinationOfPhoneNumberEntry,
32 | LoganWrightLetterCombinationOfPhoneNumberEntry,
33 | juliand665LetterCombinationOfPhoneNumberEntry
34 | ]
35 |
36 | func generateDataset() -> [InputType] {
37 | return ["23"]
38 | }
39 |
40 | func verifyOutput(_ output: OutputType, forInput input: InputType) -> Bool {
41 | guard let expected = verificationDictionary[input] else { return false }
42 | return output.sorted(by: <) == expected.sorted(by: <)
43 | }
44 |
45 | fileprivate let verificationDictionary = [
46 | "23": ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/LetterCombinationsOfPhoneNumber/Entries/BugKrushaLetterCombinationsOfPhoneNumberEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BugKrusha.swift
3 | // CodeChallenge
4 | //
5 | // Created by Jon-Tait Beason on 11/2/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let bugKrushaLetterCombinationOfPhoneNumberEntry = CodeChallengeEntry(name: "bugKrusha") { input in
12 | return getCombinations(digitString: input)
13 | }
14 |
15 |
16 |
17 |
18 | private enum Digit: String {
19 | case Two = "abc"
20 | case Three = "def"
21 | case Four = "ghi"
22 | case Five = "jkl"
23 | case Six = "mno"
24 | case Seven = "pqrs"
25 | case Eight = "tuv"
26 | case Nine = "wxyz"
27 | }
28 |
29 |
30 | private func getCharactersForNumber(number: String) -> Digit? {
31 | switch number {
32 | case "2": return Digit.Two
33 | case "3": return Digit.Three
34 | case "4": return Digit.Four
35 | case "5": return Digit.Five
36 | case "6": return Digit.Six
37 | case "7": return Digit.Seven
38 | case "8": return Digit.Eight
39 | case "9": return Digit.Nine
40 | default: break
41 | }
42 |
43 | return nil
44 | }
45 |
46 | private func getCombinations(digitString: String) -> [String] {
47 | var arrayOfCharacterSets = [String]()
48 | for (index, character) in digitString.characters.enumerated() {
49 | if let charactersForNumber = getCharactersForNumber(number: "\(character)")?.rawValue {
50 | if index == 0 {
51 | arrayOfCharacterSets = charactersForNumber.characters.map { "\($0)" }
52 | } else {
53 | var tempArray = [String]()
54 | for char in charactersForNumber.characters {
55 | for characterSet in arrayOfCharacterSets {
56 | let newString = characterSet + "\(char)"
57 | tempArray.append(newString)
58 | }
59 | }
60 | arrayOfCharacterSets = tempArray
61 | }
62 | }
63 | }
64 | return arrayOfCharacterSets
65 | }
66 |
--------------------------------------------------------------------------------
/CodeChallenge.xcodeproj/xcshareddata/xcschemes/CodeChallengeTests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
14 |
15 |
17 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
39 |
40 |
41 |
42 |
48 |
49 |
51 |
52 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/Entries/juliand665TwoSumEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // juliand665TwoSumEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Julian Dunskus on 06.01.17.
6 | // Copyright © 2017 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | let juliand665TwoSumEntryNice = CodeChallengeEntry(name: "juliand665 (swiftier)", block: findPairNice)
12 |
13 | private func findPairNice(in nums: [Int], targeting target: Int) -> (Int, Int)? { // O(log n)
14 | var numbers = nums.enumerated().sorted() { $0.1 < $1.1 } // I assume the closure is making it slower
15 | var i1 = numbers.startIndex
16 | var i2 = numbers.endIndex - 1
17 |
18 | // how to C
19 | while true { // solution guaranteed
20 | let n1 = numbers[i1]
21 | let n2 = numbers[i2]
22 | let sum = n1.element + n2.element
23 | if sum == target {
24 | return (n1.offset + 1, n2.offset + 1) // O(1)
25 | } else if sum < target {
26 | i1 += 1
27 | } else {
28 | i2 -= 1
29 | }
30 | }
31 | }
32 |
33 | let juliand665TwoSumEntryFast = CodeChallengeEntry(name: "juliand665 (swifter)", block: findPairFast)
34 |
35 | private func findPairFast(in nums: [Int], targeting target: Int) -> (Int, Int)? { // O(log n)
36 |
37 | var numbers = nums.sorted()
38 | var i1 = numbers.startIndex
39 | var i2 = numbers.endIndex - 1
40 |
41 | // how to C
42 | while true { // solution guaranteed
43 | let n1 = numbers[i1]
44 | let n2 = numbers[i2]
45 | let sum = n1 + n2
46 | if sum == target {
47 | return (nums.index(of: n1)! + 1, nums.index(of: n2)! + 1) // O(n)
48 | // darn you, indices! sorting .enumerated() instead seems to be slower :(
49 | } else if sum < target {
50 | i1 += 1
51 | } else {
52 | i2 -= 1
53 | }
54 | }
55 | }
56 |
57 | let juliand665TwoSumEntryUgly = CodeChallengeEntry(name: "juliand665 (hardcoded)", block: findPairUgly)
58 |
59 | private func findPairUgly(in nums: [Int], targeting target: Int) -> (Int, Int)? { // O(n)
60 |
61 | var first: Int?
62 |
63 | for (index, num) in nums.enumerated() {
64 | if num > 2 {
65 | if let first = first {
66 | return (first + 1, index + 1) // why would you not want zero-based indices?
67 | }
68 | first = index
69 | }
70 | }
71 | return nil
72 | }
73 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/BulletMatch/BulletMatch.swift:
--------------------------------------------------------------------------------
1 | //
2 | // BulletMatch.swift
3 | // CodeChallenge
4 | //
5 | // Created by Jon-Tait Beason on 12/19/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Forensic specialists examine spent cartridges for unique
13 | markings left by parts of a gun. They can then compare
14 | these markings to the ones in any gun to determine if there
15 | is a match. A match means that the bullet was fired from
16 | that gun.
17 |
18 | Given two markings, one from a spent cartridge and the other
19 | from a suspected weapon, both as Strings, return true if they match
20 | and false if they don't.
21 |
22 | EXAMPLES:
23 | Match, returns true
24 | "| ||| | |" and
25 | "| ||| | |"
26 |
27 | Match, returns true though one is rotated. Bullets can be rotated.
28 | Your solution should account for the possible rotation of bullets.
29 | "|| ||| | " and
30 | " | || |||"
31 |
32 | Doesn't match, returns false
33 | "| ||| | |" and
34 | "||| | | |"
35 |
36 | NOTE: Markings cannot be flipped.
37 | "| ||" is not a match for
38 | "|| |"
39 |
40 | Problem adapted from http://bit.ly/2h57Wxe
41 | */
42 | final class BulletChallenge: JSONBasedChallenge {
43 | typealias InputType = (bulletMarkings: String, gunMarkings: String)
44 | typealias OutputType = Bool
45 |
46 | var title = "Bullet Challenge"
47 |
48 | // no `protected` access level (darn you, swift gods!)
49 | let fileName = "BulletMatch_dataset"
50 | var verificationData: [String : OutputType] = [:]
51 |
52 | var entries: [CodeChallengeEntry] = [
53 | bugKrushaBulletMatchEntry,
54 | codesmanBulletMatchEntry,
55 | juliand665BulletMatchEntry,
56 | FlavioSilverioBulletMatchEntry,
57 | matthijsBulletMatchEntry
58 | ]
59 |
60 | func input(from raw: String) -> InputType {
61 | let components = raw.components(separatedBy: "#")
62 | let gunMarkings = components[1]
63 | let bulletMarkings = components[0]
64 | return (bulletMarkings: bulletMarkings, gunMarkings: gunMarkings)
65 | }
66 |
67 | func raw(from input: InputType) -> String {
68 | return "\(input.bulletMarkings)#\(input.gunMarkings)"
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/TwoSum/TwoSumChallenge.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TwoSumChallenge.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/28/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /*
12 | Given an array of integers, find two numbers such that they add up to a specific target number.
13 |
14 | The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are not zero-based.
15 |
16 | You may assume that each input would have exactly one solution.
17 |
18 | Input: numbers={2, 7, 11, 15}, target=9
19 | Output: index1=1, index2=2
20 | */
21 | struct TwoSumChallenge: CodeChallengeType {
22 | typealias InputType = (numbers: [Int], target: Int)
23 | typealias OutputType = (first: Int, second: Int)?
24 |
25 | let title = "Two Sum Challenge"
26 |
27 | let entries: [CodeChallengeEntry] = [
28 | alexPersianTwoSumEntry,
29 | aranasaurusTwoSumEntry,
30 | aryaxtTwoSumEntry,
31 | bugkrushaTwoSumEntry,
32 | ianKeenTwoSumEntry,
33 | loganTwoSumEntry,
34 | mosabTwoSumEntry,
35 | nuudlesTwoSumEntry,
36 | juliand665TwoSumEntryFast,
37 | juliand665TwoSumEntryUgly
38 | ]
39 |
40 | func generateDataset() -> [InputType] {
41 | return [InputType(numbers: numbers, target: target)]
42 | }
43 |
44 | func verifyOutput(_ output: OutputType, forInput input: InputType) -> Bool {
45 | guard let output = output else { return false }
46 | return (numbers[output.first - 1] + numbers[output.second - 1] == target)
47 | }
48 | }
49 |
50 | private let target = 9
51 | private let numbers: [Int] = {
52 | let count = 1000
53 | var numbers = [Int]()
54 | for _ in 1...count {
55 | // target / 3 so that no 2 of these can add together to make target
56 | numbers.append(Int(arc4random_uniform(UInt32(target/3))))
57 | }
58 |
59 | let min = (target / 2)
60 | let max = (target - min)
61 | numbers.insert(min, at: Int(arc4random_uniform(UInt32(numbers.count))))
62 | numbers.insert(max, at: Int(arc4random_uniform(UInt32(numbers.count))))
63 | return numbers
64 | }()
65 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Clock.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Clock.swift
3 | // CodeChallenge
4 | //
5 | // Created by Jon-Tait Beason on 12/13/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | /**
12 | Given a time represented as a String, "HH:MM:SS",
13 | calculate the angle the hour hand, minute hand,
14 | and the second hand make clockwise from 12:00:00.
15 |
16 | The angles should be returned in a tuple as follows
17 | (hourHandAngle: Int, minuteHandAngle: Int, secondHandAndle: Int)
18 |
19 | EXAMPLES
20 | "06:00:00" should return (180, 0, 0)
21 | "08:30:00" should return (255, 180, 0)
22 | "10:17:55" should return (308, 107, 330)
23 |
24 | Adapted from http://bit.ly/2gEBhRh
25 | */
26 |
27 | final class ClockChallenge: JSONBasedChallenge {
28 | typealias InputType = String
29 | typealias OutputType = (hourHandeAngle: Int, minuteHandAngle: Int, secondHandAngle: Int)
30 |
31 | var title = "Clock Challenge"
32 |
33 | // no `protected` access level (darn you, swift gods!)
34 | let fileName = "Clock_dataset"
35 | var verificationData: [String: Int] = [:]
36 |
37 | var entries: [CodeChallengeEntry] = [
38 | bugKrushaClockEntry,
39 | FlavioSilverioClockEntry,
40 | ethanSchatzlineClockEntry,
41 | brandonShegaClockEntry,
42 | matthijsClockEntry,
43 | felixdumitClockEntry,
44 | juliand665ClockEntry
45 | ]
46 |
47 | // have to declare this explicitly because *of course* tuples are non-nominal and cannot be `Equatable`, despite being able to equate them
48 | func verifyOutput(_ output: (hourHandeAngle: Int, minuteHandAngle: Int, secondHandAngle: Int), forInput input: String) -> Bool {
49 | guard let expected = verificationData[input] else { return false }
50 | return (expected >> 20, expected >> 10 & 0x3ff, expected & 0x3ff) == output
51 | }
52 | }
53 |
54 | /* How I generated the dataset:
55 |
56 | func twoDigitString(from num: Int) -> String {
57 | return num < 10 ? "0\(num)" : "\(num)"
58 | }
59 |
60 | for h in 0...43200 {
61 | if arc4random_uniform(120) == 0 { // strip it down a little
62 | let m = h % 60
63 | let s = m % 60
64 | print("\"\(twoDigitString(from: h / 3600)):\(twoDigitString(from: h / 60 % 60)):\(twoDigitString(from: h % 60))\": \((h * 360 / 43200) << 20 | (m * 360 / 3600) << 10 | s * 360 / 60),")
65 | }
66 | }
67 |
68 | */
69 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Entries/felixdumitClockEntry.swift:
--------------------------------------------------------------------------------
1 | //
2 | // felixdumitClockEntry.swift
3 | // CodeChallenge
4 | //
5 | // Created by Felix Dumit on 12/22/16.
6 | // Copyright © 2016 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | private var dateFormatter: DateFormatter = {
12 | let df = DateFormatter()
13 | df.dateFormat = "HH:mm:ss"
14 | return df
15 | }()
16 |
17 | let felixdumitClockEntry = CodeChallengeEntry(name: "felix-dumit") { input in
18 | if #available(iOS 10.0, *) {
19 |
20 | guard let date = dateFormatter.date(from: input) else {
21 | fatalError("bad input")
22 | }
23 |
24 | func duration(for component: Calendar.Component) -> Measurement {
25 | let cmp = NSCalendar.current.component(component, from: date)
26 | return Measurement(value: Double(cmp), unit: component.durationUnit!)
27 | }
28 |
29 | let totalDuration = duration(for: .hour) + duration(for: .minute) + duration(for: .second)
30 |
31 | func clockAngle(unit: UnitDuration) -> Int {
32 | let percent = (totalDuration % unit.durationForClockFullTurn) / unit.durationForClockFullTurn
33 | return Int(360 * percent)
34 | }
35 |
36 | return (clockAngle(unit: .hours), clockAngle(unit: .minutes), clockAngle(unit: .seconds))
37 |
38 | } else {
39 | fatalError("this solution is only available for iOS10")
40 | }
41 | }
42 |
43 | @available(iOS 10.0, *)
44 | private func /(lhs: Measurement, rhs: Measurement) -> Double {
45 | return lhs.converted(to: D.baseUnit()).value / rhs.converted(to: D.baseUnit()).value
46 | }
47 |
48 | @available(iOS 10.0, *)
49 | private func %(lhs: Measurement, rhs: Measurement) -> Measurement {
50 | let value = lhs.converted(to: D.baseUnit()).value
51 | .truncatingRemainder(dividingBy: rhs.converted(to: D.baseUnit()).value)
52 | return Measurement(value: value, unit: D.baseUnit())
53 | }
54 |
55 | @available(iOS 10.0, *)
56 | private extension UnitDuration {
57 | var durationForClockFullTurn: Measurement {
58 | switch self {
59 | case UnitDuration.hours:
60 | return Measurement(value:12, unit: .hours)
61 | case UnitDuration.minutes:
62 | return Measurement(value:1, unit: .hours)
63 | case UnitDuration.seconds:
64 | return Measurement(value: 1, unit: .minutes)
65 | default: //should not happen
66 | return Measurement(value: 0, unit: .seconds)
67 | }
68 | }
69 | }
70 |
71 | @available(iOS 10.0, *)
72 | private extension Calendar.Component {
73 | var durationUnit: UnitDuration? {
74 | switch self {
75 | case .hour: return .hours
76 | case .minute: return .minutes
77 | case .second: return .seconds
78 | default: return nil
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/CodeChallengeTests/Base/CodeChallengeTestCase.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CodeChallengeTestCase.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import CodeChallenge
11 |
12 | class CodeChallengeTestCase: XCTestCase {
13 | /**
14 | Run all of the entries for the given challenge and print the results as nicely as we can to the console.
15 | */
16 | func runTestsForChallenge(_ challenge: ChallengeType) {
17 | // Do some formatting
18 | let charWidth = 116
19 | var headingText = "Calculating results for '\(challenge.title)'"
20 | let headingTextInnerCount = headingText.characters.count + 2
21 | headingText = headingText.padWithCharacter(" ", toLength: headingTextInnerCount)
22 | headingText = headingText.padWithCharacter("=", toLength: charWidth)
23 |
24 | let footingInnerText = "fin."
25 | var footingText = footingInnerText
26 | footingText = footingText.padWithCharacter(" ", toLength: headingTextInnerCount)
27 | footingText = footingText.padWithCharacter("=", toLength: charWidth)
28 |
29 | print(headingText)
30 | let results = challenge.runAll()
31 | printResults(results)
32 | print(footingText)
33 | }
34 |
35 | fileprivate func printResults(_ results: [AccumulatedChallengeResult]) {
36 | let formatter = NumberFormatter()
37 | formatter.numberStyle = .decimal
38 | formatter.minimumFractionDigits = 5
39 | formatter.maximumFractionDigits = 5
40 |
41 | var names = [String]()
42 | for (i, result) in results.enumerated() {
43 | names.append("\(i+1). \(result.name)")
44 | }
45 | let maxNameLength = names.reduce(0) { max($0, $1.characters.count) }
46 |
47 | for (i, result) in results.enumerated() {
48 | // Add spaces to the name to make the avg column line up with all results
49 | var nameAndNumber = names[i]
50 | while nameAndNumber.characters.count < maxNameLength {
51 | nameAndNumber.append(" ")
52 | }
53 | print("\(nameAndNumber) avg: \(formatter.string(from: NSDecimalNumber(decimal: Decimal(result.averageTime)))!)s\ttotal: \(formatter.string(from: NSDecimalNumber(decimal: Decimal(result.totalTime)))!)s\t[\(result.successRate * 100)% success rate]")
54 | }
55 | }
56 | }
57 |
58 | private extension String {
59 | func padWithCharacter(_ char: Character, toLength length: Int) -> String {
60 | let textLength = characters.count
61 | let paddedCharsCount = (length - textLength) / 2
62 | let paddedChars = String(repeating: String(char), count: paddedCharsCount)
63 | var retValue = "\(paddedChars)\(self)\(paddedChars)"
64 | while retValue.characters.count < length {
65 | retValue.append(char)
66 | }
67 | return retValue
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/CodeChallenge.xcodeproj/xcshareddata/xcschemes/CodeChallenge.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
65 |
71 |
72 |
73 |
74 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
94 |
95 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # code-challenges [](https://travis-ci.org/iosdevelopershq/code-challenges)
2 | Weekly(?) code challenges for the community to complete for learning and fun.
3 |
4 | # Submitting an Entry
5 | If you'd like to submit a solution to a challenge you'll do so by creating an instance of `CodeChallengeEntry` which specifies your name and a code block to run with your solution in it.
6 |
7 | Every challenge will have an implementation of `CodeChallengeType` which defines the `InputType` and `OutputType` that your solution block will need to take/return. This `CodeChallengeType` implementation should also include comments in it that describe the challenge itself, so it is your one-stop shop for figuring out what you need to do to successfully complete the challenge.
8 |
9 | Here's step-by-step instructions on how to get an entry submitted:
10 |
11 | 1. Fork the repo and clone it to your machine
12 | 2. Open the Xcode project and navigate to the CodeChallenge -> Challenges folder of the Challenge you'd like to submit an entry for.
13 | 3. Create a new file to put your solution in. Typically it should be named `yourUsername-challengeNameEntry.swift`.
14 | 4. In that file instantiate a `CodeChallengeEntry` object into a global named using the following format:
15 |
16 | ```
17 | let usernameChallengeNameEntry = CodeChallengeEntry(name: "username") { input in
18 | // Your implementation here, returning the appropriate `OutputType`
19 | }
20 | ```
21 | 5. Navigate to the `ChallengeNameChallenge.swift` file and add the global instance you created to the `Challenge`'s `entries` array.
22 | 6. To test your implementation and see how it compares to any previously submitted solutions just run the tests (⌘+U)!
23 | 7. Once you're happy with your results commit and push your changes to your fork and submit a Pull-Request back upstream.
24 |
25 | ## Some notes on etiquette
26 | Given that everybody's submissions all run in the same module and namespace it's good to take a few things into account while writing your solution:
27 |
28 | * It's a great idea to have additional `functions` or data structures to use in your implementation but please, if you do, mark them `private` so that they don't pollute the global namespace.
29 | * Don't `print` _anything_. These will probably get flagged when you submit your PR, but save us a step and just don't commit 'em (or use custom breakpoints to do the trick ;) )! Currently we use the debug console from the test runs to output the results of the challenge runs, so the less console noise the better.
30 |
31 | If you're just wanting to submit entries to an existing challenge, you're done! The rest of this README is for folks wanting to create new challenges, if that's you... read on!
32 |
33 |
34 |
35 | ---
36 |
37 | # Submitting a new Challenge
38 |
39 | In order to submit a new challenge you'll need to create an implementation of `CodeChallengeType`. This protocol defines:
40 | * The input and output types for the entries' `block` property
41 | * A title for the challenge
42 | * The Array of entries that will be run (you just have to make an empty array of the appropriate type: `[CodeChallengeEntry]`)
43 | * A function to generate the dataset which is just an array of `InputTypes` which will be fed to each entry over multiple iterations to run the challenge.
44 | * A function to verify the output of the entry for a given input.
45 |
46 | Your implementation should be named using the following format: `FooChallenge` for a Challenge named Foo. You should also include the description of the challenge as comments in this implementation file.
47 |
48 | This Challenge implementation should be created in a subfolder of the Challenges directory and, in this case, the subfolder would be named `Foo` and the file would be `FooChallenge.swift`.
49 |
50 | Check out `CodeChallenge/Base/ExampleCodeChallenge.swift` for a very simple challenge, or the TwoSum challenge for a bit more involved example.
51 |
52 | Last step is you'll need to add a test file for this challenge. The test mostly writes itself. Just create a new test in `CodeChallengeTests/Challenges/FooTests.swift` which will look approximately like this:
53 |
54 | ```
55 | @testable import CodeChallenge
56 |
57 | class FooTests: CodeChallengeTestCase {
58 | func testFooEntries() {
59 | runTestsForChallenge(FooChallenge())
60 | }
61 | }
62 | ```
63 |
64 | That's it! Submit a PR and watch everyone toil over your challenge!
65 |
--------------------------------------------------------------------------------
/CodeChallenge/Challenges/Clock/Clock_dataset.json:
--------------------------------------------------------------------------------
1 | {
2 | "00:00:01": 6,
3 | "00:01:17": 7270,
4 | "00:05:51": 2133298,
5 | "00:06:05": 3182622,
6 | "00:09:41": 4253942,
7 | "00:10:18": 5305452,
8 | "00:11:12": 5311560,
9 | "00:13:03": 6371346,
10 | "00:14:48": 7430432,
11 | "00:19:25": 9556118,
12 | "00:22:52": 11674936,
13 | "00:22:59": 11674978,
14 | "00:23:18": 11676780,
15 | "00:26:23": 13793418,
16 | "00:28:32": 14855360,
17 | "00:32:38": 16977124,
18 | "00:35:35": 18044114,
19 | "00:38:13": 20157518,
20 | "00:39:40": 20166896,
21 | "00:40:24": 21219472,
22 | "00:45:03": 23345170,
23 | "00:45:17": 23346278,
24 | "00:45:34": 23348428,
25 | "00:46:14": 24400980,
26 | "00:46:54": 24405316,
27 | "00:52:11": 27583554,
28 | "00:56:29": 29706414,
29 | "01:02:02": 32518156,
30 | "01:05:02": 33585164,
31 | "01:05:20": 33587320,
32 | "01:06:33": 34643142,
33 | "01:07:44": 34650376,
34 | "01:08:59": 35706210,
35 | "01:09:16": 35708000,
36 | "01:09:29": 35709102,
37 | "01:09:41": 35711222,
38 | "01:11:16": 36768864,
39 | "01:14:22": 38885508,
40 | "01:19:22": 41013380,
41 | "01:22:39": 43130090,
42 | "01:24:07": 44187690,
43 | "01:24:23": 44189834,
44 | "01:24:41": 44191990,
45 | "01:26:51": 45253938,
46 | "01:26:59": 45253986,
47 | "01:28:48": 46313760,
48 | "01:30:57": 47375702,
49 | "01:32:30": 48434356,
50 | "01:32:47": 48435482,
51 | "01:35:07": 49498154,
52 | "01:35:11": 49499202,
53 | "01:36:36": 50556120,
54 | "01:36:54": 50558276,
55 | "01:38:52": 51619128,
56 | "01:42:56": 53740880,
57 | "01:43:26": 53743772,
58 | "01:43:42": 53745916,
59 | "01:45:09": 54802486,
60 | "01:46:27": 55859362,
61 | "01:51:47": 57989402,
62 | "01:54:38": 60103908,
63 | "01:56:41": 61165814,
64 | "01:59:14": 62229588,
65 | "02:03:38": 63984868,
66 | "02:04:51": 65041714,
67 | "02:06:10": 66098236,
68 | "02:08:58": 67163484,
69 | "02:13:46": 69290260,
70 | "02:15:01": 70346758,
71 | "02:15:02": 70346764,
72 | "02:23:19": 74591346,
73 | "02:23:43": 74594562,
74 | "02:28:05": 77766686,
75 | "02:31:43": 78838018,
76 | "02:32:10": 79889468,
77 | "02:33:32": 79897792,
78 | "02:36:46": 82014484,
79 | "02:38:30": 83074228,
80 | "02:39:45": 83081486,
81 | "02:40:13": 84132942,
82 | "02:42:58": 85198172,
83 | "02:46:59": 87319906,
84 | "02:49:31": 88384698,
85 | "02:49:33": 88384710,
86 | "02:49:45": 88385806,
87 | "02:50:30": 89439412,
88 | "02:51:44": 89446664,
89 | "02:52:58": 90502492,
90 | "02:54:23": 91560074,
91 | "03:01:52": 94383416,
92 | "03:03:00": 95438848,
93 | "03:03:27": 95441058,
94 | "03:06:43": 97558786,
95 | "03:10:23": 99678346,
96 | "03:16:21": 102860926,
97 | "03:16:57": 102864214,
98 | "03:19:26": 103927964,
99 | "03:22:18": 106042476,
100 | "03:24:31": 107105466,
101 | "03:25:01": 107108358,
102 | "03:26:54": 108168516,
103 | "03:31:45": 110295310,
104 | "03:31:54": 110296388,
105 | "03:32:20": 111347832,
106 | "03:36:21": 113469566,
107 | "03:36:26": 113469596,
108 | "03:38:44": 114532616,
109 | "03:40:04": 115589144,
110 | "03:45:24": 117719184,
111 | "03:47:55": 118783306,
112 | "03:48:36": 119835864,
113 | "03:51:19": 120900722,
114 | "03:52:17": 121955430,
115 | "03:53:07": 121960490,
116 | "03:55:22": 123023492,
117 | "03:55:23": 123023498,
118 | "03:57:04": 124082200,
119 | "03:57:44": 124086536,
120 | "04:01:19": 125836402,
121 | "04:01:53": 125840702,
122 | "04:06:05": 129011742,
123 | "04:08:38": 130075876,
124 | "04:09:57": 130084182,
125 | "04:10:08": 131133488,
126 | "04:13:13": 132201550,
127 | "04:15:46": 133265684,
128 | "04:18:00": 135376896,
129 | "04:23:12": 137505864,
130 | "04:24:21": 138561662,
131 | "04:24:49": 138563878,
132 | "04:27:00": 139626496,
133 | "04:28:17": 140682342,
134 | "04:30:22": 141744260,
135 | "04:38:39": 145988842,
136 | "04:39:16": 145992800,
137 | "04:39:53": 145997118,
138 | "04:41:47": 147056922,
139 | "04:42:16": 148108384,
140 | "04:44:28": 149170344,
141 | "04:44:55": 149173578,
142 | "04:45:10": 149175356,
143 | "04:46:21": 150231166,
144 | "04:46:34": 150232268,
145 | "04:47:12": 150236232,
146 | "04:47:23": 150237322,
147 | "04:50:21": 152352894,
148 | "04:53:12": 153418824,
149 | "04:54:01": 154472454,
150 | "04:56:58": 155538780,
151 | "04:58:42": 156598524,
152 | "05:00:59": 157291874,
153 | "05:01:28": 157294760,
154 | "05:01:48": 157296928,
155 | "05:05:04": 159414296,
156 | "05:10:15": 162591834,
157 | "05:15:00": 164718592,
158 | "05:15:36": 164721880,
159 | "05:18:30": 166837428,
160 | "05:19:39": 166843626,
161 | "05:20:45": 167899406,
162 | "05:21:26": 167903388,
163 | "05:22:50": 168961324,
164 | "05:27:18": 171084908,
165 | "05:29:27": 172146850,
166 | "05:31:01": 173205510,
167 | "05:33:44": 174270728,
168 | "05:34:33": 175324358,
169 | "05:36:14": 176383060,
170 | "05:38:15": 177443930,
171 | "05:38:49": 177447206,
172 | "05:40:58": 178509148,
173 | "05:42:57": 179570006,
174 | "05:43:16": 179571808,
175 | "05:44:43": 180629762,
176 | "05:46:44": 181690632,
177 | "05:50:46": 183812372,
178 | "05:51:07": 183814186,
179 | "05:51:47": 183818522,
180 | "05:52:23": 184871050,
181 | "05:58:28": 188053672,
182 | "06:04:52": 190870840,
183 | "06:05:58": 190877020,
184 | "06:11:35": 194057426,
185 | "06:11:48": 194058528,
186 | "06:12:10": 195109948,
187 | "06:16:33": 197233862,
188 | "06:20:02": 199352332,
189 | "06:20:39": 199355626,
190 | "06:20:40": 199356656,
191 | "06:24:06": 201474084,
192 | "06:26:20": 202537080,
193 | "06:26:46": 202539284,
194 | "06:26:49": 202539302,
195 | "06:28:08": 203595824,
196 | "06:29:02": 203601932,
197 | "06:34:26": 206780572,
198 | "06:37:56": 207850832,
199 | "06:38:23": 208902282,
200 | "06:39:08": 208906288,
201 | "06:39:52": 208911672,
202 | "06:40:03": 209960978,
203 | "06:40:22": 209963140,
204 | "06:46:37": 213146846,
205 | "06:49:47": 214214938,
206 | "06:50:44": 215269640,
207 | "06:56:18": 218449004,
208 | "06:57:08": 218454064,
209 | "06:57:16": 218455136,
210 | "06:57:21": 218456190,
211 | "06:59:59": 219520354,
212 | "07:00:12": 220202056,
213 | "07:07:41": 223394038,
214 | "07:08:53": 224449854,
215 | "07:09:17": 224451686,
216 | "07:10:14": 225506388,
217 | "07:11:53": 225516862,
218 | "07:12:25": 226568342,
219 | "07:12:57": 226571606,
220 | "07:13:13": 226573390,
221 | "07:13:56": 226577744,
222 | "07:14:21": 227629182,
223 | "07:15:18": 227634284,
224 | "07:22:49": 231874854,
225 | "07:25:08": 232937520,
226 | "07:25:40": 232941808,
227 | "07:27:17": 233999462,
228 | "07:30:40": 236118256,
229 | "07:31:13": 236121166,
230 | "07:34:30": 238238900,
231 | "07:38:51": 240362802,
232 | "07:39:24": 240365712,
233 | "07:41:12": 241425480,
234 | "07:44:32": 243543232,
235 | "07:45:05": 243546142,
236 | "07:49:59": 245673314,
237 | "07:50:13": 246723662,
238 | "07:54:09": 248844342,
239 | "07:56:19": 249906290,
240 | "08:00:38": 251661540,
241 | "08:05:34": 253789388,
242 | "08:06:35": 254844114,
243 | "08:07:44": 254851336,
244 | "08:10:33": 256965830,
245 | "08:12:15": 258024538,
246 | "08:13:17": 258030694,
247 | "08:17:41": 260155638,
248 | "08:20:25": 262269078,
249 | "08:20:27": 262269090,
250 | "08:21:01": 262273030,
251 | "08:22:55": 263333194,
252 | "08:22:58": 263333212,
253 | "08:28:02": 266510348,
254 | "08:28:14": 266511444,
255 | "08:28:53": 266515774,
256 | "08:33:53": 268643646,
257 | "08:41:59": 272887138,
258 | "08:42:01": 273936390,
259 | "08:42:22": 273938564,
260 | "08:44:50": 275002668,
261 | "08:44:58": 275002716,
262 | "08:44:59": 275002722,
263 | "08:45:24": 275005584,
264 | "08:49:06": 277125156,
265 | "08:51:27": 278188194,
266 | "08:51:33": 278189254,
267 | "08:51:47": 278190362,
268 | "08:52:07": 279240746,
269 | "08:54:39": 280304874,
270 | "08:58:53": 282428734,
271 | "09:00:51": 283120946,
272 | "09:06:24": 286300304,
273 | "09:07:59": 286309730,
274 | "09:10:25": 288422038,
275 | "09:13:01": 289486854,
276 | "09:13:07": 289486890,
277 | "09:21:01": 293730310,
278 | "09:24:39": 295849194,
279 | "09:24:52": 295851320,
280 | "09:26:59": 296912226,
281 | "09:30:03": 299028498,
282 | "09:30:04": 299028504,
283 | "09:32:01": 300089350,
284 | "09:33:48": 300099872,
285 | "09:33:53": 300100926,
286 | "09:38:00": 303271936,
287 | "09:39:35": 303281362,
288 | "09:44:02": 306454540,
289 | "09:46:46": 307519764,
290 | "09:47:17": 307522662,
291 | "09:47:19": 307522674,
292 | "09:49:13": 308583502,
293 | "09:49:41": 308586742,
294 | "09:50:54": 309642564,
295 | "09:51:49": 309647654,
296 | "09:52:11": 310699074,
297 | "09:57:46": 312830228,
298 | "09:59:37": 313890014,
299 | "10:00:59": 314578274,
300 | "10:01:37": 314582238,
301 | "10:01:53": 314584382,
302 | "10:03:27": 315642018,
303 | "10:03:38": 315643108,
304 | "10:03:41": 315644150,
305 | "10:05:21": 316702846,
306 | "10:10:10": 319878204,
307 | "10:12:07": 320938026,
308 | "10:12:57": 320943446,
309 | "10:14:18": 321999980,
310 | "10:14:57": 322004310,
311 | "10:16:26": 323061916,
312 | "10:17:29": 323068078,
313 | "10:17:36": 323069144,
314 | "10:18:58": 324126044,
315 | "10:19:14": 324127828,
316 | "10:21:27": 325189794,
317 | "10:23:12": 326249544,
318 | "10:24:06": 327303204,
319 | "10:29:31": 329434298,
320 | "10:30:48": 330490144,
321 | "10:34:56": 332612944,
322 | "10:35:15": 332614746,
323 | "10:35:48": 332618016,
324 | "10:39:21": 334737534,
325 | "10:40:26": 335792284,
326 | "10:41:58": 335801692,
327 | "10:44:16": 337912928,
328 | "10:47:06": 338978852,
329 | "10:50:35": 341097682,
330 | "10:52:45": 342159630,
331 | "10:53:33": 342164678,
332 | "10:57:14": 344284244,
333 | "11:00:21": 346032254,
334 | "11:08:03": 350273554,
335 | "11:08:42": 350277884,
336 | "11:11:39": 351343850,
337 | "11:17:48": 354527520,
338 | "11:23:42": 357710076,
339 | "11:27:17": 359828582,
340 | "11:29:05": 360888350,
341 | "11:29:31": 360891578,
342 | "11:29:42": 360892668,
343 | "11:32:16": 363005024,
344 | "11:32:43": 363008258,
345 | "11:32:59": 363009378,
346 | "11:34:52": 364070200,
347 | "11:35:20": 364073080,
348 | "11:36:24": 365127824,
349 | "11:39:11": 366193730,
350 | "11:40:20": 367249528,
351 | "11:41:33": 367256774,
352 | "11:47:41": 370440438,
353 | "11:48:40": 371495152,
354 | "11:49:57": 371502422,
355 | "11:50:10": 372552764,
356 | "11:50:31": 372554938,
357 | "11:51:01": 372557830,
358 | "11:51:51": 372563250,
359 | "11:52:26": 373614748,
360 | "11:56:04": 375734296,
361 | "11:57:36": 375743704
362 | }
--------------------------------------------------------------------------------
/CodeChallenge/Base/CodeChallengeType.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CodeChallengeType.swift
3 | // CodeChallenge
4 | //
5 | // Created by Ryan Arana on 10/31/15.
6 | // Copyright © 2015 iosdevelopers. All rights reserved.
7 | //
8 |
9 | import Foundation
10 |
11 | // MARK: - Challenge Definition
12 |
13 | /**
14 | Protocol for defining a new Challenge.
15 |
16 | This protocol defines the Input/Output types for the Entry's `block` property. HINT: Use a tuple for multiple inputs! It also defines the interface that whatever will run the challenges (currently our tests) uses to run the entries and verify their output.
17 | */
18 | protocol CodeChallengeType {
19 | /// The type for the input(s) for the challenge.
20 | associatedtype InputType
21 | /// The type that the entry's function will return.
22 | associatedtype OutputType
23 |
24 | /// The heading title for this challenge
25 | var title: String { get }
26 |
27 | /// The entries to be run. Participants will need to add their `CodeChallengeEntry` instance to this array in the challeng's definition.
28 | var entries: [CodeChallengeEntry] { get }
29 |
30 | /**
31 | A function to generate the dataset that the entries will be run against. Each `InputType` in the returned array will be run by each entry multiple times and then averaged in the results.
32 | */
33 | func generateDataset() -> [InputType]
34 |
35 | /**
36 | A function which verifies the output from running an entry's block with the given input.
37 |
38 | - Returns: True if the output is valid, false if not.
39 | */
40 | func verifyOutput(_ output: OutputType, forInput input: InputType) -> Bool
41 | }
42 |
43 | /**
44 | Convenient protocol for defining challenges that verify entries using a JSON file.
45 |
46 | Fields required by `JSONBasedChallenge`:
47 | - `fileName`
48 | - `verificationData`
49 |
50 | Fields required by `CodeChallengeType`:
51 | - `title`
52 | - `entries`
53 | - `InputType`
54 | - `OutputType`
55 |
56 | In most cases, this should take over `generateDataset` and `verifyOutput` for you.
57 | The more your types are simple `String`s, the less methods you'll have to implement yourself.
58 | */
59 | protocol JSONBasedChallenge: class, CodeChallengeType {
60 |
61 | /// The type the output is encoded as in the JSON file. This can usually be inferred from methods you define; you shouldn't have to add it manually.
62 | associatedtype RawOutputType
63 |
64 | /// The name of the JSON file. You shouldn't need to add any path components in here.
65 | /// Recommended placement of the JSON file is in your challenge folder.
66 | var fileName: String { get }
67 |
68 | /// You have to implement this yourself, since protocols can't store anything for you. The types should match those of the JSON file.
69 | var verificationData: [String: RawOutputType] { get set }
70 |
71 |
72 | /// Converts the JSON key into an input for the challenge. (Used for dataset generation.)
73 | ///
74 | /// If your `InputType` is `String`, you don't have to implement this.
75 | ///
76 | /// - Parameter raw: Raw input from the JSON file
77 | /// - Returns: Input to feed into entries
78 | func input(from raw: String) -> InputType
79 |
80 | /// Converts the challenge input back into raw JSON. (Used for output verification.)
81 | ///
82 | /// If your `InputType` is `String`, you don't have to implement this.
83 | ///
84 | /// - Parameter input: Input used for the entry
85 | /// - Returns: Raw input, as in the JSON file, to use for accessing `verificationData`
86 | func raw(from input: InputType) -> String
87 | }
88 |
89 | // Default Implementations
90 |
91 | extension JSONBasedChallenge {
92 |
93 | func generateDataset() -> [InputType] {
94 | // Extract data from JSON file
95 | let bundle = Bundle(for: Self.self)
96 | guard
97 | let dataUrl = bundle.url(forResource: fileName, withExtension: "json"),
98 | let data = try? Data(contentsOf: dataUrl),
99 | let jsonObjects = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
100 | let vd = jsonObjects as? [String: RawOutputType] else { fatalError() }
101 |
102 | verificationData = vd
103 |
104 | // Map key `String`s to `InputType`
105 | return vd.keys.map { input(from: $0) }
106 | }
107 | }
108 |
109 | extension JSONBasedChallenge where OutputType: Equatable, RawOutputType == OutputType {
110 |
111 | func verifyOutput(_ output: OutputType, forInput input: InputType) -> Bool {
112 | guard let expected = verificationData[raw(from: input)] else { return false }
113 | return expected == output
114 | }
115 | }
116 |
117 | extension JSONBasedChallenge where InputType == String {
118 |
119 | func input(from raw: String) -> InputType {
120 | return raw
121 | }
122 |
123 | func raw(from input: InputType) -> String {
124 | return input
125 | }
126 | }
127 |
128 | // MARK: - Entry Definition
129 |
130 | /// An entry for a `CodeChallengeType`.
131 | struct CodeChallengeEntry {
132 | /// This entry's author's name.
133 | let name: String
134 |
135 | /// The block to be run to evaluate this entry.
136 | let block: (ChallengeType.InputType) -> ChallengeType.OutputType
137 | }
138 |
139 | // MARK: - Test Evaluation
140 |
141 | /// A structure to hold the result of a single run of an Entry's `block`.
142 | struct CodeChallengeResult {
143 | /// The name of the Entry's participant
144 | let name: String
145 |
146 | /// The input that generated the result.
147 | let input: ChallengeType.InputType
148 |
149 | /// The output received from the block. There should be one output in this array for each iteration, and the index will match the corresponding time measurement in the `times` array. NOTE: These should all be the same value, as they are all the result of the entry processing the same input, but we store them all here for just in case.
150 | let outputs: [ChallengeType.OutputType]
151 |
152 | /// The amount of wall-clock time it took to process the input. There should be one time measurment in this array for each iteration, and the index here will match the corresponding output in the `outputs` array.
153 | let times: [TimeInterval]
154 |
155 | /// The number of times the entry was run.
156 | let iterations: Int
157 |
158 | /// The total wall-clock time it took to process input `iterations` times.
159 | var totalTime: TimeInterval { return times.reduce(0) { $0 + $1 } }
160 |
161 | /// The average wall-clock time a single iteration took to process the input.
162 | var averageTime: TimeInterval {
163 | // computers don't like dividing by zero.
164 | guard times.count != 0 else { return TimeInterval.infinity }
165 | return Double(totalTime) / Double(times.count)
166 | }
167 | }
168 |
169 | /// A structure to hold the result of running an Entry's `block` multiple times.
170 | struct AccumulatedChallengeResult {
171 | /// The name of the Entry's participant.
172 | let name: String
173 |
174 | /// How many total runs does this AccumulatedResult represent.
175 | let total: Int
176 |
177 | /// How many of the runs passed verification.
178 | let successes: Int
179 |
180 | /// How many of the runs did not pass verification.
181 | let failures: Int
182 |
183 | /// The ratio of successes to failures (0.0 - 1.0)
184 | let successRate: Double
185 |
186 | /// The array of individual runs' `CodeChallengeResult`s.
187 | let results: [CodeChallengeResult]
188 |
189 | /// The total wall-clock time it took to process all results.
190 | let totalTime: TimeInterval
191 |
192 | /// The average wall-clock time a single iteration took to process its input.
193 | let averageTime: TimeInterval
194 |
195 | /**
196 | Create a new AccumulatedChallengeResult from the given set of results. The time properties will be calculated using the given parameters to this init.
197 | */
198 | init(name: String, results: [CodeChallengeResult], successes: Int, failures: Int) {
199 | self.name = name
200 | self.results = results
201 | self.successes = successes
202 | self.failures = failures
203 | self.total = successes + failures
204 | self.totalTime = results.reduce(0) { $0 + $1.totalTime }
205 | self.successRate = Double(successes) / Double(total)
206 |
207 | if total == 0 {
208 | self.averageTime = TimeInterval.infinity
209 | } else {
210 | self.averageTime = Double(results.reduce(0) { $0 + $1.averageTime }) / Double(total)
211 | }
212 | }
213 | }
214 |
215 | extension CodeChallengeType {
216 | fileprivate typealias ResultType = CodeChallengeResult
217 | fileprivate typealias OperationType = RunOperation
218 |
219 | typealias AccumulatedResultType = AccumulatedChallengeResult
220 |
221 | /**
222 | Run all of this Challenge's entries using the same generated dataset.
223 |
224 | This function calls `generateDataset()` and then runs each input in the dataset through each entry in the `entries` multiple times, concurrently. It then processes all of the `CodeChallengeResult`s into `AcummulatedChallengeResult`s for each participant and returns them sorted by `totalTime`.
225 |
226 | - Returns: An array of `AcummulatedChallengeResult`s for each participant sorted by `averageTime`.
227 | */
228 | func runAll() -> [AccumulatedResultType] {
229 |
230 | // Generate the dataset, everybody gets the same one
231 | let dataset = generateDataset()
232 |
233 | // Make a worker queue so that we can run through everything concurrently and save the runner some time.
234 | let workerQueue = OperationQueue()
235 | workerQueue.maxConcurrentOperationCount = 30
236 | var workers = [OperationType]()
237 | let iterations = 10
238 |
239 | // For each entry
240 | for entry in entries {
241 | workers.append(contentsOf: dataset.map { OperationType(entry: entry, input: $0, iterations: iterations) })
242 | }
243 |
244 | print("Adding \(workers.count) operations to the queue and running them \(min(workerQueue.maxConcurrentOperationCount, workers.count)) at a time")
245 | workerQueue.addOperations(workers, waitUntilFinished: true)
246 |
247 | // Gather up all of the results grouped by Participant name.
248 | var resultsByName = [String: [ResultType]]()
249 | for worker in workers {
250 | if resultsByName[worker.entry.name] == nil {
251 | resultsByName[worker.entry.name] = []
252 | }
253 | resultsByName[worker.entry.name]?.append(worker.result)
254 | }
255 |
256 | // Generate AccumulatedResults for each participant
257 | var accumulatedResults = [AccumulatedResultType]()
258 | for (name, results) in resultsByName {
259 | var successes = 0
260 | var failures = 0
261 | for result in results {
262 | for output in result.outputs {
263 | if verifyOutput(output, forInput: result.input) {
264 | successes += 1
265 | } else {
266 | failures += 1
267 | }
268 | }
269 | }
270 | let result = AccumulatedResultType(name: name, results: results, successes: successes, failures: failures)
271 | accumulatedResults.append(result)
272 | }
273 |
274 | // Return the accumulated results sorted by average time.
275 | return accumulatedResults.sorted { $0.averageTime < $1.averageTime }
276 | }
277 | }
278 |
279 | private class RunOperation: Operation {
280 | let entry: CodeChallengeEntry
281 | let input: ChallengeType.InputType
282 | let iterations: Int
283 |
284 | var result: CodeChallengeResult!
285 |
286 | init(entry: CodeChallengeEntry, input: ChallengeType.InputType, iterations: Int) {
287 | self.entry = entry
288 | self.input = input
289 | self.iterations = iterations
290 | }
291 |
292 | override func main() {
293 | var outputs = Array()
294 | var times = Array()
295 | for _ in 1...iterations {
296 | let start = Date()
297 | outputs.append(entry.block(input))
298 | times.append(-start.timeIntervalSinceNow)
299 | }
300 | result = CodeChallengeResult(name: entry.name, input: input, outputs: outputs, times: times, iterations: iterations)
301 | }
302 | }
303 |
--------------------------------------------------------------------------------
/CodeChallenge.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1B1F0A4E1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B1F0A4D1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift */; };
11 | 1B31586F1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B31586E1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift */; };
12 | 1B49C0501E0850D90094121E /* BugKrushaBulletMatchEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B49C04F1E0850D90094121E /* BugKrushaBulletMatchEntry.swift */; };
13 | 1B49C0531E0855C90094121E /* BulletMatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B49C0521E0855C90094121E /* BulletMatchTests.swift */; };
14 | 1B4ECDA51E08267B00767EBD /* BulletMatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B4ECDA41E08267B00767EBD /* BulletMatch.swift */; };
15 | 1B9E113F1E005A7C00B9FA5A /* Clock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B9E113E1E005A7C00B9FA5A /* Clock.swift */; };
16 | 1B9E11411E006A2B00B9FA5A /* BugKrushaClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B9E11401E006A2B00B9FA5A /* BugKrushaClockEntry.swift */; };
17 | 1B9E11461E006F0800B9FA5A /* ClockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B9E11451E006F0800B9FA5A /* ClockTests.swift */; };
18 | 1BBAB4801E41D6190038BCB1 /* FlavioSilverioBulletMatchEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1BBAB47F1E41D6190038BCB1 /* FlavioSilverioBulletMatchEntry.swift */; };
19 | 2EB83A801E03290400FAAB32 /* EthanSchatzline-ClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB83A7F1E03290400FAAB32 /* EthanSchatzline-ClockEntry.swift */; };
20 | 3D00956F1E03200C004E631A /* BrandonShegaClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D00956E1E03200C004E631A /* BrandonShegaClockEntry.swift */; };
21 | 7B1BF2D01E3F9CFA00AEAC0E /* matthijsBulletMatchEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B1BF2CF1E3F9CFA00AEAC0E /* matthijsBulletMatchEntry.swift */; };
22 | 7B925E521E05AFFF0009B0CD /* matthijsClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B925E511E05AFFF0009B0CD /* matthijsClockEntry.swift */; };
23 | 809B704A1BF01B68004131BE /* LoganWrightEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 809B70491BF01B68004131BE /* LoganWrightEntry.swift */; };
24 | 9272E1AF1BD7F6560030B403 /* CodeChallenge.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9272E1A41BD7F6560030B403 /* CodeChallenge.framework */; };
25 | 9272E1E41BDED71C0030B403 /* LongestSubstringWithoutRepeatingCharactersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9272E1E31BDED71C0030B403 /* LongestSubstringWithoutRepeatingCharactersTests.swift */; };
26 | 9272E1E61BDED73A0030B403 /* LetterCombinationsOfPhoneNumberTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9272E1E51BDED73A0030B403 /* LetterCombinationsOfPhoneNumberTests.swift */; };
27 | 94350F5F1BE5D721003592FB /* CodeChallengeTestCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F5E1BE5D721003592FB /* CodeChallengeTestCase.swift */; };
28 | 94350F611BE5D859003592FB /* ExampleChallengeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F601BE5D859003592FB /* ExampleChallengeTests.swift */; };
29 | 94350F651BE5E836003592FB /* TwoSumTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F641BE5E836003592FB /* TwoSumTests.swift */; };
30 | 94350F691BE5EB90003592FB /* Aranasaurus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F681BE5EB90003592FB /* Aranasaurus.swift */; };
31 | 94350F6B1BE5EBD3003592FB /* AlexPersian.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F6A1BE5EBD3003592FB /* AlexPersian.swift */; };
32 | 94350F701BE5EE94003592FB /* Aryaxt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F6F1BE5EE94003592FB /* Aryaxt.swift */; };
33 | 94350F721BE5EF9F003592FB /* BugKrusha.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F711BE5EF9F003592FB /* BugKrusha.swift */; };
34 | 94350F741BE5F04A003592FB /* IanKeen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F731BE5F04A003592FB /* IanKeen.swift */; };
35 | 94350F761BE5F0F6003592FB /* Logan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F751BE5F0F6003592FB /* Logan.swift */; };
36 | 94350F781BE5F174003592FB /* Mosab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F771BE5F174003592FB /* Mosab.swift */; };
37 | 94350F7A1BE5F24A003592FB /* Nuudles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94350F791BE5F24A003592FB /* Nuudles.swift */; };
38 | 944CFCD81BE72B3C00FD2E41 /* LetterCombinationsOfPhoneNumberChallenge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 944CFCD71BE72B3C00FD2E41 /* LetterCombinationsOfPhoneNumberChallenge.swift */; };
39 | 944CFCDB1BE7310B00FD2E41 /* LongestSubstringWithoutRepeatingCharactersChallenge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 944CFCDA1BE7310B00FD2E41 /* LongestSubstringWithoutRepeatingCharactersChallenge.swift */; };
40 | 9489866A1BE5CFB000D34976 /* CodeChallengeType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948986691BE5CFB000D34976 /* CodeChallengeType.swift */; };
41 | 948986701BE5D28500D34976 /* ExampleCodeChallenge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9489866F1BE5D28500D34976 /* ExampleCodeChallenge.swift */; };
42 | 94FB98CA1BE1B5D800228845 /* TwoSumChallenge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94FB98C91BE1B5D800228845 /* TwoSumChallenge.swift */; };
43 | 953445F81E21ED03008AC0B3 /* BulletMatch_dataset.json in Resources */ = {isa = PBXBuildFile; fileRef = 953445F71E21ED03008AC0B3 /* BulletMatch_dataset.json */; };
44 | 953445FA1E21ED07008AC0B3 /* Clock_dataset.json in Resources */ = {isa = PBXBuildFile; fileRef = 953445F91E21ED07008AC0B3 /* Clock_dataset.json */; };
45 | 9572008E1E1F19F9006BB4D6 /* juliand665BulletMatchEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9572008D1E1F19F9006BB4D6 /* juliand665BulletMatchEntry.swift */; };
46 | 957200991E206A35006BB4D6 /* juliand665LetterCombinationOfPhoneNumberEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 957200981E206A35006BB4D6 /* juliand665LetterCombinationOfPhoneNumberEntry.swift */; };
47 | 9572009C1E206A4B006BB4D6 /* juliand665LSWRCEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9572009B1E206A4B006BB4D6 /* juliand665LSWRCEntry.swift */; };
48 | 9572009E1E206A5E006BB4D6 /* juliand665ClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9572009D1E206A5E006BB4D6 /* juliand665ClockEntry.swift */; };
49 | 957200A01E206A65006BB4D6 /* juliand665TwoSumEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9572009F1E206A65006BB4D6 /* juliand665TwoSumEntry.swift */; };
50 | 957200A21E206A94006BB4D6 /* CodesmanBulletMatchEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 957200A11E206A94006BB4D6 /* CodesmanBulletMatchEntry.swift */; };
51 | D5D15B361E0C966A00CC9B1C /* felixdumitClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5D15B351E0C966A00CC9B1C /* felixdumitClockEntry.swift */; };
52 | /* End PBXBuildFile section */
53 |
54 | /* Begin PBXContainerItemProxy section */
55 | 9272E1B01BD7F6560030B403 /* PBXContainerItemProxy */ = {
56 | isa = PBXContainerItemProxy;
57 | containerPortal = 9272E19B1BD7F6560030B403 /* Project object */;
58 | proxyType = 1;
59 | remoteGlobalIDString = 9272E1A31BD7F6560030B403;
60 | remoteInfo = CodeChallange;
61 | };
62 | /* End PBXContainerItemProxy section */
63 |
64 | /* Begin PBXFileReference section */
65 | 1B1F0A4D1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BugKrushaLetterCombinationsOfPhoneNumberEntry.swift; sourceTree = ""; };
66 | 1B31586E1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlavioSilverioClockEntry.swift; sourceTree = ""; };
67 | 1B49C04F1E0850D90094121E /* BugKrushaBulletMatchEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BugKrushaBulletMatchEntry.swift; path = BulletMatch/Entries/BugKrushaBulletMatchEntry.swift; sourceTree = ""; };
68 | 1B49C0521E0855C90094121E /* BulletMatchTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BulletMatchTests.swift; sourceTree = ""; };
69 | 1B4ECDA41E08267B00767EBD /* BulletMatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BulletMatch.swift; path = BulletMatch/BulletMatch.swift; sourceTree = ""; };
70 | 1B9E113E1E005A7C00B9FA5A /* Clock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Clock.swift; sourceTree = ""; };
71 | 1B9E11401E006A2B00B9FA5A /* BugKrushaClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BugKrushaClockEntry.swift; sourceTree = ""; };
72 | 1B9E11451E006F0800B9FA5A /* ClockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClockTests.swift; sourceTree = ""; };
73 | 1BBAB47F1E41D6190038BCB1 /* FlavioSilverioBulletMatchEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FlavioSilverioBulletMatchEntry.swift; path = BulletMatch/Entries/FlavioSilverioBulletMatchEntry.swift; sourceTree = ""; };
74 | 2EB83A7F1E03290400FAAB32 /* EthanSchatzline-ClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "EthanSchatzline-ClockEntry.swift"; sourceTree = ""; };
75 | 3D00956E1E03200C004E631A /* BrandonShegaClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrandonShegaClockEntry.swift; sourceTree = ""; };
76 | 7B1BF2CF1E3F9CFA00AEAC0E /* matthijsBulletMatchEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = matthijsBulletMatchEntry.swift; path = BulletMatch/Entries/matthijsBulletMatchEntry.swift; sourceTree = ""; };
77 | 7B925E511E05AFFF0009B0CD /* matthijsClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = matthijsClockEntry.swift; sourceTree = ""; };
78 | 809B70491BF01B68004131BE /* LoganWrightEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoganWrightEntry.swift; sourceTree = ""; };
79 | 9272E1A41BD7F6560030B403 /* CodeChallenge.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CodeChallenge.framework; sourceTree = BUILT_PRODUCTS_DIR; };
80 | 9272E1AE1BD7F6560030B403 /* CodeChallenge.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CodeChallenge.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
81 | 9272E1B51BD7F6560030B403 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
82 | 9272E1E31BDED71C0030B403 /* LongestSubstringWithoutRepeatingCharactersTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LongestSubstringWithoutRepeatingCharactersTests.swift; sourceTree = ""; };
83 | 9272E1E51BDED73A0030B403 /* LetterCombinationsOfPhoneNumberTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LetterCombinationsOfPhoneNumberTests.swift; sourceTree = ""; };
84 | 94350F5A1BE5D698003592FB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
85 | 94350F5E1BE5D721003592FB /* CodeChallengeTestCase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeChallengeTestCase.swift; sourceTree = ""; };
86 | 94350F601BE5D859003592FB /* ExampleChallengeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleChallengeTests.swift; sourceTree = ""; };
87 | 94350F641BE5E836003592FB /* TwoSumTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoSumTests.swift; sourceTree = ""; };
88 | 94350F681BE5EB90003592FB /* Aranasaurus.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Aranasaurus.swift; sourceTree = ""; };
89 | 94350F6A1BE5EBD3003592FB /* AlexPersian.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlexPersian.swift; sourceTree = ""; };
90 | 94350F6F1BE5EE94003592FB /* Aryaxt.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Aryaxt.swift; sourceTree = ""; };
91 | 94350F711BE5EF9F003592FB /* BugKrusha.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BugKrusha.swift; sourceTree = ""; };
92 | 94350F731BE5F04A003592FB /* IanKeen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IanKeen.swift; sourceTree = ""; };
93 | 94350F751BE5F0F6003592FB /* Logan.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logan.swift; sourceTree = ""; };
94 | 94350F771BE5F174003592FB /* Mosab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mosab.swift; sourceTree = ""; };
95 | 94350F791BE5F24A003592FB /* Nuudles.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Nuudles.swift; sourceTree = ""; };
96 | 944CFCD71BE72B3C00FD2E41 /* LetterCombinationsOfPhoneNumberChallenge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LetterCombinationsOfPhoneNumberChallenge.swift; sourceTree = ""; };
97 | 944CFCDA1BE7310B00FD2E41 /* LongestSubstringWithoutRepeatingCharactersChallenge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LongestSubstringWithoutRepeatingCharactersChallenge.swift; sourceTree = ""; };
98 | 948986691BE5CFB000D34976 /* CodeChallengeType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CodeChallengeType.swift; sourceTree = ""; };
99 | 9489866F1BE5D28500D34976 /* ExampleCodeChallenge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExampleCodeChallenge.swift; sourceTree = ""; };
100 | 94FB98C91BE1B5D800228845 /* TwoSumChallenge.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoSumChallenge.swift; sourceTree = ""; };
101 | 953445F71E21ED03008AC0B3 /* BulletMatch_dataset.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = BulletMatch_dataset.json; path = BulletMatch/BulletMatch_dataset.json; sourceTree = ""; };
102 | 953445F91E21ED07008AC0B3 /* Clock_dataset.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Clock_dataset.json; sourceTree = ""; };
103 | 9572008D1E1F19F9006BB4D6 /* juliand665BulletMatchEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = juliand665BulletMatchEntry.swift; path = BulletMatch/Entries/juliand665BulletMatchEntry.swift; sourceTree = ""; };
104 | 957200981E206A35006BB4D6 /* juliand665LetterCombinationOfPhoneNumberEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = juliand665LetterCombinationOfPhoneNumberEntry.swift; sourceTree = ""; };
105 | 9572009B1E206A4B006BB4D6 /* juliand665LSWRCEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = juliand665LSWRCEntry.swift; sourceTree = ""; };
106 | 9572009D1E206A5E006BB4D6 /* juliand665ClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = juliand665ClockEntry.swift; sourceTree = ""; };
107 | 9572009F1E206A65006BB4D6 /* juliand665TwoSumEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = juliand665TwoSumEntry.swift; sourceTree = ""; };
108 | 957200A11E206A94006BB4D6 /* CodesmanBulletMatchEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = CodesmanBulletMatchEntry.swift; path = BulletMatch/Entries/CodesmanBulletMatchEntry.swift; sourceTree = ""; };
109 | D5D15B351E0C966A00CC9B1C /* felixdumitClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = felixdumitClockEntry.swift; sourceTree = ""; };
110 | /* End PBXFileReference section */
111 |
112 | /* Begin PBXFrameworksBuildPhase section */
113 | 9272E1A01BD7F6560030B403 /* Frameworks */ = {
114 | isa = PBXFrameworksBuildPhase;
115 | buildActionMask = 2147483647;
116 | files = (
117 | );
118 | runOnlyForDeploymentPostprocessing = 0;
119 | };
120 | 9272E1AB1BD7F6560030B403 /* Frameworks */ = {
121 | isa = PBXFrameworksBuildPhase;
122 | buildActionMask = 2147483647;
123 | files = (
124 | 9272E1AF1BD7F6560030B403 /* CodeChallenge.framework in Frameworks */,
125 | );
126 | runOnlyForDeploymentPostprocessing = 0;
127 | };
128 | /* End PBXFrameworksBuildPhase section */
129 |
130 | /* Begin PBXGroup section */
131 | 1B1F0A4C1BE7E9820030135C /* Entries */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 957200981E206A35006BB4D6 /* juliand665LetterCombinationOfPhoneNumberEntry.swift */,
135 | 1B1F0A4D1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift */,
136 | 809B70491BF01B68004131BE /* LoganWrightEntry.swift */,
137 | );
138 | path = Entries;
139 | sourceTree = "";
140 | };
141 | 1B49C0511E0850DD0094121E /* Entries */ = {
142 | isa = PBXGroup;
143 | children = (
144 | 957200A11E206A94006BB4D6 /* CodesmanBulletMatchEntry.swift */,
145 | 1B49C04F1E0850D90094121E /* BugKrushaBulletMatchEntry.swift */,
146 | 9572008D1E1F19F9006BB4D6 /* juliand665BulletMatchEntry.swift */,
147 | 1BBAB47F1E41D6190038BCB1 /* FlavioSilverioBulletMatchEntry.swift */,
148 | 7B1BF2CF1E3F9CFA00AEAC0E /* matthijsBulletMatchEntry.swift */,
149 | );
150 | name = Entries;
151 | sourceTree = "";
152 | };
153 | 1B4ECDA61E0826B000767EBD /* BulletMatch */ = {
154 | isa = PBXGroup;
155 | children = (
156 | 1B49C0511E0850DD0094121E /* Entries */,
157 | 1B4ECDA41E08267B00767EBD /* BulletMatch.swift */,
158 | 953445F71E21ED03008AC0B3 /* BulletMatch_dataset.json */,
159 | );
160 | name = BulletMatch;
161 | sourceTree = "";
162 | };
163 | 1B9E11421E006A2F00B9FA5A /* Entries */ = {
164 | isa = PBXGroup;
165 | children = (
166 | 9572009D1E206A5E006BB4D6 /* juliand665ClockEntry.swift */,
167 | 3D00956E1E03200C004E631A /* BrandonShegaClockEntry.swift */,
168 | 1B9E11401E006A2B00B9FA5A /* BugKrushaClockEntry.swift */,
169 | 2EB83A7F1E03290400FAAB32 /* EthanSchatzline-ClockEntry.swift */,
170 | 1B31586E1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift */,
171 | 7B925E511E05AFFF0009B0CD /* matthijsClockEntry.swift */,
172 | D5D15B351E0C966A00CC9B1C /* felixdumitClockEntry.swift */,
173 | );
174 | path = Entries;
175 | sourceTree = "";
176 | };
177 | 1B9E11471E010A3500B9FA5A /* Clock */ = {
178 | isa = PBXGroup;
179 | children = (
180 | 1B9E11421E006A2F00B9FA5A /* Entries */,
181 | 1B9E113E1E005A7C00B9FA5A /* Clock.swift */,
182 | 953445F91E21ED07008AC0B3 /* Clock_dataset.json */,
183 | );
184 | path = Clock;
185 | sourceTree = "";
186 | };
187 | 9272E19A1BD7F6560030B403 = {
188 | isa = PBXGroup;
189 | children = (
190 | 9272E1A61BD7F6560030B403 /* CodeChallenge */,
191 | 9272E1B21BD7F6560030B403 /* CodeChallengeTests */,
192 | 9272E1A51BD7F6560030B403 /* Products */,
193 | );
194 | sourceTree = "";
195 | };
196 | 9272E1A51BD7F6560030B403 /* Products */ = {
197 | isa = PBXGroup;
198 | children = (
199 | 9272E1A41BD7F6560030B403 /* CodeChallenge.framework */,
200 | 9272E1AE1BD7F6560030B403 /* CodeChallenge.xctest */,
201 | );
202 | name = Products;
203 | sourceTree = "";
204 | };
205 | 9272E1A61BD7F6560030B403 /* CodeChallenge */ = {
206 | isa = PBXGroup;
207 | children = (
208 | 948986681BE5CEB400D34976 /* Base */,
209 | 94350F591BE5D5C1003592FB /* Challenges */,
210 | 94350F5A1BE5D698003592FB /* Info.plist */,
211 | );
212 | path = CodeChallenge;
213 | sourceTree = "";
214 | };
215 | 9272E1B21BD7F6560030B403 /* CodeChallengeTests */ = {
216 | isa = PBXGroup;
217 | children = (
218 | 94350F621BE5D89F003592FB /* Base */,
219 | 94350F631BE5E7DD003592FB /* Challenges */,
220 | 9272E1B51BD7F6560030B403 /* Info.plist */,
221 | );
222 | path = CodeChallengeTests;
223 | sourceTree = "";
224 | };
225 | 94350F591BE5D5C1003592FB /* Challenges */ = {
226 | isa = PBXGroup;
227 | children = (
228 | 1B9E11471E010A3500B9FA5A /* Clock */,
229 | 94350F661BE5EB21003592FB /* TwoSum */,
230 | 944CFCD61BE72AEB00FD2E41 /* LetterCombinationsOfPhoneNumber */,
231 | 944CFCD91BE730A700FD2E41 /* LongestSubstringWithoutRepeatingCharacters */,
232 | 1B4ECDA61E0826B000767EBD /* BulletMatch */,
233 | );
234 | path = Challenges;
235 | sourceTree = "";
236 | };
237 | 94350F621BE5D89F003592FB /* Base */ = {
238 | isa = PBXGroup;
239 | children = (
240 | 94350F5E1BE5D721003592FB /* CodeChallengeTestCase.swift */,
241 | 94350F601BE5D859003592FB /* ExampleChallengeTests.swift */,
242 | );
243 | path = Base;
244 | sourceTree = "";
245 | };
246 | 94350F631BE5E7DD003592FB /* Challenges */ = {
247 | isa = PBXGroup;
248 | children = (
249 | 94350F641BE5E836003592FB /* TwoSumTests.swift */,
250 | 1B49C0521E0855C90094121E /* BulletMatchTests.swift */,
251 | 9272E1E51BDED73A0030B403 /* LetterCombinationsOfPhoneNumberTests.swift */,
252 | 1B9E11451E006F0800B9FA5A /* ClockTests.swift */,
253 | 9272E1E31BDED71C0030B403 /* LongestSubstringWithoutRepeatingCharactersTests.swift */,
254 | );
255 | path = Challenges;
256 | sourceTree = "";
257 | };
258 | 94350F661BE5EB21003592FB /* TwoSum */ = {
259 | isa = PBXGroup;
260 | children = (
261 | 94350F671BE5EB38003592FB /* Entries */,
262 | 94FB98C91BE1B5D800228845 /* TwoSumChallenge.swift */,
263 | );
264 | path = TwoSum;
265 | sourceTree = "";
266 | };
267 | 94350F671BE5EB38003592FB /* Entries */ = {
268 | isa = PBXGroup;
269 | children = (
270 | 9572009F1E206A65006BB4D6 /* juliand665TwoSumEntry.swift */,
271 | 94350F681BE5EB90003592FB /* Aranasaurus.swift */,
272 | 94350F6A1BE5EBD3003592FB /* AlexPersian.swift */,
273 | 94350F6F1BE5EE94003592FB /* Aryaxt.swift */,
274 | 94350F711BE5EF9F003592FB /* BugKrusha.swift */,
275 | 94350F731BE5F04A003592FB /* IanKeen.swift */,
276 | 94350F751BE5F0F6003592FB /* Logan.swift */,
277 | 94350F771BE5F174003592FB /* Mosab.swift */,
278 | 94350F791BE5F24A003592FB /* Nuudles.swift */,
279 | );
280 | path = Entries;
281 | sourceTree = "";
282 | };
283 | 944CFCD61BE72AEB00FD2E41 /* LetterCombinationsOfPhoneNumber */ = {
284 | isa = PBXGroup;
285 | children = (
286 | 1B1F0A4C1BE7E9820030135C /* Entries */,
287 | 944CFCD71BE72B3C00FD2E41 /* LetterCombinationsOfPhoneNumberChallenge.swift */,
288 | );
289 | path = LetterCombinationsOfPhoneNumber;
290 | sourceTree = "";
291 | };
292 | 944CFCD91BE730A700FD2E41 /* LongestSubstringWithoutRepeatingCharacters */ = {
293 | isa = PBXGroup;
294 | children = (
295 | 9572009A1E206A4B006BB4D6 /* Entries */,
296 | 944CFCDA1BE7310B00FD2E41 /* LongestSubstringWithoutRepeatingCharactersChallenge.swift */,
297 | );
298 | path = LongestSubstringWithoutRepeatingCharacters;
299 | sourceTree = "";
300 | };
301 | 948986681BE5CEB400D34976 /* Base */ = {
302 | isa = PBXGroup;
303 | children = (
304 | 948986691BE5CFB000D34976 /* CodeChallengeType.swift */,
305 | 9489866F1BE5D28500D34976 /* ExampleCodeChallenge.swift */,
306 | );
307 | path = Base;
308 | sourceTree = "";
309 | };
310 | 9572009A1E206A4B006BB4D6 /* Entries */ = {
311 | isa = PBXGroup;
312 | children = (
313 | 9572009B1E206A4B006BB4D6 /* juliand665LSWRCEntry.swift */,
314 | );
315 | path = Entries;
316 | sourceTree = "";
317 | };
318 | /* End PBXGroup section */
319 |
320 | /* Begin PBXHeadersBuildPhase section */
321 | 9272E1A11BD7F6560030B403 /* Headers */ = {
322 | isa = PBXHeadersBuildPhase;
323 | buildActionMask = 2147483647;
324 | files = (
325 | );
326 | runOnlyForDeploymentPostprocessing = 0;
327 | };
328 | /* End PBXHeadersBuildPhase section */
329 |
330 | /* Begin PBXNativeTarget section */
331 | 9272E1A31BD7F6560030B403 /* CodeChallenge */ = {
332 | isa = PBXNativeTarget;
333 | buildConfigurationList = 9272E1B81BD7F6560030B403 /* Build configuration list for PBXNativeTarget "CodeChallenge" */;
334 | buildPhases = (
335 | 9272E19F1BD7F6560030B403 /* Sources */,
336 | 9272E1A01BD7F6560030B403 /* Frameworks */,
337 | 9272E1A11BD7F6560030B403 /* Headers */,
338 | 9272E1A21BD7F6560030B403 /* Resources */,
339 | );
340 | buildRules = (
341 | );
342 | dependencies = (
343 | );
344 | name = CodeChallenge;
345 | productName = CodeChallange;
346 | productReference = 9272E1A41BD7F6560030B403 /* CodeChallenge.framework */;
347 | productType = "com.apple.product-type.framework";
348 | };
349 | 9272E1AD1BD7F6560030B403 /* CodeChallengeTests */ = {
350 | isa = PBXNativeTarget;
351 | buildConfigurationList = 9272E1BB1BD7F6560030B403 /* Build configuration list for PBXNativeTarget "CodeChallengeTests" */;
352 | buildPhases = (
353 | 9272E1AA1BD7F6560030B403 /* Sources */,
354 | 9272E1AB1BD7F6560030B403 /* Frameworks */,
355 | 9272E1AC1BD7F6560030B403 /* Resources */,
356 | );
357 | buildRules = (
358 | );
359 | dependencies = (
360 | 9272E1B11BD7F6560030B403 /* PBXTargetDependency */,
361 | );
362 | name = CodeChallengeTests;
363 | productName = CodeChallangeTests;
364 | productReference = 9272E1AE1BD7F6560030B403 /* CodeChallenge.xctest */;
365 | productType = "com.apple.product-type.bundle.unit-test";
366 | };
367 | /* End PBXNativeTarget section */
368 |
369 | /* Begin PBXProject section */
370 | 9272E19B1BD7F6560030B403 /* Project object */ = {
371 | isa = PBXProject;
372 | attributes = {
373 | LastSwiftUpdateCheck = 0710;
374 | LastUpgradeCheck = 0810;
375 | ORGANIZATIONNAME = iosdevelopers;
376 | TargetAttributes = {
377 | 9272E1A31BD7F6560030B403 = {
378 | CreatedOnToolsVersion = 7.0;
379 | LastSwiftMigration = 0810;
380 | };
381 | 9272E1AD1BD7F6560030B403 = {
382 | CreatedOnToolsVersion = 7.0;
383 | LastSwiftMigration = 0810;
384 | };
385 | };
386 | };
387 | buildConfigurationList = 9272E19E1BD7F6560030B403 /* Build configuration list for PBXProject "CodeChallenge" */;
388 | compatibilityVersion = "Xcode 3.2";
389 | developmentRegion = English;
390 | hasScannedForEncodings = 0;
391 | knownRegions = (
392 | en,
393 | Base,
394 | );
395 | mainGroup = 9272E19A1BD7F6560030B403;
396 | productRefGroup = 9272E1A51BD7F6560030B403 /* Products */;
397 | projectDirPath = "";
398 | projectRoot = "";
399 | targets = (
400 | 9272E1A31BD7F6560030B403 /* CodeChallenge */,
401 | 9272E1AD1BD7F6560030B403 /* CodeChallengeTests */,
402 | );
403 | };
404 | /* End PBXProject section */
405 |
406 | /* Begin PBXResourcesBuildPhase section */
407 | 9272E1A21BD7F6560030B403 /* Resources */ = {
408 | isa = PBXResourcesBuildPhase;
409 | buildActionMask = 2147483647;
410 | files = (
411 | 953445F81E21ED03008AC0B3 /* BulletMatch_dataset.json in Resources */,
412 | 953445FA1E21ED07008AC0B3 /* Clock_dataset.json in Resources */,
413 | );
414 | runOnlyForDeploymentPostprocessing = 0;
415 | };
416 | 9272E1AC1BD7F6560030B403 /* Resources */ = {
417 | isa = PBXResourcesBuildPhase;
418 | buildActionMask = 2147483647;
419 | files = (
420 | );
421 | runOnlyForDeploymentPostprocessing = 0;
422 | };
423 | /* End PBXResourcesBuildPhase section */
424 |
425 | /* Begin PBXSourcesBuildPhase section */
426 | 9272E19F1BD7F6560030B403 /* Sources */ = {
427 | isa = PBXSourcesBuildPhase;
428 | buildActionMask = 2147483647;
429 | files = (
430 | 957200A21E206A94006BB4D6 /* CodesmanBulletMatchEntry.swift in Sources */,
431 | 94350F7A1BE5F24A003592FB /* Nuudles.swift in Sources */,
432 | 957200991E206A35006BB4D6 /* juliand665LetterCombinationOfPhoneNumberEntry.swift in Sources */,
433 | 94350F6B1BE5EBD3003592FB /* AlexPersian.swift in Sources */,
434 | 1B9E113F1E005A7C00B9FA5A /* Clock.swift in Sources */,
435 | 1B9E11411E006A2B00B9FA5A /* BugKrushaClockEntry.swift in Sources */,
436 | 94350F781BE5F174003592FB /* Mosab.swift in Sources */,
437 | 9572008E1E1F19F9006BB4D6 /* juliand665BulletMatchEntry.swift in Sources */,
438 | 94FB98CA1BE1B5D800228845 /* TwoSumChallenge.swift in Sources */,
439 | 7B925E521E05AFFF0009B0CD /* matthijsClockEntry.swift in Sources */,
440 | 2EB83A801E03290400FAAB32 /* EthanSchatzline-ClockEntry.swift in Sources */,
441 | 957200A01E206A65006BB4D6 /* juliand665TwoSumEntry.swift in Sources */,
442 | 9489866A1BE5CFB000D34976 /* CodeChallengeType.swift in Sources */,
443 | 1B4ECDA51E08267B00767EBD /* BulletMatch.swift in Sources */,
444 | 94350F701BE5EE94003592FB /* Aryaxt.swift in Sources */,
445 | 9572009C1E206A4B006BB4D6 /* juliand665LSWRCEntry.swift in Sources */,
446 | 948986701BE5D28500D34976 /* ExampleCodeChallenge.swift in Sources */,
447 | 1B31586F1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift in Sources */,
448 | 9572009E1E206A5E006BB4D6 /* juliand665ClockEntry.swift in Sources */,
449 | 1BBAB4801E41D6190038BCB1 /* FlavioSilverioBulletMatchEntry.swift in Sources */,
450 | 944CFCDB1BE7310B00FD2E41 /* LongestSubstringWithoutRepeatingCharactersChallenge.swift in Sources */,
451 | 1B1F0A4E1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift in Sources */,
452 | 3D00956F1E03200C004E631A /* BrandonShegaClockEntry.swift in Sources */,
453 | 1B49C0501E0850D90094121E /* BugKrushaBulletMatchEntry.swift in Sources */,
454 | 94350F741BE5F04A003592FB /* IanKeen.swift in Sources */,
455 | 94350F761BE5F0F6003592FB /* Logan.swift in Sources */,
456 | 94350F721BE5EF9F003592FB /* BugKrusha.swift in Sources */,
457 | D5D15B361E0C966A00CC9B1C /* felixdumitClockEntry.swift in Sources */,
458 | 809B704A1BF01B68004131BE /* LoganWrightEntry.swift in Sources */,
459 | 944CFCD81BE72B3C00FD2E41 /* LetterCombinationsOfPhoneNumberChallenge.swift in Sources */,
460 | 94350F691BE5EB90003592FB /* Aranasaurus.swift in Sources */,
461 | 7B1BF2D01E3F9CFA00AEAC0E /* matthijsBulletMatchEntry.swift in Sources */,
462 | );
463 | runOnlyForDeploymentPostprocessing = 0;
464 | };
465 | 9272E1AA1BD7F6560030B403 /* Sources */ = {
466 | isa = PBXSourcesBuildPhase;
467 | buildActionMask = 2147483647;
468 | files = (
469 | 1B9E11461E006F0800B9FA5A /* ClockTests.swift in Sources */,
470 | 1B49C0531E0855C90094121E /* BulletMatchTests.swift in Sources */,
471 | 9272E1E61BDED73A0030B403 /* LetterCombinationsOfPhoneNumberTests.swift in Sources */,
472 | 94350F611BE5D859003592FB /* ExampleChallengeTests.swift in Sources */,
473 | 94350F651BE5E836003592FB /* TwoSumTests.swift in Sources */,
474 | 94350F5F1BE5D721003592FB /* CodeChallengeTestCase.swift in Sources */,
475 | 9272E1E41BDED71C0030B403 /* LongestSubstringWithoutRepeatingCharactersTests.swift in Sources */,
476 | );
477 | runOnlyForDeploymentPostprocessing = 0;
478 | };
479 | /* End PBXSourcesBuildPhase section */
480 |
481 | /* Begin PBXTargetDependency section */
482 | 9272E1B11BD7F6560030B403 /* PBXTargetDependency */ = {
483 | isa = PBXTargetDependency;
484 | target = 9272E1A31BD7F6560030B403 /* CodeChallenge */;
485 | targetProxy = 9272E1B01BD7F6560030B403 /* PBXContainerItemProxy */;
486 | };
487 | /* End PBXTargetDependency section */
488 |
489 | /* Begin XCBuildConfiguration section */
490 | 9272E1B61BD7F6560030B403 /* Debug */ = {
491 | isa = XCBuildConfiguration;
492 | buildSettings = {
493 | ALWAYS_SEARCH_USER_PATHS = NO;
494 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
495 | CLANG_CXX_LIBRARY = "libc++";
496 | CLANG_ENABLE_MODULES = YES;
497 | CLANG_ENABLE_OBJC_ARC = YES;
498 | CLANG_WARN_BOOL_CONVERSION = YES;
499 | CLANG_WARN_CONSTANT_CONVERSION = YES;
500 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
501 | CLANG_WARN_EMPTY_BODY = YES;
502 | CLANG_WARN_ENUM_CONVERSION = YES;
503 | CLANG_WARN_INFINITE_RECURSION = YES;
504 | CLANG_WARN_INT_CONVERSION = YES;
505 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
506 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
507 | CLANG_WARN_UNREACHABLE_CODE = YES;
508 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
509 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
510 | COPY_PHASE_STRIP = NO;
511 | CURRENT_PROJECT_VERSION = 1;
512 | DEBUG_INFORMATION_FORMAT = dwarf;
513 | ENABLE_STRICT_OBJC_MSGSEND = YES;
514 | ENABLE_TESTABILITY = YES;
515 | GCC_C_LANGUAGE_STANDARD = gnu99;
516 | GCC_DYNAMIC_NO_PIC = NO;
517 | GCC_NO_COMMON_BLOCKS = YES;
518 | GCC_OPTIMIZATION_LEVEL = 0;
519 | GCC_PREPROCESSOR_DEFINITIONS = (
520 | "DEBUG=1",
521 | "$(inherited)",
522 | );
523 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
524 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
525 | GCC_WARN_UNDECLARED_SELECTOR = YES;
526 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
527 | GCC_WARN_UNUSED_FUNCTION = YES;
528 | GCC_WARN_UNUSED_VARIABLE = YES;
529 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
530 | MTL_ENABLE_DEBUG_INFO = YES;
531 | ONLY_ACTIVE_ARCH = YES;
532 | SDKROOT = iphoneos;
533 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
534 | TARGETED_DEVICE_FAMILY = "1,2";
535 | VERSIONING_SYSTEM = "apple-generic";
536 | VERSION_INFO_PREFIX = "";
537 | };
538 | name = Debug;
539 | };
540 | 9272E1B71BD7F6560030B403 /* Release */ = {
541 | isa = XCBuildConfiguration;
542 | buildSettings = {
543 | ALWAYS_SEARCH_USER_PATHS = NO;
544 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
545 | CLANG_CXX_LIBRARY = "libc++";
546 | CLANG_ENABLE_MODULES = YES;
547 | CLANG_ENABLE_OBJC_ARC = YES;
548 | CLANG_WARN_BOOL_CONVERSION = YES;
549 | CLANG_WARN_CONSTANT_CONVERSION = YES;
550 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
551 | CLANG_WARN_EMPTY_BODY = YES;
552 | CLANG_WARN_ENUM_CONVERSION = YES;
553 | CLANG_WARN_INFINITE_RECURSION = YES;
554 | CLANG_WARN_INT_CONVERSION = YES;
555 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
556 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
557 | CLANG_WARN_UNREACHABLE_CODE = YES;
558 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
559 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
560 | COPY_PHASE_STRIP = NO;
561 | CURRENT_PROJECT_VERSION = 1;
562 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
563 | ENABLE_NS_ASSERTIONS = NO;
564 | ENABLE_STRICT_OBJC_MSGSEND = YES;
565 | GCC_C_LANGUAGE_STANDARD = gnu99;
566 | GCC_NO_COMMON_BLOCKS = YES;
567 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
568 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
569 | GCC_WARN_UNDECLARED_SELECTOR = YES;
570 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
571 | GCC_WARN_UNUSED_FUNCTION = YES;
572 | GCC_WARN_UNUSED_VARIABLE = YES;
573 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
574 | MTL_ENABLE_DEBUG_INFO = NO;
575 | SDKROOT = iphoneos;
576 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
577 | TARGETED_DEVICE_FAMILY = "1,2";
578 | VALIDATE_PRODUCT = YES;
579 | VERSIONING_SYSTEM = "apple-generic";
580 | VERSION_INFO_PREFIX = "";
581 | };
582 | name = Release;
583 | };
584 | 9272E1B91BD7F6560030B403 /* Debug */ = {
585 | isa = XCBuildConfiguration;
586 | buildSettings = {
587 | CLANG_ENABLE_MODULES = YES;
588 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
589 | DEFINES_MODULE = YES;
590 | DYLIB_COMPATIBILITY_VERSION = 1;
591 | DYLIB_CURRENT_VERSION = 1;
592 | DYLIB_INSTALL_NAME_BASE = "@rpath";
593 | INFOPLIST_FILE = CodeChallenge/Info.plist;
594 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
595 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
596 | PRODUCT_BUNDLE_IDENTIFIER = com.iosdevelopershq.CodeChallenge;
597 | PRODUCT_NAME = CodeChallenge;
598 | SKIP_INSTALL = YES;
599 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
600 | SWIFT_VERSION = 3.0;
601 | };
602 | name = Debug;
603 | };
604 | 9272E1BA1BD7F6560030B403 /* Release */ = {
605 | isa = XCBuildConfiguration;
606 | buildSettings = {
607 | CLANG_ENABLE_MODULES = YES;
608 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
609 | DEFINES_MODULE = YES;
610 | DYLIB_COMPATIBILITY_VERSION = 1;
611 | DYLIB_CURRENT_VERSION = 1;
612 | DYLIB_INSTALL_NAME_BASE = "@rpath";
613 | INFOPLIST_FILE = CodeChallenge/Info.plist;
614 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
615 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
616 | PRODUCT_BUNDLE_IDENTIFIER = com.iosdevelopershq.CodeChallenge;
617 | PRODUCT_NAME = CodeChallenge;
618 | SKIP_INSTALL = YES;
619 | SWIFT_VERSION = 3.0;
620 | };
621 | name = Release;
622 | };
623 | 9272E1BC1BD7F6560030B403 /* Debug */ = {
624 | isa = XCBuildConfiguration;
625 | buildSettings = {
626 | INFOPLIST_FILE = CodeChallengeTests/Info.plist;
627 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
628 | PRODUCT_BUNDLE_IDENTIFIER = com.iosdevelopershq.CodeChallengeTests;
629 | PRODUCT_MODULE_NAME = CodeChallengeTests;
630 | PRODUCT_NAME = CodeChallenge;
631 | SWIFT_VERSION = 3.0;
632 | };
633 | name = Debug;
634 | };
635 | 9272E1BD1BD7F6560030B403 /* Release */ = {
636 | isa = XCBuildConfiguration;
637 | buildSettings = {
638 | INFOPLIST_FILE = CodeChallengeTests/Info.plist;
639 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
640 | PRODUCT_BUNDLE_IDENTIFIER = com.iosdevelopershq.CodeChallengeTests;
641 | PRODUCT_MODULE_NAME = CodeChallengeTests;
642 | PRODUCT_NAME = CodeChallenge;
643 | SWIFT_VERSION = 3.0;
644 | };
645 | name = Release;
646 | };
647 | /* End XCBuildConfiguration section */
648 |
649 | /* Begin XCConfigurationList section */
650 | 9272E19E1BD7F6560030B403 /* Build configuration list for PBXProject "CodeChallenge" */ = {
651 | isa = XCConfigurationList;
652 | buildConfigurations = (
653 | 9272E1B61BD7F6560030B403 /* Debug */,
654 | 9272E1B71BD7F6560030B403 /* Release */,
655 | );
656 | defaultConfigurationIsVisible = 0;
657 | defaultConfigurationName = Release;
658 | };
659 | 9272E1B81BD7F6560030B403 /* Build configuration list for PBXNativeTarget "CodeChallenge" */ = {
660 | isa = XCConfigurationList;
661 | buildConfigurations = (
662 | 9272E1B91BD7F6560030B403 /* Debug */,
663 | 9272E1BA1BD7F6560030B403 /* Release */,
664 | );
665 | defaultConfigurationIsVisible = 0;
666 | defaultConfigurationName = Release;
667 | };
668 | 9272E1BB1BD7F6560030B403 /* Build configuration list for PBXNativeTarget "CodeChallengeTests" */ = {
669 | isa = XCConfigurationList;
670 | buildConfigurations = (
671 | 9272E1BC1BD7F6560030B403 /* Debug */,
672 | 9272E1BD1BD7F6560030B403 /* Release */,
673 | );
674 | defaultConfigurationIsVisible = 0;
675 | defaultConfigurationName = Release;
676 | };
677 | /* End XCConfigurationList section */
678 | };
679 | rootObject = 9272E19B1BD7F6560030B403 /* Project object */;
680 | }
681 |
--------------------------------------------------------------------------------