Skip to content

Commit

Permalink
Merge pull request #130
Browse files Browse the repository at this point in the history
Overhaul of Fibonacci<T>
  • Loading branch information
oscbyspro authored Nov 14, 2024
2 parents bd598e0 + d93e588 commit cd3662d
Show file tree
Hide file tree
Showing 21 changed files with 1,494 additions and 321 deletions.
89 changes: 89 additions & 0 deletions Sources/FibonacciKit/Fibonacci+Fast.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit

//*============================================================================*
// MARK: * Fibonacci x Fast
//*============================================================================*

extension Fibonacci {

//=------------------------------------------------------------------------=
// MARK: Initializers
//=------------------------------------------------------------------------=

/// Returns the sequence pair at `index`, or `nil`.
///
/// ### Fibonacci
///
/// - Note: It produces `nil` of the operation is `lossy`.
///
/// - Note: It produces `nil` if the `index` is `infinite`.
///
@inlinable public init?(_ index: consuming Element) {
let base = Self.exactly(index, as: Indexacci.self)
guard let base = base?.optional() else { return nil }
self.init(unsafe: base)
}
}

//=----------------------------------------------------------------------------=
// MARK: + Algorithms
//=----------------------------------------------------------------------------=

extension Fibonacci {

//=------------------------------------------------------------------------=
// MARK: Initializers
//=------------------------------------------------------------------------=s

@inlinable package static func exactly(
_ index: consuming Element,
as type: Indexacci<Element>.Type = Indexacci<Element>.self
) -> Optional<Fallible<Indexacci<Element>>> {

guard let tuple: Fallible<Tupleacci> = Self.exactly(index) else {
return nil
}

return Indexacci(tuple: tuple.value, index: index).veto(tuple.error)
}

@inlinable package static func exactly(
_ index: borrowing Element,
as type: Tupleacci<Element>.Type = Tupleacci<Element>.self
) -> Optional<Fallible<Tupleacci<Element>>> {

if index.isInfinite {
return nil
}

var value = Tupleacci<Element>.fibonacci()
var error = false
let limit = UX(raw: index.nondescending(index.appendix))
let minus = U8(Bit( index.isNegative))

index.withUnsafeBinaryIntegerBody(as: U8.self) {
for count in (0 ..< limit).reversed() {
value = Self.doubled(value).sink(&error)

if $0[unchecked: IX(raw: count) &>> 3] &>> U8(load: count) & 1 != minus {
value = value.incremented().sink(&error)
}
}
}

if !minus.isZero {
value = Self.toggled(value, index: index.lsb.toggled()).sink(&error)
}

return value.veto(error)
}
}
170 changes: 170 additions & 0 deletions Sources/FibonacciKit/Fibonacci+Stride.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit

//*============================================================================*
// MARK: * Fibonacci x Stride
//*============================================================================*

extension Fibonacci {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Returns the sequence pair at `index + 1`, or `nil`.
///
/// ### Fibonacci
///
/// - Note: It produces `nil` of the operation is `lossy`.
///
@inlinable public consuming func incremented() -> Optional<Self> {
self.base.incremented().map(Self.init(unsafe:)).optional()
}

/// Returns the sequence pair at `index - 1`, or `nil`.
///
/// ### Fibonacci
///
/// - Note: It produces `nil` of the operation is `lossy`.
///
@inlinable public consuming func decremented() -> Optional<Self> {
self.base.decremented().map(Self.init(unsafe:)).optional()
}

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Returns the sequence pair at `index * 2`, or `nil`.
///
/// ### Fibonacci
///
/// - Note: It produces `nil` of the operation is `lossy`.
///
@inlinable public consuming func doubled() -> Optional<Self> {
Self.doubled(self.base).map(Self.init(unsafe:)).optional()
}

/// Returns the sequence pair at `index + other.index`, or `nil`.
///
/// ### Fibonacci
///
/// - Note: It produces `nil` of the operation is `lossy`.
///
@inlinable public consuming func incremented(by other: borrowing Self) -> Optional<Self> {
Self.incremented(self.base, by: other.base).map(Self.init(unsafe:)).optional()
}

/// Returns the sequence pair at `index - other.index`, or `nil`.
///
/// ### Fibonacci
///
/// - Note: It produces `nil` of the operation is `lossy`.
///
@inlinable public consuming func decremented(by other: borrowing Self) -> Optional<Self> {
Self.decremented(self.base, by: other.base).map(Self.init(unsafe:)).optional()
}
}

//=----------------------------------------------------------------------------=
// MARK: + Algorithms
//=----------------------------------------------------------------------------=

