[SWIFT] Madness Maniac "Aucune opération de bit n'est incluse"

Apparemment, je ne suis pas bon en mathématiques, à part le type qui garde les illusions qui ne sont pas productives tous les jours, comme s'il est possible de définir des opérations de bits sur des nombres ordinaux.

Préface omise.

\def\coloneqq{\mathrel{≔}}
\def\notni{\mathrel{\not \ni}}
\def\Brace#1{\left\{{#1}\right\}}
\def\Set#1#2{\left\{{#1} \; \middle| \; {#2}\right\}}
\def\bit{\mathbin{\text{bit}}}
\def\inc{\mathbin{\text{inc}}}
\def\shl{\mathbin{\text{shl}}}
\def\shr{\mathbin{\text{shr}}}

Il est devenu plus facile de jouer avec Swift, alors j'ai copié mon code préféré

Hyahou, Windows propose désormais une chaîne d'outils Swift!

J'ai l'impression que les pauvres gens qui sont trempés dans l'idée de choisir les gens disent: "Mah, utiliser Swift avec un jouet sauvage fabriqué par Microsoft nuira à la marque", mais je peux l'utiliser, c'est donc la victoire. L'empereur Zul est la justice.

Alors, copions le [Code qui compose les nombres naturels de Neumann avec Swift] de @ taketo1024 (https://qiita.com/taketo1024/items/2ab856d21bf9b9f30357). Ikansen Swift est un code de l'époque où il était instable, il y a donc de nombreuses parties qui ne fonctionnent pas même si vous le copiez tel quel, mais faisons de notre mieux.

import Foundation

postfix operator +
postfix operator -

struct N {
    private let val: [Any]
}

extension N {
    private init(_ val: [Any]) {
        self.val = val
    }

    static var zero: N {
        return N([])
    }

    static postfix func +(n: N) -> N {
        return N(n.val + [n.val])
    }
    
    static postfix func -(n: N) -> N {
        if n.val.isEmpty {
           assertionFailure("0- doesn't exist.")
        }
        return N(n.val.last as![Any])
    }

    static func +(n: N, m: N) -> N {
        if m.val.isEmpty {
            return n
        } else {
            return (n + m-)+
        }
    }

    static func *(n: N, m: N) -> N {
        if m.val.isEmpty {
            return N.zero
        } else {
            return (n * m-) + n
        }
    }
}

extension N: CustomStringConvertible {
    var description: String {
        return "\(val.count)"
    }
}

extension N: Equatable {
    static func ==(n: N, m: N) -> Bool {
        if (n.val.isEmpty && m.val.isEmpty) {
            return true
        } else if (n.val.isEmpty || m.val.isEmpty) {
            return false
        } else {
            return (n- == m-)
        }
    }
}

extension N: ExpressibleByIntegerLiteral {
    init(integerLiteral value: IntegerLiteralType) {
        var n = N.zero
        for i in 0..<value {
            n = n+
        }
        self.val = n.val
    }
}

C'était terminé comme ça. Le style Rust consiste à séparer la structure, la mise en œuvre et la conformité. Rust étudie peut-être aussi, mais vous!

let a: N = 2
let b: N = 3

print("\(a + b)")
print("\(a * b)")

5
6

C'est parfait. Les réalisations de nos prédécesseurs sont formidables.

Il n'y a pas d'opération de bit, pourquoi ne faites-vous pas cela?

Aye fou !!

C'est pourquoi nous allons implémenter l'arithmétique des bits.

Commencez par mettre en œuvre le 冪 comme préparation préliminaire.

extension N {
    func pow(_ m: N) -> N {
        if m.val.isEmpty {
            return N.zero+
        } else {
            return self.pow(m-) * self
        }
    }
}

n^m \coloneqq
\begin{cases}
    \Brace{\varnothing} & \text{($m = \varnothing$)} \\
    n^{\hat{m}} \times n & \text{($m = \hat{m}^+$)}
\end{cases}

Il n'y a rien d'étrange à cela.

Ensuite, je veux penser à "un ensemble de nombres naturels", c'est-à-dire à "Set ", donc j'adapte "N" à "Hashable".

extension N: Hashable {
    func hash(into hasher: inout Hasher) {
        hasher.combine(self.val.count)
    }
}

La définition de la fonction de hachage est devenue beaucoup plus simple.

Ici, le mappage $ \ inc: 2 ^ \ mathbb {N} \ à 2 ^ \ mathbb {N} $ est défini.

extension N {
    static func inc(_ s: Set<N>) -> Set<N> {
        if s.contains(N.zero) {
            return Set(inc(Set(s.subtracting([N.zero]).map {$0-})).map {$0+})
        } else {
            return s.union([N.zero])
        }
    }
}

\inc(S) \coloneqq
\begin{cases}
    S \cup \Brace{\varnothing} & \text{($S \notni \varnothing$)} \\
    \Brace{n^+ \mid n \in \inc(\Brace{\bigcup n \mid n \in S \setminus \Brace{\varnothing}})} & \text{($S \ni \varnothing$)}
\end{cases}

Wow, c'est ...

Il sera plus facile à comprendre si vous définissez les deux mappages suivants $ \ shl, \ shr: 2 ^ \ mathbb {N} \ to 2 ^ \ mathbb {N} $.

\begin{aligned}
    \shl(S) &\coloneqq \Brace{n^+ \mid n \in S} \\
    \shr(S) &\coloneqq \Set{\bigcup n}{n \in S \setminus \Brace{\varnothing}}
\end{aligned}

En d'autres termes, c'est un mappage qui augmente ou diminue 1 $ pour tout le contenu.

\inc(S) \coloneqq
\begin{cases}
    S \cup \Brace{\varnothing} & \text{($S \notni \varnothing$)} \\
    \shl \circ \inc \circ \shr(S) & \text{($S \ni \varnothing$)}
\end{cases}

C'était plutôt rafraîchissant. ~~ Au fait, pourquoi la valeur de retour de Set <T> # map ʻArray `? ~~ $ \ inc $ a été défini dans this

\bit(x) \coloneqq
\begin{cases}
    \varnothing & \text{($x = 0$)} \\
    \bit(\hat{x}) \cup \Brace{m} \setminus \Brace{n \in \mathbb{N} \mid n < m} \text{, where $m = \min(\bit(\hat{x})^c)$} & \text{($x = \hat{x}^+)$} 
\end{cases}

Pour éviter de demander $ m $ qui apparaît dans. Si vous utilisez $ \ inc $

extension N {
    static func bit(_ n: N) -> Set<N> {
        if n.val.isEmpty {
            return Set()
        } else {
            return inc(bit(n-))
        }
    }
}

\bit(n) \coloneqq
\begin{cases}
    \varnothing & \text{($n = \varnothing$)} \\
    \inc \circ \bit(\hat{n}) & \text{($n = \hat{n}^+$)}
\end{cases}

Peut être défini de manière récursive.

Ensuite, définissez le mappage inverse de $ \ bit $ $ \ bit ^ {-1} $.

extension N {
    static func invBit(_ s: Set<N>) -> N {
        return s.reduce(N.zero) {$0 + (N.zero+)+.pow($1)}
    }
}

\bit^{-1}(S) = \sum_{n \in S} 2^n

Ce n'est pas particulièrement difficile.

Si vous pouvez vous préparer jusqu'ici, il est facile d'implémenter une opération de bit en utilisant l'opération set qui est incluse dans Set depuis le début.

extension N {
    static func |(n: N, m: N) -> N {
        return invBit(bit(n).union(bit(m))) //Fusion d'ensembles
    }

    static func &(n: N, m: N) -> N {
        return invBit(bit(n).intersection(bit(m))) //Croisement d'ensembles
    }

    static func ^(n: N, m: N) -> N {
        return invBit(bit(n).symmetricDifference(bit(m))) //Différence de symétrie de l'ensemble
    }
}

let a: N = 2
let b: N = 3

print("\(a + b)")
print("\(a * b)")
print("\(a ^ b)")

5
6
1

Je l'ai fait.

Vue d'ensemble du code final

C'est 14 millions 3000 yens.

import Foundation

postfix operator +
postfix operator -

struct N {
    private let val: [Any]
}

extension N {
    private init(_ val: [Any]) {
        self.val = val
    }

    static var zero: N {
        return N([])
    }

    static postfix func +(n: N) -> N {
        return N(n.val + [n.val])
    }
    
    static postfix func -(n: N) -> N {
        if n.val.isEmpty {
           assertionFailure("0- doesn't exist.")
        }
        return N(n.val.last as![Any])
    }

    static func +(n: N, m: N) -> N {
        if m.val.isEmpty {
            return n
        } else {
            return (n + m-)+
        }
    }

    static func *(n: N, m: N) -> N {
        if m.val.isEmpty {
            return N.zero
        } else {
            return (n * m-) + n
        }
    }

    static func |(n: N, m: N) -> N {
        return invBit(bit(n).union(bit(m)))
    }

    static func &(n: N, m: N) -> N {
        return invBit(bit(n).intersection(bit(m)))
    }

    static func ^(n: N, m: N) -> N {
        return invBit(bit(n).symmetricDifference(bit(m)))
    }

    func pow(_ m: N) -> N {
        if m.val.isEmpty {
            return N.zero+
        } else {
            return self.pow(m-) * self
        }
    }
    
    static func inc(_ s: Set<N>) -> Set<N> {
        if s.contains(N.zero) {
            return Set(inc(Set(s.subtracting([N.zero]).map {$0-})).map {$0+})
        } else {
            return s.union([N.zero])
        }
    }

    static func bit(_ n: N) -> Set<N> {
        if n.val.isEmpty {
            return Set()
        } else {
            return inc(bit(n-))
        }
    }

    static func invBit(_ s: Set<N>) -> N {
        return s.reduce(N.zero) {$0 + (N.zero+)+.pow($1)}
    }
}

extension N: CustomStringConvertible {
    var description: String {
        return "\(val.count)"
    }
}

extension N: Equatable {
    static func ==(n: N, m: N) -> Bool {
        if (n.val.isEmpty && m.val.isEmpty) {
            return true
        } else if (n.val.isEmpty || m.val.isEmpty) {
            return false
        } else {
            return (n- == m-)
        }
    }
}

extension N: ExpressibleByIntegerLiteral {
    init(integerLiteral value: IntegerLiteralType) {
        var n = N.zero
        for i in 0..<value {
            n = n+
        }
        self.val = n.val
    }
}

extension N: Hashable {
    func hash(into hasher: inout Hasher) {
        hasher.combine(self.val.count)
    }
}

Recommended Posts

Madness Maniac "Aucune opération de bit n'est incluse"