プライム水曜日


22

プライム水曜日

あなたの仕事は、特定の年の月のプライム日に当たる水曜日の数を数えることです。たとえば7-13-16、最高の水曜日です。一貫性を保つため、すべての日付にグレゴリオ暦を使用します。

入力

プログラム/機能への入力は1年(例2016)であり、柔軟性があります。今年は間の整数になります1912年2233年包括的。

出力

出力も柔軟で、水曜日のプライム数(例:)である必要があり18ます。

得点

これはので、バイト単位の最短コードが勝ちです!

テストケース

入力- >出力
--------------------
1912 - > 19
1914 - > 16
1984 - > 17
1996 - > 19
2063 - > 19
2150 - > 16
2199 - > 18
2233- > 18

回答:


7

MATL38 36 34バイト

FT+"@llI$YO]q&:t8XO!s9\~)9#1$ZOZps

オンラインでお試しください!または、すべてのテストケースを確認します(数秒かかります)。

説明

FT+     % Input year implicitly. Add [0 1] element-wise. Gives array with input year
        % and next year
"       % For each of those two years
  @     %   Push year
  ll    %   Push 1 twice. This indicates January 1.
  I$YO  %   Convert year, month, day to serial date number
]       % End for each. We now have the serial date number for January 1 of the input
        % year and that of the following year
q       % Subtract 1 to the latter, to yield December 31 of the input year
&:      % Inclusive range between those two numbers. This gives an array of serial date
        % numbers for the whole input year
t       % Push another copy of that array
8XO     % Convert to date string with format 8. This gives weekday as "Mon", "Tue" etc.
        % The result is a 3-column 2D char array, where each row is a day
!s      % Transpose, sum of each column. 'Wed' gives 288 (sum of ASCII codes)
9\~     % 288 gives 0 modulo 9, and is the only weekday to do so. So we compute modulo 9
        % and negate. This gives true for Wednesdays, false for the rest
)       % Apply as logical index into the array of serial date numbers
9#1$ZO  % Array of month numbers corresponding to those serial date numbers
Zp      % Array that contains true for prime numbers, false for the rest
s       % Sum of array. Display implicitly

日付ベースのチャレンジでMATLを破ることはできないと確信しています。日付ベースの課題を処理するためにさらに最適化されたDATLを作成する必要があります。
-Suever

@Suever Haha、いい名前
ルイスメンドー

20

Python 2、95 93 68 67バイト

lambda y:0x10ea2c8dbb06c5619/5**((y+((y-22)/99-y/2002)*16)%28)%5+16

1バイトのゴルフをしてくれた@Josayに感謝します!

Ideoneでテストします。


3
0x10ea2c8dbb06c5619代わりに1文字を保存できます19501370182350951961
SylvainD

私はそのアイデアを理解してbig_constant//5**long_expressionいますが、一体どのようにしてその定数とその表現を手に入れたのですか?クレイジーだ:D
Sherlock9

2
定数は、基数5を使用する単純なルックアップテーブルですが、基数10に変換されるため、文字列インデックスを使用するのではなく、数字が数値として抽出されます。この表現は、私にとって永久カレンダーのように見えます。(問題は、1901年から2099年までの期間に限定されている場合、その間隔内で28年ごとに回答が繰り返されるため、あまりにも簡単になります。 )
ニール

13

Brain-Flak 658823102308、2290のバイト

まず最初に、このプログラムのほぼ100%を作成しませんでした。これは、おそらくプログラムの巨大なサイズによって証明されます。このコードの大部分は、独自のBrain-Flakゴルフアルゴリズムによって作成されました。追加のpythonスクリプトと共に、正しい方向にプロンプ​​トを出すように書きました。

オンラインでお試しください!

({}<(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((()()())){}{}){})[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])()())[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])())()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())[()()()])())())[()])[()])()()())[()()])()())[()()()()])()())())[()()])())()())[()()()()])())()()())[()()()])()())[()()()])()())[()]))())()())[()()()()])())()()())>[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}]){({}[()]<{}>)}{}({}<{{}}>)

このプログラムはコードゴルフにはかなり長いですが、Brain-Flakにはかなり短いです。現在、整数除算の世界記録は1000バイトを超えています。

説明

アルゴリズムは非常に簡単です。利用可能な年数が限られているため(321)、入力の下で単純に回答を逆順にプッシュし、ルックアップアルゴリズムを使用して正しい回答を見つけます。321のすべての可能性をハードコーディングすることは、このタスクと同じくらい複雑なタスクとブレインフレークのような難解な言語ではかなり非効率に思えるかもしれませんが、最良の解決策になる可能性があります。(私は来週に調べる予定です)。

