#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
struct PT {
  long long x, y;
  PT(long long x = 0, long long y = 0) : x(x), y(y) {}
  PT operator-(const PT& o) const { return PT(x - o.x, y - o.y); }
  PT operator+(const PT& o) const { return PT(x + o.x, y + o.y); }
  PT operator*(long long k) const { return PT(k * x, k * y); }
  long long operator*(const PT& o) const { return x * o.x + y * o.y; }
  long long operator%(const PT& o) const { return x * o.y - y * o.x; }
  bool operator<(const PT& o) const { return x == o.x ? y < o.y : x < o.x; }
  bool operator==(const PT& o) const { return x == o.x && y == o.y; }
};
long long norm(PT v) { return v * v; }
template <class F>
int search(int l, int r, F test) {
  while (l < r) {
    int m = l + r >> 1;
    if (test(m))
      r = m;
    else
      l = m + 1;
  }
  return test(l) ? l : l + 1;
}
struct CHT {
  vector<vector<PT>> h;
  vector<int> sgn;
  CHT(vector<PT>& in) : h(2), sgn({1, -1}) {
    sort(in.begin(), in.end());
    in.erase(unique(in.begin(), in.end()), in.end());
    for (int b = 0; b < 2; b++) {
      int n = 0;
      for (PT& p : in) {
        while (n > 1 &&
               (p - h[b][n - 2]) % (h[b][n - 1] - h[b][n - 2]) * sgn[b] <= 0) {
          h[b].resize(--n);
        }
        h[b].resize(++n, p);
      }
    }
  }
  bool half(PT q) { return q.y < 0 || q.y == 0 && q.x < 0; }
  PT find(PT q, bool b) {
    if (half(q)) {
      return find(q * -1, !b);
    } else if (h[b].size() == 1) {
      return h[b][0];
    } else {
      int i = search(0, h[b].size() - 2, [&](int i) {
        return q * sgn[b] * (h[b][i] - h[b][i + 1]) >= 0;
      });
      return h[b][i];
    }
  }
  PT argmax(PT q) { return find(q, 0); }
  PT argmin(PT q) { return find(q, 1); }
  long long max(PT q) { return argmax(q) * q; }
  long long min(PT q) { return argmin(q) * q; }
};
PT perp(PT v) { return {-v.y, v.x}; }
struct Ray {
  PT v;
  Ray(int l, int r, int u, int d) : v(r - l, d - u) {}
  bool operator<(const Ray& o) const { return v % o.v > 0; };
};
struct Segment {
  int l, r, h;
  bool operator<(const Segment& o) const { return h < o.h; }
};
const int X = 1000000;
int main() {
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  int n;
  cin >> n;
  vector<Segment> s(n);
  for (int i = 0; i < n; i++) {
    cin >> s[i].l >> s[i].r >> s[i].h;
  }
  sort(s.begin(), s.end());
  vector<pair<Ray, int>> e;
  for (int i = 0; i < n; i++) {
    for (int j = i; j < n; j++) {
      if (s[i].h == s[j].h) continue;
      Ray a(s[j].r, s[i].l, s[j].h, s[i].h);
      e.emplace_back(a, 1);
      Ray b(s[j].l, s[i].r, s[j].h, s[i].h);
      e.emplace_back(b, -1);
    }
  }
  double ans;
  if (e.empty()) {
    int right = -X, left = X;
    for (int i = 0; i < n; i++) {
      right = max(right, s[i].r);
      left = min(left, s[i].l);
    }
    ans = right - left;
  } else {
    vector<PT> p;
    for (int i = 0; i < n; i++) {
      p.emplace_back(s[i].l, s[i].h);
      p.emplace_back(s[i].r, s[i].h);
    }
    CHT cht(p);
    sort(e.begin(), e.end());
    int open = 0;
    ans = numeric_limits<double>::max();
    for (auto [cur, d] : e) {
      bool ok = open == 0;
      open += d;
      ok |= open == 0;
      if (ok) {
        PT u = perp(cur.v);
        double right = cht.max(u);
        right /= u.x;
        double left = cht.min(u);
        left /= u.x;
        ans = min(ans, right - left);
      }
    }
  }
  cout << setprecision(6) << fixed;
  cout << ans << '\n';
}
