Jump to content

Range modifications: Difference between revisions

m (→‎{{header|Wren}}: Minor tidy)
Line 864:
remove 7 => 1-5,10-25,27-30
</pre>
 
=={{header|jq}}==
{{Works with|jq}}
 
'''Also works with gojq, the Go implementation of jq (*)'''
 
In this entry, a closed interval [i,j] is represented by the JSON array [i, j],
and a sequence of such intervals is represented as a sorted array of such arrays,
with the understanding that [] represents the null sequence.
 
In order to show progress using the string representation of ranges,
jq's "debug" filter is used to show intermediate steps.
 
(*) For gojq, a def of debug/1 may be required as follows:
<pre>
def debug(msg): (msg | debug | empty), .;
</pre>
<syntaxhighlight lang="jq">
# Conversion between string and JSON representations of ranges
# Allow negative integers
def r2j:
[ scan( "(-?[0-9]+)-(-?[0-9]+)|(-?[0-9]+)" )
| map(select(. != null) | tonumber)
| if length==1 then [first,first] end ] ;
 
def j2r:
map( if first == last then "\(first)"
else "\(first)-\(last)"
end )
| join(",");
 
# A quick determination of whether $n is in a sequence of intervals
def indexOf($n):
(first( range(0;length) as $i
| if .[$i][0] <= $n and $n <= .[$i][1] then $i
elif $n < .[$i][0] then -1
else empty
end ) // -1)
| if . == -1 then null else . end ;
 
def rangesAdd($n):
 
# Detect the special case where $i is the only integer in the gap between .[$i] and .[$i+1]
def tween($i):
-1 < $i and $i < length - 1 and .[$i][1] == $i - 1 and .[$i+1][0] == $i + 1;
 
# First handle the boundary cases:
if length == 0 then [[$n, $n]]
elif $n < .[0][0]-1 then [[$n,$n]] + .
elif $n == .[0][0]-1 then [[$n, .[0][1]]] + .[1:]
elif $n > .[-1][1]+1 then . + [[$n,$n]]
elif $n == .[-1][1]+1 then .[:-1] + [[.[-1][0], $n]]
else (map(first) | bsearch($n)) as $ix
| if $ix >= 0 then .
else (-2-$ix) as $i # $i >= 0 is the interval at the insertion point minus 1
| if tween($i)
then .[:$i] + [[.[$i][0], .[$i+1][1]]] + .[$i+2:] # coalesce
else .[$i] as $x # the preliminary checks above ensure 0 <= $i < $length-1
| if $x[0] <= $n and $n <= $x[1] # [_ $n _]
then .
elif $n == $x[1] + 1 # [ *] $n
then (if $i == 0 then null else .[$i-1:] end) + [[$x[0], $n]] + .[$i+1:]
elif $n == .[$i+1][0] - 1 # $n [* _]
then .[:$i+1] + [[$n, .[$i+1][1]]] + .[$i+2:]
else # assert($x[1] < $n and $n < .[$i+1][0]) # [] $n []
.[:$i+1] + [[$n,$n]] + .[$i+1:]
end
end
end
end ;
 
def rangesRemove($n):
# remove a value from a single interval
def remove($n):
. as [$a,$b]
| if $a == $b and $a == $n then null
elif $a == $n then [[$n+1, $b]]
elif $b == $n then [[$a, $n-1]]
else [[$a, $n-1], [$n+1, $b]]
end;
indexOf($n) as $ix
| if $ix then .[:$ix] + (.[$ix]|remove($n)) + .[$ix+1:]
else .
end ;
 
### Pretty printing
def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;
 
# Functions for showing intermediate results, in string form:
# Input: the JSON representation
def add(n):
rangesAdd(n)
| debug(" add \(n|lpad(3)) => \(j2r)");
def remove(n):
rangesRemove(n)
| debug(" remove \(n|lpad(3)) => \(j2r)");
 
# The tasks expressed as sequences of operations on the JSON representation
def s0:
add(77)
| add(79)
| add(78)
| remove(77)
| remove(78)
| remove(79)
;
 
def s1:
add(1)
| remove(4)
| add(7)
| add(8)
| add(6)
| remove(7)
;
 
def s2:
add(26)
| add(9)
| add(7)
| remove(26)
| remove(9)
| remove(7)
;
 
def ex0: "Starting with \(.)", "Ending with \(r2j | s0 | j2r)\n";
def ex1: "Starting with \(.)", "Ending with \(r2j | s1 | j2r)\n";
def ex2: "Starting with \(.)", "Ending with \(r2j | s2 | j2r)\n";
 
("" | ex0),
("1-3,5" | ex1),
("1-5,10-25,27-30" | ex2)
</syntaxhighlight>
{{output}}
<pre>
Starting with
["DEBUG:"," add 77 => 77"]
["DEBUG:"," add 79 => 77,79"]
["DEBUG:"," add 78 => 77-79"]
["DEBUG:"," remove 77 => 78-79"]
["DEBUG:"," remove 78 => 79"]
["DEBUG:"," remove 79 => "]
Ending with
 
Starting with 1-3,5
["DEBUG:"," add 1 => 1-3,5"]
["DEBUG:"," remove 4 => 1-3,5"]
["DEBUG:"," add 7 => 1-3,5,7"]
["DEBUG:"," add 8 => 1-3,5,7-8"]
["DEBUG:"," add 6 => 1-3,5-8"]
["DEBUG:"," remove 7 => 1-3,5-6,8"]
Ending with 1-3,5-6,8
 
Starting with 1-5,10-25,27-30
["DEBUG:"," add 26 => 1-5,10-30"]
["DEBUG:"," add 9 => 1-5,9-30"]
["DEBUG:"," add 7 => 1-5,7,9-30"]
["DEBUG:"," remove 26 => 1-5,7,9-25,27-30"]
["DEBUG:"," remove 9 => 1-5,7,10-25,27-30"]
["DEBUG:"," remove 7 => 1-5,10-25,27-30"]
Ending with 1-5,10-25,27-30
</pre>
 
 
=={{header|Julia}}==
2,442

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.