ほとんどの321の数値は平均で約18であり、すべての数値を個別にプッシュするのではなく、年ごとにわずかに異なるため、最初の年(2233)を通常どおりプッシュしてから、各年の値を少しずつ複製して変更します後。この方法では、321年すべてに対して18プッシュするために支払う代わりに、毎年2プッシュするために支払うだけです。

すべての回答がプッシュされると、入力から1912が差し引かれます ({}[(((((((((()()()()())){}{}){}){}){}){}[()]){}){}){}])(これは最適ではない可能性があります。ハードコーディングの数値は超指数関数プロセスであるため、最適ではないと思われる特定の値をスキップするようにオプティマイザーを書き直しました。数日かかります)。

次に、最初の要素から1を減算し、結果がゼロになるまで2番目の要素をポップします{({}[()]<{}>)}

ゼロ{}と、上の要素の下にあるすべての要素をポップします({}<{{}}>)


ゴルフ数に対する一般的なアプローチは何ですか?
ニール

単純な考えは、係数nとmを持つ数がある場合、nをm-1回プッシュしてからm-1回ポップします。最初のプッシュはnとして評価され、各ポップは追加のnとして評価され、mnと同じ(1 + m-1)(n)になります。これは再帰的に行われます。nをプッシュするにはnもゴルフする必要があるからです。この方法は一部の数、特に素数ではうまく機能しないため、近くにもっと効率的な数があるかどうかを確認し、そうであればその数と差の合計としてこれを表現します。
小麦ウィザード

私はので、2つの番号を付し...見るnmその長さを持っているkl私は仮定し、n+m長さを持っているでしょうかk+l?どうn*m
ニール

n*mだろうk+4m-4l+4n-4。これは、乗算がハードコーディングされているためです。最初にプッシュしn m-1ます。これを実行するために、我々は必要とk表現するために、シンボルn2m-2プッシュを(各プッシュは2つのシンボルである)を発現するようにシンボルを。次にm-1、時間をポップし、追加2m-2料金がかかります(ポップには2シンボルもかかります)。これは合計k+4m-4です。m*n(可換プロパティ)を取得して取得することもできますl+4n-4。結果は、2つのうち短い方になります。
小麦ウィザード

1
まあ、それが本当なら、+1コスト2、*2コスト4、*3コスト8、*4コスト12よりも高価なので*2*2、それは価値がありません(1000未満の数字のうち、使用していない10個しか見つかりませんでした*2:1、2、3 、4、5、9、15、27、45、135)。1912年の((((((1+1+1)*2+1)*2*2+1)*2+1)*2+1)*2+1)*2*2*2長さは52でした。-
ニール

7

Bash +共通ユーティリティ、39

ncal $1|grep W|factor|egrep -c ': \S+$'

入力された年をコマンドラインパラメーターとして受け取ります。通常、このようなメッセージをSTDERRに出力します。これは、このメタアンサーによると合法だと思います

factor: We is not a valid positive integer

STDERR出力を明示的に抑制したい場合は、代わりにスコア43でこれを行うことができます。

ncal $1|grep W|factor 2>-|egrep -c ': \S+$'

これは、英語またはC / POSIXロケールを想定していることに注意してください。gd_GB.utf8すべての曜日名がに短縮されているので、それはあまりうまくいきませんDi
トビーSpeight

6

オクターブ、86バイト

これはどんなストレッチでも速くありません。しかし、それは本当にコードゴルフの目標ではありませんか?

function r=p(y)r=0;for(i=698346:7:815953)d=datevec(i);r+=d(1)==y*isprime(d(3));end;end

Octaveは、「日付番号」-1月1日、0日が1日である経過日数で日付を追跡できます。この基準では、1912年1月3日(セットの最初の水曜日)は698,346日です。そこから開始し、2233の終わりまで7日ごと(すべての水曜日)に繰り返し、年がターゲット年で月日がプライムの場合は1を追加します。


5

パイソン2.7、166165、150のバイト

from datetime import*
y=input()
d,c=date(y,1,1),0
while d.year==y:n=d.day;c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n));d+=timedelta(1)
print c

ここには確かに改善の余地があります。私はPythonでゴルフをするのはかなり新しいです。これはdatetimeモジュールをます。基準に適合する場合、年のすべての日をループして、アキュムレーターに1を追加します。その後、結果を出力します。重荷のほとんどはモジュール内にあるため、コードは非常にスリムになります。