extension Fibonacci {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

@inlinable package static func doubled(
_ value: consuming Indexacci<Element>
) -> Fallible<Indexacci<Element>> {

var (error) = false
value.tuple = Self.doubled(value.tuple).sink(&error)
value.index = ((value)).index.doubled().sink(&error)
return value.veto(error)
}

@inlinable package static func doubled(
_ value: consuming Tupleacci<Element>
) -> Fallible<Tupleacci<Element>> {

var (error) = false
let (extra) = value.major.doubled().sink(&error).minus(value.minor).sink(&error).times(value.minor).sink(&error)
value.major = value.major.squared().sink(&error).plus((value.minor).squared().sink(&((((error)))))).sink(&error)
value.minor = extra
return value.veto(error)
}

@inlinable package static func incremented(
_ value: consuming Indexacci<Element>,
by other: borrowing Indexacci<Element>
) -> Fallible<Indexacci<Element>> {

var (error) = false
let (fails) = value.index.isNegative == other.index.isNegative
value.index = value.index.plus(other.index).sink(&error)
value.tuple = incremented(value.tuple, by: other.tuple).sink(&error)
return value.veto(fails && error)

func incremented(
_ value: consuming Tupleacci<Element>,
by other: borrowing Tupleacci<Element>
) -> Fallible<Tupleacci<Element>> {

var (error) = false
let (extra) = value.major.times(other.major).sink(&error).plus(value.minor.times(other.minor).sink(&error)).sink(&error)
value.major = value.major.minus(value.minor).sink(&error)
value.minor = value.minor.times(other.major).sink(&error).plus(value.major.times(other.minor).sink(&error)).sink(&error)
value.major = extra
return value.veto(error)
}
}

@inlinable package static func decremented(
_ value: consuming Indexacci<Element>,
by other: borrowing Indexacci<Element>
) -> Fallible<Indexacci<Element>> {

var (error) = false
var (fails) = value.index.isNegative != other.index.isNegative
value.index = value.index.minus(other.index).sink(&error)

if !Element.isSigned {
(fails) = error
}

value.tuple = decremented(value.tuple, by: other.tuple, index: other.index.lsb).sink(&error)
return value.veto(fails && error)

func decremented(
_ value: consuming Tupleacci<Element>,
by other: borrowing Tupleacci<Element>, index: Bit
) -> Fallible<Tupleacci<Element>> {

var (error) = false
var (((a))) = value.minor.times(other.major).sink(&error)
var (((b))) = value.major.times(other.minor).sink(&error)
var (((c))) = value.major.times(other.major).sink(&error)
var (((d))) = value.major.plus (value.minor).sink(&error).times(other.minor).sink(&error)

if Bool(index) {
Swift.swap(&a, &b)
Swift.swap(&c, &d)
}

value.minor = a.minus(b).sink(&error)
value.major = c.minus(d).sink(&error)
return value.veto(error)
}
}
}
25 changes: 25 additions & 0 deletions Sources/FibonacciKit/Fibonacci+Text.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit

//*============================================================================*
// MARK: * Fibonacci x Text
//*============================================================================*

extension Fibonacci {

//=------------------------------------------------------------------------=
// MARK: Utilities
//=------------------------------------------------------------------------=

@inlinable public var description: String {
self.base.description
}
}
65 changes: 65 additions & 0 deletions Sources/FibonacciKit/Fibonacci+Toggle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//=----------------------------------------------------------------------------=
// This source file is part of the Ultimathnum open source project.
//
// Copyright (c) 2023 Oscar Byström Ericsson
// Licensed under Apache License, Version 2.0
//
// See http://www.apache.org/licenses/LICENSE-2.0 for license information.
//=----------------------------------------------------------------------------=

import CoreKit

//*============================================================================*
// MARK: * Fibonacci x Toggle
//*============================================================================*

extension Fibonacci {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

/// Returns the sequence pair reflected about `-1/2`, or `nil`.
///
/// ### Fibonacci
///
/// - Note: It produces `nil` of the operation is `lossy`.
///
@inlinable public consuming func toggled() -> Optional<Self> {
Self.toggled(self.base).map(Self.init(unsafe:)).optional()
}
}

//=----------------------------------------------------------------------------=
// MARK: + Algorithms
//=----------------------------------------------------------------------------=

extension Fibonacci {

//=------------------------------------------------------------------------=
// MARK: Transformations
//=------------------------------------------------------------------------=

@inlinable package static func toggled(
_ value: consuming Indexacci<Element>
) -> Fallible<Indexacci<Element>> {

var (error) = false
value.tuple = Self.toggled(value.tuple, index: value.index.lsb).sink(&error)
value.index = ((value)).index.toggled()
return value.veto(error)
}

@inlinable package static func toggled(
_ value: consuming Tupleacci<Element>, index: Bit
) -> Fallible<Tupleacci<Element>> {

if Bool(index) {
value.major.negate().discard()
} else {
value.minor.negate().discard()
}

return value.swapped().veto(!Element.isSigned)
}
}
Loading

0 comments on commit cd3662d

Please sign in to comment.