# Comparing Adjacent Elements in Ruby

# CodinGame

Shout-Out to CodinGame… it’s perhaps the best place to practice coding puzzles, learn more about your favorite languages, and, optionally, learn some pretty cool game AI specific techniques. One of the greatest features they have is the ability to see other’s solutions to a problem after you’ve completed yours, complete with full comments from other users and rankings for the best solutions per-language to each challenge. This is a great way to discover new language features or algorithmic approaches you may not be familiar with. You can also follow me there!

While exploring some coding puzzles there I found a couple neat tricks for comparing adjacent elements in Ruby that I’d like to share.

# The Problem

The challenge (simplified here) is fairly straight-forward:

**Given a list of integers, identify the two closest integers and output their difference.**

Assuming we have the list of digits sorted already in an array called **nums**

```
nums = 10.times.map { rand(100) }.sort
=> [55, 59, 65, 70, 75, 79, 84, 87, 89, 94]
```

a straight-forward solution in Ruby might be to loop through the list, calcuate the difference between adjacent digits, and remember the smallest difference.

```
min_distance = (nums[1] - nums[0])
for i in (2...nums.length)
distance = (nums[i] - nums[i-1])
if distance < min_distance
min_distance = distance
end
end
```

After reviewing the top-ranked solutions on CodinGame however, I discovered 2 new Ruby solutions that are much more elegant. One using the each_cons method, the other using a combination of zip and rotate.

# each_cons approach

**each_cons** groups n consective elements together:

```
nums
=> [55, 59, 65, 70, 75, 79, 84, 87, 89, 94]
nums.each_cons(2).to_a
=> [[55, 59], [59, 65], [65, 70], [70, 75], [75, 79], [79, 84], [84, 87], [87, 89], [89, 94]]
```

From here, you could simply map the elements in main array to their differences and then take the min:

```
diffs = nums.each_cons(2).map { |n1, n2| n2 - n1 }
=> [4, 6, 5, 5, 4, 5, 3, 2, 5]
diffs.min
=> 2
```

or in a nice one-liner:

```
nums.each_cons(2).map { |n1, n2| n2 - n1 }.min
```

# zip and rotate approach

**rotate** … rotates the array, by n elements:

```
nums
=> [55, 59, 65, 70, 75, 79, 84, 87, 89, 94]
nums.rotate(1)
=> [59, 65, 70, 75, 79, 84, 87, 89, 94, 55]
nums.rotate(3)
=> [70, 75, 79, 84, 87, 89, 94, 55, 59, 65]
```

**zip** sort of ‘zips up’ or merges N arrays together to create a new array with elements of length N. In our case,
we can zip the rotated array together with the original:

```
nums
=> [55, 59, 65, 70, 75, 79, 84, 87, 89, 94]
nums.rotate(1)
=> [59, 65, 70, 75, 79, 84, 87, 89, 94, 55]
nums.zip(nums.rotate(1))
=> [[55, 59], [59, 65], [65, 70], [70, 75], [75, 79], [79, 84], [84, 87], [87, 89], [89, 94], [94, 55]]
```

Now we can simply map this array to the differences of its elements and take the min:

```
diffs = nums.zip(nums.rotate).map{|n1 , n2| (n2 - n1).abs}
=> [4, 6, 5, 5, 4, 5, 3, 2, 5, 39]
diffs.min
=> 2
```

One strange thing with the rotate and zip approach is that you end up comparing the largest and smallest elements (giving us 39 in this particular case). It doesn’t matter here as the difference between the largest and smallest elements in the array will always be larger than the minimum which we’re looking for, and can be discarded safely. Still; a bit of a strange artifact of this solution if you ask me!

# Conclusion

Comparing adjacent elements is a common-enough problem in programming that these tools feel like really useful additions to my toolbox. I’d definitely prefer the `each_cons`

solution over the `zip`

and `rotate`

solution, though `zip`

and `rotate`

are surely useful tools for the right application. I’d seen `zip`

and `rotate`

before but never really played with them, and `each_cons`

was totally new to me. I can’t wait to learn even more exploring the challenges on CodinGame!.