11import ArgumentParser
2+ import Foundation
23
34// Add each new day implementation to this array:
45let allChallenges : [ any AdventDay ] = [
5- Day00 ( )
6+ Day00 ( ) ,
7+ // Day01(),
8+ // Day02(),
9+ // Day03(),
10+ // Day04(),
11+ // Day05(),
12+ // Day06(),
13+ // Day07(),
14+ // Day08(),
15+ // Day09(),
16+ // Day10(),
17+ // Day11(),
18+ // Day12(),
19+ // Day13(),
20+ // Day14(),
21+ // Day15(),
22+ // Day16(),
23+ // Day17(),
24+ // Day18(),
25+ // Day19(),
26+ // Day20(),
27+ // Day21(),
28+ // Day22(),
29+ // Day23(),
30+ // Day24(),
31+ // Day25(),
632]
733
834@main
935struct AdventOfCode : AsyncParsableCommand {
1036 @Argument ( help: " The day of the challenge. For December 1st, use '1'. " )
1137 var day : Int ?
1238
39+ @Flag ( help: " Create new code, data, and test files for the next day. " )
40+ var new : Bool = false
41+
1342 @Flag ( help: " Benchmark the time taken by the solution " )
1443 var benchmark : Bool = false
1544
@@ -57,6 +86,16 @@ struct AdventOfCode: AsyncParsableCommand {
5786 }
5887
5988 func run( ) async throws {
89+ if self . new {
90+ let day = ( allChallenges. last? . day ?? 0 ) + 1
91+ try createFiles ( for: day)
92+ let year = Calendar ( identifier: . gregorian) . component ( . year, from: Date ( ) )
93+ try uncommentAllChallenges ( for: day)
94+ print ( " See your question at https://adventofcode.com/ \( year) /day/ \( day) " )
95+ print ( " Good luck! " )
96+ return
97+ }
98+
6099 let challenges =
61100 if all {
62101 allChallenges
@@ -78,4 +117,49 @@ struct AdventOfCode: AsyncParsableCommand {
78117 }
79118 }
80119 }
120+
121+ private func createFiles( for day: Int ) throws {
122+ let fileManager = FileManager . default
123+ let currentPath = fileManager. currentDirectoryPath
124+ let className = String ( format: " Day%02d " , Int ( day) )
125+
126+ // Data file
127+ let newDataFilePath = " \( currentPath) /Sources/Data/ \( className) .txt "
128+ try createFile ( atPath: newDataFilePath, content: " " )
129+
130+ // Code file
131+ let templateFilePath = " \( currentPath) /Sources/DayTemplate.swift "
132+ let newCodeFilePath = " \( currentPath) /Sources/ \( className) .swift "
133+ let newCodeFileContent = try String ( contentsOfFile: templateFilePath, encoding: . utf8)
134+ . replacingOccurrences ( of: " DayTemplate " , with: className)
135+ try createFile ( atPath: newCodeFilePath, content: newCodeFileContent)
136+
137+ // Test file
138+ let templateTestFilePath = " \( currentPath) /Tests/DayTemplate.swift "
139+ let newTestFilePath = " \( currentPath) /Tests/ \( className) .swift "
140+ let newTestFileContent = try String ( contentsOfFile: templateTestFilePath, encoding: . utf8)
141+ . replacingOccurrences ( of: " DayTemplate " , with: className)
142+ try createFile ( atPath: newTestFilePath, content: newTestFileContent)
143+ }
144+
145+ private func createFile( atPath path: String , content: String ) throws {
146+ let fileManager = FileManager . default
147+ guard !fileManager. fileExists ( atPath: path) else {
148+ fatalError ( " File already exists at \( path) . " )
149+ }
150+ try content. write ( toFile: path, atomically: true , encoding: . utf8)
151+ print ( " Created \( path) " )
152+ }
153+
154+ private func uncommentAllChallenges( for day: Int ) throws {
155+ let fileManager = FileManager . default
156+ let currentPath = fileManager. currentDirectoryPath
157+ let filePath = " \( currentPath) /Sources/AdventOfCode.swift "
158+ let className = String ( format: " Day%02d " , Int ( day) )
159+
160+ let fileContent = try String ( contentsOfFile: filePath, encoding: . utf8)
161+ let newFileContent = fileContent. replacingOccurrences ( of: " // \( className) () " , with: " \( className) () " )
162+ try newFileContent. write ( toFile: filePath, atomically: true , encoding: . utf8)
163+ }
164+
81165}
0 commit comments