牛乳は期限切れですか?


98

ああ、この有効期限は月を文字で書かない!私はそれが3月10か10月3日に期限が切れるなら...教えていない、気にしないで、待つことができない、今年は言う2012年(路地-おっとプロが好きなことができますゴミ箱にチーズのレンガを半使用)

したがって、しばらくの間、このマリナラの瓶が期限切れになると推測するのに忙しすぎると仮定しましょう。クリフノーツバージョンが必要なだけです。期限が過ぎている可能性はどのくらいですか。いくつかのコードを書きましょう!

製造元は、次の3つの形式のいずれかで、順序付けされた整数のトリプルとして日付を印刷することを知っています。

YEAR  MONTH DAY
MONTH DAY   YEAR
DAY   MONTH YEAR

また、一部の日付は3つすべてではなく、1つまたは2つの方法でしか解釈できないことを知っています。55 55-11-5インチは1年である必要があります。 2つではなく、いくつかのオプションを除外できます。ただし、2桁の場合、50..99は1950..1999を意味し、0..49は2000..2049を意味します。

あなたの仕事は、上記の解釈の少なくとも1つで有効な日付である整数の配列を取り、それがまだ良い確率を出力するプログラムまたは関数を書くことです。可能性の割合は、単に今日の日付以降の日付の有効な解釈の割合です。

整数の配列は[Int]、関数への引数の場合、言語の長さ3 のタイプになり、STDINの入力として使用される場合、ダッシュ、スラッシュ、またはスペースで区切られた(選択する)整数として与えられます。完全なプログラム。*

「今日の日付」は、日付関数を介して取得した今日の実際の日付、または関数への追加の引数またはSTDINの追加のパラメーターで指定した日付にすることができます。Unixエポック秒、上記の3つの方法のいずれかで入力された別の年月日トリプル、または別のより便利な方法があります。

いくつか例を挙げましょう!有効期限の入力はダッシュで区切られたスタイルになり、以下の例では、今日の日付が2006年7月5日であると想定しています。

  • 14-12-14-これに対する有効な解釈(DMYとYMD)はどちらも同等です(2014年12月14日)。この製品は間違いなく優れているため、出力は100です。
  • 8-2-2006-最後の数字は4桁なので、確かに1年です。これは、2月8日(期限切れ)または8月2日(まだ良い)のいずれかです。出力は50です。
  • 6-7-5-これは何でもいい!「2006年7月5日」の解釈は依然として良好です(1日のみ)が、残りの2つは両方とも2005年であり、できるだけ早く投げるべきです。出力は33です。
  • 6-5-7-ここでは、3つの解釈のうち2つが安全です。小数を切り上げまたは切り捨てることができるため、66または67の両方で問題ありません。
  • 12-31-99-さて、これは世紀の変わり目から明白です(50から99の年は19XXであり、31は月ではない可能性があります)。大きな脂肪0で、冷蔵庫をもっと頻繁に掃除する必要があります。

上記の基準を満たしていない入力は、上記の出力ルールに含まれていないとみなしても安全です。

Webリクエストや標準の抜け穴はありません。日付処理ライブラリが許可されています。これはコードゴルフです。最短のプログラムが勝つかもしれません。

* Brainfuckまたは同様のデータ型ハンディキャップ言語を使用している場合、入力の最初の3文字のASCII値が日付の整数であると想定できます。確かに、これは4桁の年のロジックを除外しますが、Brainfuckでこれに対する解決策を見れば、あなたを軽視するにはあまりにも驚かされると思います。


39
うーん...現在の年は2006年ではなく2014年です。あなたの牛乳はせいぜいその有効期限を8年過ぎています。
ジョン・ドヴォルザーク

11
@JanDvorak意味のあるサンプルを作成するために一生懸命やりたくなかったので、今日の日付を調整して簡単にしました。
algorithmshark 14

7
@ Dgrin91気にしない、私はまだそれらを食べます:D
aditsu 14

