2011-09-29 3 views
0

두 가지 유형의 time_block-free 약속이 있습니다. 각 time_block에는 start_time 및 end_time이 있습니다.
5 개의 약속 time_blocks와 2 개의 무료 time_blocks가 있다고 가정 해보십시오.
약속이 발생한 경우 일정 시간 분할 (해결 된 종류)

나는과 같이, 약속 사이에 자유 시간을 채우기 실제 무료 time_blocks 작성해야합니다 : === 이 죄로 못생긴 솔루션의

$appointments = array(
    array(
     'start_time' => 730, 
     'end_time' => 830), 
    array(
     'start_time' => 830, 
     'end_time' => 930), 
    array(
     'start_time' => 945, 
     'end_time' => 1000), 
    array(
     'start_time' => 1045, 
     'end_time' => 1100), 
    array(
     'start_time' => 1130, 
     'end_time' => 1145) 
); 

$free_time_blocks = array(
    array(
     'start_time' => 900, 
     'end_time' => 1000), 
    array(
     'start_time' => 1030, 
     'end_time' => 1200) 
); 


// Result should be 
$actual_free_time = array(
    array(
     'start_time' => 930, 
     'end_time' => 945 
    ), 
    array(
     'start_time' => 1030, 
     'end_time' => 1045 
    ), 
    array(
     'start_time' => 1100, 
     'end_time' => 1130 
    ), 
    array(
     'start_time' => 1145, 
     'end_time' => 1200 
    ), 
) 

=== 정렬하지만, 내가 처한 모든 상황에서 작동합니다. 시행 착오로 문제를 해결하는 것이 싫어. 누구든지 좀 더 우아한 해결책이 있다면 듣고 싶다. 나는 내가 필요로하는 것보다 훨씬 더 복잡하게 만들고 있다고 느낄 수밖에 없다.

<?php 
function getAppointmentsInRange($start_time, $end_time){ 
    $appointments = array(
     array(
      'start_time' => 730, 
      'end_time' => 830), 
     array(
      'start_time' => 830, 
      'end_time' => 930), 
     array(
      'start_time' => 945, 
      'end_time' => 1000), 
     array(
      'start_time' => 1000, 
      'end_time' => 1035), 
     array(
      'start_time' => 1035, 
      'end_time' => 1100), 
     array(
      'start_time' => 1105, 
      'end_time' => 1125), 
     array(
      'start_time' => 1130, 
      'end_time' => 1230) 
    ); 

    foreach($appointments as $appointment){ 
     if($appointment['start_time'] < $end_time && $appointment['end_time'] > $start_time){ 
      $return[] = $appointment; 
     } 
    } 
    return $return; 
} 

function setFreeTime($start_time, $end_time){ 
    echo "Free Time. Start: $start_time, End: $end_time <br/>"; 
} 

$free_time_blocks = array(
    array(
     'start_time' => 900, 
     'end_time' => 1000), 
    array(
     'start_time' => 1030, 
     'end_time' => 1200) 
); 



foreach($free_time_blocks as $free_time_block){ 

    // Get appointments with any part falling inside the range (eg. starting before but ending after the start) 
    $appointments = getAppointmentsInRange($free_time_block['start_time'], $free_time_block['end_time']); 

    $start_time = $free_time_block['start_time']; 
    $end_time = $free_time_block['start_time']; 

    $finished = false; 

    $i = 0; 
    foreach($appointments as $appointment){ 
     echo "trying...<br/>"; 

     $next = $i + 1; 
     $prev = $i - 1; 

     if($appointment['start_time'] <= $free_time_block['start_time']){ 
      echo "case 1 <br/>"; 
      // If appointment starts before ftb then start ftb at end of appointment, and end at start of next appointment or end of ftb 
      if($appointment['end_time'] < $free_time_block['end_time']){ 
       $start_time = $appointment['end_time']; 
      }else{ 
       $start_time = $end_time; 
       break; 
      } 
      if(isset($appointments[$next])){ 
       $end_time = $appointments[$next]['start_time']; 
      }else{ 
       $end_time = $free_time_block['end_time']; 
      } 
     } 
     elseif($appointment['start_time'] > $free_time_block['start_time']){ 
      echo 'case 2 <br/>'; 
      // If appointment starts during ftb then start ftb at last end time 
      // Start time = previous end time 

      if($appointment['end_time'] < $free_time_block['end_time']){ 
       if(isset($appointments[$next])){ 
        $end_time = $appointment['start_time']; 
       }else{ 
        $end_time = $free_time_block['end_time']; 
       } 
      }elseif($start_time < $appointment['start_time']){ 
       if(isset($appointments[$prev])){ 
        $start_time = $appointments[$prev]['end_time']; 
       } 
       $end_time = $appointment['start_time']; 
      }else{ 
       break; 
      } 

     } 
     elseif($appointment['start_time'] == $end_time){ 
      echo "case 3 <br/>"; 
      if($appointment['end_time'] < $free_time_block['end_time']){ 
       $start_time = $appointment['start_time']; 
      }else{ 
       break; 
      } 
      if(isset($appointments[$next])){ 
       $end_time = $appointments[$next]['start_time']; 
      }else{ 
       $end_time = $free_time_block['end_time']; 
      } 
     } 

     if($start_time != $end_time){ 
      setFreeTime($start_time, $end_time); 
      $start_time = $end_time; 
     } 

     $i++; 
    } 
    echo "<hr/>"; 
} 

답변

2
  1. 정렬 모든 시작 시간을 기준으로 약속
  2. 무료 슬롯은

내가 당신을 제안

  • 무료 슬롯이 다음 약속 슬롯의 시작과 종료 이전 약속 슬롯 종료 시간 시작 사용 된 타임 스탬프.

  • +0

    감사합니다. 시간은 예제 일 뿐이며, 실제 코드는 타임 스탬프를 사용하고 있습니다. 문제는 가변적 인 상황입니다. 약속 시간은 자유 시간 전에 시작되지만 끝나기 전에 끝납니다. – DTownsend

    +0

    우리는 해결책을 찾을 수 있습니다. 요구 사항을 자세하게 자세히 설명해 주시겠습니까? –

    +0

    실제 비어있는 시간은 비어있는 시간 범위 내에서 약속 사이의 시간을 나타내는 시작/끝 시간의 배열이어야합니다. 즉. 자유 시간 - 9-10. 약속 830-930. 실제 자유 시간 - 930-10. 시스템은 자유 시간 범위 내에서 여러 약속을 처리해야하며, 전에 시작했지만 끝나는 약속과 그 중 시작하지만 끝나는 약속을 처리해야합니다. 이 경우 실제 자유 시간 시작은 약속의 끝이거나 실제 시간은 약속의 시작일 것입니다. – DTownsend

    관련 문제