11use std:: env;
2- use std:: fs:: { File , OpenOptions } ;
3- use std:: io:: { BufRead , BufReader , Write } ;
2+ use std:: fs:: OpenOptions ;
3+ use std:: io:: Write ;
44use std:: path:: Path ;
55use std:: time:: { SystemTime , UNIX_EPOCH , Duration , Instant } ;
66use std:: collections:: VecDeque ;
@@ -64,27 +64,12 @@ fn detect_outcome(start: &BigUint) -> Outcome {
6464 Outcome :: NontrivialCycle
6565}
6666
67- fn read_last_start ( path : & str ) -> Option < BigUint > {
68- let f = File :: open ( path) . ok ( ) ?;
69- let reader = BufReader :: new ( f) ;
70- let mut last: Option < BigUint > = None ;
71- for l in reader. lines ( ) . map_while ( Result :: ok) {
72- let t = l. trim ( ) ;
73- if t. is_empty ( ) { continue ; }
74- if let Ok ( v) = t. parse :: < BigUint > ( ) { last = Some ( v) ; }
75- }
76- last
77- }
78-
7967#[ allow( clippy:: type_complexity) ]
80- fn parse_args ( ) -> ( Option < BigUint > , Option < u64 > , bool , String , String , u64 , bool , bool , u64 , u64 ) {
68+ fn parse_args ( ) -> ( Option < BigUint > , Option < u64 > , String , bool , bool , u64 , u64 ) {
8169 let mut start: Option < BigUint > = None ;
8270 let mut count: Option < u64 > = None ;
83- let mut resume = true ;
84- let mut output = String :: from ( "progress.txt" ) ;
8571 let mut solution = String :: from ( "solution.txt" ) ;
86- let mut progress_interval: u64 = 1000 ;
87- let mut random = false ; // default OFF
72+ let mut random = true ; // default ON
8873 let mut viz = true ; // default ON
8974 let mut viz_interval: u64 = 1_000 ; // draw often by default
9075 let mut viz_max_steps: u64 = 10_000 ; // limit steps when rendering
@@ -98,17 +83,9 @@ fn parse_args() -> (Option<BigUint>, Option<u64>, bool, String, String, u64, boo
9883 "--count" | "-n" => {
9984 if let Some ( v) = args. next ( ) { count = v. parse :: < u64 > ( ) . ok ( ) ; }
10085 }
101- "--resume" => resume = true ,
102- "--no-resume" => resume = false ,
103- "--output" | "-o" | "--progress" => {
104- if let Some ( v) = args. next ( ) { output = v; }
105- }
10686 "--solution" => {
10787 if let Some ( v) = args. next ( ) { solution = v; }
10888 }
109- "--progress-interval" | "-pi" => {
110- if let Some ( v) = args. next ( ) { if let Ok ( n) = v. parse :: < u64 > ( ) { progress_interval = n; } }
111- }
11289 "--random" => {
11390 random = true ;
11491 }
@@ -139,46 +116,24 @@ fn parse_args() -> (Option<BigUint>, Option<u64>, bool, String, String, u64, boo
139116 }
140117 }
141118
142- ( start, count, resume , output , solution, progress_interval , random, viz, viz_interval, viz_max_steps)
119+ ( start, count, solution, random, viz, viz_interval, viz_max_steps)
143120}
144121
145122fn real_main ( ) -> Result < ( ) , Box < dyn std:: error:: Error > > {
146- let ( start_arg, count_arg, resume , output , solution, progress_interval_arg , random, viz, viz_interval_arg, viz_max_steps) = parse_args ( ) ;
123+ let ( start_arg, count_arg, solution, random, viz, viz_interval_arg, viz_max_steps) = parse_args ( ) ;
147124
148- // Determine start number, possibly resuming from last written line
149- // Default start is 2^68 when not resuming and not provided explicitly.
125+ // Determine start number. Default start is 2^68 when not provided explicitly.
150126 let default_start: BigUint = BigUint :: one ( ) << 68 ; // 2^68
151- let start: BigUint = if let Some ( s) = start_arg {
152- s
153- } else if resume {
154- match read_last_start ( & output) {
155- Some ( last) => last + BigUint :: one ( ) ,
156- None => default_start,
157- }
158- } else {
159- default_start
160- } ;
127+ let start: BigUint = start_arg. unwrap_or ( default_start) ;
161128
162129 let count = count_arg; // None => run indefinitely
163- let progress_interval = progress_interval_arg. max ( 1 ) ;
164130 let viz_interval = viz_interval_arg. max ( 1 ) ;
165-
166- let progress_path = Path :: new ( & output) ;
167131 let solution_path = Path :: new ( & solution) ;
168132
169133 if random {
170- eprintln ! (
171- "Random mode: sampling starts in [2^68, 2^2000-1]; progress in {}" ,
172- progress_path. display( )
173- ) ;
134+ eprintln ! ( "Random mode: sampling starts in [2^68, 2^2000-1]" ) ;
174135 } else {
175- eprintln ! ( "Starting at {}{} -> recording progress in {}" , start,
176- if resume { " (resume)" } else { "" } , progress_path. display( ) ) ;
177- }
178-
179- // Ensure the progress file exists and reflects the starting point (sequential mode only).
180- if !random {
181- write_progress_number ( progress_path, & start) ?;
136+ eprintln ! ( "Starting sequential scan at {start}" ) ;
182137 }
183138
184139 let mut processed: u64 = 0 ;
@@ -208,10 +163,7 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
208163 } ;
209164 let outcome = detect_outcome ( & current) ;
210165
211- // Update progress occasionally (single-line file), only in sequential mode
212- if !random && processed % progress_interval == 0 {
213- write_progress_number ( progress_path, & current) ?;
214- }
166+ // No progress writes in random or sequential modes
215167
216168 // Send trajectory data at configured cadence
217169 if let Some ( ref tx) = viz_sender {
@@ -231,15 +183,12 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
231183 Outcome :: NontrivialCycle => {
232184 eprintln ! ( "Found nontrivial loop starting from {current}." ) ;
233185 write_solution ( solution_path, & format ! ( "NONTRIVIAL_CYCLE_START {current}" ) ) ?;
234- // Also update progress to this current number (sequential mode only)
235- if !random { write_progress_number ( progress_path, & current) ?; }
236186 break ;
237187 }
238188 Outcome :: StepsOverflow => {
239189 let kind = "RUNAWAY_STEPS_OVERFLOW_START" ;
240190 eprintln ! ( "Detected runaway ({kind}). Start: {current}" ) ;
241191 write_solution ( solution_path, & format ! ( "{kind} {current}" ) ) ?;
242- if !random { write_progress_number ( progress_path, & current) ?; }
243192 break ;
244193 }
245194 }
@@ -282,16 +231,6 @@ fn real_main() -> Result<(), Box<dyn std::error::Error>> {
282231 Ok ( ( ) )
283232}
284233
285- fn write_progress_number ( path : & Path , value : & BigUint ) -> std:: io:: Result < ( ) > {
286- // Truncate and write a single line with the current start
287- let mut f = OpenOptions :: new ( ) . create ( true ) . write ( true ) . truncate ( true ) . open ( path) ?;
288- writeln ! ( f, "{}" , value. to_str_radix( 10 ) ) ?;
289- f. flush ( ) ?;
290- // Ensure durability so we don't lose our place on crashes
291- f. sync_all ( ) ?;
292- Ok ( ( ) )
293- }
294-
295234fn write_solution ( path : & Path , line : & str ) -> std:: io:: Result < ( ) > {
296235 // Overwrite solution.txt with a single line describing the finding
297236 let mut f = OpenOptions :: new ( ) . create ( true ) . write ( true ) . truncate ( true ) . open ( path) ?;
0 commit comments