Range modifications: Difference between revisions

Added Go
(Added Go)
Line 52:
remove 9
remove 7
 
=={{header|Go}}==
{{trans|Wren}}
<lang go>package main
 
import (
"fmt"
"strings"
)
 
type rng struct{ from, to int }
 
type fn func(rngs *[]rng, n int)
 
func (r rng) String() string { return fmt.Sprintf("%d-%d", r.from, r.to) }
 
func rangesAdd(rngs []rng, n int) []rng {
if len(rngs) == 0 {
rngs = append(rngs, rng{n, n})
return rngs
}
for i, r := range rngs {
if n < r.from-1 {
rngs = append(rngs, rng{})
copy(rngs[i+1:], rngs[i:])
rngs[i] = rng{n, n}
return rngs
} else if n == r.from-1 {
rngs[i] = rng{n, r.to}
return rngs
} else if n <= r.to {
return rngs
} else if n == r.to+1 {
rngs[i] = rng{r.from, n}
if i < len(rngs)-1 && (n == rngs[i+1].from || n+1 == rngs[i+1].from) {
rngs[i] = rng{r.from, rngs[i+1].to}
copy(rngs[i+1:], rngs[i+2:])
rngs[len(rngs)-1] = rng{}
rngs = rngs[:len(rngs)-1]
}
return rngs
} else if i == len(rngs)-1 {
rngs = append(rngs, rng{n, n})
return rngs
}
}
return rngs
}
 
func rangesRemove(rngs []rng, n int) []rng {
if len(rngs) == 0 {
return rngs
}
for i, r := range rngs {
if n <= r.from-1 {
return rngs
} else if n == r.from && n == r.to {
copy(rngs[i:], rngs[i+1:])
rngs[len(rngs)-1] = rng{}
rngs = rngs[:len(rngs)-1]
return rngs
} else if n == r.from {
rngs[i] = rng{n + 1, r.to}
return rngs
} else if n < r.to {
rngs[i] = rng{r.from, n - 1}
rngs = append(rngs, rng{})
copy(rngs[i+2:], rngs[i+1:])
rngs[i+1] = rng{n + 1, r.to}
return rngs
} else if n == r.to {
rngs[i] = rng{r.from, n - 1}
return rngs
}
}
return rngs
}
 
func standard(rngs []rng) string {
if len(rngs) == 0 {
return ""
}
var sb strings.Builder
for _, r := range rngs {
sb.WriteString(fmt.Sprintf("%s,", r))
}
s := sb.String()
return s[:len(s)-1]
}
 
func main() {
const add = 0
const remove = 1
fns := []fn{
func(prngs *[]rng, n int) {
*prngs = rangesAdd(*prngs, n)
fmt.Printf(" add %2d => %s\n", n, standard(*prngs))
},
func(prngs *[]rng, n int) {
*prngs = rangesRemove(*prngs, n)
fmt.Printf(" remove %2d => %s\n", n, standard(*prngs))
},
}
 
var rngs []rng
ops := [][2]int{{add, 77}, {add, 79}, {add, 78}, {remove, 77}, {remove, 78}, {remove, 79}}
fmt.Printf("Start: %q\n", standard(rngs))
for _, op := range ops {
fns[op[0]](&rngs, op[1])
}
 
rngs = []rng{{1, 3}, {5, 5}}
ops = [][2]int{{add, 1}, {remove, 4}, {add, 7}, {add, 8}, {add, 6}, {remove, 7}}
fmt.Printf("\nStart: %q\n", standard(rngs))
for _, op := range ops {
fns[op[0]](&rngs, op[1])
}
 
rngs = []rng{{1, 5}, {10, 25}, {27, 30}}
ops = [][2]int{{add, 26}, {add, 9}, {add, 7}, {remove, 26}, {remove, 9}, {remove, 7}}
fmt.Printf("\nStart: %q\n", standard(rngs))
for _, op := range ops {
fns[op[0]](&rngs, op[1])
}
}</lang>
 
{{out}}
<pre>
Start: ""
add 77 => 77-77
add 79 => 77-77,79-79
add 78 => 77-79
remove 77 => 78-79
remove 78 => 79-79
remove 79 =>
 
Start: "1-3,5-5"
add 1 => 1-3,5-5
remove 4 => 1-3,5-5
add 7 => 1-3,5-5,7-7
add 8 => 1-3,5-5,7-8
add 6 => 1-3,5-8
remove 7 => 1-3,5-6,8-8
 
Start: "1-5,10-25,27-30"
add 26 => 1-5,10-30
add 9 => 1-5,9-30
add 7 => 1-5,7-7,9-30
remove 26 => 1-5,7-7,9-25,27-30
remove 9 => 1-5,7-7,10-25,27-30
remove 7 => 1-5,10-25,27-30
</pre>
 
=={{header|Phix}}==
9,482

edits