Skip to content

Commit

Permalink
Update exercises batch 6 (#657)
Browse files Browse the repository at this point in the history
* Update exercises batch 6

* Fix luhn

* Fix matrix

* Fix plugins

* Fix generator
  • Loading branch information
meatball133 authored Aug 3, 2023
1 parent e02bf3b commit a596065
Show file tree
Hide file tree
Showing 26 changed files with 689 additions and 482 deletions.
61 changes: 14 additions & 47 deletions exercises/practice/luhn/.meta/Sources/Luhn/LuhnExample.swift
Original file line number Diff line number Diff line change
@@ -1,51 +1,18 @@
import Foundation

struct Luhn {

var number: Int64 = 0
var numberString: String = ""
var addends: [Int] { return addendsFunc(numberString) }
var checksum: Int { return addends.reduce(0, +) }
var isValid: Bool = false

init(_ num: String ) {
self.numberString = num.replacingOccurrences(of: " ", with: "")
let num = Int64(numberString)
if self.numberString.utf16.count <= 1 {
self.isValid = false
} else if num == nil {
isValid = false
} else {
self.number = num!
isValid = checksum % 10 == 0
}
}

func addendsFunc(_ num: String) -> [Int] {
func oddIndexInt64Minus9( _ input: [Int]) -> [Int] {
var input = input
input = Array(input.reversed())
var tempArray: [Int] = []
for (inx, each) in input.enumerated() {
var tempEach: Int = each
if (inx+1) % 2 == 0 {
tempEach *= 2
if tempEach >= 10 {
tempEach -= 9
}
tempArray.insert(tempEach, at: 0)
} else {
tempArray.insert(tempEach, at: 0)
}
}
return tempArray
}
func char2Int(_ input: Character) -> Int {
let tempInt = Int(String(input)) ?? -1 // -1 = error
return tempInt
}

return oddIndexInt64Minus9(Array(num).map { char2Int($0) })
func isValidLuhn(_ number: String) -> Bool {
var number = number
var sum = 0
var odd = true
number = number.replacingOccurrences(of:" ", with: "")
guard number.count > 1 else { return false }
for char in number.reversed() {
if let digit = Int(String(char)) {
sum += odd ? digit : digit < 5 ? digit * 2 : digit * 2 - 9
odd.toggle()
} else {
return false
}

}
return sum % 10 == 0
}
3 changes: 2 additions & 1 deletion exercises/practice/luhn/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"lyuha",
"nickkjordan",
"robtimp",
"ThomasHaz"
"ThomasHaz",
"meatball133"
],
"files": {
"solution": [
Expand Down
20 changes: 20 additions & 0 deletions exercises/practice/luhn/.meta/template.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import XCTest
@testable import {{exercise|camelCase}}
class {{exercise|camelCase}}Tests: XCTestCase {
let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false

{% for case in cases %}
{% if forloop.first -%}
func test{{case.description |camelCase }}() {
{% else -%}
func test{{case.description |camelCase }}() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
{% endif -%}
{%- if case.expected -%}
XCTAssertTrue(isValidLuhn("{{case.input.value}}"))
{%- else -%}
XCTAssertFalse(isValidLuhn("{{case.input.value}}"))
{%- endif %}
}
{% endfor -%}
}
9 changes: 9 additions & 0 deletions exercises/practice/luhn/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ description = "invalid credit card"
[20e67fad-2121-43ed-99a8-14b5b856adb9]
description = "invalid long number with an even remainder"

[7e7c9fc1-d994-457c-811e-d390d52fba5e]
description = "invalid long number with a remainder divisible by 5"

[ad2a0c5f-84ed-4e5b-95da-6011d6f4f0aa]
description = "valid number with an even number of digits"

Expand All @@ -57,6 +60,12 @@ description = "more than a single zero is valid"
[ab56fa80-5de8-4735-8a4a-14dae588663e]
description = "input digit 9 is correctly converted to output digit 9"

[b9887ee8-8337-46c5-bc45-3bcab51bc36f]
description = "very long input is valid"

[8a7c0e24-85ea-4154-9cf1-c2db90eabc08]
description = "valid luhn with an odd number of digits and non zero first digit"

[39a06a5a-5bad-4e0f-b215-b042d46209b1]
description = "using ascii value for non-doubled non-digit isn't allowed"

Expand Down
30 changes: 15 additions & 15 deletions exercises/practice/luhn/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
import PackageDescription

let package = Package(
name: "Luhn",
products: [
.library(
name: "Luhn",
targets: ["Luhn"]),
],
dependencies: [],
targets: [
.target(
name: "Luhn",
dependencies: []),
.testTarget(
name: "LuhnTests",
dependencies: ["Luhn"]),
]
name: "Luhn",
products: [
.library(
name: "Luhn",
targets: ["Luhn"])
],
dependencies: [],
targets: [
.target(
name: "Luhn",
dependencies: []),
.testTarget(
name: "LuhnTests",
dependencies: ["Luhn"]),
]
)
4 changes: 3 additions & 1 deletion exercises/practice/luhn/Sources/Luhn/Luhn.swift
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
//Solution goes in Sources
func isValidLuhn(_ number: String) -> Bool {
// Write your code for the 'Luhn' exercise in this file.
}
174 changes: 110 additions & 64 deletions exercises/practice/luhn/Tests/LuhnTests/LuhnTests.swift
Original file line number Diff line number Diff line change
@@ -1,70 +1,116 @@
import XCTest

@testable import Luhn

class LuhnTests: XCTestCase {
let runAll = Bool(ProcessInfo.processInfo.environment["RUNALL", default: "false"]) ?? false

func testSingleDigitStringsCanNotBeValid() {
XCTAssertFalse(isValidLuhn("1"))
}

func testASingleZeroIsInvalid() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("0"))
}

func testASimpleValidSinThatRemainsValidIfReversed() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("059"))
}

func testASimpleValidSinThatBecomesInvalidIfReversed() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("59"))
}

