#include <bits/stdc++.h>
using namespace std;
string to_string(char c) { return string(1, c); }
string to_string(bool b) { return b ? "true" : "false"; }
string to_string(const char* s) { return string(s); }
string to_string(string s) { return s; }
string to_string(vector<bool> v) {
  string res;
  for (int i = 0; i < (int)v.size(); i++) res += char('0' + v[i]);
  return res;
}
template <size_t second>
string to_string(bitset<second> b) {
  string res;
  for (int i = 0; i < second; i++) res += char('0' + b[i]);
  return res;
}
template <class T>
string to_string(T v) {
  bool f = 1;
  string res;
  for (auto x : v) {
    if (!f) res += ' ';
    f = 0;
    res += to_string(x);
  }
  return res;
}
void DBG() { cerr << "]" << endl; }
template <class H, class... T>
void DBG(H h, T... t) {
  cerr << to_string(h);
  if (sizeof...(t)) cerr << ", ";
  DBG(t...);
}
const int INF = 1e9 + 7, N = 2e3 + 7;
int l[N], r[N], y[N];
struct Hull {
  vector<pair<int, int>> lines;
  void add_line(int m, int b) { lines.emplace_back(m, b); }
  struct line {
    int m, b;
    line(int _m = 0, int _b = 0) { m = _m, b = _b; }
    double at(double x) { return m * x + b; }
  };
  deque<line> dk;
  bool last_is_useless(int m, int b) {
    if (dk.size() < 2) return false;
    long long m0 = dk[dk.size() - 2].m, b0 = dk[dk.size() - 2].b;
    long long m1 = dk.back().m, b1 = dk.back().b;
    return (b0 - b) * (m1 - m0) <= (m - m0) * (b0 - b1);
  }
  void add(int m, int b) {
    line l = line(m, b);
    if (dk.size() && dk.back().m == l.m && l.b >= dk.back().b) dk.pop_back();
    if (dk.size() && dk.back().m == l.m) return;
    while (last_is_useless(m, b)) dk.pop_back();
    dk.push_back(l);
  }
  double qry(double x) {
    while (dk.size() >= 2 && dk[0].at(x) <= dk[1].at(x)) dk.pop_front();
    return dk[0].at(x);
  }
  vector<double> go(vector<double> to_check) {
    sort((lines).begin(), (lines).end());
    for (pair<int, int> line : lines) add(line.first, line.second);
    vector<double> ans;
    for (double x : to_check) ans.push_back(qry(x));
    return ans;
  }
} mx, mn;
signed main() {
  std::ios::sync_with_stdio(0);
  std::cin.tie(0);
  ;
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> l[i] >> r[i] >> y[i];
    mx.add_line(y[i], l[i]);
    mx.add_line(y[i], r[i]);
    mn.add_line(-y[i], -l[i]);
    mn.add_line(-y[i], -r[i]);
  }
  vector<array<int, 3>> ev;
  int limit = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++)
      if (y[i] > y[j]) {
        ev.push_back({-1, l[j] - r[i], y[j] - y[i]});
        ev.push_back({1, r[j] - l[i], y[j] - y[i]});
        limit++;
      }
  }
  sort((ev).begin(), (ev).end(), [&](array<int, 3> a, array<int, 3> b) {
    long long cross = (long long)a[1] * b[2] - (long long)a[2] * b[1];
    if (cross == 0) return a[0] > b[0];
    return cross > 0;
  });
  vector<double> to_check;
  int cnt = limit;
  for (auto e : ev) {
    if (e[0] == 1) {
      cnt++;
      if (cnt == limit) to_check.emplace_back((double)-e[1] / e[2]);
    } else {
      if (cnt == limit) to_check.emplace_back((double)-e[1] / e[2]);
      cnt--;
    }
  }
  if (to_check.empty()) to_check.push_back(0);
  sort((to_check).begin(), (to_check).end());
  vector<double> mxs = mx.go(to_check);
  vector<double> mns = mn.go(to_check);
  double ans = 1e18;
  for (int i = 0; i < to_check.size(); i++) ans = min(ans, mxs[i] + mns[i]);
  cout << fixed << setprecision(10) << ans << endl;
}
