Common list elements: Difference between revisions

From Rosetta Code
Content added Content deleted
(Added Perl)
Line 119: Line 119:
{{out}}
{{out}}
<pre>3 6 9</pre>
<pre>3 6 9</pre>

=={{header|Phix}}==
<lang Phix>function intersection(sequence s)
sequence res = {}
if length(s) then
for i=1 to length(s[1]) do
integer candidate = s[1][i]
bool bAdd = not find(candidate,res)
for j=2 to length(s) do
if not find(candidate,s[j]) then
bAdd = false
exit
end if
end for
if bAdd then res &= candidate end if
end for
end if
return res
end function
?intersection({{2,5,1,3,8,9,4,6},{3,5,6,2,9,8,4},{1,3,7,6,9}})
?intersection({{2,2,1,3,8,9,4,6},{3,5,6,2,2,2,4},{2,3,7,6,2}})</lang>
{{out}}
<pre>
{3,9,6}
{2,3,6}
</pre>


=={{header|Raku}}==
=={{header|Raku}}==

Revision as of 17:47, 25 February 2021

Common list elements is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Given an integer array nums, find the common list elements.


Example

nums = [2,5,1,3,8,9,4,6], [3,5,6,2,9,8,4], [1,3,7,6,9]

output = [3,6,9]

F#

Of course it is possible to use sets but I thought the idea was not to? <lang fsharp> // Common list elements. Nigel Galloway: February 25th., 2021 let nums=[|[2;5;1;3;8;9;4;6];[3;5;6;2;9;8;4];[1;3;7;6;9]|] printfn "%A" (nums|>Array.reduce(fun n g->n@g)|>List.distinct|>List.filter(fun n->nums|>Array.forall(fun g->List.contains n g)));; </lang>

Output:
[3; 9; 6]

Factor

Note: in older versions of Factor, intersect-all was called intersection.

Works with: Factor version 0.99 2021-02-05

<lang factor>USING: prettyprint sets ;

{ { 2 5 1 3 8 9 4 6 } { 3 5 6 2 9 8 4 } { 1 3 7 6 9 } } intersect-all .</lang>

Output:
{ 3 6 9 }

Go

Translation of: Wren

<lang go>package main

import "fmt"

func indexOf(l []int, n int) int {

   for i := 0; i < len(l); i++ {
       if l[i] == n {
           return i
       }
   }
   return -1

}

func common2(l1, l2 []int) []int {

   // minimize number of lookups
   c1, c2 := len(l1), len(l2)
   shortest, longest := l1, l2
   if c1 > c2 {
       shortest, longest = l2, l1
   }
   longest2 := make([]int, len(longest))
   copy(longest2, longest) // matching duplicates will be destructive
   var res []int
   for _, e := range shortest {
       ix := indexOf(longest2, e)
       if ix >= 0 {
           res = append(res, e)
           longest2 = append(longest2[:ix], longest2[ix+1:]...)
       }
   }
   return res

}

func commonN(ll [][]int) []int {

   n := len(ll)
   if n == 0 {
       return []int{}
   }
   if n == 1 {
       return ll[0]
   }
   res := common2(ll[0], ll[1])
   if n == 2 {
       return res
   }
   for _, l := range ll[2:] {
       res = common2(res, l)
   }
   return res

}

func main() {

   lls := [][][]int{
       {{2, 5, 1, 3, 8, 9, 4, 6}, {3, 5, 6, 2, 9, 8, 4}, {1, 3, 7, 6, 9}},
       {{2, 2, 1, 3, 8, 9, 4, 6}, {3, 5, 6, 2, 2, 2, 4}, {2, 3, 7, 6, 2}},
   }
   for _, ll := range lls {
       fmt.Println("Intersection of", ll, "is:")
       fmt.Println(commonN(ll))
       fmt.Println()
   }

}</lang>

Output:
Intersection of [[2 5 1 3 8 9 4 6] [3 5 6 2 9 8 4] [1 3 7 6 9]] is:
[3 6 9]

Intersection of [[2 2 1 3 8 9 4 6] [3 5 6 2 2 2 4] [2 3 7 6 2]] is:
[3 6 2 2]

Julia

<lang julia> julia> intersect([2,5,1,3,8,9,4,6], [3,5,6,2,9,8,4], [1,3,7,6,9]) 3-element Array{Int64,1}:

3
9
6

</lang>

Perl

<lang perl>@nums = ([2,5,1,3,8,9,4,6], [3,5,6,2,9,8,4], [1,3,7,6,9]); map { print "$_ " if @nums == ++$c{$_} } @$_ for @nums;</lang>

Output:
3 6 9

Phix

<lang Phix>function intersection(sequence s)

   sequence res = {}
   if length(s) then
       for i=1 to length(s[1]) do
           integer candidate = s[1][i]
           bool bAdd = not find(candidate,res)
           for j=2 to length(s) do
               if not find(candidate,s[j]) then
                   bAdd = false
                   exit
               end if
           end for
           if bAdd then res &= candidate end if
       end for
   end if
   return res

