合計100歳の誕生日


26

私は最近、自分と妻と子供の年齢を合計していましたが、それほど遠くない将来のある時点で、私たちの年齢はすべて正確に100年になると気付きました。

チャレンジ

合計(合計)年齢と生年月日のリストで構成される入力の場合、合計年齢が指定された合計に達する日付を出力します。

  1. 入力された年齢(年)は正の整数になります
  2. 誕生日の入力リストは、日、月、年の数値表現を含む必要がある日付のリスト(言語に都合のよい形式)になります。特定のエポックが受け入れられないための日数。入力日付のリストは時系列でソートされていると想定できます。
  3. 出力は、入力日付と同じ形式の単一の日付になります
  4. 複合年齢の場合、1年は正確に365.25日と見なされます
  5. 一部の入力では、すべての生年月日が合計年齢に達すると、すべての生年月日の後に日付を見つけることができなくなります。たとえば、20年離れた2つの生年月日を検討しますが、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

最後の2つの例では、ルール5に従って、出力日付が入力日付の範囲内にあることに注意してください。


1
@TimmyD。規則7があることが、あなたがしたくない場合は、それに従う必要はありませんので、ルール。日付時刻関数は、入力日付の解析および出力日付の書式設定に役立つと思われます。YMMV。
デジタル外傷

5
ルール7は5月のルールです。今月(および次の半年)は無視しても問題ありません。
マーティンエンダー

現実的には、家族は誕生日を毎回チェックし、年を整数としてカウントし、日を合計しようとしないと考えています(0.25で問題を複雑にします)。
edc65

@ edc65誰が現実に良いPPCGチャレンジの邪魔をさせたのでしょうか?;-)
デジタル外傷

回答:


4

Mathematicaの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の、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での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

編集-誕生日の反復方法を変更し、do / untilの代わりにwhileを使用して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.