Morgan Thrappのおかげで1バイト、Pietu1998で15バイトが節約されました


1
に切り替えるn%x==0と1バイト節約できますn%x<1
モーガンスラップ16

2
-1必要ではないrangeの終了インデックスは排他的です。さらに、をfilterジェネレータに変換できます。[0for x in range(2,n)if n%x<1]
-PurkkaKoodari

any(...)またはのall(...)代わりに使用できますnot filter(...)
ケニー

1
連鎖比較を組み合わせるallことで、全体を節約できます。c+=n>1<2==d.weekday()>0<all(n%x for x in range(2,n))
-PurkkaKoodari

3

J、44バイト

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)

Jに日付操作用のビルトインがあることを発見しました。

使用法

追加のコマンドは、複数の入出力をフォーマットするために使用されます。

   f =: +/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)
   (,.f"0) 1912 1914 1984 1996 2063 2150 2199 2233
1912 19
1914 16
1984 17
1996 19
2063 19
2150 16
2199 18
2233 18

説明

+/@(valdate*3=weekday)@,.&(,/(>:,"0/p:)i.12)  Input: year
                                       i.12   The range [0, ..., 11]
                              >:              Increment each to get the months [1, ..., 12]
                                    p:        Get the first 12 primes [2, ..., 37]
                                ,"0/          Make a table between each month and prime
                           ,/                 Join the rows
                       ,.&                    Prepend the year to each
                                              The date format is YYYY MM DD
            3=weekday                         Check if each date occurs on Wednesday
    valdate*                                  and is a valid date
+/@                                           Count the number of true values and return

1

PowerShell v3 +、99 95バイト

ブルートフォースアプローチ-

param($y)(1..12|%{$m=$_;2,3,5,7,11,13,17,19,23,29,31|?{(date "$m-$_-$y").DayofWeek-eq3}}).Count

入力を受け取り$y1to からループし12、月を一時的に格納して$mから、2to からすべての素数をループします31。それらのそれぞれについてGet-Date、その特定の日のを構築し、DayOfWeek -equal to 3(すなわち水曜日)を持つもののみを選択します。それらをすべて括弧にカプセル化して配列を作成し、それを取得し.Countます。


あるいは、数学的アプローチ-

PowerShell v3 +、105バイト

param($y)(16,19,18,20,16,18,19)[($a=(date "1-1-$y").DayOfWeek)]+(1,-3,0,1,2)[$y%5]*($a-in0,2,3,4)*!($y%4)

強引なアプローチよりも長い髪になってしまいますが、他の人にとっては有益かもしれないので、ここに含めています。

再び年を入力$yします。今回は、1年の初日に基づいて厳密に数学演算を実行しています。まず、何曜日かを計算し$a、後で使用するために保存します。これは最初の配列にインデックスを付け、通常正しい数を取得します。うるう年になる可能性があるかどうか、日曜日、火曜日、水曜日、木曜日であるかどうか、および年に基づいて、2番目のインデックスを追加する必要があります。

これは、次の観察に基づいています。最初の列は1月1日の曜日で、2番目の列は通常の出力です。年が中間の数字の1つでない限り、代わりに括弧で囲まれた数字です。最後の列は、%5インデックスの仕組みを説明しています。

Jan-1 -> #  ... Except if $y=       (then it's this number) | $y % 5 =
Sun   -> 16 ... 1928 1956 1984 etc. (17)                    |    3
Mon   -> 19
Tue   -> 18 ... 1924 1952 1980 etc. (20)                    |    4
Wed   -> 20 ... 1936 1964 1992 etc. (17)                    |    1
Thur  -> 16 ... 1920 1948 1976 etc. (17)                    |    0
Fri   -> 18
Sat   -> 19

注:これらは両方とも、en-usカルチャ/日付情報の現在のPowerShell設定であると想定しています。日付の形式とDayOfWeek番号は、他の文化の種類に応じて調整する必要がある場合があります。



1

JavaScriptのES6、187の 182 181 179バイト

179 whileループのforループで交換

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);for(;a()<=y;c())N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

181 三元の圧縮

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=y-a()?0:-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());c()}return N}

182 2つのループの結合

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<=y){N+=a()==y?-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b()):0;c()}return N}

187

