You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

compress.go 1.9KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package main
  2. import "strings"
  3. func compress(parts []string) (main, a, b, c string) {
  4. for _, candidateA := range prefixes(parts) {
  5. remainderA := replace(parts, candidateA, "A")
  6. for _, candidateB := range prefixes(remainderA) {
  7. remainderB := replace(remainderA, candidateB, "B")
  8. for _, candidateC := range prefixes(remainderB) {
  9. remainderC := replace(remainderB, candidateC, "C")
  10. if acceptableRoutine(remainderC) {
  11. return strings.Join(remainderC, ","), strings.Join(candidateA, ","), strings.Join(candidateB, ","), strings.Join(candidateC, ",")
  12. }
  13. }
  14. }
  15. }
  16. return
  17. }
  18. func replace(parts []string, function []string, name string) []string {
  19. var res []string
  20. for start := 0; start < len(parts); start++ {
  21. if start+len(function) <= len(parts) && equals(parts[start:start+len(function)], function) {
  22. res = append(res, name)
  23. start += len(function) - 1
  24. } else {
  25. res = append(res, parts[start])
  26. }
  27. }
  28. return res
  29. }
  30. func equals(a, b []string) bool {
  31. for i, p := range a {
  32. if b[i] != p {
  33. return false
  34. }
  35. }
  36. return true
  37. }
  38. func prefixes(parts []string) [][]string {
  39. start := 0
  40. for start < len(parts) && (parts[start] == "A" || parts[start] == "B") {
  41. start++
  42. }
  43. if start == len(parts) {
  44. return nil
  45. }
  46. var res [][]string
  47. for end := start + 1; end <= len(parts) && acceptableFunction(parts[start:end]); end++ {
  48. res = append(res, parts[start:end])
  49. }
  50. // Reverse the slice so the longest element is first
  51. for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
  52. res[i], res[j] = res[j], res[i]
  53. }
  54. return res
  55. }
  56. func acceptableRoutine(parts []string) bool {
  57. for _, p := range parts {
  58. if p != "A" && p != "B" && p != "C" {
  59. return false
  60. }
  61. }
  62. return true
  63. }
  64. func acceptableFunction(parts []string) bool {
  65. length := 0
  66. for i, part := range parts {
  67. if i > 0 {
  68. length++
  69. }
  70. length += len(part)
  71. if strings.ContainsAny(part, "ABC") || length > 20 {
  72. return false
  73. }
  74. }
  75. return true
  76. }