#include <bits/stdc++.h>
const int MAX = 200010;
const long long MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const long long LLINF = 0x3f3f3f3f3f3f3f3f;
const long double EPS = 1e-6;
const long double PI = acos(-1.0);
using namespace std;
const long double is_query = -LLINF;
struct Line {
  long double m, b;
  mutable function<const Line*()> succ;
  bool operator<(const Line& rhs) const {
    if (rhs.b != is_query) return m < rhs.m;
    const Line* s = succ();
    if (!s) return 0;
    long double x = rhs.m;
    return b - s->b < (s->m - m) * x;
  }
};
struct Cht : public multiset<Line> {
  bool bad(iterator y) {
    auto z = next(y);
    if (y == begin()) {
      if (z == end()) return 0;
      return y->m == z->m && y->b <= z->b;
    }
    auto x = prev(y);
    if (z == end()) return y->m == x->m && y->b <= x->b;
    return (long double)(x->b - y->b) * (z->m - y->m) >=
           (long double)(y->b - z->b) * (y->m - x->m);
  }
  void insert_line(long double m, long double b) {
    auto y = insert({m, b});
    y->succ = [=] { return next(y) == end() ? 0 : &*next(y); };
    if (bad(y)) {
      erase(y);
      return;
    }
    while (next(y) != end() && bad(next(y))) erase(next(y));
    while (y != begin() && bad(prev(y))) erase(prev(y));
  }
  long double eval(long double x) {
    auto l = *lower_bound((Line){x, is_query});
    return l.m * x + l.b;
  }
};
struct seg {
  int xl, xr, y;
  bool operator<(const seg& o) const { return y < o.y; }
};
vector<seg> vet;
long double get_diff(long double ang) {
  long double m = LLINF, M = -LLINF;
  for (auto v : vet) {
    m = min(m, v.xl + ang * v.y);
    M = max(M, v.xr + ang * v.y);
  }
  return M - m;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int n, xl, xr, y;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> xl >> xr >> y;
    seg a = {xl, xr, y};
    vet.push_back(a);
  }
  vector<pair<long double, int> > angs;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (vet[i].y <= vet[j].y) continue;
      angs.emplace_back(
          (vet[j].xl - vet[i].xr) / (long double)(vet[i].y - vet[j].y), 1);
      angs.emplace_back(
          (vet[j].xr - vet[i].xl) / (long double)(vet[i].y - vet[j].y), 0);
    }
  }
  vector<long double> escolhas;
  if (angs.empty()) {
    cout << get_diff(0) << '\n';
    return 0;
  } else {
    int k = 0;
    sort(angs.begin(), angs.end());
    for (auto a : angs) {
      if ((a.second == 1 and k == 0) or (a.second == 0 and k == 1))
        escolhas.push_back(a.first);
      k += (a.second ? 1 : -1);
    }
  }
  long double ans = LLINF;
  Cht lower_hull, upper_hull;
  for (auto v : vet) {
    upper_hull.insert_line(v.y, v.xr);
    lower_hull.insert_line(-v.y, -v.xl);
  }
  for (auto e : escolhas) {
    long double M = upper_hull.eval(e);
    long double m = -lower_hull.eval(e);
    ans = min(ans, M - m);
  }
  cout << fixed << setprecision(10) << ans << '\n';
  return 0;
}
