Skip to content
This repository was archived by the owner on Aug 17, 2022. It is now read-only.

Bullet match #11

Merged
merged 18 commits into from
Jan 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions CodeChallenge.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
/* Begin PBXBuildFile section */
1B1F0A4E1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B1F0A4D1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift */; };
1B31586F1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B31586E1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift */; };
1B49C0501E0850D90094121E /* BugKrushaBulletMatchEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B49C04F1E0850D90094121E /* BugKrushaBulletMatchEntry.swift */; };
1B49C0531E0855C90094121E /* BulletMatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B49C0521E0855C90094121E /* BulletMatchTests.swift */; };
1B4ECDA51E08267B00767EBD /* BulletMatch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B4ECDA41E08267B00767EBD /* BulletMatch.swift */; };
1B5C1BC51E1EB242002E9254 /* markings_short.json in Resources */ = {isa = PBXBuildFile; fileRef = 1B5C1BC41E1EB242002E9254 /* markings_short.json */; };
1B9E113F1E005A7C00B9FA5A /* Clock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B9E113E1E005A7C00B9FA5A /* Clock.swift */; };
1B9E11411E006A2B00B9FA5A /* BugKrushaClockEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B9E11401E006A2B00B9FA5A /* BugKrushaClockEntry.swift */; };
1B9E11461E006F0800B9FA5A /* ClockTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B9E11451E006F0800B9FA5A /* ClockTests.swift */; };
Expand Down Expand Up @@ -50,6 +54,10 @@
/* Begin PBXFileReference section */
1B1F0A4D1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BugKrushaLetterCombinationsOfPhoneNumberEntry.swift; sourceTree = "<group>"; };
1B31586E1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlavioSilverioClockEntry.swift; sourceTree = "<group>"; };
1B49C04F1E0850D90094121E /* BugKrushaBulletMatchEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BugKrushaBulletMatchEntry.swift; path = BulletMatch/Entries/BugKrushaBulletMatchEntry.swift; sourceTree = "<group>"; };
1B49C0521E0855C90094121E /* BulletMatchTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BulletMatchTests.swift; sourceTree = "<group>"; };
1B4ECDA41E08267B00767EBD /* BulletMatch.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BulletMatch.swift; path = BulletMatch/BulletMatch.swift; sourceTree = "<group>"; };
1B5C1BC41E1EB242002E9254 /* markings_short.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = markings_short.json; sourceTree = "<group>"; };
1B9E113E1E005A7C00B9FA5A /* Clock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Clock.swift; sourceTree = "<group>"; };
1B9E11401E006A2B00B9FA5A /* BugKrushaClockEntry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BugKrushaClockEntry.swift; sourceTree = "<group>"; };
1B9E11451E006F0800B9FA5A /* ClockTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClockTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -109,6 +117,23 @@
path = Entries;
sourceTree = "<group>";
};
1B49C0511E0850DD0094121E /* Entries */ = {
isa = PBXGroup;
children = (
1B49C04F1E0850D90094121E /* BugKrushaBulletMatchEntry.swift */,
);
name = Entries;
sourceTree = "<group>";
};
1B4ECDA61E0826B000767EBD /* BulletMatch */ = {
isa = PBXGroup;
children = (
1B49C0511E0850DD0094121E /* Entries */,
1B4ECDA41E08267B00767EBD /* BulletMatch.swift */,
);
name = BulletMatch;
sourceTree = "<group>";
};
1B9E11421E006A2F00B9FA5A /* Entries */ = {
isa = PBXGroup;
children = (
Expand All @@ -130,6 +155,13 @@
path = Clock;
sourceTree = "<group>";
};
1BB33E9E1E15BA5200C83E3F /* Resources */ = {
isa = PBXGroup;
children = (
);
path = Resources;
sourceTree = "<group>";
};
9272E19A1BD7F6560030B403 = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -171,10 +203,13 @@
94350F591BE5D5C1003592FB /* Challenges */ = {
isa = PBXGroup;
children = (
1B5C1BC41E1EB242002E9254 /* markings_short.json */,
1BB33E9E1E15BA5200C83E3F /* Resources */,
1B9E11471E010A3500B9FA5A /* Clock */,
94350F661BE5EB21003592FB /* TwoSum */,
944CFCD61BE72AEB00FD2E41 /* LetterCombinationsOfPhoneNumber */,
944CFCD91BE730A700FD2E41 /* LongestSubstringWithoutRepeatingCharacters */,
1B4ECDA61E0826B000767EBD /* BulletMatch */,
);
path = Challenges;
sourceTree = "<group>";
Expand All @@ -192,6 +227,7 @@
isa = PBXGroup;
children = (
94350F641BE5E836003592FB /* TwoSumTests.swift */,
1B49C0521E0855C90094121E /* BulletMatchTests.swift */,
9272E1E51BDED73A0030B403 /* LetterCombinationsOfPhoneNumberTests.swift */,
1B9E11451E006F0800B9FA5A /* ClockTests.swift */,
9272E1E31BDED71C0030B403 /* LongestSubstringWithoutRepeatingCharactersTests.swift */,
Expand Down Expand Up @@ -342,6 +378,7 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1B5C1BC51E1EB242002E9254 /* markings_short.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -368,12 +405,14 @@
7B925E521E05AFFF0009B0CD /* matthijsClockEntry.swift in Sources */,
2EB83A801E03290400FAAB32 /* EthanSchatzline-ClockEntry.swift in Sources */,
9489866A1BE5CFB000D34976 /* CodeChallengeType.swift in Sources */,
1B4ECDA51E08267B00767EBD /* BulletMatch.swift in Sources */,
94350F701BE5EE94003592FB /* Aryaxt.swift in Sources */,
948986701BE5D28500D34976 /* ExampleCodeChallenge.swift in Sources */,
1B31586F1E02FC7E0052ACBD /* FlavioSilverioClockEntry.swift in Sources */,
944CFCDB1BE7310B00FD2E41 /* LongestSubstringWithoutRepeatingCharactersChallenge.swift in Sources */,
1B1F0A4E1BE7EA060030135C /* BugKrushaLetterCombinationsOfPhoneNumberEntry.swift in Sources */,
3D00956F1E03200C004E631A /* BrandonShegaClockEntry.swift in Sources */,
1B49C0501E0850D90094121E /* BugKrushaBulletMatchEntry.swift in Sources */,
94350F741BE5F04A003592FB /* IanKeen.swift in Sources */,
94350F761BE5F0F6003592FB /* Logan.swift in Sources */,
94350F721BE5EF9F003592FB /* BugKrusha.swift in Sources */,
Expand All @@ -388,6 +427,7 @@
buildActionMask = 2147483647;
files = (
1B9E11461E006F0800B9FA5A /* ClockTests.swift in Sources */,
1B49C0531E0855C90094121E /* BulletMatchTests.swift in Sources */,
9272E1E61BDED73A0030B403 /* LetterCombinationsOfPhoneNumberTests.swift in Sources */,
94350F611BE5D859003592FB /* ExampleChallengeTests.swift in Sources */,
94350F651BE5E836003592FB /* TwoSumTests.swift in Sources */,
Expand Down
80 changes: 80 additions & 0 deletions CodeChallenge/Challenges/BulletMatch/BulletMatch.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
//
// BulletMatch.swift
// CodeChallenge
//
// Created by Jon-Tait Beason on 12/19/16.
// Copyright © 2016 iosdevelopers. All rights reserved.
//

import Foundation
/**
Forensic specialists examine spent cartridges for unique
markings left by parts of a gun. They can then compare
these markings to the ones in any gun to determine if there
is a match. A match means that the bullet was fired from
that gun.

Given two markings, one from a spent cartridge and the other
from a suspected weapon, both as Strings, return true if they match
and false if they don't.

EXAMPLES:
Match, returns true
"| ||| | |" and
"| ||| | |"

Match, returns true though one is rotated. Bullets can be rotated.
Your solution should account for the possible rotation of bullets.
"|| ||| | " and
" | || |||"

Doesn't match, returns false
"| ||| | |" and
"||| | | |"

NOTE: Markings cannot be flipped.
"| ||" is not a match for
"|| |"

Problem adapted from http://bit.ly/2h57Wxe
*/

final class BulletChallenge: CodeChallengeType {
typealias InputType = (bulletMarkings: String, gunMarkings: String)
typealias OutputType = Bool

var title = "Bullet Challenge"
private let separator = "#"

var entries: [CodeChallengeEntry<BulletChallenge>] = [
bugKrushaBulletMatchEntry
]

func generateDataset() -> [InputType] {
let bundle = Bundle(for: BulletChallenge.self)
guard
let dataUrl = bundle.url(forResource: "markings_short", withExtension: "json"),
let data = try? Data(contentsOf: dataUrl),
let jsonObjects = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
let vd = jsonObjects as? [String: Bool]
else { fatalError() }

verificationData = vd
let markings = verificationData.keys.map { key -> (String, String) in
let components = key.components(separatedBy: self.separator)
let gunMarkings = components[1]
let bulletMarkings = components[0]
return (bulletMarkings: bulletMarkings, gunMarkings: gunMarkings)
}

return Array(markings)
}

func verifyOutput(_ output: Bool, forInput input: (bulletMarkings: String, gunMarkings: String)) -> Bool {
return verificationData[input.bulletMarkings + separator + input.gunMarkings] == output
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the dataset being random because then each test run is going to be run with different inputs, which feels like not the most empirical of comparisons. That may not matter for this particular problem, I haven't spent enough time with it to know, but I thought I'd bring it up.

The alternative would be to generate a dataset randomly as you've done here, and then write that out to a file and add that file to the repo and then just load the file here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Word. Lemme look into that.


private var verificationData = [String: Bool]()


Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// BugKrushaBulletMatchEntry.swift
// CodeChallenge
//
// Created by Jon-Tait Beason on 12/19/16.
// Copyright © 2016 iosdevelopers. All rights reserved.
//

import Foundation

let bugKrushaBulletMatchEntry = CodeChallengeEntry<BulletChallenge>(name: "bugKrusha") { input in
let count = input.0.characters.count

guard
count == input.1.characters.count
else { return false }

var resets = count
var bulletIndex = 0
var gunIndex = 0
var matches = 0

let bulletMarks = input.0.characters.flatMap { String($0) }
var gunMarks = input.1.characters.flatMap { String($0) }

while resets >= 0 && gunIndex < count {
if bulletMarks[bulletIndex] == gunMarks[gunIndex] {
gunIndex += 1
matches += 1
bulletIndex += 1
} else {
let last = gunMarks.removeLast()
gunMarks = [last] + gunMarks
gunIndex = 0
bulletIndex = 0
matches = 0

resets -= 1
}

if matches == count { return true }
}
return false
}
Loading