z=y=>{D=new Date("1/3/1912");N=0;a=()=>D.getFullYear();b=()=>D.getDate();c=()=>D.setDate(b()+7);while(a()<y)c();for(;a()==y;c())N+=-1<[2,3,5,7,11,13,17,19,23,29,31].indexOf(b());return N}

この例では、特定の年の最初の最初の水曜日を指定したので、これは重要ではないと思います。OPの課題は、唯一のパラメーターとして年が必要であると述べています...しかし、これまでの多大な努力
...- WallyWest

「プログラム/機能への入力は1年になります」-しかし、あなたが指摘しているのはそれではありません。1912年の最初の水曜日をシードとして使用します。これは、OPによって指定された期間の隔週水曜日であるか、それよりも前にあるためです。私の関数への入力はまだ1年であり、関数はOPによって提案された時間枠内の任意の年のプライムウォーターズの数を計算します。そのため、これがどのように課題に適合しないかわかりません。
パンダコーダー

ああ、謝罪...私は...特にあなたのソリューションを考慮すると、約30で鉱山を打つ..あなたしているが、播種コンポーネント...素晴らしいアイデアとしてあることを利用して最初に実現しませんでした。)
WallyWest

1
ありがとう。Eamon OliveのBrain-Flak実装からインスピレーションを得ました。実際には、彼の説明によると、すべての回答が事前にプログラムされています。
パンダコーダー

1

バッチ、248バイト

@set/ad=0,l=1,n=20
@for /l %%i in (1913,1,%1)do @set/ad=(d+l+1)%%7,l=!(%%i%%4)-!(%%i%%100)+!(%%i%%400)
@goto %l%%d%
:03
:06
@set/an-=1
:12
:13
:16
@set/an-=1
:01
:04
:14
@set/an-=1
:00
:05
:10
:15
@set/an-=1
:02
:11
@echo %n%

説明:d曜日で、0月曜日は1912年1月1日が便利です。1912年lはyear年かどうかのフラグ1です。その後、1913年から入力年までループして、週とうるう年フラグを再計算します。最後に、うるう年のフラグと曜日を使用して、実質的なn水曜日の数を決定するための実質的に大きな切り替えステートメントにインデックスを付けます。n20に設定し、フォールでデクリメントするのはフロー制御ロジックを使用するよりも安いですが、結果は、うるう年以外の年の1月1日が木曜日または日曜日である場合、16のプライム水曜日などであるということです。


1

JavaScriptのES6 206 203 199 197 195 183 182 179

最短ではありませんが、今のところできることは最高です...ゴルフの提案を歓迎します...

p=n=>--d-1?n%d&&p(n):1;v=Date;D=(x,y)=>new v(x.setDate(x.getDate()-y));W=a=>eval('for(Z=0,z=D(w=new v(a,11,31),(w.getDay()+4)%7);z>new v(a,0,1);)Z+=~~p(d=z.getDate()),z=D(z,7);Z')

変更点:

  1. 3成分の変更:3>=x?3-x:10-xto 6-(x+10)%7、保存:3宣言位置の変更。
  2. 合併x=w.getDay();z=D(w,6-(x+10)%7)z=D(w,6-(w.getDay()+10)%7)の保存、:4
  3. ループから日付宣言にシフトしZ=0forループにプッシュz=D(w,6-(x+10)%7)forて整理し、保存します:2
  4. w=new Date(a,Z=0,1)宣言をforループにシフトし、既存のw宣言とマージして、保存します:2
  5. 素数発見関数を素数テスト関数に書き換え、保存:12
  6. をに変更+!!~~p(d=1)からNaNに変換し、引き続きからに変換して0、Prime Test機能を引き続き機能させ、保存します。1
  7. すべての追加関数をメインの呼び出し関数から移動しWforループを再定義しました。12月31日から逆になり、Dateオブジェクトを別の変数として書き出し、forループをeval呼び出しに書き直しました。保存3。

@PandaCoder、私はあなたに追いついています、仲間!


1

R、149 147バイト

y=function(x){s=strftime;b=ISOdate
a=seq(b(x,1,1),t=b(x,12,31),b='d')
length(a[s(a,'%u')==3&trimws(s(a,'%e'))%in%c(2,3,5,7,11,13,17,19,23,29,31)])}

Ideoneでテストします。


0

グルーヴィー、126

Groovyには素数検証がなく、それも構築する必要がありました。

{n->p={x->x<3||(2..Math.sqrt(x)).every{x%it}};(new Date("1/1/$n")..new Date("12/31/$n")).collect{it[7]==4&&p(it[5])?it:0}-[0]}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.