100 년 생일 결합


26

나는 최근에 나와 내 아내와 아이들의 나이를 더하고 있었고, 그렇게 멀지 않은 미래의 어느 시점에서 우리 나이는 모두 정확히 100 년까지 늘어날 것이라는 것을 깨달았습니다.

도전

결합 된 (총) 연령과 생년월일 목록으로 구성된 입력의 경우 결합 된 연령이 모두 주어진 합계에 합산 된 날짜를 출력하십시오.

  1. 입력 결합 연령 (년)은 양의 정수입니다.
  2. 생년월일 입력 목록은 일, 월 및 연도의 숫자 표현을 포함해야하는 날짜 (언어에 편리한 형식) 목록입니다. 특정 에포크 (epoch) 이후의 일수는 허용되지 않습니다. 입력 날짜 목록이 시간순으로 정렬되어 있다고 가정 할 수 있습니다.
  3. 출력은 입력 날짜와 동일한 형식의 단일 날짜입니다.
  4. 결합 연령의 경우 1 년은 정확히 365.25 일로 간주됩니다.
  5. 일부 입력의 경우, 모든 생년월일이 모두 합쳐진 연령에 합산되면 모든 생년월일 이후의 날짜를 찾는 것은 불가능합니다. 예를 들어 20 년 간격 인 두 개의 생년월일을 고려하지만 10 년의 결합 날짜를 원합니다. 이 경우 출력은 더 높은 생년월일의 10 번째 생일이됩니다. 다시 말해, 개별 연령은 해당 개인의 생년월일 이전의 모든 날짜에 대해 0으로 간주됩니다
  6. 출력은 결합 연령 이 입력 연령 이상으로 합산 된 첫 번째 날짜입니다.
  7. 내장 함수를 사용할 수 있습니다
  8. 1970/01/01까지 거슬러 올라가는 날짜를 지원해야합니다.

여기서는 모든 날짜를 YYYY / MM / DD 형식으로 제공하지만 원하는 형식을 사용할 수 있습니다.

Input                                               Output

 10  2000/01/01                                     2010/01/01
100  1975/03/05,1978/07/23,2008/11/12,2012/12/20    2018/11/22
100  1975/03/06,1978/07/23,2008/11/12,2012/12/20    2018/11/23
100  1975/03/09,1978/07/23,2008/11/12,2012/12/20    2018/11/23
100  1975/03/10,1978/07/23,2008/11/12,2012/12/20    2018/11/24
  3  1990/08/01,1995/07/02                          1993/08/01
 50  1975/03/05,1978/07/23,2008/11/12,2012/12/20    2001/11/13

마지막 두 예에서 출력 날짜는 규칙 5에 따라 입력 날짜 범위 내에 있습니다.


1
@TimmyD. 규칙 7은 규칙 일 있으므로 원하지 않는 경우 따를 필요가 없습니다. 날짜-시간 함수가 입력 날짜를 구문 분석하고 출력 날짜를 형식화하는 데 유용 할 것으로 생각됩니다. YMMV.
Digital Trauma

5
규칙 7은 5 월 규칙입니다. 이번 달 (및 다음 반년)에는 무시해도됩니다.
Martin Ender

현실적으로, 나는 가족이 생일마다 몇 년을 정수로 세고 일을 요약하지 않으려 고 생각합니다 (질문을 복잡하게하기 위해 0.25).
edc65

@ edc65 누가 현실이 PPCG 도전에 방해가 되었습니까? ;-)
Digital Trauma

답변:


4

매쓰 138 107 237 바이트

나의 첫 시도는 조잡하고 합당하지 않았다. 테스트 사례에서와 같이 생년월일이 가장 빠른 순서로 제공되는 경우 일반적으로 작동합니다.

테스트 사례는 잘 선택되었고 올바르게 구현하기가 어렵습니다. 코드가 내가 기대했던 것보다 길었습니다.

일반적인 논리는

  1. x에서 각 생년월일까지의 거리가 목표 시간 경과 (예를 들어 100 년을 일로 변환)와 합치도록 x (일)를 구하십시오.
  2. 가장 빠른 날짜 + x 일> 가장 최근 생년월일 인 경우 가장 최근 생년월일을 제거하고 (1) 단계를 반복하십시오. 그렇지 않으면 (3)으로 이동하십시오.
  3. 반품 (최초 + x 일)

