While exploring algorithms in Swift, couldn't find algorithm for array rotation in swift without using funcs shiftLeft / shiftRight.
C has this graceful algo with time complexity of O(N):
/* Function to left rotate arr[] of size n by d */
void leftRotate(int arr[], int d, int n)
{
rvereseArray(arr, 0, d-1);
rvereseArray(arr, d, n-1);
rvereseArray(arr, 0, n-1);
}
/*Function to reverse arr[] from index start to end*/
void rvereseArray(int arr[], int start, int end)
{
int temp;
while (start < end)
{
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}
I'm struggling with converting this into swift:
func rotate(array:[Int], positions:Int, arSize:Int) {
var a = array
var p = positions
var s = arSize
reverseArray(array: a, start: 0, end: p-1)
reverseArray(array: a, start: p, end: s-1)
reverseArray(array: a, start: 0, end: s-1)
}
func reverseArray(array: [Int], start:Int, end:Int) {
var a = array
var s = start
var e = end
var temp = 0
while s < e {
temp = a[s]
a[s] = a[e]
a[e] = temp
s += 1
e -= 1
}
}
As I understand, for swift, we need to specify return types.
How they should be configured without increasing space(memory) complexity? (aka, without creating new temporary arrays)
This question is different from others, because its about how returns work in swift compare to C.
Edit update:
Swift 5 or later
extension RangeReplaceableCollection {
func rotatingLeft(positions: Int) -> SubSequence {
let index = self.index(startIndex, offsetBy: positions, limitedBy: endIndex) ?? endIndex
return self[index...] + self[..<index]
}
mutating func rotateLeft(positions: Int) {
let index = self.index(startIndex, offsetBy: positions, limitedBy: endIndex) ?? endIndex
let slice = self[..<index]
removeSubrange(..<index)
insert(contentsOf: slice, at: endIndex)
}
}
extension RangeReplaceableCollection {
func rotatingRight(positions: Int) -> SubSequence {
let index = self.index(endIndex, offsetBy: -positions, limitedBy: startIndex) ?? startIndex
return self[index...] + self[..<index]
}
mutating func rotateRight(positions: Int) {
let index = self.index(endIndex, offsetBy: -positions, limitedBy: startIndex) ?? startIndex
let slice = self[index...]
removeSubrange(index...)
insert(contentsOf: slice, at: startIndex)
}
}
var test = [1,2,3,4,5,6,7,8,9,10]
test.rotateLeft(positions: 3) // [4, 5, 6, 7, 8, 9, 10, 1, 2, 3]
var test2 = "1234567890"
test2.rotateRight(positions: 3) // "8901234567"
We can use Slice
func rotLeft(a: [Int], d: Int) -> [Int] {
let slice1 = a[..<d]
let slice2 = a[d...]
return Array(slice2) + Array(slice1)
}
print(rotLeft(a:[1, 2, 3, 4, 5], d: 4))
//prints [5, 1, 2, 3, 4]
Why create a reverse function when we already have it in the Swift standard library?
My solution (derived from Leo Dabus'):
extension Array {
mutating func rotate(positions: Int, size: Int? = nil) {
let size = size ?? count
guard positions < count && size <= count else { return }
self[0..<positions].reverse()
self[positions..<size].reverse()
self[0..<size].reverse()
}
}
Approach 1:
func rotate(_ nums: inout [Int], _ k: Int) {
nums.enumerated().forEach { nums[ (k + $0) % nums.count] = $1 }
}
Approach 2:
func rotLeft(a: [Int], d: Int) -> [Int] {
var a = a
reverse(&a, 0, d)
reverse(&a, d, a.count)
reverse(&a, 0, a.count)
return a
}
func reverse(_ a: inout [Int], _ s: Int, _ r: Int) {
var r = r, s = s
while s < r {
a.swapAt(s, r - 1)
s += 1
r -= 1
}
}
To be complete, the rotation function should support negative (right) rotations and rotating more than the array's size
extension Array
{
mutating func rotateLeft(by rotations:Int)
{
// rotation irrelevant when less than 2 elements
if count < 2 { return }
// effective left rotation for negative and > count
let rotations = (rotations%count + count) % count
// no use rotating by zero
if rotations == 0 { return }
// rotate
(1..<count).reduce(0)
{ let i = ($0.0+rotations)%count; swap(&self[$0.0],&self[i]); return i }
}
mutating func reverse()
{
(0..<count/2).forEach{ swap(&self[$0],&self[count-$0-1]) }
}
}
// a is the array to be left rotated
// d is the number of unit for left rotation
func rotLeft(a: [Int], d: Int) -> [Int] {
var a = a
for index in 0...(d - 1) {
a.append(a[0])
a.remove(at: 0)
}
return a
}
// calling Function
rotLeft(a: [1,2,3,4,5], d: 4)
// OutPut
[5, 1, 2, 3, 4]
This solution rotates the element of time complexity O(n)
func rotLeft(a: [Int], d: Int) -> [Int] {
var arr = a
var size = arr.count - 1
for i in 0...size {
let newloc = (i + (arr.count - d)) % arr.count
arr[newloc] = a[i]
}
return arr
}
you shouldn't use .append(x) as in the worst case it can be
O(n) and you shouldn't use .remove(at: x) as its O(n) when you can avoid using those methods As when using them you basically get n + n + n which isn't that great
If anybody lands here after watching the Embracing Algorithms WWDC18 session by David Abrahams, here is one of the implementations of rotate from the swift/test/Prototypes/Algorithms.swift file.
extension MutableCollection where Self: BidirectionalCollection {
/// Rotates the elements of the collection so that the element
/// at `middle` ends up first.
///
/// - Returns: The new index of the element that was first
/// pre-rotation.
/// **- Complexity: O(*n*)**
#discardableResult
public mutating func rotate(shiftingToStart middle: Index) -> Index {
self[..<middle].reverse()
self[middle...].reverse()
let (p, q) = _reverseUntil(middle)
self[p..<q].reverse()
return middle == p ? q : p
}
}
This algorithms depends on reverseUntil(:) defined in the same file
extension MutableCollection where Self: BidirectionalCollection {
/// Reverses the elements of the collection, moving from each end until
/// `limit` is reached from either direction. The returned indices are the
/// start and end of the range of unreversed elements.
///
/// Input:
/// [a b c d e f g h i j k l m n o p]
/// ^
/// limit
/// Output:
/// [p o n m e f g h i j k l d c b a]
/// ^ ^
/// f l
///
/// - Postcondition: For returned indices `(f, l)`:
/// `f == limit || l == limit`
#inline(__always)
#discardableResult
internal mutating func _reverseUntil(_ limit: Index) -> (Index, Index) {
var f = startIndex
var l = endIndex
while f != limit && l != limit {
formIndex(before: &l)
swapAt(f, l)
formIndex(after: &f)
}
return (f, l)
}
}
You need to consider the scenario such as-
The number of rotation can be equal/more than the size of array you need to rotate.
To handle this scenario use modulo operator to find the actual number of rotation as you will find out rotating an array by a number equal to its size result in same array.
func rotateLeft(array:[Int],numberOfRotation:Int) -> [Int]
{
let offset = numberOfRotation % array.count
let tempResult = array[offset...] + array[..<offset]
return Array(tempResult)
}
We can do it using Array's dropFirst() and dropLast() functions.
func rotateLeft(arrToRotate: inout [Int], positions: Int){
if arrToRotate.count == 0 || positions == 0 || positions > arrToRotate.count{
print("invalid")
return
}
arrToRotate = arrToRotate.dropFirst(positions) + arrToRotate.dropLast(arrToRotate.count-positions)
}
var numbers : [Int] = [1, 2, 3, 4, 5]
rotateLeft(arrToRotate: &numbers, positions:2)
print(numbers) //prints [3, 4, 5, 1, 2]
here is a way to rotate left or right. Just call rotate on your array as shown. This does not mutate the array, if you wish to mutate the array, set the array equal to the rotation.
extension Array {
func rotate(moveRight: Bool, numOfRotations: Int) -> Array<Element>{
var arr = self
var i = 0
while i < numOfRotations {
if moveRight {
arr.insert(arr.remove(at: arr.count - 1), at: 0)
} else {
arr.append(arr.remove(at: 0))
}
i += 1
}
return arr
}
}
var arr = ["a","b","c","d","e"]
print(arr.rotate(moveRight: true, numOfRotations: 2))
// ["d", "e", "a", "b", "c"]
print(arr)
// ["a", "b", "c", "d", "e"]
arr = arr.rotate(moveRight: true, numOfRotations: 2)
print(arr)
// ["d", "e", "a", "b", "c"]
Related
I'm practicing this problem
Given an array of integers nums and an integer target, return indices
of the two numbers such that they add up to target.
You may assume that each input would have exactly one solution, and
you may not use the same element twice.
You can return the answer in any order.
and came up with
class Solution {
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var indices = [Int]()
for (firstIndex, firstNum) in nums.enumerated() {
for (secondIndex, secondNum) in nums.enumerated() {
if firstNum + secondNum == target && firstIndex != secondIndex {
indices = [firstIndex, secondIndex]
}
}
}
return indices
}
}
However, it has quadratic time complexity because of the nested for-in loops. What would be a good way to optimize this to run in linear time?
Here's an idea that results in a O(n) time ans space solution.
Have a hashtable that maps elements to their indices.
As you iterate through the input array check whether target - element is in the hashtable already. If so, return the indices of the current element and target - element in the hashtable.
If not, add current element as key and its index as value to the hashtable.
Using #user1984 comment your solution should look like this:
class Solution {
func twoSum(_ nums: [Int], _ target: Int) -> [Int] {
var indices = [Int]()
var dictionary: [Int: Int] = [:]
for (index, num) in nums.enumerated()
{
let diff = target - num
if let index2 = dictionary[diff] {
return [index2, index]
}
else {
dictionary[num] = index
}
}
return []
}
}
There are several approaches (depending on your requirements and time/space constraints)
final class Solution {
// Time Complexity: O(n * (n - 1) / 2) = O(n^2)
// Auxiliary Space: O(1)
func twoSum1(_ nums: [Int], _ target: Int) -> [Int] {
for firstIndex in nums.indices {
for secondIndex in (firstIndex + 1)..<nums.count {
if nums[firstIndex] + nums[secondIndex] == target {
return [firstIndex, secondIndex]
}
}
}
return []
}
// Time Complexity: O(n log n).
// Auxiliary Space: O(n). Can be O(1) if do in-place sort
func twoSum2(_ nums: [Int], _ target: Int) -> [Int] {
let sorted = nums.sorted()
var left = 0
var right = nums.count - 1
while left < right {
if sorted[left] + sorted[right] == target {
return [left, right]
} else if sorted[left] + sorted[right] < target {
left += 1
} else {
right -= 1
}
}
return []
}
// Time Complexity: O(n). (Amortized)
// Auxiliary Space: O(n).
func twoSum3(_ nums: [Int], _ target: Int) -> [Int] {
var differences = [Int: Int]()
for (index, element) in nums.enumerated() {
let difference = target - element
if let dIndex = differences[difference] {
return [index, dIndex]
}
differences[element] = index
}
return []
}
static func test() {
// Given
let nums = [1, 5, 4, 3, 7, 9, -3]
let target = 7
let solution = Solution()
let expectedResult = [2, 3]
// When
let result1 = solution.twoSum1(nums, target)
let result2 = solution.twoSum2(nums, target)
let result3 = solution.twoSum3(nums, target)
// Then
assert(Set(result1) == Set(expectedResult))
assert(Set(result2) == Set(expectedResult))
assert(Set(result3) == Set(expectedResult))
}
}
If I have two int arrays such as
var array1 = [1,2,3]
var array2 = [1,2,3,5]
I'd like to be able to add the first element of the first array with the first element of the second array, and so on. However if an array has a different length than the other I'd like to keep the element that was not added in the return array. For this example my return array would be [2,4,6,5].
I tried using zip(array1,array2).map(+) but it would exclude the 5 from array2.
After adding the elements at the index positions which are common to both arrays (what you already did with zip and map) just append the remaining elements from both arrays (using append(contentsOf:) and dropFirst):
let array1 = [1, 2, 3]
let array2 = [1, 2, 3, 5]
var combined = zip(array1, array2).map(+)
let commonCount = combined.count
combined.append(contentsOf: array1.dropFirst(commonCount))
combined.append(contentsOf: array2.dropFirst(commonCount))
print(combined) // [2, 4, 6, 5]
AnySequence(zip: (1...3, [1, 2, 3, 5])).map {
Optional($0).map(+) ?? firstNonNil($0)!
}
public extension AnySequence {
/// Like `zip`, but with `nil` elements for the shorter sequence after it is exhausted.
init<Sequence0: Sequence, Sequence1: Sequence>(
zip zipped: (Sequence0, Sequence1)
) where Element == (Sequence0.Element?, Sequence1.Element?) {
self.init(
sequence(
state: (zipped.0.makeIterator(), zipped.1.makeIterator())
) { iterators in
((iterators.0.next(), iterators.1.next()) as Optional)
.filter { $0 != nil || $1 != nil }
}
)
}
}
public extension Optional {
/// Exchange two optionals for a single optional tuple.
/// - Returns: `nil` if either tuple element is `nil`.
init<Wrapped0, Wrapped1>(_ optionals: (Wrapped0?, Wrapped1?))
where Wrapped == (Wrapped0, Wrapped1) {
switch optionals {
case let (wrapped0?, wrapped1?):
self = (wrapped0, wrapped1)
default:
self = nil
}
}
/// Transform `.some` into `.none`, if a condition fails.
/// - Parameters:
/// - isSome: The condition that will result in `nil`, when evaluated to `false`.
func filter(_ isSome: (Wrapped) throws -> Bool) rethrows -> Self {
try flatMap { try isSome($0) ? $0 : nil }
}
}
public func firstNonNil<Element>(_ tuple: (Element?, Element?)) -> Element? {
switch tuple {
case (let _0?, _):
return _0
case (nil, let _1?):
return _1
case (nil, nil):
return nil
}
}
func combine2Arrays(array1:[Int], array2:[Int]) -> [Int] {
var finalArray:[Int] = []
let maxSize = max(array1.count, array2.count)
for i in 0..<maxSize {
let valToAdd1 = (array1.count > i ? array1[i] : 0)
let valToAdd2 = (array2.count > i ? array2[i] : 0)
let finalVal = valToAdd1 + valToAdd2
finalArray.append(finalVal)
}
return finalArray
}
print(combine2Arrays(array1: [1,2,3], array2: [1,2,3,5]))
OR
func combine2Arrays(array1:[Int], array2:[Int]) -> [Int] {
var finalArray:[Int] = zip(array1,array2).map(+)
let largerArray = array1.count > array2.count ? array1 : array2
let smallerArray = array1.count > array2.count ? array2 : array1
let min = smallerArray.count
let max = largerArray.count
for i in min..<max {
finalArray.append(largerArray[i])
}
return finalArray
}
print(combine2Arrays(array1: [1,2,3], array2: [1,2,3,5]))
You can fill your smaller array with zeroes, then use zip. inout means that arrays are mutable, or you can make the copy of function parameters inside the function to make them mutable.
private func combineArrays(array1: inout [Int], array2: inout [Int]) -> [Int] {
let maxSize = max(array1.count, array2.count)
if (array1.count > array2.count) {
array2.append(contentsOf: [Int](repeating: 0, count: maxSize - array2.count))
} else if (array2.count > array1.count) {
array1.append(contentsOf: [Int](repeating: 0, count: maxSize - array1.count))
}
return zip(array1, array2).map(+)
}
//javaScript
var array1 = [1,2,3,4,5];
var array2 = [9,7,8,6,5,6,7];
let a= array1.length;
let b = array2.length;
var array3 = [];
let c = a>b?a:b;
for(let i=0; i<c; i++){
if(i < a && i < b){
array3.push(array1[i] + array2[i]);
} else if(i >= a){
array3.push(array2[i])
} else{
array3.push(array1[i])
}
}
console.log(array3)
Can anyone write run-length encoding code in swift that is easier to read than the one below or at least explains the one i got from rosettecode.org ?
Here is the input& output and the code
// "WWWBWW" -> [(3, W), (1, B), (2, W)]
func encode(input: String) -> [(Int, Character)] {
return input.characters.reduce([(Int, Character)]()) {
if $0.last?.1 == $1 { var r = $0; r[r.count - 1].0++; return r }
return $0 + [(1, $1)]
}
}
It would be easier to understand if you use reduce(into:) instead:
func encode(input: String) -> [(Int, Character)] {
input.reduce(into: [(Int, Character)]()) {
// if the second element of the last tuple of the result is equal to the current element (character) of the collection
if $0.last?.1 == $1 {
// increase the first element of the last tuple tuple of the result
$0[$0.index(before: $0.endIndex)].0 += 1
} else {
// otherwise add a new tuple with a value of 1 and the current element (character) to the result
$0 += CollectionOfOne((1, $1))
}
}
}
encode(input: "WWWBWW") // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]
You can also extend Collection and implement a generic method/property
extension Collection where Element: Equatable {
var groupped: [(Int, Element)] {
reduce(into: []) {
if $0.last?.1 == $1 {
$0[$0.index(before: $0.endIndex)].0 += 1
} else {
$0 += CollectionOfOne((1, $1))
}
}
}
}
"WWWBWW".groupped // [(.0 3, .1 "W"), (.0 1, .1 "B"), (.0 2, .1 "W")]
Hope this make it easier for you to understand.
func encode2(input: String) -> [(Int, Character)] {
var result = [(Int, Character)]()
input.forEach { char in
if result.last?.1 == char {
result[result.count - 1].0 += 1
} else {
result.append((1, char))
}
}
return result
}
I've solved the task with the following way, which may be more clear for someone:
func compress(input: String) -> [(Int, Character)] {
var output = [(Int, Character)]()
var count: Int = 1 // count of repeated characters
var i = 0
while i < input.count { // select the current character
var j = i + 1
while j < input.count &&
input[input.index(input.startIndex, offsetBy: i)] == input[input.index(input.startIndex, offsetBy: j)] { // count repeated charactes followed the current one
count += 1
j += 1
}
output.append((count, input[input.index(input.startIndex, offsetBy: i)]))
i = j // move index for the current character to the index of the last repeated one
count = 1 // reset count
}
return output
}
I'd like to write an extension on CollectionType in Swift that will find the x objects after an object in an array. Obviously it needs be protected to work even if there are no objects after the item.
In my head the signatures something like this:
func itemsAfterItem(item: T, limit: Int?) -> [T]
I can't figure out how to implement it though, could someone help?
A possible implementation for arbitrary collections of
Equatable elements (explanations inline). The main
challenge is to get the parameter types and constraints right.
extension CollectionType where Generator.Element: Equatable,
SubSequence.Generator.Element == Generator.Element {
func itemsAfterItem(item: Generator.Element, limit: Index.Distance?) -> [Generator.Element] {
if let idx = indexOf(item) where idx != endIndex {
// Start after the given item:
let from = idx.advancedBy(1)
// Up to min(from + limit, endIndex):
let to = limit.map { from.advancedBy($0, limit: endIndex) } ?? endIndex
// Return slice as an array:
return Array(self[from..<to])
} else {
// Item not found, or only at the last position.
return []
}
}
}
Understanding the
let to = limit.map { from.advancedBy($0, limit: endIndex) } ?? endIndex
part is left as an exercise to the reader :)
Examples:
[1, 2, 3, 4, 5, 6].itemsAfterItem(2, limit: 2) // [3, 4]
["x", "y", "z"].itemsAfterItem("y", limit: 4) // ["z"]
[1, 2, 3].itemsAfterItem(7, limit: 4) // []
[1.1, 2.2, 3.3].itemsAfterItem(1.1, limit: nil) // [2.2, 3.3]
Example for a non-array collection:
"abcdef".characters.itemsAfterItem("b", limit: 2) // ["c", "d"]
Just because I liked the challenge ;)
extension Array where Element : Equatable {
func itemsAfterItem(item: Element, limit: Int? = nil) -> [Element] {
if let from = self.indexOf(item) where from < self.count - 1 {
if let limit = limit where from + limit < self.count {
return Array(self[from+1...from + limit])
}
return Array(self[from+1...self.count-1])
} else {
return []
}
}
}
For the input
let arr = [1, 2, 4, 6, 9]
It results in
arr.itemsAfterItem(2) // [4, 6, 9]
arr.itemsAfterItem(2, limit: 2) // [4, 6]
arr.itemsAfterItem(2, limit: 100) // [4, 6, 9]
arr.itemsAfterItem(9, limit: 2) // []
arr.itemsAfterItem(3, limit: 100) // []
I think you can try this:
func itemsAfterItem(item: T, limit: Int?) -> [T] {
var counter: Int = 0
var isAfter: Bool = false
let array = [T]()
let newLimit = limit != nil ? limit : myArray.count
for tmpItem in myArray {
if tmpItem == T {
isAfter = true
}
if isAfter && counter < limit {
array.append(tmpItem)
counter += 1
}
}
}
This function will put your T item at the start of the array.
I've not test this function
Does anyone know how to get the sum of all the digits in a number in Swift?
For example using the number 845 would result in 17
update: Swift 5 or later We can use then new Character property wholeNumberValue:
let string = "845"
let sum = string.compactMap{$0.wholeNumberValue}.reduce(0, +)
print(sum) // 17
let integer = 845
let sumInt = String(integer).compactMap{$0.wholeNumberValue}.reduce(0, +)
print(sumInt) // 17
Here is a solution that uses simple integer arithmetic only:
func digitSum(var n : Int) -> Int {
var sum = 0
while n > 0 {
sum += n % 10 // Add least significant digit ...
n /= 10 // ... and remove it from the number.
}
return sum
}
println(digitSum(845)) // 17
Update for Swift 3/4:
func digitSum(_ n : Int) -> Int {
var n = n
var sum = 0
while n > 0 {
sum += n % 10 // Add least significant digit ...
n /= 10 // ... and remove it from the number.
}
return sum
}
print(digitSum(845)) // 17
Another implementation, just for fun:
func digitSum(_ n : Int) -> Int {
return sequence(state: n) { (n: inout Int) -> Int? in
defer { n /= 10 }
return n > 0 ? n % 10 : nil
}.reduce(0, +)
}
The recursive solution in Swift 3!
func digitSum(of number: Int) -> Int {
if(number < 10) {
return number
} else {
return (number % 10) + digitSum(of: (number/10))
}
}
For the sake of completeness, and for those who would like to see or understand a math-based approach, here's a real-number function based technique ported to Swift.
This is not the most efficient way to tally the digits of an integer in Swift. I don't recommend using it. I would personally use #LeoLDbus map/reduce answer to the question, because it is so cool and illustrates a powerful set of Swift features yet short, or #MartinR integer mod/divide answer, due to its utter simplicity and relative speed of integer arithmetic .
Cocoa and UIKit have the requisite math methods, so you'll probably need to import one of those packages.
func sumDigits(var i : Int) -> Int {
var sum = 0
var nDigits = floor(log10(Double(i))) + 1
for var r = nDigits; r > 0; r-- {
var p = pow(10, r - 1)
var d = floor(Double(i) / p)
sum += Int(d)
i -= Int(d * p)
}
return sum
}
for swift4, try below function:
func sumDigits(num: Int) -> Int {
return String(num).compactMap { Int(String($0)) }.reduce(0, +)
}
Split it into two pieces:
digits
public extension UnsignedInteger {
/// The digits that make up this number.
/// - Parameter radix: The base the result will use.
func digits(radix: Self = 10) -> [Self] {
sequence(state: self) { quotient in
guard quotient > 0
else { return nil }
let division = quotient.quotientAndRemainder(dividingBy: radix)
quotient = division.quotient
return division.remainder
}
.reversed()
}
}
XCTAssertEqual(
(867_5309 as UInt).digits(),
[8,6,7, 5,3,0,9]
)
XCTAssertEqual(
(0x00_F0 as UInt).digits(radix: 0b10),
[1,1,1,1, 0,0,0,0]
)
XCTAssertEqual(
(0xA0_B1_C2_D3_E4_F5 as UInt).digits(radix: 0x10),
[10,0, 11,1, 12,2, 13,3, 14,4, 15,5]
)
XCTAssertEqual(
(0o00707 as UInt).digits(radix: 0o10),
[0b111, 0, 0b111]
)
sum
public extension Sequence where Element: AdditiveArithmetic {
var sum: Element? { reduce(+) }
}
public extension Sequence {
/// The first element of the sequence.
/// - Note: `nil` if the sequence is empty.
var first: Element? {
var iterator = makeIterator()
return iterator.next()
}
/// - Returns: `nil` If the sequence has no elements, instead of an "initial result".
func reduce(
_ getNextPartialResult: (Element, Element) throws -> Element
) rethrows -> Element? {
guard let first = first
else { return nil }
return try dropFirst().reduce(first, getNextPartialResult)
}
}
XCTAssertEqual([1, 2, 3].sum, 6)
XCTAssertEqual([0.5, 1, 1.5].sum, 3)
XCTAssertNil([CGFloat]().sum)