6
オーストラリアでは、牛乳は日付までに使用する約1週間前に失効します
ニブラー14

5
有効な日または月にはなり得ないため、00を含むテストを追加する必要があります。
MtnViewMark 14

回答:


5

k4 (90) (88) (87)(82)

{100*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(x<100)*100*19+x<50}.'y@/:3 3#.:'$21020101}

今日と比較するためにxof .z.D(組み込み)を呼び出すか、そうでない場合は選択した日付リテラルを呼び出します。

  f:{100*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(x<100)*100*19+x<50}.'y@/:3 3#.:'$21020101}
  .z.D f'(14 12 14;8 2 2006;6 7 5;6 5 7;12 31 99)
100 0 0 0 0f
  2006.07.05 f'(14 12 14;8 2 2006;6 7 5;6 5 7;12 31 99)
100 50 33.33333 66.66667 0

これは基本的に@ Alex-lのPythonソリューションの移植であり、いくつかのその他のゴルフトリックが追加されています。

  • 再配置命令は文字列にエンコードされ、数文字を節約します。
  • 条件付きロジック(ab)は、integer-as-integerを使用します(ただし、Pythonソリューションとは異なります)。
  • 妥当性テストはわずかに異なります。k4/ qは任意の文字列を任意のデータ型に喜んで解析します。意味をなさない場合は、nullを返します。したがって、内部関数から日付のリストを返します。これは、nullである場合とそうでない場合があります。
  • 最終結果は、可能な日付の解釈の数がnullであるか、比較の日付よりも少ないかをチェックすることから得られます。ここでは、null日付が他のどの日付よりも小さいと見なされることが重要です。

1
アイテムを周期的に取得する"012201210"ため、から最後の0を削除することにより、文字を保存できます#。実際、最後の2つのケースを交換することにより、この方法で2番目の文字を保存できます3 3#.:'"0122102"
algorithmshark 14

内側の関数の引数を逆にして、括弧を保存することにより、もう1つの文字を剃りました(ただし、逆を追加しました)。誰かが別の2つの文字を保存するのを手伝ってくれますか?APLが私を打ち負かしています!
アーロンデイヴィス14

最後に数学を書き直して、さらに5人を剃りました。リードを取り戻す!
アーロンデイヴィス14

そして、もし私が真剣に機能しないコードを書くことを急いでいるなら、グローバル名前空間を汚染することでもう一つのバイトを削ることができます:{c*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(c*19+x<50)*x<c::100}.'y@/:3 3#.:'$21020101}
アーロンデイヴィス14

14

ルビー、115文字

f=->a,t{[a,a.rotate(~s=r=0),a.reverse].map{|x,*y|(t>Time.gm(x<100?x+2e3-100*x/=50:x,*y)||r+=100
s+=1)rescue p}
r/s}

これはf、入力を含む配列と「今日の」日付の2つの引数を取る関数を定義します。

例:

f[[14,12,14], Time.new]
100
f[[8,2,2006], Time.new]
0
f[[8,2,2006], Time.new(2006, 7, 5)]
50
f[[6,7,5], Time.new(2006, 7, 5)]
33

12

Python 2.7-172

日付の有効性と比較のためにdatetimeモジュールを使用します。date入力から有効な日時を作成できない場合は、を発生させValueErrorます。この方法sは、有効期限のない日付tの合計であり、有効な日付の総数です。私はTrue == 1、Pythonでの追加とインデックス作成の目的のためにそれを利用しています。また、(1900,2000)の代わりに25 *(76,80)を使用してキャラクターを保存します。

インデントの第2レベルの行では、2つのスペースではなくタブ文字が使用されていることに注意してください。

def f(e,c,s=0,t=3):
 for Y,M,D in(0,1,2),(2,0,1),(2,1,0):
  y=e[Y]
  try:s+=date(y+25*[[76,80][y<50],0][y>99],e[M],e[D])>=c
  except:t-=1
 return 100*s/t

