g | x | w | all
Bytes Lang Time Link
022Haskell + hgl250625T044904ZWheat Wi
037Haskell250625T041234ZWheat Wi
042Ruby250611T025325ZValue In
026APLDyalog Unicode250617T110219ZMat_rdv
112Mathematica250616T105058ZChris De
057Python 3250614T233617ZLucenapo
513JavaScript Node.js250616T110529ZChris De
036Uiua250611T104539ZMaki
nanCommodore 64 Assembler250611T092810ZJani Joe
051JavaScript Node.js250610T114037Zl4m2
009Jelly250611T013410ZJonathan
020K ngn/k250610T183746Zatt
070Haskell250610T151214ZIbozz91
023Charcoal250610T060356ZNeil
071JavaScript ES6250610T100447ZArnauld
01005AB1E250610T084554ZKevin Cr

Haskell + hgl, 22 bytes

cnT<jl2(lt<>cr><ge<st)

Attempt This Online!

Explanation

This is a loose port of my vanilla haskell answer.

Reflection

This is completely satisfactory. There's nothing really missing and my suggestions are sort of a reach.

Haskell, 37 bytes

f a=sum[1|u<-a,v<-a,u<v,fst v<=snd u]

Try it online!

We count the number of pairs u and v where

  1. u<v, that is the start point of u is before or equal to the start point of v (and if they are equal than the end point of u is before that of v)
  2. The end point of u is after the start point of v

By 1. we already know the start point of u is before that of v, so we can check for intersection rather simply with just 2.

This also avoids a couple of issues we could run into:

We don't have to spend any bytes correcting for these over counts.

Ruby, 69 51 42 bytes

-18 -27 bytes from G B.

->a{a.sum{|x,y|a.count{y>=_1&&_2>=x}-1}/2}

Attempt This Online!

->a{
    a.sum{|x,y|             # For each interval [L1,R1], get value and sum
      a.count{              #   Count all intervals [L2,R2] where
        y>=_1&&_2>=x        #     R1 is NOT below L2 and L1 is NOT above R2
                            #       (if R1 < L2 OR L1 > R2 there's no overlap;
                            #        invert via De Morgan's Law)
      }-1                   #   Account for interval comparing to itself
    }/2                     # Account for all pairs being counted twice
}

APL(Dyalog Unicode), 26 bytes SBCS

2÷⍨{+/,∨∘⍉⍨∨⌿⍤2≠/×∘.-⍨⍵}-≢

Try it on APLgolf!

An argument is a matrix of shape n×2.

Explanation

The main part, dfn:

{                   }      dfn
                   ⍵       the right argument
                  ⍨        Selfie: f⍨ Y ←→ Y f Y
                 -     
               ∘.          Outer product
                           (table of all combinations of elements of both arguments)
               ∘.-⍨⍵       Array of differences of shape n×2×n×2
              ×            Signum (positive→1, negative→¯1, 0→0)
             /             Reduction (along the last axis)
            ≠              Not equal
            ≠/             if for some point p: (× p - L2) ≠ (× p - R2), hence p∊[L2, R2]
                            now the array has a shape n 2 n
          ⍤2                at Rank 2
         ⌿                  Reduce first
         ⌿⍤2                Reduce along the 2nd axis from the end
        ∨                  Logical or
        ∨⌿⍤2≠/∘.-⍨⍵        n×n matrix, each cell shows
                           whether at least one end of the [L1, R1] lies in the [L2, R2]
                           (thus two ranges intersect except when the second lies inside the first)
       ⍨               
      ⍉                   Transpose
     ∘                     X f∘g Y ←→ X f (g Y)
    ∨                  
    ∨∘⍉⍨                  matrix ∨-symmetrization
    ∨∘⍉⍨∨⌿⍤2≠/∘.-⍨⍵      Intersection table
   ,                       Ravel (list elements of the matrix in one vector)
  /                    
 +                     
 +/                        sum
{+/,∨∘⍉⍨∨⌿⍤2≠/×∘.-⍨⍵}    Number of intersections but
                           including selfintersections and doubling others