end function ?intersection({{2,5,1,3,8,9,4,6},{3,5,6,2,9,8,4},{1,3,7,6,9}}) ?intersection({{2,2,1,3,8,9,4,6},{3,5,6,2,2,2,4},{2,3,7,6,2}})</lang>

Output:
{3,9,6}
{2,3,6}

Raku

<lang perl6>put [∩] [2,5,1,3,8,9,4,6], [3,5,6,2,9,8,4], [1,3,7,6,9,3];</lang>

Output:
6 9 3

REXX

This REXX version properly handles the case of duplicate entries in a list   (which shouldn't happen in a true list). <lang rexx>/*REXX program finds and displays the common list elements from a collection of sets. */ parse arg a /*obtain optional arguments from the CL*/ if a= | a="," then a= '[2,5,1,3,8,9,4,6] [3,5,6,2,9,8,4] [1,3,7,6,9]' /*defaults.*/

  1. = words(a) /*the number of sets that are specified*/
           do j=1  for #                        /*process each set  in  a list of sets.*/
           @.j= translate( word(a, j), ,'],[')  /*extract   a   "  from "   "   "   "  */
           end   /*j*/

$= /*the list of common elements (so far).*/

  do k=1  for #-1                               /*use the last set as the base compare.*/
     do c=1  for words(@.#);  x= word(@.#, c)   /*obtain an element from a set.        */
        do f=1  for #-1                         /*verify that the element is in the set*/
        if wordpos(x, @.f)==0  then iterate c   /*Is in the set?  No, then skip element*/
        end   /*f*/
     if wordpos(x, $)==0  then $= $ x           /*Not already in the set?  Add common. */
     end      /*c*/
  end         /*k*/
                                                /*stick a fork in it,  we're all done. */

say 'the list of common elements in all sets: ' "["translate(space($), ',', " ")']'</lang>

output   when using the default inputs:
the list of common elements in all sets:  [3,6,9]

Ring

<lang ring> nums = [[2,5,1,3,8,9,4,6],[3,5,6,2,9,8,4],[1,3,7,6,9]] sumNums = [] result = []

for n = 1 to len(nums)

   for m = 1 to len(nums[n])
       add(sumNums,nums[n][m])
   next

next

sumNums = sort(sumNums) for n = len(sumNums) to 2 step -1

   if sumNums[n] = sumNums[n-1]
      del(sumNums,n)
   ok

next

for n = 1 to len(sumNums)

   flag = list(len(nums))
   for m = 1 to len(nums)
       flag[m] = 1
       ind = find(nums[m],sumNums[n])
       if ind < 1
          flag[m] = 0
       ok
   next
   flagn = 1
   for p = 1 to len(nums)
       if flag[p] = 1
          flagn = 1
       else
          flagn = 0
          exit
       ok
   next
   if flagn = 1
      add(result,sumNums[n])
   ok

next

see "common list elements are: " showArray(result)

func showArray(array)

    txt = ""
    see "["
    for n = 1 to len(array)
        txt = txt + array[n] + ","
    next
    txt = left(txt,len(txt)-1)
    txt = txt + "]"
    see txt

</lang>

Output:
common list elements are: [3,6,9]

Wren

Library: Wren-seq

As we're dealing here with lists rather than sets, some guidance is needed on how to deal with duplicates in each list in the general case. A drastic solution would be to remove all duplicates from the result. Instead, the following matches duplicates - so if List A contains 2 'a's and List B contains 3 'a's, there would be 2 'a's in the result. <lang ecmascript>import "/seq" for Lst

var common2 = Fn.new { |l1, l2|

   // minimize number of lookups
   var c1 = l1.count
   var c2 = l2.count
   var shortest = (c1 < c2) ? l1 : l2
   var longest = (l1 == shortest) ? l2 : l1
   longest = longest.toList // matching duplicates will be destructive
   var res = []
   for (e in shortest) {
       var ix = Lst.indexOf(longest, e)
       if (ix >= 0) {
           res.add(e)
           longest.removeAt(ix)
       }
   }
   return res

}

var commonN = Fn.new { |ll|

   var n = ll.count
   if (n == 0) return ll
   if (n == 1) return ll[0]
   var first2 = common2.call(ll[0], ll[1])
   if (n == 2) return first2
   return ll.skip(2).reduce(first2) { |acc, l| common2.call(acc, l) }

}

var lls = [

   [[2, 5, 1, 3, 8, 9, 4, 6], [3, 5, 6, 2, 9, 8, 4], [1, 3, 7, 6, 9]],
   [[2, 2, 1, 3, 8, 9, 4, 6], [3, 5, 6, 2, 2, 2, 4], [2, 3, 7, 6, 2]]

]

for (ll in lls) {

   System.print("Intersection of %(ll) is:")
   System.print(commonN.call(ll))
   System.print()

}</lang>

Output:
Intersection of [[2, 5, 1, 3, 8, 9, 4, 6], [3, 5, 6, 2, 9, 8, 4], [1, 3, 7, 6, 9]] is:
[3, 6, 9]

Intersection of [[2, 2, 1, 3, 8, 9, 4, 6], [3, 5, 6, 2, 2, 2, 4], [2, 3, 7, 6, 2]] is:
[2, 3, 6, 2]