これを最後に追加してテストします。

examples = [[14,12,14],[8,2,2006],[6,7,5],[6,5,7],[12,31,99]]
for e in examples:
 print f(e, date(2006,7,5))

10

PowerShellの、183 173 168

[int](100*(($d=@(($a,$b,$c=$args[0]),($c,$a,$b),($c,$b,$a)|%{$_[0]+=1900*($_[0]-le99)+100*($_[0]-le49)
.{date($_-join'-')}2>$x}|sort -u))-ge(date)+'-1').Count/$d.Count)
  • int[]パラメータを介した入力、たとえば

    PS> ./milk.ps1 5,6,7
    
  • エラーメッセージは、stderrでの出力が許可されているかどうかわからない限り、try/ を介して沈黙しますcatch
  • 現在の日付を1日ずらす+"-1"よう.AddDays(-1)に解釈される日付で使用し、昨日と比較できるようにします(今日だけではなく)。これにより、時刻が0:00の日付を取得するが、今日からの日付と比較する必要があるという問題が解決されます。
  • 今までに大きくインライン化
  • かなり短いエラー消すための新しいトリックを使用する

6

R、269

Rではこれは簡単だと思っていましたが、1桁の年はかなり大きなカーブボールでした。これはそれよりもはるかに優れていると思います。

lubridateはCRANのパッケージであるため、を使用してインストールする必要がありますinstall.packages("lubridate")

require(lubridate)
f = function(d){
d=sapply(d,function(l)if(nchar(l)==1)sprintf("%02d",l)else l)
d=paste0(d,collapse="-")
t=ymd(Sys.Date())
s=na.omit(c(ymd(d),mdy(d),dmy(d)))
s=lapply(s,function(d){
if(year(d)>2049){year(d)=year(d)-100;d}
else d})
sum(s>t)/length(s)}

使用法:整数のベクトルです。f(c(d1,d2,d3))c(d1,d2,d3)

たとえばを f(c(6,10,14))返します0.3333333

lubridateパッケージには、異なる順序で日付を解析するためのラッパー関数のシリーズを持っています。これらを使用して、有効な日付を生成する形式を確認し、無効な日付を除外してから、まだ発生していない日付を確認します。


6

Mathematica、163 153 164バイト

編集: 1950年から2049年の範囲外の日付を修正)

