รวมวันเกิดครบ 100 ปี


26

เมื่อเร็ว ๆ นี้ฉันได้เพิ่มอายุตัวฉันและภรรยาและลูก ๆ ของฉันและตระหนักว่าในบางจุดในอนาคตที่ไม่ไกลเกินไปทุกวัยของเราจะเพิ่มขึ้นเป็น 100 ปี

ท้าทาย

สำหรับอินพุตประกอบด้วยอายุ (ทั้งหมด) รวมและรายการวันเดือนปีเกิดเอาท์วันที่ซึ่งรวมอายุทั้งหมดเพิ่มขึ้นรวมทั้งหมด

  1. อินพุตที่รวมอายุ (เป็นปี) จะเป็นจำนวนเต็มบวก
  2. รายการป้อนข้อมูลของวันเกิดจะเป็นรายการ (รูปแบบใดก็ตามที่สะดวกสำหรับภาษาของคุณ) ของวันที่ที่ต้องมีการแสดงตัวเลขของวันเดือนและปี จำนวนวันตั้งแต่ยุคที่เฉพาะเจาะจงไม่เป็นที่ยอมรับ คุณอาจคิดว่ารายการวันที่ป้อนเข้าจะเรียงตามลำดับเวลา
  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 เป็นกฎเดือนพฤษภาคม สามารถละเว้นได้อย่างปลอดภัยในเดือนนี้ (และสำหรับครึ่งปีถัดไป)
Martin Ender

จริง ๆ แล้วฉันคิดว่าครอบครัวจะตรวจสอบวันเกิดของแต่ละคนนับปีเป็นจำนวนเต็มและไม่พยายามสรุปจำนวนวัน (ด้วย 0.25 เพื่อทำให้เรื่องซับซ้อน)
edc65

@ edc65 ใครเคยปล่อยให้ความเป็นจริงเข้าสู่ความท้าทาย PPCG ที่ดี? ;-)
Digital Trauma

คำตอบ:


4

Mathematica 138 107 237 ไบต์

ความพยายามครั้งแรกของฉันเลอะเทอะและไม่คู่ควร สิ่งนี้ควรใช้งานได้ดีโดยมีเงื่อนไขว่าวันเดือนปีเกิดจะถูกจัดเรียงอย่างเร็วที่สุดเช่นในกรณีทดสอบ

กรณีทดสอบถูกเลือกอย่างดีและใช้งานได้ยาก รหัสเปิดออกนานกว่าที่ฉันคาดไว้

ตรรกะทั่วไปคือการ

  1. หาค่า x (เป็นวัน) เพื่อให้ระยะทางจาก x ถึงวันที่เกิดแต่ละครั้งจะเท่ากับระยะเวลาเป้าหมาย (เช่น 100 ปีเปลี่ยนเป็นวัน)
  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, 145 125 ไบต์

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)

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

นี่คือรุ่นที่ไม่ได้แต่งแต้ม:

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.