過去問やってると、(Command+Uが染みついてて)UnitTestつかいたくなるし、かといって入力をいちいち手作業でリテラルにするのはおっくうで。
そこで!
struct AtCoderRunner { typealias Print = (String) -> Void typealias Solver = (Print) -> Void let solver: Solver func run(input: String) -> String { var output: [String] = [] var buffer: [Int8] = input.utf8CString + [0] let count = buffer.count buffer.withUnsafeMutableBytes { let file = fmemopen($0.baseAddress, count, "r") assert(file != nil) let backup = stdin stdin = file! solver() { output.append($0) } stdin = backup } return output.joined(separator: "\n") } }
例えばこんな解答関数があったとすると
func TemplateSolver(print: (String) -> Void) { let N = Int(Swift.readLine()!)! print("\(N)") }
こんな風にテストできます。
final class AtCoderTemplateTests: XCTestCase { var stdinCopy: UnsafeMutablePointer<FILE>? override func setUpWithError() throws { // 念のため stdinCopy = stdin // でもテストが並列で動くとおじゃん } override func tearDownWithError() throws { // 念のため stdin = stdinCopy! // でもテストが並列で動くとおじゃん } // Greenだよー func testTemplate() throws { XCTAssertEqual( AtCoderRunner(solver: TemplateSolver) .run(input: """ 0 """), """ 0 """) } }
提出するときは、雑に説明するとこんな感じです。
TemplateSolver {
print($0)
}
どうぞご自由におつかいください。
(いまさらですが、過去記事も同様です)
あ、Swiftです。