Kombine 100 yıl doğum günü


26

Geçenlerde kendimin, karımın ve çocuklarımın yaşlarını ekliyordum ve çok uzak olmayan bir gelecekte bir noktada yaşlarımızın tamamen 100 yıla kadar çıkacağını fark ettim.

Meydan okuma

Birleştirilmiş (toplam) yaş ve doğum tarihleri ​​listesinden oluşan bir girdi için, birleştirilmiş yaşların hepsinin belirtilen toplamı topladığı tarihi belirtin.

  1. Birleştirilmiş girdi yaşı (yıl olarak) pozitif bir tamsayı olacak
  2. Doğum tarihlerinin giriş listesi, Gün, Ay ve Yılı sayısal olarak temsil etmesi gereken tarihlerin bir listesi (dilinize hangi formatta uygunsa) olacaktır. Belirli bir çağdan beri gün sayısı kabul edilemez. Giriş tarihlerinin listesinin kronolojik sıraya göre sıralandığını varsayabilirsiniz.
  3. Çıktı, giriş tarihleri ​​ile aynı formatta tek bir tarih olacaktır.
  4. Birleşik yaşın amaçları doğrultusunda, 1 yıl tam olarak 365.25 gün olarak kabul edilir.
  5. Bazı girdiler için, bütün doğum tarihlerinden sonra birleşik yaşlara eklendiklerinde bir tarih bulmak mümkün olmayacaktır. Örneğin, 20 yıl arayla iki doğum tarihi düşünün, ancak 10 yıl bir araya gelmesini istiyoruz. Bu durumda, çıktı eski doğum tarihinin 10. doğum günü olur. Diğer bir deyişle, bireyin yaşından önceki tüm tarihler için bireysel yaş 0 olarak kabul edilir.
  6. Çıktı, birleştirilmiş yaşların en azından giriş yaşına kadar topladığı ilk tarih olacaktır.
  7. Yerleşik işlevlerini kullanabilirsiniz
  8. 1970/01 / 01'e kadar uzanan tarihleri ​​desteklemelisiniz.

Örnekler

Burada tüm tarihleri ​​YYYY / AA / GG formatında veriyorum, ancak istediğiniz formatı seçebilirsiniz.

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

Son iki örnekte, çıkış tarihinin kural 5 uyarınca giriş tarihleri ​​aralığında olduğunu unutmayın.


1
@TimmyD. Kural 7 bir olduğunu olabilir size istemediğiniz takdirde bunu takip etmek zorunda kalmamak, kural. Tarih-zaman fonksiyonlarının, giriş tarihlerinin ayrıştırılması ve çıkış tarihlerinin formatlanması için faydalı olacağını düşünüyorum. YMMV.
Dijital Travma

5
Kural 7, bir Mayıs kuralıdır. Bu ay güvenli bir şekilde göz ardı edilebilir (ve sonraki yarım yıl için)
Martin Ender

Gerçekçi olarak, bir ailenin her doğum gününü kontrol edip yıllarca tamsayı olarak saydığını ve günleri toplamaya çalışmadığını (maddeyi zorlaştırmak için 0.25 ile) olacağını düşünüyorum.
edc65

@ edc65 Gerçekliğin iyi bir PPCG mücadelesine girmesine kim izin verdi? ;-)
Digital Trauma

Yanıtlar:


4

Mathematica 138 107 237 bayt

İlk girişimlerim özensiz ve değersizdi. Bu, genel olarak, doğum tarihlerinin test vakalarında olduğu gibi en erken sırayla verilmiş olması koşuluyla çalışmalıdır.

Test vakaları iyi seçildi ve doğru uygulanması zordu. Kod umduğumdan çok daha uzun sürdü.

Genel mantık

  1. X için (gün cinsinden) x'in her doğum tarihine olan mesafesinin hedef zaman geçişine (örn. Günlere dönüştürülmüş 100 yıl) kadar toplanacağı şekilde çözün.
  2. En erken tarih + x gün> son doğum tarihini gösteriyorsa, son doğum tarihini kaldırın ve (1) numaralı adımı tekrarlayın, Başka seçeneğe (3) gidin.
  3. İade (en erken tarih + x gün)

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]

Test Kılıfları

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}}]

Resimler


Ayrıca, boşluğa ihtiyacınız yok.
LegionMammal978

1

PowerShell, 145 125 Bayt

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

Oldukça hileci bir meydan okuma, ancak bir zamanlar anlaşılan nispeten basit.

Genişletilmiş ve Yorumlanan:

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

Örnek:

Girişin açıkça biçimlendirilmiş bir dizi tarih gösterimi içermesi gerekir. Çıktı MM/DD/YYYYbiçiminde (PowerShell'de yerelleştirme için varsayılan ayar).

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

Düzenleme - Doğum günleri boyunca yinelememizi değiştirerek ve bunu yapmak için / yerine


0

PHP, 220 bayt

Okunabilirlik için bazı yeni satırlar ekledim.

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

İşte ungolfed versiyonu:

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');
    }
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.