aboutsummaryrefslogtreecommitdiff
path: root/challenge-127/james-smith/README.md
blob: 10adb6a346a0e2504181c4d7e2d1afd18cdb3720 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# Perl Weekly Challenge #127

You can find more information about this weeks, and previous weeks challenges at:

  https://perlweeklychallenge.org/

If you are not already doing the challenge - it is a good place to practise your
**perl** or **raku**. If it is not **perl** or **raku** you develop in - you can
submit solutions in whichever language you feel comfortable with.

You can find the solutions here on github at:

https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-127/james-smith/perl

# Task 1 -  Disjoint Sets

***You are given two sets with unique integers. Write a script to figure out if they are disjoint.***

## The solution

This is a rewording of simple perl, which is to see if there any elements of set 1 in set 2. To avoid nested loops, we use the efficiency of perl's hash key search to search for members. So for set 1 we create a hash who's keys are the members of set 1. We then search through set 2 to see which members are keys in this hash (and so in both sets). If there are any we return 0 o/w return 1.

```perl
sub disjoint_sets {
  my %m = map { $_=>1 } @{$_[0]};
  return grep( { $m{$_} } @{$_[1]}) ? 0 : 1;
}
```

# Task 2 - Conflict Intervals

***You are given a list of intervals. Write a script to find out if the current interval conflicts with any of the previous intervals.***

## Background

This is going back to my day job again - but I thought I would add a bit of background this time. I'm not a geneticist, but a web developer working at an institution that uses DNA sequencing to use genomics to investigate genetics. My first project was to develop/lead the developers for a genome browser. Often we had to display information about genomic features and whether or not they overlapped a particular region (to know whether to display them or not) or to bump them for display (to make sure features didn't merge/overlap)...

## Solution


There are six arrangements more any two regions..... See picture below...

```
         [============]
[------]    [++++++]    [------]
     [++++++++++++++++++++]
     [++++++]      [++++++]
```

Over the 6 we have two of regions which are disjoint from the top region: Where `region_2_start > region_1_end` or `region_1_start > region_2_end`...

Our loop finally becomes....

```perl
sub conflict_intervals {
  my @in = @{ $_[0] };
  my @conf;
  while( my $int = pop @in ) {
    foreach(@in) {
      next unless $int->[1] < $_->[0] || $int->[0] < $_->[1];
      unshift @conf, $int;
      last;
    }
  }
  return \@conf;
}
```

**Notes:**
 # Note we work from the end backwards - this is easier as we just pop the last interval off the loop each time and compare it with previous ones.
 # We then use unshift to add it to the start of what we return.

We can compact this slightly using the `&&` trick in the foor loop to do away with the `next`/`last` combination:

```perl
sub conflict_intervals_compact {
  my(@i,@o) = @{$_[0]};
  while(my $r = pop @i) {
    ($r->[1]<$_->[0] || $r->[0]<$_->[1]) && (unshift @o, $r) && last foreach @i;
  }
  return \@o;
}
```