Tacit function: (f g h) Y ←→ (f Y) g (h Y) and (A f g) Y ←→ A f (g Y)

                           ≢   Tally (size of the first axis, n)
                          -
   {+/,∨∘⍉⍨∨⌿⍤2≠/×∘.-⍨⍵}-≢    Doubled number of intersections
  ⍨                            Commute: X f⍨ Y ←→ Y f X
 ÷                              Divide
2÷⍨{+/,∨∘⍉⍨∨⌿⍤2≠/×∘.-⍨⍵}-≢   solution

Mathematica 112 characters

p = {{0, 3}, {3, 4}, {3, 8}, {5, 6}, {8, 9}};

Length@Select[{##,Or[#1[[1]]<=#2[[1]]<= #1[[2]],#2[[1]]<=#1[[1]]<=#2[[2]]]}&
   @@@Union[Sort/@Subsets[p,{2}]],Last]

5

These are the 5 unique intersecting pairs for the above case.

 L1,R1 L2,R2

{{0,3},{3,4}  L1 <= L2 <= R1
{{0,3},{3,8}  L1 <= L2 <= R1
{{3,4},{3,8}  L1 <= L2 <= R1  and  L2 <= L1 <= R2
{{3,8},{5,6}  L1 <= L2 <= R1
{{3,8},{8,9}  L1 <= L2 <= R1

With the sort, if the first test is passed the second is unnecessary.

Therefore, in 68 characters

Count[#1[[1]]<=#2[[1]]<=#1[[2]]&@@@Union[Sort/@Subsets[p,{2}]],True]

Python 3, 57 bytes

lambda x:-len(x)/2-sum((b<c)-.5for a,b in x for c,d in x)

Try it online!

Takes input as [[1,2],[3,4],[5,6]].

Python 2, 49 bytes

lambda x,y:sum(.5-(b<c)for b in y for c in['']+x)

Try it online!

JavaScript (Node.js), 513 bytes

function c(p) {
	function s(v) {
		let r = [];
		for (let i = 0; i < v.length; i++) {
			for (let j = i + 1; j < v.length; j++) {
				r.push([v[i], v[j]]);
			}
		}
		return r;
	}

	function t(q) {
		let [a, b] = q;
		return (
			(a[0] <= b[0] && b[0] <= a[1]) ||
			 (b[0] <= a[0] && a[0] <= b[1])
		);
	}

	let u = s(p).map(k => k.sort((x, y) => x[0] - y[0] || x[1] - y[1]));
	return [...new Set(u.filter(t).map(JSON.stringify))].length;
}

const p = [[0, 3], [3, 4], [3, 8], [5, 6], [8, 9]];
console.log(c(p));

Try it online!

This finds 5 unique intersecting pairs in agreement with my Mathematica answer.

 L1,R1  L2,R2

[[0,3], [3,4]]     L1 <= L2 <= R1     0 <= 3 <= 3
[[0,3], [3,8]]     L1 <= L2 <= R1     0 <= 3 <= 3
[[3,4], [3,8]]     L1 <= L2 <= R1     3 <= 3 <= 4
[[3,8], [5,6]]     L1 <= L2 <= R1     3 <= 5 <= 8
[[3,8], [8,9]]     L1 <= L2 <= R1     3 <= 8 <= 8

Uiua, 50 44 42 41 37 36 bytes

/+/+×⊞⊃(>∩□|⊢≤⇌).⍆

Try it here!

Uiua is read right-to-left. First we sort the list of input pairs lexicographically with .

Then we duplicate that list . and build two tables in parallel ⊞⊃, using the carthesian product of the copies. In the first table >∩□, the upper right triangle (without the diagonal) is 1, and the rest is 0

The second becomes a table of all intersections ⊢≤⇌, which gives 0 for no intersection and 1 for intersection, using the knowledge the list is already sorted to skip the L1 <= L2 check.

Finally, we multiply these tables element by element with ×, which is equivalent to a boolean and, and sum up all the 1s with /+/+ to get the final result.

Note: /+♭ would be shorter in characters, but is longer in bytes using UTF-8

Commodore 64 Assembler, 39 Bytes (6502/KickAssembler)

According to the author: "You may write a full program or a function. Input is the array in any reasonable form". I interpreted this so that only the size of the routine (function) itself counts, and it doesn't really matter how the input array is passed to the routine.

Thus for convenience, I made a test program where the array is just a list of bytes and gets compiled with the program itself. There would have been other options to input the array (create a separate routine to read user input, read from screen, read from a file etc.) but as the point is just to prove that the routine itself works, this was the easiest solution that required least effort.

Explanation

Complete Test Program

BasicUpstart2(start)    // Basic program to help us run our machine language
                        // routine with RUN, without typing in a SYS command

start:  ldx #0          // Reset [L1,R1] array element pointer
        stx $2          // Reset intersections count on zero page
inc_1:  inx             // Increase [L1,R1] array element pointer
        inx             // (starts from first element)
        txa             // Copy [L1,R1] array element pointer...
        tay             // ...to [L2,R2] pointer
inc_2:  iny             // Increase [L2,R2] array element pointer
        iny             // (starts from element after [L1,R1])
        lda array-1,x   // Load R1 to A
        beq print       // [0,0] indicates end of array - we're done
        cmp array-2,y   // Compare to L2
        bcc inc_2       // If R1 ends before L2 starts, no overlap
        lda array-1,y   // Load R2 to A
        beq inc_1       // If [L2,R2] = [0,0], a round is done
        cmp array-2,x   // Compare to L1
        bcc inc_2       // If R2 ends before L1 starts, no overlap
        inc $2          // Otherwise, there must be overlap - increase count
        bcs inc_2       // Continue to next comparison (branch always taken)
print:  ldx $2          // Load number of intersections to X
        jmp $bdcf       // Call ROM routine to print it out in decimal

.print "ROUTINE SIZE: " + toIntString(*-start)

array:  .by 1,2,5,6,1,5,4,7
        .by 0,0         // Null termination of the array

Routine Breakdown

start:  ldx #0          // Reset [L1,R1] array element pointer
        stx $2          // Reset intersections count on zero page

Resetting the 1st element pointer (held in X) and intersections count on zero page address $2 on every run of the routine. Intersections count is kept on zero page to be able to use an 8bit address instead of 16bit address when referring to it, thus saving a couple bytes in the routine.

inc_1:  inx             // Increase [L1,R1] array element pointer
        inx             // (starts from first element)
        txa             // Copy [L1,R1] array element pointer...
        tay             // ...to [L2,R2] pointer

inc_1 is what we could call an outer loop, where we increase the 1st array element pointer and reset the 2nd element pointer to prepare for inner loop. Pointers will actually point one element too deep into the array, but we'll correct the offset later when accessing the array.

inc_2:  iny             // Increase [L2,R2] array element pointer
        iny             // (starts from element after [L1,R1])

In the inner loop, as the first thing increment 2nd array element pointer. This guarantees that an element is never compared to itself.

        lda array-1,x   // Load R1 to A
        beq print       // [0,0] indicates end of array - we're done
        cmp array-2,y   // Compare to L2
        bcc inc_2       // If R1 ends before L2 starts, no overlap

First comparison (lda and cmp): Does 1st element end before 2nd element starts? If so, there cannot be any overlap - bcc will branch to beginning of inner loop. Even before comparison,beq checks if 1st element is already a null element, and if so, whole array is processed and we can branch to printing the result.

        lda array-1,y   // Load R2 to A
        beq inc_1       // If [L2,R2] = [0,0], a round is done
        cmp array-2,x   // Compare to L1
        bcc inc_2       // If R2 ends before L1 starts, no overlap

Second comparison: Does second element end before first element starts? If so, there cannot be any overlap - bcc will branch to beginning of inner loop. Even before comparison,beq checks if 2nd element is already a null element, and if so, we've compared 1st element to all subsequent elements in array and can exit to the outer loop to increase 1st element pointer.

        inc $2          // Otherwise, there must be overlap - increase count
        bcs inc_2       // Continue to next comparison (branch always taken)

If both comparisons were false, the elements must overlap, thus increase the intersections count and continue the inner loop.

print:  ldx $2          // Load number of intersections to X
        jmp $bdcf       // Call ROM routine to print it out in decimal

If we've reached this far, whole array is processed - print out the total number of intersections with a ROM routine. After it is done, the ROM routine does an rts (return to system), thus ending the execution of our whole routine (and in this case, returning to BASIC prompt).

JavaScript (Node.js), 51 bytes

x=>x.map(a=>x.map(b=>r-=a[1]<b[0]||-1,r--),r=0)|r/2

Try it online!

By default each ordered pair(including self to self) score 1, reduce 2 for every segment pair A,B s.t. A is on left of B, reduce 1 for each segment(self pairs)

JavaScript (Node.js), 61 bytes

f=([e,...x],c=0)=>e&&x.map(t=>c+=t[0]>e[1]^t[1]>=e[0])|f(x,c)

Try it online!

Note: Last map operation returns an array of a single number, which is or'ed with undefined

Jelly, 9 bytes

r/€Œcf/ƇL

A monadic Link that accepts a list of pairs of integers and yields the number of overlapping pairs.

Try it online!

How?

r/€Œcf/ƇL - Link: list of pairs of integers
  €       - for each pair:
 /        -   reduce by:
r         -     inclusive range
   Œc     - unordered pairs of those ranges
       Ƈ  - keep those for which:
      /   -   reduce by:
     f    -     filter keep
        L - length

K (ngn/k), 20 bytes

+/>/&{~x>,\y}/+.1<:\

Try it online!

Port of Kevin Cruijssen's approach.

               .1<:\    sort
     {~x>,\y}/+         l_i ≤ r_j for i≥j
+/>/&                   count
  >/                              for i>j

Haskell, 70 bytes

f a=div(sum[1|(w,x)<-a,(y,z)<-a,(w<=y&&y<=x)||(y<=w&&w<=z)]-length a)2

Try it online!

Takes in a list of tuples.

Charcoal, 24 23 bytes

IΣ⭆θ⭆E…θκ⟦ιλ⟧¬›§⌈λ⁰§⌊λ¹

Try it online! Link is to verbose version of code. Explanation:

   θ                    Input array
  ⭆                     Map over elements and join
       θ                Input array
      …                 Truncated to length
        κ               Current index
     E                  Map over elements
         ⟦ιλ⟧           Pair outer and inner element
    ⭆                   Map over pairs and join
               §⌈λ⁰     Lower end of upper range
             ¬›         Is less than or equal to
                   §⌊λ¹ Upper end of lower range
 Σ                      Count the `1`s
I                       Cast to string
                        Implicitly print

Edit: Saved 1 byte by porting @KevinCruijssen's approach of just checking the ends of the maximum and minimum range.

JavaScript (ES6), 71 bytes

Very basic.

a=>a.map(([b,c],i)=>a.map(([d,e],j)=>n+=i<j&!(b>d|d>c&&d>b|b>e)),n=0)|n

Try it online!

05AB1E, 10 bytes

.Æʒ{`R@θ}g

Try it online.

Explanation:

Instead of checking both \$L1 \leq L2 \leq R1\$ and \$L2 \leq L1 \leq R2\$ with a logical OR in between them, I first sort the pair of pairs based on the \$L\$s:

  1. If \$L1<L2\$\$[[L1,R1],[L2,R2]]\$ remains unchanged
  2. If \$L2<L1\$\$[[L1,R1],[L2,R2]]\$ becomes \$[[L2,R2],[L1,R1]]\$
  3. If \$L1=L2\$ → Sort based on the \$R\$s, so could becomes either

After which I can simply check for \$l2 \leq r1\$.

.Æ       # Get all 2-element combinations of the (implicit) input-list
  ʒ      # Filter this list of pairs of pairs by:
   {     #  Sort the pair of pairs based on the first elements
         #  (aka, sort [[L1,R1],[L2,R2]] based on just the L1 & L2)
         #   let's call this sorted pair [[l1,r1],[l2,r2]]
    `    #  Pop and push both pairs separated to the stack
         #   → [l1,r1] and [l2,r2]
     R   #  Reverse the top/second pair
         #   → [l1,r1] and [r2,l2]
      @  #  Do an >= check
         #   → [l1>=r2,r1>=l2]
       θ #  Pop and leave the last check of the pair
         #   → r1>=l2
  }g     # After the filter: pop and push the length
         # (which is output implicitly as result)