Non-continuous subsequences: Difference between revisions
m
→{{header|Wren}}: Minor tidy
m (→{{header|Wren}}: Minor tidy) |
|||
(17 intermediate revisions by 13 users not shown) | |||
Line 8:
Note: Subsequences are defined ''structurally'', not by their contents.
So a sequence ''a,b,c,d'' will always have the same subsequences and continuous subsequences, no matter which values are substituted; it may even be the same value.
'''Task''': Find all non-continuous subsequences for a given sequence.
;Example:
For the sequence ''1,2,3,4'', there are five non-continuous subsequences, namely:
::::* ''1,3''
::::* ''1,4''
Line 18 ⟶ 21:
::::* ''1,2,4''
;Goal:
There are different ways to calculate those subsequences.
Demonstrate algorithm(s) that are natural for the language.
{{Template:Strings}}
<br><br>
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">F ncsub(seq, s = 0)
I seq.empty
R I s >= 3 {[[Int]()]} E [[Int]]()
E
V x = seq[0.<1]
V xs = seq[1..]
V p2 = s % 2
V p1 = !p2
R ncsub(xs, s + p1).map(ys -> @x + ys) [+] ncsub(xs, s + p2)
print(ncsub(Array(1..3)))
print(ncsub(Array(1..4)))
print(ncsub(Array(1..5)))</syntaxhighlight>
{{out}}
<pre>
[[1, 3]]
[[1, 2, 4], [1, 3, 4], [1, 3], [1, 4], [2, 4]]
[[1, 2, 3, 5], [1, 2, 4, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4, 5], [1, 3, 4], [1, 3, 5], [1, 3], [1, 4, 5], [1, 4], [1, 5], [2, 3, 5], [2, 4, 5], [2, 4], [2, 5], [3, 5]]
</pre>
=={{header|Ada}}==
===Recursive===
<
procedure Test_Non_Continuous is
Line 58 ⟶ 92:
Put_NCS ((1,2,3,4)); New_Line;
Put_NCS ((1,2,3,4,5)); New_Line;
end Test_Non_Continuous;</
{{out}}
Line 93 ⟶ 127:
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d]}}
<
MODE SEQMODE = CHAR;
MODE SEQ = [1:0]SEQMODE;
Line 127 ⟶ 161:
print((seq, new line))
# OD # )
END; test non continuous</
{{out}}
<pre>
Line 157 ⟶ 191:
Note: This specimen can only handle sequences of length less than ''bits width'' of '''bits'''.
<
MODE SEQ = [1:0]SEQMODE;
MODE YIELDSEQ = PROC(SEQ)VOID;
Line 203 ⟶ 237:
print((seq, new line))
# OD # )
)</
{{out}}
<pre>
Line 228 ⟶ 262:
ahk forum: [http://www.autohotkey.com/forum/viewtopic.php?p=277328#277328 discussion]
<
MsgBox % noncontinuous("1,2,3,4", ",")
Line 247 ⟶ 281:
ToBin(n,W=16) { ; LS W-bits of Binary representation of n
Return W=1 ? n&1 : ToBin(n>>1,W-1) . n&1
}</
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
list1$() = "1", "2", "3", "4"
PRINT "For [1, 2, 3, 4] non-continuous subsequences are:"
Line 282 ⟶ 316:
NEXT g%
NEXT s%
ENDPROC</
{{out}}
<pre>
Line 311 ⟶ 345:
=={{header|Bracmat}}==
<
= sub
. ( sub
Line 331 ⟶ 365:
& noncontinuous$(e r n i t)
);
</syntaxhighlight>
{{out}}
<pre>e n t
Line 352 ⟶ 386:
=={{header|C}}==
Note: This specimen can only handle lists of length less than the number of bits in an '''int'''.
<
#include <stdio.h>
Line 371 ⟶ 405:
return 0;
}</
Example use:
<pre>
Line 385 ⟶ 419:
Using "consecutive + gap + any subsequence" to produce disjointed sequences:
<
#include <stdio.h>
#include <stdlib.h>
Line 409 ⟶ 443:
return 0;
}</
===Recursive method===
Using recursion and a state transition table.
<
typedef unsigned char sint;
Line 462 ⟶ 496:
pick(c - 1, 0, s_blnk, v + 1, 0);
return 0;
}</
<pre>% ./a.out 1 2 3 4
1 3
Line 471 ⟶ 505:
% ./a.out 1 2 3 4 5 6 7 8 9 0 | wc -l
968</pre>
=={{header|C sharp}}==
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public static void Main() {
var sequence = new[] { "A", "B", "C", "D" };
foreach (var subset in Subsets(sequence.Length).Where(s => !IsContinuous(s))) {
Console.WriteLine(string.Join(" ", subset.Select(i => sequence[i])));
}
}
static IEnumerable<List<int>> Subsets(int length) {
int[] values = Enumerable.Range(0, length).ToArray();
var stack = new Stack<int>(length);
for (int i = 0; stack.Count > 0 || i < length; ) {
if (i < length) {
stack.Push(i++);
yield return (from index in stack.Reverse() select values[index]).ToList();
} else {
i = stack.Pop() + 1;
if (stack.Count > 0) i = stack.Pop() + 1;
}
}
}
static bool IsContinuous(List<int> list) => list[list.Count - 1] - list[0] + 1 == list.Count;
}</syntaxhighlight>
{{out}}
<pre>
A B D
A C
A C D
A D
B D
</pre>
=={{header|C++}}==
<
/*
* Nigel Galloway, July 19th., 2017 - Yes well is this any better?
Line 489 ⟶ 563:
uint next() {return g;}
};
</syntaxhighlight>
Which may be used as follows:
<
int main(){
N n(4);
while (n.hasNext()) std::cout << n.next() << "\t* " << std::bitset<4>(n.next()) << std::endl;
}
</syntaxhighlight>
{{out}}
<pre>
Line 506 ⟶ 580:
</pre>
I can count the length of the sequence:
<
int main(){
N n(31);
int z{};for (;n.hasNext();++z); std::cout << z << std::endl;
}
</syntaxhighlight>
{{out}}
<pre>
2147483151
</pre>
Line 561 ⟶ 595:
Here's a simple approach that uses the clojure.contrib.combinatorics library to generate subsequences, and then filters out the continuous subsequences using a naïve subseq test:
<
(use '[clojure.contrib.combinatorics :only (subsets)])
Line 578 ⟶ 612:
(filter (of-min-length 2) (non-continuous-subsequences [:a :b :c :d]))
</syntaxhighlight>
=={{header|CoffeeScript}}==
Use binary bitmasks to enumerate our sequences.
<
is_contigous_binary = (n) ->
# return true if binary representation of n is
Line 640 ⟶ 674:
num_solutions = non_contig_subsequences(arr).length
console.log "for n=#{n} there are #{num_solutions} solutions"
</syntaxhighlight>
{{out}}
Line 668 ⟶ 702:
looking at the screen wondering what's wrong for about half an hour -->
<
(labels ((subsequences (tail &optional (acc '()) (result '()))
"Return a list of the subsequence designators of the
Line 688 ⟶ 722:
(map-into subsequence-d 'first subsequence-d)))
(let ((nc-subsequences (delete-if #'continuous-p (subsequences list))))
(map-into nc-subsequences #'designated-sequence nc-subsequences))))</
{{trans|Scheme}}
<
(labels ((recurse (s list)
(if (endp list)
Line 707 ⟶ 741:
(recurse s xs))
(recurse (+ s 1) xs)))))))
(recurse 0 list)))</
=={{header|D}}==
===Recursive Version===
{{trans|Python}}
<
if (seq.length) {
typeof(return) aux;
Line 729 ⟶ 763:
foreach (const nc; [1, 2, 3, 4, 5].ncsub)
nc.writeln;
}</
{{out}}
<pre>[[1, 3]]
Line 752 ⟶ 786:
===Faster Lazy Version===
This version doesn't copy the sub-arrays.
<
T[] seq;
Line 794 ⟶ 828:
counter++;
assert(counter == 16_776_915);
}</
===Generator Version===
This version doesn't copy the sub-arrays, and it's a little slower than the opApply-based version.
<
Generator!(T[]) ncsub(T)(in T[] seq) {
Line 831 ⟶ 865:
foreach (const nc; [1, 2, 3, 4, 5].ncsub)
nc.writeln;
}</
=={{header|Elixir}}==
{{trans|Erlang}}
<
defp masks(n) do
maxmask = trunc(:math.pow(2, n)) - 1
Line 858 ⟶ 892:
IO.inspect RC.ncs([1,2,3])
IO.inspect RC.ncs([1,2,3,4])
IO.inspect RC.ncs('abcd')</
{{out}}
Line 870 ⟶ 904:
Erlang's not optimized for strings or math, so this is pretty inefficient. Nonetheless, it works by generating the set of all possible "bitmasks" (represented as strings), filters for those with non-continuous subsequences, and maps from that set over the list. One immediate point for optimization that would complicate the code a bit would be to compile the regular expression, the problem being where you'd put it.
<
-export([ncs/1]).
Line 893 ⟶ 927:
ncs(List) ->
lists:map(fun(Mask) -> apply_mask_to_list(Mask, List) end,
masks(length(List))).</
{{out}}
Line 906 ⟶ 940:
=={{header|F_Sharp|F#}}==
===Generate only the non-continuous subsequences===
<
(*
A function to generate only the non-continuous subsequences.
Line 915 ⟶ 949:
let rec fg n = seq{if n>0 then yield! seq{1..((1<<<n)-1)}|>fn n; yield! fg (n-1)|>fn n}
Seq.collect fg ({1..(n-2)})
</syntaxhighlight>
This may be used as follows:
<
let Ng ng = N ng |> Seq.iter(fun n->printf "%2d -> " n; {0..(ng-1)}|>Seq.iter (fun g->if (n&&&(1<<<g))>0 then printf "%d " (g+1));printfn "")
Ng 4
</syntaxhighlight>
{{out}}
<pre>
Line 945 ⟶ 979:
</pre>
===Generate all subsequences and filter out the continuous===
<
(*
A function to filter out continuous subsequences.
Line 956 ⟶ 990:
|(n,_) ->n
{5..(1<<<n)-1}|>Seq.choose(fun i->if fst({0..n-1}|>Seq.takeWhile(fun n->(1<<<(n-1))<i)|>Seq.fold(fun n g->fn (n,(i&&&(1<<<g)>0)))(0,0)) > 1 then Some(i) else None)
</syntaxhighlight>
Again counting the number of non-continuous subsequences
<pre>
Line 974 ⟶ 1,008:
===Conclusion===
Find a better filter or use the generator.
=={{header|FreeBASIC}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="freebasic">Sub Subsecuencias_no_continuas(l() As String)
Dim As Integer i, j, g, n, r, s, w
Dim As String a, b, c
n = Ubound(l)
For s = 0 To n-2
For g = s+1 To n-1
a = "["
For i = s To g-1
a += l(i) + ", "
Next i
For w = 1 To n-g
r = n+1-g-w
For i = 1 To 2^r-1 Step 2
b = a
For j = 0 To r-1
If i And 2^j Then b += l(g+w+j) + ", "
Next j
'Print Left(Left(b)) + "]"
c = (Left(b, Len (b)-1))
Print Left(c, Len(c)-1) + "]"
Next i
Next w
Next g
Next s
End Sub
Dim lista1(3) As String = {"1", "2", "3", "4"}
Print "Para [1, 2, 3, 4] las subsecuencias no continuas son:"
Subsecuencias_no_continuas(lista1())
Dim lista2(4) As String = {"e", "r", "n", "i", "t"}
Print "Para [e, r, n, i, t] las subsecuencias no continuas son:"
Subsecuencias_no_continuas(lista2())
Sleep</syntaxhighlight>
{{out}}
<pre>
Para [1, 2, 3, 4] las subsecuencias no continuas son:
[1, 3]
[1, 3, 4]
[1, 4]
[1, 2, 4]
[2, 4]
Para [e, r, n, i, t] las subsecuencias no continuas son:
[e, n]
[e, n, i]
[e, n, t]
[e, n, i, t]
[e, i]
[e, i, t]
[e, t]
[e, r, i]
[e, r, i, t]
[e, r, t]
[e, r, n, t]
[r, i]
[r, i, t]
[r, t]
[r, n, t]
[n, t]
</pre>
=={{header|Go}}==
Generate the power set (power sequence, actually) with a recursive function, but keep track of the state of the subsequence on the way down. When you get to the bottom, if state == non-continuous, then include the subsequence. It's just filtering merged in with generation.
<
import "fmt"
Line 1,015 ⟶ 1,113:
fmt.Println(" ", s)
}
}</
{{out}}
<pre>
Line 1,030 ⟶ 1,128:
===Generalized monadic filter===
<
fenceM p q s [] = guard (q s) >> return []
Line 1,038 ⟶ 1,136:
return $ f x ys
ncsubseq = fenceM [((:), action even), (flip const, action odd)] (>= 3) 0</
{{out}}
Line 1,052 ⟶ 1,150:
This implementation works by computing templates of all possible subsequences of the given length of sequence, discarding the continuous ones, then applying the remaining templates to the input list.
<
ncs xs = map (map fst . filter snd . zip xs) $
filter (not . continuous) $
mapM (const [True,False]) xs</
===Recursive===
Recursive method with powerset as helper function.
<
poset = foldr (\x p -> p ++ map (x:) p) [[]]
Line 1,069 ⟶ 1,167:
nc [_] [] = [[]]
nc (_:x:xs) [] = nc [x] xs
nc xs (y:ys) = (nc (xs++[y]) ys) ++ map (xs++) (tail $ poset ys)</
{{out}}
Line 1,089 ⟶ 1,187:
A disjointed subsequence is a consecutive subsequence followed by a gap,
then by any nonempty subsequence to its right:
<
disjoint a = concatMap (cutAt a) [1..length a - 2] where
Line 1,096 ⟶ 1,194:
(left, _:right) = splitAt n s
main = print $ length $ disjoint [1..20]</
Build a lexicographic list of consecutive subsequences,
and a list of all subsequences, then subtract one from the other:
<
subseqs = foldr (\x s -> [x] : map (x:) s ++ s) []
Line 1,113 ⟶ 1,211:
disjoint s = (subseqs s) `minus` (consecs s)
main = mapM_ print $ disjoint [1..4]</
=={{header|J}}==
We select those combinations where the end of the first continuous subsequence appears before the start of the last continuous subsequence:
<
firstend=:1 0 i.&1@E."1 ]
laststart=: 0 1 {:@I.@E."1 ]
noncont=: <@#~ (#~ firstend < laststart)@allmasks</
Example use:
<
┌───┬───┬───┬─────┬─────┐
│2 4│1 4│1 3│1 3 4│1 2 4│
Line 1,133 ⟶ 1,231:
└──┴──┴──┴───┴───┴──┴──┴───┴──┴───┴───┴────┴───┴───┴────┴────┘
#noncont i.10
968</
Alternatively, since there are relatively few continuous sequences, we could specifically exclude them:
<
noncont=: <@#~ (allmasks -. contmasks)</
(we get the same behavior from this implementation)
=={{header|Java}}==
<
public static void main(String args[]) {
Line 1,158 ⟶ 1,256:
}
}
}</
<pre>12 4
Line 1,170 ⟶ 1,268:
{{works with|SpiderMonkey}}
<
var non_continuous = new Array();
for (var i = 0; i < ary.length; i++) {
Line 1,193 ⟶ 1,291:
load('json2.js'); /* http://www.json.org/js.html */
print(JSON.stringify( non_continuous_subsequences( powerset([1,2,3,4]))));</
{{out}}
Line 1,207 ⟶ 1,305:
subsets, we will use the powerset approach, and accordingly begin by
defining subsets/0 as a generator.
<
def subsets:
if length == 0 then []
Line 1,222 ⟶ 1,320:
def non_continuous_subsequences:
(length | non_continuous_indices) as $ix
| [.[ $ix[] ]] ;</
'''Example''':
To show that the above approach can be used for relatively large n, let us count the number of non-continuous subsequences of [0, 1, ..., 19].
<
count( [range(0;20)] | non_continuous_subsequences)
</syntaxhighlight>
{{out}}
$ jq -n -f powerset_generator.jq
Line 1,241 ⟶ 1,339:
'''Iterator and Functions'''
<
import Base.IteratorSize, Base.iterate, Base.length
Line 1,299 ⟶ 1,397:
@printf "%7d → %d\n" x length(NCSubSeq(x))
end
</
<pre>
Testing NCSubSeq for 4 items:
Line 1,348 ⟶ 1,446:
=={{header|Kotlin}}==
<
fun <T> ncs(a: Array<T>) {
Line 1,380 ⟶ 1,478:
val ca = arrayOf('a', 'b', 'c', 'd', 'e')
ncs(ca)
}</
{{out}}
Line 1,407 ⟶ 1,505:
a c d e
</pre>
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Non_continuous_subsequences (item$(), display){
Function positions(n) {
Line 1,459 ⟶ 1,558:
Non_continuous_subsequences ("1","2","3","4","5","6","7","8","9","0"), false
clipboard doc$
</syntaxhighlight>
{{out}}
Line 1,590 ⟶ 1,689:
</pre >
=={{header|Mathematica}}/{{header|Wolfram Language}}==
We make all the subsets then filter out the continuous ones:
<syntaxhighlight lang="mathematica">GoodBad[i_List]:=Not[MatchQ[Differences[i],{1..}|{}]]
n=5
Select[Subsets[Range[n]],GoodBad]</
{{out}}
<pre>{{1,3},{1,4},{1,5},{2,4},{2,5},{3,5},{1,2,4},{1,2,5},{1,3,4},{1,3,5},{1,4,5},{2,3,5},{2,4,5},{1,2,3,5},{1,2,4,5},{1,3,4,5}}</pre>
=={{header|Nim}}==
{{trans|Python}}
<
proc ncsub[T](se: seq[T], s = 0): seq[seq[T]] =
Line 1,610 ⟶ 1,706:
let
x = se[0..0]
xs = se[1 ..
p2 = s mod 2
p1 = (s + 1) mod 2
Line 1,621 ⟶ 1,717:
echo "ncsub(", toSeq 1.. 3, ") = ", ncsub(toSeq 1..3)
echo "ncsub(", toSeq 1.. 4, ") = ", ncsub(toSeq 1..4)
echo "ncsub(", toSeq 1.. 5, ") = ", ncsub(toSeq 1..5)</
{{out}}
<pre>ncsub(@[1, 2, 3]) = @[@[1, 3]]
Line 1,631 ⟶ 1,727:
{{trans|Generalized monadic filter}}
<
[] ->
if s >= 3 then
Line 1,652 ⟶ 1,748:
fence (s + 1) xs
let ncsubseq = fence 0</
{{out}}
Line 1,667 ⟶ 1,763:
=={{header|Oz}}==
A nice application of finite set constraints. We just describe what we want and the constraint system will deliver it:
<
fun {NCSubseq SeqList}
Seq = {FS.value.make SeqList}
Line 1,691 ⟶ 1,787:
end
in
{Inspect {NCSubseq [1 2 3 4]}}</
=={{header|PARI/GP}}==
Just a simple script, but it's I/O bound so efficiency isn't a concern. (Almost all subsequences are non-contiguous so looping over all possibilities isn't that bad. For length 20 about 99.98% of subsequences are non-contiguous.)
<
nonContigSubseq(v)={
for(i=5,2^#v-1,
Line 1,704 ⟶ 1,800:
};
nonContigSubseq([1,2,3])
nonContigSubseq(["a","b","c","d","e"])</
{{out}}
<pre>[1, 3]
Line 1,726 ⟶ 1,822:
=={{header|Perl}}==
<
sub non_continuous {
my ($idx, $has_gap) = @_;
Line 1,743 ⟶ 1,839:
$max = 20;
print "found ", non_continuous(1), " sequences\n";</
{{out}}
<pre>found 1048365 sequences</pre>
=={{header|Phix}}==
Straightforward recursive implementation, the only minor trick is that a gap does not
mean non-contiguous until you actually take something later.<br>
Counts non-contiguous subsequences of sequences of length 1..20 in
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">ncs</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">rest</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">object</span> <span style="color: #000000;">taken</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ri</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">contig</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">gap</span><span style="color: #0000FF;">=</span><span style="color: #004600;">false</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">ri</span><span style="color: #0000FF;">>=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rest</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">contig</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color:
<span style="color: #0000FF;">?</span><span style="color: #000000;">taken</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">ri</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #000000;">ncs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rest</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">rest</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">]),</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gap</span><span style="color: #0000FF;">,</span><span style="color: #000000;">gap</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">ncs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rest</span><span style="color: #0000FF;">,</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ri</span><span style="color: #0000FF;">,</span><span style="color: #000000;">contig</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">)?</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">taken</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">ncs</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">},{})</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"==="</span>
<span style="color: #000000;">ncs</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">},{})</span>
<span style="color: #0000FF;">?</span><span style="color: #008000;">"==="</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">20</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #000000;">ncs</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">),</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">count</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,808 ⟶ 1,891:
{2,4}
"==="
"0.
{0,0,1,5,16,42,99,219,466,968,1981,4017,8100,16278,32647,65399,130918,261972,524097,1048365}
</pre>
=={{header|Picat}}==
This approach uses <code>power_set/1</code> (from the <code>util</code> module) to get the proper indices.
<syntaxhighlight lang="picat">import util.
go =>
println(1..4=non_cont(1..4)),
L = "abcde".reverse(),
println(L=non_cont(L)),
println(ernit=non_cont("ernit")),
println(aaa=non_cont("aaa")),
println(aeiou=non_cont("aeiou")),
nl,
println("Printing just the lengths for 1..N for N = 1..20:"),
foreach(N in 1..20)
println(1..N=non_cont(1..N).length) % just the length
end,
nl.
% get all the non-continuous subsequences
non_cont(L) = [ [L[I] : I in S] : S in non_cont_ixs(L.length)].
% get all the index positions that are non-continuous
non_cont_ixs(N) = [ P: P in power_set(1..N), length(P) > 1, P.last() - P.first() != P.length-1].</syntaxhighlight>
{{out}}
<pre>[1,2,3,4] = [[2,4],[1,4],[1,3],[1,3,4],[1,2,4]]
edcba = [ca,da,db,dba,dca,ea,eb,eba,ec,eca,ecb,ecba,eda,edb,edba,edca]
ernit = [nt,rt,ri,rit,rnt,et,ei,eit,en,ent,eni,enit,ert,eri,erit,ernt]
aaa = [aa]
aeiou = [iu,eu,eo,eou,eiu,au,ao,aou,ai,aiu,aio,aiou,aeu,aeo,aeou,aeiu]
Printing just the lengths for 1..N for N = 1..20:
[1] = 0
[1,2] = 0
[1,2,3] = 1
[1,2,3,4] = 5
[1,2,3,4,5] = 16
[1,2,3,4,5,6] = 42
[1,2,3,4,5,6,7] = 99
[1,2,3,4,5,6,7,8] = 219
[1,2,3,4,5,6,7,8,9] = 466
[1,2,3,4,5,6,7,8,9,10] = 968
[1,2,3,4,5,6,7,8,9,10,11] = 1981
[1,2,3,4,5,6,7,8,9,10,11,12] = 4017
[1,2,3,4,5,6,7,8,9,10,11,12,13] = 8100
[1,2,3,4,5,6,7,8,9,10,11,12,13,14] = 16278
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15] = 32647
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] = 65399
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] = 130918
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18] = 261972
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19] = 524097
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] = 1048365</pre>
=={{header|PicoLisp}}==
{{trans|Scheme}}
<
(let S 0
(recur (S Lst)
Line 1,828 ⟶ 1,966:
(mapcar '((YS) (cons X YS))
(recurse S XS) )
(recurse (inc S) XS) ) ) ) ) ) ) )</
=={{header|Pop11}}==
Line 1,835 ⟶ 1,973:
variables to keep track if subsequence is continuous.
<
lvars acc = [], gap_started = false, is_continuous = true;
define do_it(l1, l2);
Line 1,858 ⟶ 1,996:
enddefine;
ncsubseq([1 2 3 4 5]) =></
{{out}}
Line 1,865 ⟶ 2,003:
=={{header|PowerShell}}==
<
{
$sc = $S.count
Line 1,933 ⟶ 2,071:
}
( NonContinuous-SubSequence 'a','b','c','d','e' ) | Select-Object length, @{Name='value';Expression={ $_ } } | Sort-Object length, value | ForEach-Object { $_.value }</
=={{header|Prolog}}==
Line 1,939 ⟶ 2,077:
We explain to Prolog how to build a non continuous subsequence of a list L, then we ask Prolog to fetch all the subsequences.
<syntaxhighlight lang="prolog">
% fetch all the subsequences
ncsubs(L, LNCSL) :-
Line 1,965 ⟶ 2,103:
reverse(L, [_|SL1]),
reverse(SL1, SL)).
</syntaxhighlight>
Example :
<
L = [[a,e,i,u],[a,e,o],[a,e,o,u],[a,e,u],[a,i],[a,i,o],[a,i,o,u],[a,i,u],[a,o],[a,o,u],[a,u],[e,i,u],[e,o],[e,o,u],[e,u],[i,u]]</
=={{header|Python}}==
{{trans|Scheme}}
<
if seq:
x = seq[:1]
Line 1,981 ⟶ 2,119:
return [x + ys for ys in ncsub(xs, s + p1)] + ncsub(xs, s + p2)
else:
return [[]] if s >= 3 else []</
{{out}}
Line 1,995 ⟶ 2,133:
A faster Python + Psyco JIT version:
<
import psyco
Line 2,034 ⟶ 2,172:
psyco.full()
n = 10 if len(argv) < 2 else int(argv[1])
print len( ncsub(range(1, n)) )</
=={{header|Quackery}}==
A sequence of n items has 2^n possible subsequences, including the empty sequence. These correspond to the numbers 0 to 2^n-1, where a one in the binary expansion of the number indicates inclusion in the subsequence of the corresponding item in the sequence. Non-continuous subsequences correspond to numbers where the binary expansion of the number has a one, followed by one or more zeroes, followed by a one.
<syntaxhighlight lang="quackery"> [ dup 1 & dip [ 1 >> ] ] is 2/mod ( n --> n n )
[ 0 swap
[ dup 0 != while
2/mod iff
[ dip 1+ ] done
again ]
[ dup 0 != while
2/mod not iff
[ dip 1+ ] done
again ]
[ dup 0 != while
2/mod iff
[ dip 1+ ] done
again ]
drop 3 = ] is noncontinuous ( n --> b )
[ [] unrot
[ dup 0 != while
dip behead tuck
1 & iff
[ nested dip rot
join unrot ]
else drop
1 >> again ]
2drop ] is bitems ( [ n --> [ )
[ [] swap
dup size bit times
[ i^ noncontinuous if
[ dup i^ bitems
nested rot
join swap ] ]
drop ] is ncsubs ( [ --> [ )
' [ 1 2 3 4 ] ncsubs echo cr
$ "quackery" ncsubs 72 wrap$</syntaxhighlight>
{{out}}
<pre>[ [ 1 3 4 ] [ 1 2 4 ] [ 2 4 ] [ 1 4 ] [ 1 3 ] ]
qackery quckery uckery qckery quakery uakery qakery akery qukery ukery
qkery quacery uacery qacery acery qucery ucery qcery cery quaery uaery
qaery aery query uery qery quackry uackry qackry ackry quckry uckry
qckry ckry quakry uakry qakry akry qukry ukry qkry kry quacry uacry
qacry acry qucry ucry qcry cry quary uary qary ary qury ury qry quackey
uackey qackey ackey quckey uckey qckey ckey quakey uakey qakey akey
qukey ukey qkey key quacey uacey qacey acey qucey ucey qcey cey quaey
uaey qaey aey quey uey qey ey quacky uacky qacky acky qucky ucky qcky
cky quaky uaky qaky aky quky uky qky ky quacy uacy qacy acy qucy ucy qcy
cy quay uay qay ay quy uy qy qacker qucker ucker qcker quaker uaker
qaker aker quker uker qker quacer uacer qacer acer qucer ucer qcer cer
quaer uaer qaer aer quer uer qer quackr uackr qackr ackr quckr uckr qckr
ckr quakr uakr qakr akr qukr ukr qkr kr quacr uacr qacr acr qucr ucr qcr
cr quar uar qar ar qur ur qr qacke qucke ucke qcke quake uake qake ake
quke uke qke quace uace qace ace quce uce qce ce quae uae qae ae que ue
qe qack quck uck qck quak uak qak ak quk uk qk qac quc uc qc qa
</pre>
=={{header|R}}==
The idea behind this is to loop over the possible lengths of subsequence, finding all subsequences then discarding those which are continuous.
<
{
n <- length(x)
Line 2,055 ⟶ 2,258:
# Example usage
ncsub(1:4)
ncsub(letters[1:5])</
=={{header|Racket}}==
Take a simple <tt>subsets</tt> definition:
<
(define (subsets l)
(if (null? l) '(())
(append (for/list ([l2 (subsets (cdr l))]) (cons (car l) l2))
(subsets (cdr l)))))
</syntaxhighlight>
since the subsets are returned in their original order, it is also a sub-sequences function.
Now add to it a "state" counter which count one for each chunk of items included or excluded. It's always even when we're in an excluded chunk (including the beginning) and odd when we're including items -- increment it whenever we switch from one kind of chunk to the other. This means that we should only include subsequences where the state is 3 (included->excluded->included) or more. Note that this results in code that is similar to the "Generalized monadic filter" entry, except a little simpler.
<
#lang racket
(define (non-continuous-subseqs l)
Line 2,080 ⟶ 2,283:
(non-continuous-subseqs '(1 2 3 4))
;; => '((1 2 4) (1 3 4) (1 3) (1 4) (2 4))
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2015-09-24}}
<syntaxhighlight lang="raku" line>sub non_continuous_subsequences ( *@list ) {
@list.combinations.grep: { 1 != all( .[ 0 ^.. .end] Z- .[0 ..^ .end] ) }
}
say non_continuous_subsequences( 1..3 )».gist;
say non_continuous_subsequences( 1..4 )».gist;
say non_continuous_subsequences( ^4 ).map: {[<a b c d>[.list]].gist};</syntaxhighlight>
{{out}}
<pre>((1 3))
((1 3) (1 4) (2 4) (1 2 4) (1 3 4))
([a c] [a d] [b d] [a b d] [a c d])</pre>
=={{header|REXX}}==
This REXX version also works with non-numeric (alphabetic) items (as well as numbers).
<
parse arg list /*obtain
if list='' | list==
say 'list=' space(list);
w= words(list)
tail= right(
#= 0
do j=13 to left(
if verify(j,
f= left(j, 1)
NCS= 0
do k=2
end /*k*/
$=
end /*m*/
say 'a non─continuous subsequence: '
end /*j*/
say /*help ensure visual fidelity in output*/
if #==0 then #= 'no'
say # "non─continuous subsequence"s(#)
exit
/*──────────────────────────────────────────────────────────────────────────────────────*/
s: if arg(1)==1 then return '';
<pre>
list= 1 2 3 4
Line 2,128 ⟶ 2,347:
5 non-continuous subsequences were found.
</pre>
<pre>
list= a e I o u
Line 2,151 ⟶ 2,370:
16 non-continuous subsequences were found.
</pre>
<pre>
list= Alderney Guernsey Herm Jersey Sark
Line 2,174 ⟶ 2,393:
16 non-continuous subsequences were found.
</pre>
<pre>
list= helium neon argon krypton xenon radon
Line 2,225 ⟶ 2,444:
=={{header|Ring}}==
<
# Project : Non-continuous subsequences
Line 2,284 ⟶ 2,503:
next
return items
</syntaxhighlight>
Output:
<pre>
Line 2,318 ⟶ 2,537:
Uses code from [[Power Set]].
<
def func_power_set
inject([[]]) { |ps,item| # for each item in the Array
Line 2,339 ⟶ 2,558:
p (1..4).to_a.non_continuous_subsequences
p (1..5).to_a.non_continuous_subsequences
p ("a".."d").to_a.non_continuous_subsequences</
{{out}}
Line 2,349 ⟶ 2,568:
</pre>
It is not the value of the array element and when judging continuation in the position, it changes as follows.
<
def continuous?(seq)
seq.each_cons(2) {|a, b| return false if index(a)+1 != index(b)}
Line 2,356 ⟶ 2,575:
end
p %w(a e i o u).non_continuous_subsequences</
{{out}}
Line 2,362 ⟶ 2,581:
=={{header|Scala}}==
<
private def seqR(s: String, c: String, i: Int, added: Int): Unit = {
Line 2,374 ⟶ 2,593:
seqR("1234", "", 0, 0)
}</
=={{header|Scheme}}==
{{trans|Generalized monadic filter}}
<
(let recurse ((s 0)
(lst lst))
Line 2,394 ⟶ 2,614:
(map (lambda (ys) (cons x ys))
(recurse s xs))
(recurse (+ s 1) xs)))))))</
{{out}}
Line 2,405 ⟶ 2,625:
=={{header|Seed7}}==
<
const func array bitset: ncsub (in bitset: seq, in integer: s) is func
Line 2,434 ⟶ 2,654:
writeln(seq);
end for;
end func;</
{{out}}
Line 2,447 ⟶ 2,667:
=={{header|Sidef}}==
{{trans|Perl}}
<
static current = [];
Line 2,464 ⟶ 2,684:
say non_continuous(1, 3);
say non_continuous(1, 4);
say non_continuous("a", "d");</
{{out}}
<pre>
Line 2,476 ⟶ 2,696:
{{trans|Generalized monadic filter}}
<
if s >= 3 then
[[]]
Line 2,496 ⟶ 2,716:
fence (s + 1) xs
fun ncsubseq xs = fence 0 xs</
{{out}}
Line 2,511 ⟶ 2,731:
This Tcl implementation uses the ''subsets'' function from [[Power Set]], which is acceptable as that conserves the ordering, as well as a problem-specific test function ''is_not_continuous'' and a generic list filter ''lfilter'':
<
set res [list [list]]
foreach e $l {
Line 2,533 ⟶ 2,753:
% lfilter is_not_continuous [subsets {1 2 3 4}]
{1 3} {1 4} {2 4} {1 2 4} {1 3 4}</
=={{header|Ursala}}==
Line 2,539 ⟶ 2,759:
To do it the lazy programmer way, apply the powerset library function to the list, which will generate all continuous and non-continuous subsequences of it, and then delete the subsequences that are also substrings (hence continuous) using a judicious combination of the built in substring predicate (K3), negation (Z), and distributing filter (K17) operator suffixes. This function will work on lists of any type. To meet the requirement for structural equivalence, the list items are first uniquely numbered (num), and the numbers are removed afterwards (rSS).
<
noncontinuous = num; ^rlK3ZK17rSS/~& powerset
Line 2,545 ⟶ 2,765:
#show+
examples = noncontinuous 'abcde'</
{{out}}
Line 2,564 ⟶ 2,784:
be
ce</pre>
=={{header|VBScript}}==
{{trans|BBC BASIC}}
<syntaxhighlight lang="vb">'Non-continuous subsequences - VBScript - 03/02/2021
Function noncontsubseq(l)
Dim i, j, g, n, r, s, w, m
Dim a, b, c
n = Ubound(l)
For s = 0 To n-2
For g = s+1 To n-1
a = "["
For i = s To g-1
a = a & l(i) & ", "
Next 'i
For w = 1 To n-g
r = n+1-g-w
For i = 1 To 2^r-1 Step 2
b = a
For j = 0 To r-1
If i And 2^j Then b=b & l(g+w+j) & ", "
Next 'j
c = (Left(b, Len(b)-1))
WScript.Echo Left(c, Len(c)-1) & "]"
m = m+1
Next 'i
Next 'w
Next 'g
Next 's
noncontsubseq = m
End Function 'noncontsubseq
list = Array("1", "2", "3", "4")
WScript.Echo "List: [" & Join(list, ", ") & "]"
nn = noncontsubseq(list)
WScript.Echo nn & " non-continuous subsequences" </syntaxhighlight>
{{out}}
<pre>
List: [1, 2, 3, 4]
[1, 3]
[1, 3, 4]
[1, 4]
[1, 2, 4]
[2, 4]
5 non-continuous subsequences
</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
Needed a bit of doctoring to do the character example as Wren only has strings.
<syntaxhighlight lang="wren">import "./fmt" for Fmt
var ncs = Fn.new { |a|
var f = "$d "
if (a[0] is String) {
for (i in 0...a.count) a[i] = a[i].bytes[0]
f = "$c "
}
var generate // recursive
generate = Fn.new { |m, k, c|
if (k == m) {
if (c[m - 1] != c[0] + m - 1) {
for (i in 0...m) Fmt.write(f, a[c[i]])
System.print()
}
} else {
for (j in 0...a.count) {
if (k == 0 || j > c[k - 1]) {
c[k] = j
generate.call(m, k + 1, c)
}
}
}
}
for (m in 2...a.count) {
var c = List.filled(m, 0)
generate.call(m, 0, c)
}
}
var a = [1, 2, 3, 4]
ncs.call(a)
System.print()
var ca = ["a", "b", "c", "d", "e"]
ncs.call(ca)</syntaxhighlight>
{{out}}
<pre>
1 3
1 4
2 4
1 2 4
1 3 4
a c
a d
a e
b d
b e
c e
a b d
a b e
a c d
a c e
a d e
b c e
b d e
a b c e
a b d e
a c d e
</pre>
=={{header|XPL0}}==
{{trans|Wren}}
<syntaxhighlight lang "XPL0">proc NCS(A, Size, Char);
int A, Size, Char;
int C, M;
proc Generate(M, K, C); \recursive
int M, K, C;
int I, J;
[if K = M then
[if C(M-1) # C(0)+M-1 then
[for I:= 0 to M-1 do
[if Char then ChOut(0, A(C(I)))
else IntOut(0, A(C(I)));
ChOut(0, ^ );
];
CrLf(0);
];
]
else
[for J:= 0 to Size-1 do
[if K = 0 or J > C(K-1) then
[C(K):= J;
Generate(M, K+1, C);
];
];
];
];
[C:= Reserve(Size*4);
for M:= 2 to Size-1 do Generate(M, 0, C);
];
int A, CA;
[A:= [1, 2, 3, 4];
NCS(A, 4, false);
CrLf(0);
CA:= [^a, ^b, ^c, ^d, ^e];
NCS(CA, 5, true);
]</syntaxhighlight>
{{out}}
<pre>
1 3
1 4
2 4
1 2 4
1 3 4
a c
a d
a e
b d
b e
c e
a b d
a b e
a c d
a c e
a d e
b c e
b d e
a b c e
a b d e
a c d e
</pre>
=={{header|zkl}}==
{{trans|JavaScript}}
<
pwerSet(ary).filter(fcn(list){(not isContinuous(list)) })
}
Line 2,575 ⟶ 2,974:
return(True);
}
non_continuous_subsequences(T(1,2,3,4)).println();</
<syntaxhighlight lang="zkl">fcn pwerSet(list){
(0).pump(list.len(),List,List,Utils.Helpers.pickNFrom.fp1(list),
T(T,Void.Write,Void.Write) ) .append(list)
}</
<
pwerSet(str.split("")).apply("concat")
.filter('wrap(substr){ (not str.holds(substr)) })
}
brokenSubsequences("1234").println();</
{{out}}
<pre>
|