競プロで使える便利なエクステンション一覧(Swift)


私はSwiftにおける競プロの記事をいくつか投稿しています。

自分で武器を増やしていくのが競プロの面白さのひとつだと思っているので、まずは自分で考えるのがオススメです。
どうしてもわからないときに、私の記事が参考になると嬉しいです

はじめに

本記事は Swift/Kotlin愛好会 Advent Calendar 2020 の11日目の記事です。
空いているので埋めました。

競プロで使える便利な拡張メソッドとコンピューテッドプロパティを紹介します。

注意

  • 本記事で紹介しているソースコードが正しいかは保証できていません。
  • 本記事は随時更新予定です。

環境

  • OS:macOS Big Sur 11.1
  • Xcode:12.3 (12C33)
  • Swift:5.3.2
    5.2.1(2021/01/24現在のAtCoder)でも動作する

競プロで使える便利なエクステンション一覧

桁分割

説明

数値の桁を分割し、桁数の降順に整列した配列で返します。

ソースコード
private extension Numeric where Self: LosslessStringConvertible {
    var digits: [Int] { string.digits }
}
private extension LosslessStringConvertible {
    var string: String { String(self) }
}
private extension StringProtocol {
    var digits: [Int] { compactMap { $0.wholeNumberValue } }
}

出力例
1.digits -> [1]
32.digits -> [3, 2]
445.digits -> [4, 4, 5]
62096.digits -> [6, 2, 0, 9, 6]

参考リンク

合計

説明

配列などシーケンスの要素の合計を返します。

ソースコード
private extension Sequence where Element: AdditiveArithmetic {
    func sum() -> Element {
        reduce(.zero, +)
    }
}

出力例
[1].sum() -> 1
[1, 3].sum() -> 4
[1, 3, 4].sum() -> 8
(1...5).sum() -> 15

参考リンク

Decimal→Int変換

説明

DecimalInt に変換します。

私は pow() の戻り値を Int で欲しいときに使います。

ソースコード
import Foundation

private extension Decimal {
    var intValue: Int { NSDecimalNumber(decimal: self).intValue }
}

出力例
pow(2, 3).intValue -> 8
pow(10, 6).intValue -> 1000000

参考リンク

10進数→2進数変換

説明

10進数の数値を2進数の文字列に変換します。
digit に必要十分な大きさの値を渡さないとオーバーフローするので注意です。

まだAtCoderでは使ったことがありません。

ソースコード
private extension FixedWidthInteger {
    func binaryString(digit: Int) -> String {
        var result: [String] = []
        for i in 0..<(Self.bitWidth / 8) {
            let byte = UInt8(truncatingIfNeeded: self >> (i * 8))
            let byteString = String(byte, radix: 2)
            let padding = String(repeating: "0", count: 8 - byteString.count)
            result.append(padding + byteString)
        }
        return String(result.reversed().joined().suffix(digit))
    }
}

出力例
0.binaryString(digit: 2) -> "00"
1.binaryString(digit: 2) -> "01"
2.binaryString(digit: 4) -> "0010"
8.binaryString(digit: 8) -> "00001000"
255.binaryString(digit: 8) -> "11111111"
256.binaryString(digit: 8) -> "00000000" // !!!: オーバーフロー
256.binaryString(digit: 12) -> "000100000000"

参考リンク

素数判定

説明

整数が素数か判定します。

まだAtCoderでは使ったことがありません。

ソースコード
private extension Int {
    var isPrime: Bool {
        guard self > 1 else {
            return false
        }
        return (2..<self).lazy.filter { self % $0 == 0 } .count == 0
    }
}

出力例
1.isPrime -> false
2.isPrime -> true
3.isPrime -> true
4.isPrime -> false
5.isPrime -> true

参考リンク

回文判定

説明

整数または文字列が回文か判定します。

まだAtCoderでは使ったことがありません。

ソースコード
private extension Int {
    var isPalindrome: Bool { String(self).isPalindrome }
}

private extension String {
    var isPalindrome: Bool { self == String(self.reversed()) }
}

出力例
1.isPalindrome -> true
2.isPalindrome -> true
10.isPalindrome -> false
11.isPalindrome -> true
100.isPalindrome -> false
101.isPalindrome -> true

参考リンク

おわりに

以上、 Swift/Kotlin愛好会 Advent Calendar 2020 の11日目の記事でした。

参考リンク