t_~f~d_:=If[DateDifference[a=DateObject[DatePlus[d[[1]],Solve[t 365.25==Tr@(x-Join[{0},
QuantityMagnitude@(DateDifference[d[[1]],#,"Day"]&/@Rest@d)]),{x}][[1,1,2]]]/.
{y_,m_,n_,h_}:>{y,m,n+1}],d[[-1]]]>Quantity[0,"Days"],f[t,Most@d],a]

테스트 사례

f[10, {{2000, 1, 1}}]
f[100, {{1975, 3, 5}, {1978, 7, 23}, {2008, 11, 12}, {2012, 12, 20}}]
f[100, {{1975, 3, 6}, {1978, 7, 23}, {2008, 11, 12}, {2012, 12, 20}}]
f[100, {{1975, 3, 9}, {1978, 7, 23}, {2008, 11, 12}, {2012, 12, 20}}]
f[100, {{1975, 3, 10}, {1978, 7, 23}, {2008, 11, 12}, {2012, 12,  20}}]
f[3, {{1990, 8, 1}, {1995, 7, 2}}]
f[50, {{1975, 3, 5}, {1978, 7, 23}, {2008, 11, 12}, {2012, 12, 20}}]

사진


또한 공간이 필요하지 않습니다.
LegionMammal978

1

PowerShell, 145125 바이트

param($a,$b)$c=@();$b|%{$c+=date $_};$t=$a*365.25;$d=$c[0];while($t-gt0){$c|%{if($_-le$d){$t--}};$d=$d.AddDays(1)}"{0:d}"-f$d

꽤 까다로운 도전이지만 한 번 이해하면 비교적 간단합니다.

확장 및 댓글 달기 :

param($a,$b)          # Take our input
$c=@()                # Make a new array $c
$b|%{$c+=date $_}     # Change our input array $b of strings into dates, store in $c
$t=$a*365.25          # Target number of days we need to account for
$d=$c[0]              # Our starting date, also our cumulative date for output
while($t-gt0){        # While we still have days remaining
  $c|%{               # Iterate through our birthdays
    if($_-le$d){$t--} # If the birthday is less than our cumulutive day, subtract a day
  }
  $d=$d.AddDays(1)    # We've accounted for another day, so increment our cumulative day
}
"{0:d}"-f$d           # Format output

예:

입력은 명시 적으로 형식화 된 문자열 날짜 표현 배열을 포함해야합니다. 출력 MM/DD/YYYY형식입니다 (PowerShell에서 en-us 지역화의 기본값).

PS C:\Tools\Scripts\golfing> .\combined-100-year-birthday.ps1 50 @('03/05/1975','07/23/1978','11/12/2008','12/20/2012')
11/13/2001

편집-생일을 반복하는 방식을 변경하고 할 때까지 동안을 사용하여 20 바이트 골프


0

PHP, 220 바이트

가독성을 위해 줄 바꿈을 추가했습니다.

function c($y,$s){for($d=$y*365.25;++$i<count($l=array_map(date_create,$s));)$d+=
$l[0]->diff($l[$i])->days;($l[$i-1]>$r=$l[0]->add(new DateInterval(P.ceil($d/$i).D)
))?c($y,array_slice($s,0,-1)):print$r->format('Y/m/d');}

Ideone

ungolfed 버전은 다음과 같습니다.

function printCombinedBirthday($combinedAgeInYears, $listOfBirthDatesStrings)
{
    $combinedAgeInDays = $combinedAgeInYears * 365.25;
    $listOfBirthDates = array_map('date_create', $listOfBirthDatesStrings);
    $numberOfBirthDates = count($listOfBirthDates);

    for ($i = 0; $i < $numberOfBirthDates; ++$i) {
        $combinedAgeInDays += $listOfBirthDates[0]->diff($listOfBirthDates[$i])->days;
    }

    $combinedAgeInDays = ceil($combinedAgeInDays / $numberOfBirthDates);
    $interval = new DateInterval('P'. $combinedAgeInDays .'D');
    $result = $listOfBirthDates[0]->add($interval);

    if ($listOfBirthDates[$numberOfBirthDates - 1] > $result)
    {
        printCombinedBirthday(
            $combinedAgeInYears,
            array_slice($listOfBirthDatesStrings, 0, -1)
        );
    }
    else {
        echo $result->format('Y/m/d');
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.