Range modifications: Difference between revisions

m
→‎{{header|jq}}: negative integers allowed
m (→‎{{header|Phix}}: syntax coloured, made p2js compatible)
m (→‎{{header|jq}}: negative integers allowed)
 
(3 intermediate revisions by 3 users not shown)
Line 60:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">T Sequence
[(Int, Int)] ranges
 
Line 164:
remove 26
remove 9
remove 7’)</langsyntaxhighlight>
 
{{out}}
Line 195:
 
=={{header|Action!}}==
<langsyntaxhighlight Actionlang="action!">DEFINE PTR="CARD"
TYPE Range=[BYTE low,high]
TYPE Ranges=[
Line 408:
TestRemove(rs,9)
TestRemove(rs,7)
RETURN</langsyntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Range_modifications.png Screenshot from Atari 8-bit computer]
Line 438:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">RangeModifications(arr, Modify, v){
global steps ; optional line to track examples steps
if (Modify = "add")
Line 484:
x := StrSplit(v, "-"), arr.push([x.1, x.2])
return arr
}</langsyntaxhighlight>
Examples:<langsyntaxhighlight AutoHotkeylang="autohotkey">arr := string2obj("")
steps .= "start with`t:`t" obj2string(arr) "`n"
arr := RangeModifications(arr, "Add", 77)
Line 516:
arr := RangeModifications(arr, "Remove", 7)
MsgBox % steps
return</langsyntaxhighlight>
{{out}}
<pre>start with :
Line 543:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">#include <algorithm>
#include <iomanip>
#include <iostream>
Line 684:
test3();
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 715:
=={{header|Go}}==
{{trans|Wren}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 836:
fns[op[0]](&rngs, op[1])
}
}</langsyntaxhighlight>
 
{{out}}
Line 863:
remove 9 => 1-5,7-7,10-25,27-30
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. i and j may be negative.
 
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}}==
Julia has iterator classes called a type of Range, such as integer UnitRanges, that are like the "10-10" of the task but are stated as 10:10, with a colon not a minus sign. This implementation uses Julia's UnitRange class internally.
<langsyntaxhighlight lang="julia">import Base.parse, Base.print, Base.reduce
 
const RangeSequence = Array{UnitRange, 1}
Line 962 ⟶ 1,126:
println("Parse \"10-25, 1-5, 27-30\" => ", parse(RangeSequence, "10-25, 1-5, 27-30"))
println("Parse \"3-1,15-5,25-10,30-27\" => ", parse(RangeSequence, "3-1,15-5,25-10,30-27"))
</langsyntaxhighlight>{{out}}
<pre>
Start: ""
Line 993 ⟶ 1,157:
 
=={{header|Nim}}==
<langsyntaxhighlight Nimlang="nim">import algorithm, sequtils, strscans, strutils
 
type
Line 1,143 ⟶ 1,307:
r.remove 26
r.remove 9
r.remove 7</langsyntaxhighlight>
 
{{out}}
Line 1,170 ⟶ 1,334:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict;
Line 1,237 ⟶ 1,401:
remove 26
remove 9
remove 7</langsyntaxhighlight>
{{out}}
<pre>
Line 1,266 ⟶ 1,430:
 
=={{header|Phix}}==
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">ranges</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">v</span><span style="color: #0000FF;">)</span>
Line 1,379 ⟶ 1,543:
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
{{out}}
<small>(Note that all double-quotes in the output were deliberately added in the last two printf() statements, mainly to prove there are no unnecessary spaces, etc, and are (see ^^) obviously trivial to remove.)</small>
Line 1,418 ⟶ 1,582:
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">class Sequence():
def __init__(self, sequence_string):
Line 1,524 ⟶ 1,688:
remove 7
""")
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,561 ⟶ 1,725:
Won't handle negative numbers as written, mostly due the need to work around the syntax requirements for output.
 
<syntaxhighlight lang="raku" perl6line>my @seq;
 
-> $op, $string { printf "%20s -> %s\n", $op, $string } for
Line 1,667 ⟶ 1,831:
}
@ranges
}</langsyntaxhighlight>
 
{{out}}
Line 1,710 ⟶ 1,874:
=={{header|Wren}}==
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "./fmt" for Fmt
 
var rangesAdd = Fn.new { |ranges, n|
Line 1,793 ⟶ 1,957:
Fmt.print("\nStart: $q", standard.call(ranges))
for (op in ops) fns[op[0]].call(ranges, op[1])
</syntaxhighlight>
</lang>
 
{{out}}
2,446

edits