func testAValidCanadianSin() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("055 444 285"))
}

func testInvalidCanadianSin() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("055 444 286"))
}

func testInvalidCreditCard() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("8273 1232 7352 0569"))
}

func testInvalidLongNumberWithAnEvenRemainder() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("1 2345 6789 1234 5678 9012"))
}

func testInvalidLongNumberWithARemainderDivisibleBy5() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("1 2345 6789 1234 5678 9013"))
}

func testValidNumberWithAnEvenNumberOfDigits() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("095 245 88"))
}

func testValidNumberWithAnOddNumberOfSpaces() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("234 567 891 234"))
}

func testValidStringsWithANonDigitAddedAtTheEndBecomeInvalid() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("059a"))
}

func testValidStringsWithPunctuationIncludedBecomeInvalid() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("055-444-285"))
}

func testValidStringsWithSymbolsIncludedBecomeInvalid() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("055# 444$ 285"))
}

func testSingleZeroWithSpaceIsInvalid() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn(" 0"))
}

func testMoreThanASingleZeroIsValid() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("0000 0"))
}

func testInputDigit9IsCorrectlyConvertedToOutputDigit9() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("091"))
}

func testVeryLongInputIsValid() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("9999999999 9999999999 9999999999 9999999999"))
}

func testValidLuhnWithAnOddNumberOfDigitsAndNonZeroFirstDigit() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertTrue(isValidLuhn("109"))
}

func testUsingAsciiValueForNonDoubledNonDigitIsntAllowed() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("055b 444 285"))
}

func testUsingAsciiValueForDoubledNonDigitIsntAllowed() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn(":9"))
}

func testSingleDigitInvalid() {
let luhn = Luhn("1")
XCTAssertEqual (false, luhn.isValid)
}

func testSingleZeroInvalid() {
let luhn = Luhn("0")
XCTAssertEqual (false, luhn.isValid)
}

func testSimpleReversableValid() {
let luhn = Luhn("059")
XCTAssertEqual (true, luhn.isValid)
}

func testSimpleIrreversableValid() {
let luhn = Luhn("59")
XCTAssertEqual (true, luhn.isValid)
}

func testCanadianValid() {
let luhn = Luhn("055 444 285")
XCTAssertEqual (true, luhn.isValid)
}

func testCanadianInvalid() {
let luhn = Luhn("055 444 286")
XCTAssertEqual (false, luhn.isValid)
}

func testCreditCardInvalid() {
let luhn = Luhn("8273 1232 7352 0569")
XCTAssertEqual (false, luhn.isValid)
}

func testNonDigitInvalid() {
let luhn = Luhn("055a 444 285")
XCTAssertEqual (false, luhn.isValid)
}

func testPunctuationInvalid() {
let luhn = Luhn("055-444-285")
XCTAssertEqual (false, luhn.isValid)
}

func testSymbolsInvalid() {
let luhn = Luhn("055£ 444$ 285")
XCTAssertEqual (false, luhn.isValid)
}

func testZeroWithSpaceInvalid() {
let luhn = Luhn(" 0")
XCTAssertEqual (false, luhn.isValid)
}

func testMultipleZeroesValid() {
let luhn = Luhn("0000 0")
XCTAssertEqual (true, luhn.isValid)
}

func testInputNineOutputNine() {
let luhn = Luhn("091")
XCTAssertEqual (true, luhn.isValid)
}
func testNonNumericNonSpaceCharInTheMiddleWithASumThatsDivisibleBy10IsntAllowed() throws {
try XCTSkipIf(true && !runAll) // change true to false to run this test
XCTAssertFalse(isValidLuhn("59%59"))
}
}
1 change: 1 addition & 0 deletions exercises/practice/matching-brackets/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Instructions

Given a string containing brackets `[]`, braces `{}`, parentheses `()`, or any combination thereof, verify that any and all pairs are matched and nested correctly.
The string may also contain other characters, which for the purposes of this exercise should be ignored.
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
struct MatchingBrackets {

private static let brackets: [Character: Character] = [
")": "(",
"]": "[",
"}": "{"
]
private static let brackets: [Character: Character] = [
")": "(",
"]": "[",
"}": "{",
]

static func paired(text: String) -> Bool {
var stack = [Character]()
static func paired(text: String) -> Bool {
var stack = [Character]()

for character in text {
if brackets.values.contains(character) {
stack.append(character)
} else if brackets.keys.contains(character) {
guard let last = stack.popLast(),
last == brackets[character] else {
return false
}
}
for character in text {
if brackets.values.contains(character) {
stack.append(character)
} else if brackets.keys.contains(character) {
guard let last = stack.popLast(),
last == brackets[character]
else {
return false
}

return stack.isEmpty
}
}

return stack.isEmpty
}
}
Loading

0 comments on commit a596065

Please sign in to comment.