f=100.Count[#,x_/;x<1]/Length@#&[DateDifference[#,Date[]]&/@Cases[{If[#<100,Mod[#+50,100]+1950,#],##2}&@@@{{##},{#3,#2,#},{#3,#,#2}}&@@#,d_/;DateList@d~Take~3==d]]&

これは、次のように呼び出すことができる関数を定義します

f[{6,7,5}]

現在、パーセンテージは丸められていません(OPが明確になるのを待っています)。

ここでは任意のMathematicaの知識がなくても理解できるはずです少し長い説明(ノートで&パラメータ無名関数が呼ばれ、それを左にすべてのものを作る##2#3...)は:

{{##},{#3,#2,#},{#3,#,#2}}&

これは、3つのパラメーターa,b,cを3つのリストに変換する関数を定義します{{a,b,c},{c,b,a},{c,a,b}。これ##はすべてのパラメーターのシーケンスにすぎないことに注意してください。

{{##},{#3,#2,#},{#3,#,#2}}&@@#

有効期限に適用する{y,m,d}と、3つの可能な順列それぞれのリストが得られます。

{If[#<100,Mod[#+50,100]+1950,#],##2}&

これは、3つのパラメータを取り匿名関数であるa,b,cとの数字:最初は、与えられたルールに従って年間に換算されていて、3のリストを返し、50そして99(モジュロは100)20世紀の年になっている、数字の間049( modulo 100)は21世紀の年になり、他のすべては残されます。以下##2は、2番目のパラメーターで始まるパラメーターのシーケンスですb,c

{If[#<100,Mod[#+50,100]+1950,#],##2}&@@@{{##},{#3,#2,#},{#3,#,#2}}&@@#

これまでの3つの結果のそれぞれに適用され、これは単に年形式を標準化します。これcanonicalDatesを呼び出して、次の式を短くしましょう。

Cases[canonicalDates,d_/;DateList@d~Take~3==d]

これにより、無効な解釈が除外されます。さまざまな日付形式をDateList@d完全に{y,m,d,h,m,s}表現します。リストを同じ順序で解釈しますが、キャッチするのは、その場合に計算するようなもの渡すことができるということです。したがって、返されたリストの最初の3つの要素が入力と同一であることを確認します(これは、月と日が適切な範囲にある場合にのみ発生します)。{8,2,2006}8 years + 2 months + 2006 days

次の行を短くするために、この式の結果を今後参照しますvalidDates

DateDifference[#,Date[]]&

日付を取り、今日までの日数の差を返す別の匿名関数(から取得Date[])。

DateDifference[#,Date[]]&/@validDates

それを有効な日付解釈にマッピングします。

100.Count[#,x_/;x<1]/Length@#&

リスト(#)が与えられると、そのリスト内の正でない数の割合を返すさらに別の匿名関数。.結果として有理数を回避するために、乗算ちょうど十進数ではない(あなたは次のようなものを取得したい100/3の代わりに33.333-それが問題だ場合、私は実際には知りません)。

100.Count[#,x_/;x<1]/Length@#&[DateDifference[#,Date[]]&/@validDates]

日付の違いのリストに適用すると、これにより、まだ期限切れになっていない解釈の割合がわかります。


2999や2099のような年を1999年に誤って変換すると思います。
Ventero 14

@Venteroそれは本当です。1950年から2049年(およびその1桁または2桁のバージョン)のみを扱っていたと思いますが、その課題については読み直せません。
マーティンエンダー14

@Venteroが修正されました(しかし、とにかくすでにかなり私をsignificantly打していました;))
マーティンエンダー14

Mathematicaのアカウントを持っているが、質問や回答がまだ投稿されていないことに驚いています。何かがあなたを妨げていますか?
ミスターウィザード14

@ Mr.Wizard申し訳ありませんが、完全にあなたに返信するのを忘れていました。質問:これまでのところ、グーグル/その他のSEの質問で解決できたすべての問題。回答:私は私のように自分自身を見ていないと思います...知らないこと、それは生産Mathematicaを使用することになると...私は唯一の迅速あちこちスニペット(およびコードゴルフ)のためにそれを使用堪能。また、質問に答えるために、新しい質問を積極的に監視して、答えを確認する必要があります。現在、すべてのSE時間はPPCGに割り当てられています。;)他の方法で私を説得したい場合は、チャットで気軽にそうしてください!:)
マーティンエンダー14

4

JavaScript(E6)159164172

編集ヒントと、もう一度考えさせてくれたnderscoreに感謝します。Dを再編成してパラメーターを回避し、一部の文字をカットしました。

編集2 nderscoreによる別のトリック、2つの関数が1にマージされました。その後、2つの括弧が削除され、カンマ区切りの式が1つにマージされました。読みやすさ:0

F=(a,t)=>t?100*(3-((i=F([y,m,d]=a))<t)-((j=F([m,d,y]=a))<t)-((k=F([d,m]=a))<t))/(3-!i-!j-!k)|0:(q=new Date(y<50?y+2e3:y,--m,d)).getMonth()==m&q.getDate()==d&&q

FireFoxコンソールでテストする

;[[14,12,14],[8,2,2006],[6,7,5],[6,5,7],[12,31,99]]
.map(x=>x + ' ' + F(x, new Date(2006,6,5)))

出力:

["14,12,14 100", "8,2,2006 50", "6,7,5 33", "6,5,7 66", "12,31,99 0"]

非ゴルフ

NB D関数は、指定された年、月、日で日付を作成しようとしますが、作成された日付が意図したものではない場合(!=日または月)にfalseを返します

F=(d,t)=>
(
  D=(y,m,d)=>(
    q=new Date(y<50?y+2000:y, --m, d), // decr m as javascript (like java) counts months starting at 0
    q.getMonth() == m & q.getDate() == d && q
  ),
  [a,b,c] = d, 
  x=D(...d), // three ways of express the date ...
  y=D(c,a,b),
  z=D(c,b,a),
  100 * (3-(x<t)-(y<t)-(z<t)) / (3-!x-!y-!z) | 0  
)   

@nderscore Dの変更はOK、もう一方はsintaxエラー。しかし、さらに、とにかく保存
edc65

奇妙な。コメントに貼り付けたときに何かが起こったに違いありません。あなたの最新の最適化は:)しかし、それは無関係作る
nderscore

1
SEのコメントがもう信用できないので、これを貼り付けます。(-3)pastie.org/private/6bemdweyndcaiseay70kia
nderscore 14

4

LINQPadのC# - 446 408 272のバイト

第三の編集: DateTime.NowではなくDateTime.Todayが正しいことを指摘してくれたLe Canard fouに感謝します。 2番目の編集:この賢い解決策をVisualMelonに感謝します!

void g(int[]d){var p=".";int a=d[2],b=d[1],e=d[0],y=a+(a<100?a>49?1900:2000:0),q=0,s=0;DateTime c;Action<string>z=x=>{if(DateTime.TryParse(x,out c)){s++;if(c>=DateTime.Today)q+=100;}};z(e+p+b+p+y);z(b+p+e+p+y);z(a+p+b+p+(e<100?‌​e>49?1900+e:2000+e:e));(q/(s>0?s:1)).Dump();}

編集:コードの短縮を支援してくれたpodiluskaとedc65に感謝します!また、年の入力が4バイト長の場合、私の解決策が正しくないことに気づいたため、その問題の修正を含めました。このソリューションのスコアは408バイトです。

以前の回答のいずれも破っていませんが、C#ソリューションを共有したかったのです。どんな助け/提案も大歓迎です!;)

void g(int[]d){var q=new List<DateTime>();var p=".";int s=0,a=d[2],b=d[1],e=d[0],y=0;var c=new DateTime();y=(a<100)?(a>49)?1900+a:2000+a:a;if(DateTime.TryParse(e+p+b+p+y,out c)){q.Add(c);s++;}if(DateTime.TryParse(b+p+e+p+y,out c)){q.Add(c);s++;}y=(e<100)?(e>49)?1900+e:2000+e:e;if(DateTime.TryParse(a+p+b+p+y,out c)){q.Add(c);s++;}q=q.Where(i=>i>=DateTime.Now).ToList();if(s==0){s=1;}(q.Count*100/s).Dump();}

フォーマットされていないバージョン:

void g(int[] d)
    {
        var q = new List<DateTime>();
        var p = ".";
        int s = 0, a = d[2],b = d[1],e = d[0], y=0;
        var c = new DateTime();
        y = (a < 100) ?((a > 49) ? 1900 + a : 2000 + a) : a;

        if (DateTime.TryParse(e + p + b + p + y, out c))
        {
            q.Add(c);
            s++;
        }
        if (DateTime.TryParse(b + p + e + p + y, out c))
        {
            q.Add(c);
            s++;
        }
        y = (e < 100) ? ((e > 49) ? 1900 + e : 2000 + e) : e;

        if (DateTime.TryParse(a + p + b + p + y, out c))
        {
            q.Add(c);
            s++;
        }
        q = q.Where(i => i >= DateTime.Now).ToList();
        if (s == 0)
        {
            s = 1;
        }
        (q.Count*100/s).Dump();
    }

「DateTime.TryParse」パートがこのソリューションのように繰り返されないソリューションを作成しようとしましたが、21バイト長くなりました。

「DateTime.TryParse」を繰り返さないソリューション:467バイト

void g(int[]d){var q=new List<DateTime>();int s=0;int a=d[2];int b=d[1];int e=d[0];int y=0;if(a<100){if(a>49){y=1900+a;}else{y=2000+a;}}if(z(e,b,y,q)){s++;}if(z(b,e,y,q)){s++;}if(e<100){if(e>49){y=1900+e;}else{y=2000+e;}}if(z(a,b,y,q)){s++;}q=q.Where(i=>i>=DateTime.Now).ToList();if(s==0){s=1;}(q.Count*100/s).Dump();}bool z(int a,int b,int d,List<DateTime> q){var c=new DateTime();var p=".";if(DateTime.TryParse(a+p+b+p+d,out c)){q.Add(c);return true;}return false;}

ゴルフされていないバージョン:

private void g(int[] d)
    {
        var q = new List<DateTime>();
        int s = 0;
        int a = d[2];
        int b = d[1];
        int e = d[0];
        int y = 0;
        if (a < 100)
        {
            if (a > 49)
            {
                y = 1900 + a;
            }
            else
            {
                y = 2000 + a;
            }
        }
        if (z(e, b, y, q))
        {
            s++;
        }
        if (z(b, e, y, q))
        {
            s++;
        }
        if (e < 100)
        {
            if (e > 49)
            {
                y = 1900 + e;
            }
            else
            {
                y = 2000 + e;
            }
        }
        if (z(a, b, y, q))
        {
            s++;
        }
        q = q.Where(i => i >= DateTime.Now).ToList();
        if (s == 0)
        {
            s = 1;
        }
        (q.Count*100/s).Dump();
    }

    private bool z(int a, int b, int d, List<DateTime> q)
    {
        var c = new DateTime();
        string p = ".";
        if (DateTime.TryParse(a + p + b + p + d, out c))
        {
            q.Add(c);
            return true;
        }
        return false;
    }

2
int s=0;int a=d[2];int b=d[1];int e=d[0];->int s=0,a=d[2],b=d[1],e=d[0];
podiluska 14

2
提案:(三使用:)可能な場合は代わりに/他の場合はどうなりますか?
edc65

1
しゅう yには2つの異なる値があり、1回はaに依存し、もう1回はeに依存すると考えています。とにかくありがとう!
tsavinho 14

1
DateTime.TryParse呼び出しを削除することは私の最初の直感であり、値をqに戻すラムダに置き換えました。また、他のいくつかの手順を実行し(ペーストビン)328charsを取得する:void g(int[]d){var q=new List<DateTime>();var p=".";int a=d[2],b=d[1],e=d[0],y;DateTime c;y=(a<100)?(a>49)?1900+a:2000+a:a;Action<string>z=(x)=>{if(DateTime.TryParse(x,out c))q.Add(c);};z(e+p+b+p+y);z(b+p+e+p+y);y=(e<100)?(e>49)?1900+e:2000+e:e;z(a+p+b+p+y);(q.Where(i=>i>=DateTime.Now).Count()*100/(q.Any()?q.Count:1)).Dump();}
VisualMelon

1
@VisualMelonうわー、あなたは本当にコードゴルフが得意です!私は見たことがないAction<string>ので、私はあなたから何かを学ぶことができ、前;)私は置き換えることにより、318文字までのあなたの答えを得ることができた q.Where(i=>i>=DateTime.Now).Countq.Count(i=>i>=DateTime.Now。また、角かっこを削除したxので、さらに2文字を保存できました!
tsavinho

3

Haskell、171 165文字

l=length
r y|y<100=(y+50)`mod`100+1950|y>0=y
q d m y z|d<32&&m<13&&d*m>0=(r y,m,d):z|1<3=z
v(a,b,c)=q c b a$q b a c$q a b c[]
t%d=(l$filter(>t)(v d))*100`div`l(v d)

関数の名前は%です。実際の年を使用した正規の(y、m、d)順序のタプルとしてのテスト日付と、3つの数字のタプルとしてのカートンスタンプを使用して実行します。

λ: (2006,6,5)%(14,12,14)
100

λ: (2006,6,5)%(8,2,2006)
50

λ: (2006,6,5)%(6,7,5)
33

λ: (2006,6,5)%(6,5,7)
66

λ: (2006,6,5)%(12,31,99)
0

λ: (2006,6,5)%(0,1,7)
0

2

アーラン、146

f([A,B,C]=U,N)->F=[T||T<-[{(Y+50)rem 100+1950,M,D}||[Y,M,D]<-[U,[C,A,B],[C,B,A]]],calendar:valid_date(T)],100*length([1||T<-F,T>=N])div length(F).

テスト機能は次のとおりです。

t() ->
    0 = f([12,31,99],{2006,6,5}),
    66 = f([6,5,7],{2006,6,5}),
    33 = f([6,7,5],{2006,6,5}),
    100 = f([14,12,14],{2006,6,5}),
    50 = f([8,2,2006],{2006,6,5}),
    100 = f([29,2,2],{2006,6,5}).

非ゴルフ

f([A,B,C]=U,Today)->
    Perms = [U,[C,A,B],[C,B,A]],
    WithYears = [{(Y+50) rem 100+1950,M,D} || [Y,M,D] <- Perms],
    ValidDates = [T || T <- WithYears, calendar:valid_date(T)],
    100*length([1 || T <- ValidDates, T >= Today]) div length(ValidDates).

このソリューションは、リストの内包に依存しています。Haskellソリューションからその年のモジュロトリックを借りています。またcalendar:valid_date/1、特定の月の日数のために不可能な日付を処理するために使用します(たとえば、「29-2-2」はYMD形式のみです)。また、TodayはErlangのdate()形式(YMDタプル)です。


2

APL(85)

これは、Dyalog APL 14の新しい関数の一部を使用しますが、外部ライブラリは使用しません。変更については、TryAPLで機能します

{100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵}

これは、右側の()引数として3要素配列を、左側の()引数としてチェックする日付をYYYYMMDD形式の整数として受け取る関数です。つまり、日付2014-07-09は数値として表され20140709ます。

テスト:

      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 14 12 14
100
      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 8 2 2006
50
      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 6 7 5
33.3333
      20060705 {100×(+/÷⍴)⍺≤{(3/100)⊥⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵}¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵} 12 31 99
0

説明:

  • Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵:与えられた日付をひっくり返すか(⊂⌽⍵)、左に2回転する(⊂2⌽⍵)か、何もしないことでYMD形式に変えます⊂⍵。現在、これらの少なくとも1つはYMD形式の適切な日付であり、日付があいまいな場合は複数の日付になる可能性があります。
  • {∧/12 31≥1↓⍵}¨Z:各日付が有効かどうかをテストします。年(最初の要素)が削除され、月が12以下、日が31以下でなければなりません。
  • Z/⍨:から有効な日付をフィルタリングしますZ
  • {... :有効な日付ごと:
    • ⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵:年が99より大きくない場合は1900を追加し、年が50より低い場合は100を追加します。
    • (3/100)⊥:100を底とする数字のセットであるかのようにデコードします。(年は100を超えていますが、これは最初の要素なので重要ではありません。)これにより、有効な日付ごとに、左引数と同じ形式で数値が与えられます。
  • ⍺≤:日付ごとに、それがより小さいかどうかを確認します。これは、1がOK0を意味するバイナリベクトルを提供しspoiledます。
  • 100×(+/÷⍴):バイナリベクトルの合計をその長さで除算し、100で乗算します。

座礁し、暗黙の内部機能を作ると7つのバイトを保存(そして素敵なマージンでKを打つ):{100×(+/÷⍴)⍺≤((3/100)⊥⊢+(99≥⊃)×3↑1900+100×50>⊃)¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⌽⍵)(2⌽⍵)⍵}
アダム

0

Java:349文字(3つのスペースなし)

int e(int[]n,Date t){int a=n[0],b=n[1],c=n[2];Date[]d=new Date[3];if(b<13&&c<32)d[0]=new Date((a<50?100:(a>100?-1900:0))+a,b-1,c);if(b<13&&a<32)d[1]=new Date((c<50?100:(c>100?-1900:0))+c,b-1,a);if(a<13&&b<32)d[2]=new Date((c<50?100:(c>100?-1900:0))+c,a-1,b);int v=0,g=0;for(int i=0;i<3;i++)if(d[i]!=null){if(!d[i].before(t))g++;v++;}return 100*g/v;}

これは、テストのために使用できる包含クラスで、メソッドの(わずかに)デゴルフされたバージョンを含みます。

import java.util.*;
class i{

   int e(int[]n,Date t){
      int a=n[0],b=n[1],c=n[2];
      Date[]d=new Date[3];
      if(b<13&&c<32)d[0]=new Date((a<50?100:(a>100?-1900:0))+a,b-1,c);
      if(b<13&&a<32)d[1]=new Date((c<50?100:(c>100?-1900:0))+c,b-1,a);
      if(a<13&&b<32)d[2]=new Date((c<50?100:(c>100?-1900:0))+c,a-1,b);
      int v=0,g=0;
      for(int i=0;i<3;i++)
         if(d[i]!=null){
            if(!d[i].before(t))
               g++;
            v++;
         }
      return 100*g/v;}

   public static void main(String[] args){
      int[]i=new int[3];
      for(int k=0;k<3;k++)
         i[k] = Integer.parseInt(args[k]);
      int j = new i().e(i,new Date());
      System.out.println(j+"%");
   }   
}

これはコードゴルフの最初のラウンドであり、Javaゴルファーをあまり多く見ない理由がわかったと思います。


1
int[]引数としてではなく、3 を受け入れる必要がありintます。
ジョーイ14

わかった、修正した。
shieldgenerator7 14

0

C#287バイト

namespace System{class E{static float a,o,l;void M(int[]i){int d=i[0],m=i[1],y=i[2],t;if(l<3)try{if(l==1){t=y;y=d;d=t;}if(l++==0){t=d;d=m;m=t;}if(y<100&&(y+=1900)<1950)y+=100;o+=new DateTime(y,m,d)>=DateTime.Today?1:0;a++;if(l<3)i[9]=9;}catch{M(i);throw;}Console.Write(o/a);}}}

初めてのゴルフ、アドバイスを探しています。特に、名前空間によるバイトの削除。

実際のプログラムではなく、機能のみが必要であるという事実を乱用します。また、関数は常にキャッチされない例外になります。

非ゴルフ

namespace System {
    class E {
        static float a, o, l;
        void M(int[] i) {
            int d = i[0], m = i[1], y = i[2], t;
            if (l < 3)
                try {
                    if (l == 1) { 
                        t = y; y = d; d = t; 
                    } 
                    if (l++ == 0) { 
                        t = d; d = m; m = t; 
                    } 
                    if (y < 100 && (y += 1900) < 1950)
                        y += 100; 
                    o += new DateTime(y, m, d) >= DateTime.Today ? 1 : 0; // # not expired
                    a++; // # valid dates
                    if (l < 3)
                        i[9] = 9; // throw new Exception()
                } 
                catch { 
                    M(i);
                    throw; // fail after the first Console.Write()
                } 
            Console.Write(o / a); 
        } 
    } 
}

0

Mathematica、118

出発点としてm.buettnerのコードを使用すると、いくつかの改善点があります。

⌊100Mean@UnitStep@Cases[DateDifference@{If[#<100,Mod[#+50,100]+1950,#],##2}&@@@{#,RotateRight@#,Reverse@#},_Integer]⌋&

ゴルフは、引数として3 Intリストをとる関数です。
algorithmshark 14

@algorithmsharkありがとう。どうしてそれを見逃したのか分かりません。更新...
Mr.Wizard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.