package izapple2 import "fmt" type trackTracer interface { traceTrack(quarterTrack int, slot int, drive int) } // /////////////// // TrackTracerLogger is a track tracer that logs to the console type trackTracerLogger struct { } func makeTrackTracerLogger() *trackTracerLogger { return &trackTracerLogger{} } func (tt *trackTracerLogger) traceTrack(quarterTrack int, slot int, drive int) { fmt.Printf("Slot %v, drive %v, track %v\n", slot, drive, quarterTrack) } // /////////////// // TrackTracerSummary is a track tracer that stores the track changes type trackTracerSummary struct { quarterTracks []int } func makeTrackTracerSummary() *trackTracerSummary { var tt trackTracerSummary tt.quarterTracks = make([]int, 0, 100) return &tt } func (tt *trackTracerSummary) traceTrack(quarterTrack int, _slot int, _drive int) { if tt == nil { return } length := len(tt.quarterTracks) if length == 0 { // Second change, just record tt.quarterTracks = append(tt.quarterTracks, quarterTrack) return } last := tt.quarterTracks[length-1] if quarterTrack == last { // No changes return } if length == 1 { // Second change, just record tt.quarterTracks = append(tt.quarterTracks, quarterTrack) return } // We don't want to registers the initial jumps around 0 seen when initializing the disk to track 0 prevToLast := tt.quarterTracks[length-2] if length == 2 && prevToLast == 0 && (last == 1 || last == 2) && quarterTrack == 0 { tt.quarterTracks = tt.quarterTracks[0:0] } // We don't want to track each increment. If tracks goes from 1 to 14, we just want 1 and 14. wasGoingUp := last > prevToLast isGoingUp := quarterTrack > last if isGoingUp == wasGoingUp { // Same direction, update the last registry tt.quarterTracks[length-1] = quarterTrack } else { // Change direction, add a new registry tt.quarterTracks = append(tt.quarterTracks, quarterTrack) } } func (tt *trackTracerSummary) isTraceAsExpected(expected []int) bool { if len(tt.quarterTracks) != len(expected) { return false } for i, v := range tt.quarterTracks { if v != expected[i] { return false } } return true }