Sprawdzanie czy nowy zakres jest dostępny

0

Witam! Mam małą zagwozdkę związaną z przedziałami liczb. Mianowicie, mam takie przedziały wagowe:
11 - 20 kg
21 - 25 kg
41 - 48 kg

Teraz chcę dodać przedział 26-40 kg i zastanawiam się jak sprawdzić, czy jest on wolny. Liczby nie mogą na siebie nachodzić. Podaję do skryptu minimalną wartość przedziału i maksymalną i dany przedział musi być wolny, żeby go dodać.

Ktoś ma pomysł jak to rozwiązać?

0

To nie ma nic wspólnego z php. Wystarczy wpisać check if ranges overlap.

0

Akurat robię skrypt w PHP, więc tutaj napisałem posta. Nie mniej w google ciężko o jakąś sensowną odpowiedź.

1

Masz tutaj 3 możliwości:

  • nowy przedział zachodzi z którymś z lewej / prawej
  • jest zawarty przez inny przedział
  • zawiera w sobie inny przedział

Pierwszy i drugi przypadek możesz rozwiązać sprawdzając czy minimum/maximum nowego przedziału zawiera się, w którymś przedziale. Krótko mówiąc: dla wszystkich istniejących już przedziałów nowy nie może spełniać warunków:

MIN_X < MIN_NOWEGO < MAX_X || MIN_X < MAX_NOWEGO < MAX_X

żeby sprawdzić czy nie zachodzi warunek 3 możesz sprawdzić:

MIN_NOWEGO < MIN_X && MAX_X < MAX_NOWEGO 

Jeśli któryś z powyższych warunków zachodzi oznacza to, że nowy przedział nachodzi na inny. Myślę, że pod hasłem ranges overlapping w guglu można znaleźć sporo wariantów i możliwości.

0

Serio...? Wystarczy wpisać w google to, co Ci wyżej podświetliłem.

Given two ranges [x1,x2], [y1,y2]

def is_overlapping(x1,x2,y1,y2):
   return max(x1,y1) <= min(x2,y2)

źródło

Implementacja w PHP:

<?php
class Range
{
    private $start;

    private $end;

    public function __construct($start, $end)
    {
        if (gettype($start) !== gettype($end)) {
            throw new \InvalidArgumentException("Range's start and range's end must be of the same type");
        }

        if ($start > $end) {
            throw new \InvalidArgumentException("Range's start must be smaller than range's end");
        }

        $this->start = $start;
        $this->end = $end;
    }

    public function overlap(Range $range): bool
    {
        return max($this->start, $range->start) <= min($this->end, $range->end);
    }

    /**
     * @param Range[] $ranges
     * @return bool
     */
    public function overlapAny($ranges): bool
    {
        foreach ($ranges as $range) {
            if($this->overlap($range)) {
                return true;
            }
        }

        return false;
    }
}

$ranges = [
    new Range(11, 20),
    new Range(21, 25),
    new Range(41, 48)
];

var_dump((new Range(20, 49))->overlapAny($ranges) === true);
var_dump((new Range(22, 49))->overlapAny($ranges) === true);
var_dump((new Range(26, 30))->overlapAny($ranges) === false);
var_dump((new Range(26, 40))->overlapAny($ranges) === false);
var_dump((new Range(-1, 10))->overlapAny($ranges) === false);
var_dump((new Range(49, 50))->overlapAny($ranges) === false);

1 użytkowników online, w tym zalogowanych: 0, gości: 1