元ネタ
Javaの講義、試験が「自作関数を作り記述しなさい」って問題だったから
— てくも (@kumiromilk) March 9, 2016
「ズン」「ドコ」のいずれかをランダムで出力し続けて「ズン」「ズン」「ズン」「ズン」「ドコ」の配列が出たら「キ・ヨ・シ!」って出力した後終了って関数作ったら満点で単位貰ってた
RxSwiftで書いてみた
ズン
かドコ
が延々と流れてくるズンドコ川
を作って、scan
で直近5件の配列を作り、[ズン,ズン,ズン,ズン,ドコ]
になるまでtakeWhile
したらできました。RxSwift 2.2.0で動きます。
import RxSwift
import Foundation
enum ズンドコ: UInt32 {
case ズン
case ドコ
}
let ズンドコ川 = Observable<Int>.interval(0.5, scheduler: MainScheduler.instance)
.map { _ in ズンドコ(rawValue: arc4random_uniform(2))! }
_ = ズンドコ川
.doOnNext { print($0) }
.scan([]) { Array(($0 + [$1]).suffix(5)) }
.takeWhile { $0 != [.ズン, .ズン, .ズン, .ズン, .ドコ] }
.subscribeCompleted { print("キ・ヨ・シ!") }
実行例
0.5秒ごとに出力されるのでズンドコ感があり、結構ドキドキします。
ドコ
ズン
ズン
ドコ
ドコ
ズン
ドコ
ドコ
ズン
ズン
ズン
ズン
ドコ
キ・ヨ・シ!
リズム感を増す
今のままだとドコ
とキ・ヨ・シ!
が同時に出力されてしまい、少しリズム感に欠けます。takeWhile
でストリームが終了したあとに
.concat(Observable.never().take(0.5, scheduler: MainScheduler.instance))
みたいに0.5秒で終わるストリームをconcat
すると、よりよいリズムになるでしょう。
Playgroundで実行するには
interval
を動かし続けるために以下を追加してください。あと「RxSwift-iOS」ではなくて「RxSwift-OSX」のほうをビルドしておく必要があります。
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
他の言語の例
http://qiita.com/search?q=ズンドコキヨシ
http://qiita.com/shunsugai@github/items/971a15461de29563bf90
[追記] 改良してみた
より自己満足感を増した最終版を作りました。
ズンドコキヨシ with RxSwift 最終版と試行錯誤の歴史