/* This script is part of radix_info. Copyright (C) 2023 Adrien Hopkins This program is free software: you can redistribute it and/or modify it under the terms of version 3 of the GNU General Public License as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package main import ( "aphopkins/radix_info/factors" "fmt" "io" "strconv" "strings" ) // The maximum radix that is supported by writeDigitMapSmall const maxSmallRadix = 36 func writeDigitMap(w io.Writer, digitMap []factors.DigitType) { if len(digitMap) <= 36 { writeDigitMapSmall(w, digitMap) } } // Prints a digit map suitable for small bases (≤36). func writeDigitMapSmall(w io.Writer, digitMap []factors.DigitType) { radix := uint(len(digitMap)) digitsString := strings.Builder{} digitsString.Grow(int(3*radix + 6)) digitsString.WriteString("Digit:") typesString := strings.Builder{} typesString.WriteString("Class:") for digit, digitType := range digitMap { digitString := fmt.Sprintf("%2s", strings.ToUpper( strconv.FormatUint(uint64(digit), int(radix)))) typeString := digitType.String() fmt.Fprintf(&digitsString, " %s", colourString(digitString, digitType)) fmt.Fprintf(&typesString, " %s", colourString(typeString, digitType)) } fmt.Fprintln(w, digitsString.String()) fmt.Fprintln(w, typesString.String()) } // Prints a compactified digit map, used in the compact display. func writeDigitMapCompact(w io.Writer, digitMap []factors.DigitType) { radix := uint(len(digitMap)) if radix <= maxSmallRadix { fmt.Fprint(w, "Digits: ") for digit, digitType := range digitMap { fmt.Fprint(w, colourString(strings.ToUpper( strconv.FormatUint(uint64(digit), int(radix))), digitType)) } fmt.Fprintln(w) } } func colourString(s string, digitType factors.DigitType) string { var colourBegin string switch digitType.TotativeType() { case factors.Regular: switch digitType.Regularity() { case 0: colourBegin = "\x1B[48;5;5m" // special cases (1) case 1: colourBegin = "\x1B[48;5;4m" // factors case 2: colourBegin = "\x1B[48;5;6m" // 2-regulars default: colourBegin = "\x1B[48;5;2m" // other regulars } case factors.Omega, factors.Alpha, factors.Pseudoneighbour: if digitType.Regularity() == 0 { colourBegin = "\x1B[48;5;198m" // neighbourly totatives } else { colourBegin = "\x1B[48;5;136m" // neighbourly semitotatives } case factors.Opaque: if digitType.Regularity() == 0 { colourBegin = "\x1B[48;5;1m" // opaque totatives } else { colourBegin = "\x1B[48;5;130m" // opaque semitotatives } default: colourBegin = "\x1B[48;5;5m" // special cases (0) } return colourBegin + "\x1B[38;5;15m" + s + "\x1B[0m" }