package main
import (
"fmt"
"strconv"
"strings"
)
/* ---------------------------------------------------------
Compress: turn "aaabbcccc" into "a3b2c4"
This is run-length encoding (RLE)
--------------------------------------------------------- */
func compress(s string) string {
if len(s) == 0 {
return "" // Edge case: empty string
}
var out strings.Builder // Result string
count := 1 // Count of repeated characters
// Start from index 1 and compare with previous character
for i := 1; i <= len(s); i++ {
// If still repeating the same character, increase count
if i < len(s) && s[i] == s[i-1] {
count++
} else {
// Character changed OR reached end of string
out.WriteByte(s[i-1]) // Add the character
out.WriteString(strconv.Itoa(count)) // Add how many times it repeated
count = 1 // Reset counter
}
}
return out.String()
}
/* ---------------------------------------------------------
Decompress: turn "a3b2c4" into "aaabbcccc"
Reads a letter, then reads digits, expands them.
--------------------------------------------------------- */
func decompress(s string) string {
var out strings.Builder // Result string
var currentChar byte // The character being processed
var number strings.Builder // Digits representing the count
for i := 0; i < len(s); i++ {
c := s[i]
if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') { // Found a letter
// If we already have a previous letter + number, expand it
if currentChar != 0 && number.Len() > 0 {
count, _ := strconv.Atoi(number.String())
out.WriteString(strings.Repeat(string(currentChar), count))
}
currentChar = c // Start new character
number.Reset() // Reset number buffer
} else if c >= '0' && c <= '9' { // Found a digit
number.WriteByte(c) // Build multi-digit number
}
}
// Handle the last character + number pair
if currentChar != 0 && number.Len() > 0 {
count, _ := strconv.Atoi(number.String())
out.WriteString(strings.Repeat(string(currentChar), count))
}
return out.String()
}
func main() {
s := "wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww"
c := compress(s)
d := decompress(c)
fmt.Println("Original: ", s)
fmt.Println("Compressed: ", c)
fmt.Println("Decompressed:", d)
}
/*
run:
Original: wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww
Compressed: w12b1w10b3w6c4w12
Decompressed: wwwwwwwwwwwwbwwwwwwwwwwbbbwwwwwwccccwwwwwwwwwwww
*/