Sữa của tôi đã hết hạn?


98

À, anh bạn, ngày hết hạn này không viết tháng bằng chữ! Tôi không thể biết là nó sẽ hết hạn vào ngày 10 tháng 3 hay ngày 3 tháng 10 ... Đợi đã, không, đừng bận tâm, năm đó nói năm 2012. (con hẻm được sử dụng một nửa viên phô mai vào thùng rác như một người chuyên nghiệp)

Vì vậy, giả sử trong một khoảnh khắc mà bạn quá bận rộn để cố gắng giải thích khi nào lọ marinara này sẽ hết hạn. Bạn chỉ muốn phiên bản Cliff Notes: nó có khả năng đến hạn như thế nào? Hãy viết một số mã!

Bạn biết rằng các nhà sản xuất in ngày dưới dạng bộ ba số nguyên theo thứ tự, theo một trong ba định dạng:

YEAR  MONTH DAY
MONTH DAY   YEAR
DAY   MONTH YEAR

Và bạn biết rằng một số ngày chỉ có thể được diễn giải theo một hoặc hai cách, không phải cả ba: 55 trong 55-11-5 phải là một năm, có nghĩa là hộp Twinkies đặc biệt này đã hết hạn vào ngày 5 tháng 11 năm 1955. Năm đôi khi được đưa ra bằng bốn chữ số và không phải hai, có thể loại trừ một số tùy chọn. Tuy nhiên, khi đó là hai chữ số, 50..99 có nghĩa là 1950..1999 và 0..49 có nghĩa là 2000..2049.

Công việc của bạn là viết một chương trình hoặc hàm lấy một số nguyên là một ngày hợp lệ trong ít nhất một trong những cách hiểu ở trên, và đưa ra một tỷ lệ phần trăm cơ hội vẫn còn tốt. Cơ hội phần trăm chỉ đơn giản là tỷ lệ phần trăm của các diễn giải hợp lệ của ngày vào hoặc muộn hơn hơn ngày hôm nay.

Mảng số nguyên sẽ là ngôn ngữ của bạn [Int] loại độ dài ba nếu nó là đối số của hàm và được cung cấp dưới dạng dấu gạch ngang, dấu gạch chéo hoặc dấu cách (bạn có thể chọn) nếu được sử dụng làm đầu vào trên STDIN cho chương trình đầy đủ. *

"Ngày hôm nay" có thể là ngày thực tế ngày hôm nay, như được lấy thông qua hàm ngày hoặc ngày được đưa ra trong một đối số bổ sung cho chức năng hoặc tham số bổ sung trong STDIN. Nó có thể là trong Unix epoch giây, một bộ ba ngày tháng khác được nhập theo một trong ba cách trên hoặc thời trang khác thuận tiện hơn.

Hãy có một số ví dụ! Đầu vào ngày hết hạn sẽ theo kiểu phân tách dấu gạch ngang và giả sử cho các ví dụ bên dưới ngày hôm nay là ngày 5 tháng 7 năm 2006.

  • 14-12-14- Cả hai cách hiểu hợp lệ cho điều này (DMY và YMD) đều tương đương, ngày 14 tháng 12 năm 2014. Sản lượng là 100 vì sản phẩm này chắc chắn vẫn còn tốt.
  • 8-2-2006- Số cuối cùng là một năm, chắc chắn, vì nó có bốn chữ số. Điều này có thể là ngày 8 tháng 2 (hết hạn) hoặc ngày 2 tháng 8 (vẫn tốt). Đầu ra là 50 .
  • 6-7-5- Đây có thể là bất cứ điều gì! Giải thích "ngày 5 tháng 7 năm 2006" vẫn tốt (chỉ trong một ngày), nhưng hai phiên bản còn lại đều vào năm 2005 và nên được ném càng nhanh càng tốt. Đầu ra là 33 .
  • 6-5-7- Ở đây, hai trong số ba cách giải thích là an toàn. Bạn có thể làm tròn số thập phân của mình lên hoặc xuống, vì vậy 66 hoặc 67 đều ổn.
  • 12-31-99- Được rồi, cái này rõ ràng từ đầu thế kỷ (năm từ 50 đến 99 là 19XX, và 31 không thể là một tháng). Một chất béo lớn 0 , và bạn thực sự nên dọn dẹp tủ lạnh của bạn thường xuyên hơn.

Bạn có thể giả định một cách an toàn rằng bất kỳ đầu vào nào không đáp ứng các tiêu chuẩn ở trên không thuộc về các quy tắc đầu ra ở trên.

Không có yêu cầu web hoặc sơ hở tiêu chuẩn. Thư viện xử lý ngày được cho phép. Đây là mã golf: có thể chương trình ngắn nhất sẽ giành chiến thắng.

* Nếu bạn đang sử dụng brainfuck hoặc một số ngôn ngữ bị lỗi kiểu dữ liệu tương tự, bạn có thể giả sử các giá trị ASCII của ba ký tự đầu tiên trong đầu vào là các số nguyên cho ngày. Điều này không bao gồm logic năm chữ số, chắc chắn, nhưng tôi nghĩ rằng chúng ta sẽ quá kinh ngạc khi thấy một giải pháp cho vấn đề này trong Brainfuck để xem nhẹ bạn về nó.


39
Umm ... năm hiện tại là 2014, không phải năm 2006. Sữa của bạn đã hết hạn tám năm.
John Dvorak

11
@JanDvorak Tôi chỉ không muốn cố gắng hết sức để xây dựng các ví dụ có ý nghĩa, vì vậy tôi đã điều chỉnh ngày hôm nay để làm cho nó dễ dàng hơn.
thuật toán

7
@ Dgrin91 đừng quan tâm, tôi vẫn sẽ ăn chúng: D
aditsu

6
Ở Úc, sữa hết hạn khoảng một tuần trước ngày sử dụng
gnibbler

5
Bạn nên thêm một bài kiểm tra với 00 trong đó, vì đó không thể là ngày hoặc tháng hợp pháp.
MtnViewMark

Câu trả lời:


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}

Gọi với xcủa .z.D(một dựng sẵn) để so sánh với ngày hôm nay, hoặc một ngày đen của sự lựa chọn của bạn nếu không:

  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

Về cơ bản, đây là một cổng của giải pháp Python của @ Alex-l, với một vài thủ thuật đánh golf linh tinh được thêm vào:

  • Các hướng dẫn sắp xếp lại được mã hóa thành một chuỗi để lưu một vài ký tự.
  • Logic điều kiện (ab) sử dụng true-as-số nguyên (nhưng theo một cách khác với giải pháp Python).
  • Kiểm tra tính hợp lệ hơi khác nhau - k4 / q sẽ vui vẻ phân tích bất kỳ chuỗi nào vào bất kỳ kiểu dữ liệu nào; nó chỉ đơn giản trả về null nếu không thể hiểu ý nghĩa của nó. Vì vậy, tôi trả về một danh sách các ngày từ hàm bên trong, có thể có hoặc không có giá trị.
  • Kết quả cuối cùng đến từ việc kiểm tra có bao nhiêu cách hiểu ngày có thể là null so với số lượng ít hơn ngày so sánh; Điều quan trọng ở đây là ngày null được coi là ít hơn bất kỳ ngày nào khác.

1
Bạn có thể lưu char bằng cách xóa 0 cuối cùng khỏi "012201210", vì #lấy các mục của nó theo chu kỳ. Trong thực tế, bạn có thể lưu một char thứ hai theo cách này bằng cách hoán đổi hai trường hợp cuối cùng : 3 3#.:'"0122102".
thuật toán

Cạo thêm một char bằng cách đảo ngược các đối số của func bên trong, lưu các parens (nhưng thêm một đảo ngược). Bất cứ ai có thể giúp tôi lưu hai ký tự khác? APL đang đánh bại tôi!
Aaron Davies

Cạo năm cái khác bằng cách viết lại bài toán ở cuối. Trở lại vị trí dẫn đầu!
Aaron Davies

Và nếu tôi cúi xuống viết mã phi chức năng nghiêm túc, tôi có thể cạo một byte khác bằng cách làm ô nhiễm không gian tên toàn cầu : {c*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(c*19+x<50)*x<c::100}.'y@/:3 3#.:'$21020101}.
Aaron Davies

14

Ruby, 115 ký tự

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}

Điều này xác định một chức năng f có hai đối số: một mảng chứa đầu vào và ngày "hôm nay".

Ví dụ:

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

Con trăn 2.7 - 172

Tôi sử dụng mô-đun datetime để xác thực và so sánh ngày. Nếu datekhông thể tạo một datetime hợp lệ từ đầu vào, nó sẽ tăng ValueError. Cách này slà tổng của các ngày không hết hạn và tlà tổng số ngày hợp lệ. Tôi đang lợi dụng thực tế là True == 1cho các mục đích bổ sung và lập chỉ mục trong Python. Tôi cũng lưu một ký tự bằng cách sử dụng 25 * (76,80) thay vì (1900,2000).

Lưu ý các dòng ở mức thụt thứ hai sử dụng ký tự tab, không phải 2 dấu cách.

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

Thêm phần này vào cuối để kiểm tra:

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)
  • Nhập dưới dạng int[]thông qua, ví dụ:

    PS> ./milk.ps1 5,6,7
    
  • Thông báo lỗi bị tắt tiếng qua try/ catch, miễn là tôi không biết liệu đầu ra trên thiết bị lỗi chuẩn có được phép hay không.
  • Sử dụng +"-1"vào ngày, được hiểu là .AddDays(-1)thay đổi ngày hiện tại một ngày, để chúng ta có thể so sánh với ngày hôm qua (thay vì chỉ ngày hôm nay). Điều này giải quyết vấn đề chúng ta có được một ngày với 0:00 là thời gian nhưng cần so sánh với một ngày với thời gian từ hôm nay.
  • Bây giờ nặng nề
  • Sử dụng một thủ thuật mới để tắt tiếng các lỗi ngắn hơn một chút

6

R, 269

Tôi đã mong đợi điều này sẽ dễ dàng trong R, nhưng những năm một chữ số là một đường cong khá lớn. Tôi cảm thấy như thế này có thể tốt hơn nhiều so với nó.

lubridatelà một gói từ CRAN, bạn có thể cần phải cài đặt nó với 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)}

Cách sử dụng: f(c(d1,d2,d3))trong đó c(d1,d2,d3)một vectơ số nguyên.

ví dụ f(c(6,10,14))trả về 0.3333333.

Các lubridategói có một loạt các chức năng bao bọc cho phân tích số ngày trong đơn đặt hàng khác nhau. Tôi sử dụng những định dạng này để xem định dạng nào tạo ra ngày hợp lệ, loại bỏ những định dạng không hợp lệ và sau đó xem những định dạng nào chưa xảy ra.


6

Toán học, 163 153 164 byte

( chỉnh sửa: ngày cố định ngoài phạm vi 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]]&

Điều này xác định một chức năng mà bạn có thể gọi như

f[{6,7,5}]

Hiện tại, tỷ lệ phần trăm không được làm tròn (chờ OP làm rõ).

Dưới đây là một lời giải thích hơi dài mà phải dễ hiểu mà không cần bất kỳ kiến thức Mathematica (lưu ý rằng &làm tất cả mọi thứ bên trái của nó một chức năng ẩn danh có các tham số được gọi là #, #2, #3...):

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

Điều này xác định một hàm, biến 3 tham số a,b,cthành 3 danh sách {{a,b,c},{c,b,a},{c,a,b}. Lưu ý rằng đó ##chỉ là một chuỗi của tất cả các tham số.

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

Áp dụng cho ngày hết hạn, điều này đưa ra một danh sách {y,m,d}cho mỗi trong số ba hoán vị có thể.

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

Đây là một hàm ẩn danh nhận ba tham số a,b,cvà trả về một danh sách của ba, trong đó hàm đầu tiên được chuyển đổi thành một năm theo các quy tắc nhất định: các số giữa 5099(modulo 100) được chuyển thành năm thế kỷ 20, các số giữa 049( modulo 100) được chuyển thành một năm thế kỷ 21, tất cả những người khác được để lại. Ở đây, ##2là một chuỗi các tham số bắt đầu với cái thứ hai, tức là b,c.

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

Áp dụng cho từng kết quả trong ba kết quả trước đó, điều này chỉ hợp lệ hóa các định dạng năm. Hãy gọi đây canonicalDatesđể rút ngắn biểu thức sau:

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

Điều này lọc ra các giải thích không hợp lệ. DateList@dlàm cho một {y,m,d,h,m,s}đại diện đầy đủ trong các định dạng ngày khác nhau. Nó sẽ diễn giải các danh sách theo cùng một thứ tự, nhưng điều thú vị là bạn có thể vượt qua nó những thứ như {8,2,2006}trong trường hợp nào nó sẽ tính toán 8 years + 2 months + 2006 days. Vì vậy, chúng tôi kiểm tra rằng ba yếu tố đầu tiên của danh sách được trả về giống hệt với đầu vào (điều này chỉ có thể xảy ra nếu tháng và ngày trong phạm vi thích hợp).

Để rút ngắn các dòng sau, tôi sẽ đề cập đến kết quả của biểu thức đó kể validDatestừ bây giờ:

DateDifference[#,Date[]]&

Một hàm ẩn danh khác có ngày và trả lại chênh lệch tính theo ngày cho đến ngày hôm nay (có được từ Date[]).

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

Bản đồ mà vào các diễn giải ngày hợp lệ.

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

Tuy nhiên, một hàm ẩn danh khác, được đưa ra một danh sách ( #), trả về tỷ lệ phần trăm của các số không dương trong danh sách đó. Đây .không phải là phép nhân mà chỉ là chữ số thập phân, để tránh các số hữu tỷ là kết quả (bạn sẽ nhận được những thứ như 100/3thay vì 33.333- tôi thực sự không biết đó có phải là vấn đề không).

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

Áp dụng cho danh sách các khác biệt về ngày tháng, điều này cho chúng ta một phần các diễn giải chưa hết hạn.


Tôi nghĩ rằng bạn chuyển đổi không chính xác các năm như 2999 hoặc 2099 sang 1999.
Ventero

@Ventero đó là sự thật. Tôi cho rằng chúng ta chỉ giải quyết những năm 1950 - 2049 (và các phiên bản 1 hoặc 2 chữ số của họ), nhưng đọc lại thử thách thì không đề cập đến điều đó.
Martin Ender

@Ventero đã sửa (nhưng dù sao bạn cũng đã đánh bại tôi một cách đáng kể;))
Martin Ender

Tôi ngạc nhiên khi thấy rằng bạn có một tài khoản trên Mathematica nhưng chưa đăng bất kỳ Câu hỏi hoặc Câu trả lời nào. Là một cái gì đó giữ bạn lại?
Mr.Wizard

@ Mr.Wizard xin lỗi, hoàn toàn quên trả lời bạn. Câu hỏi: cho đến nay mọi vấn đề tôi có thể được giải quyết bằng cách hỏi / câu hỏi SE khác. Trả lời: Tôi không biết ... Tôi đoán tôi không xem bản thân mình thành thạo như vậy khi sử dụng Mathicala một cách hiệu quả ... Tôi chỉ sử dụng nó cho các đoạn nhanh ở đây và ở đó (và chơi golf mã). Ngoài ra, tôi đoán để trả lời các câu hỏi tôi phải chủ động xem những câu hỏi mới để xem những gì tôi có thể trả lời, và hiện tại tất cả thời gian SE của tôi được phân bổ cho PPCG. ;) Nếu bạn muốn tôi thuyết phục tôi bằng cách khác, hãy thoải mái làm điều đó trong trò chuyện! :)
Martin Ender

4

JavaScript (E6) 159 164 172

Chỉnh sửa Cảm ơn nderscore cho các gợi ý và thúc đẩy tôi suy nghĩ lại. Sắp xếp lại D tránh các tham số và cắt một số ký tự.

Chỉnh sửa 2 Một mẹo khác của nderscore, 2 hàm được hợp nhất thành 1. Sau đó, hai dấu ngoặc đơn được loại bỏ các biểu thức được phân tách bằng dấu phẩy thành một. Khả năng đọc gần 0. Sidenote: Không làm tròn có thể tiết kiệm thêm 2 ký tự (| 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

Kiểm tra trong bảng điều khiển 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)))

Đầu ra:

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

Bị đánh cắp

Hàm NB D cố gắng tạo Ngày với năm, tháng, ngày đã cho nhưng trả về sai nếu ngày được tạo không phải là ý định (! = Ngày hoặc tháng)

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 OK cho những thay đổi trong D, lỗi sintax cho người khác. Nhưng dù sao cũng được lưu nhiều hơn
edc65

Kỳ dị. Một cái gì đó đã xảy ra khi tôi dán nó vào bình luận. Tối ưu hóa mới nhất của bạn làm cho nó không liên quan mặc dù :)
nderscore

1
Đặt điều này vào một dán, vì tôi không tin vào nhận xét của SE nữa: (-3) pastie.org/private/6bemdweyndcaiseay70kia
nderscore

4

C # trong LINQPad - 446 408 272 byte

Chỉnh sửa thứ ba: Cảm ơn phạm lỗi của Le Canard vì đã chỉ ra rằng DateTime.Today là chính xác, không phải DateTime. Bây giờ. Chỉnh sửa thứ hai: Cảm ơn VisualMelon cho giải pháp thông minh này!

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();}

Chỉnh sửa: Cảm ơn podiluska và edc65 đã giúp tôi rút ngắn mã! Tôi cũng nhận thấy rằng giải pháp của tôi không đúng nếu đầu vào năm dài 4 byte, do đó tôi đã bao gồm sửa lỗi cho vấn đề đó. Điểm cho giải pháp này là 408 Byte.

Mặc dù tôi không đánh bại bất kỳ câu trả lời nào trước đây, tôi vẫn muốn chia sẻ giải pháp C # của mình. Bất kỳ trợ giúp / đề xuất được đánh giá cao! ;)

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();}

Phiên bản được định dạng và không được chỉnh sửa:

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();
    }

Tôi đã cố gắng tạo ra một giải pháp trong đó "DateTime.TryPude" -Part không lặp lại như trong giải pháp này, nhưng nó dài hơn 21 byte.

Giải pháp mà không lặp lại "DateTime.TryPude": 467 Byte

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

Phiên bản bị đánh cắp:

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

2
đề xuất: sử dụng ternary (? :) khi có thể thay vì if /
other

1
@ThomasW. Tôi không nghĩ vì y có 2 giá trị khác nhau, một lần tùy thuộc vào a, lần khác phụ thuộc vào e. Dù sao cũng cảm ơn bạn!
tsavinho

1
Loại bỏ các DateTime.TryParsecuộc gọi là bản năng đầu tiên của tôi, thay thế nó bằng lambda cũng đưa giá trị trở lại vào q. Đồng thời thực hiện một số bước khác ( pastebin ) để nhận được 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 Wow, bạn thực sự giỏi chơi golf! Tôi chưa bao giờ nhìn thấy Action<string>trước đây, vì vậy tôi có thể học được điều gì đó từ bạn;) Tôi đã có thể đưa câu trả lời của bạn xuống còn 318 ký tự bằng cách thay thế q.Where(i=>i>=DateTime.Now).Countbằng q.Count(i=>i>=DateTime.Now. Tôi cũng xóa các dấu ngoặc xung quanh xđể tôi có thể lưu thêm 2 ký tự!
tsavinho

3

Haskell, 171 165 ký tự

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)

Tên của hàm là %. Chạy với ngày thử nghiệm dưới dạng một tuple theo thứ tự chính tắc (y, m, d) với năm thực tế và tem carton dưới dạng một bộ ba số:

λ: (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

Erlang, 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).

Chức năng kiểm tra sẽ là:

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}).

Bị đánh cắp

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).

Giải pháp này dựa trên sự hiểu biết danh sách. Nó mượn thủ thuật modulo trong năm từ giải pháp Haskell. Nó cũng sử dụng calendar:valid_date/1để xử lý các ngày không thể vì số ngày trong một tháng nhất định (ví dụ: "29-2-2" chỉ có thể ở định dạng YMD). Ngoài ra, Hôm nay là ở date()định dạng của Erlang (một tuple YMD).


2

APL (85)

Điều này sử dụng một số chức năng mới của Dyalog APL 14, nhưng không có thư viện bên ngoài. Để thay đổi, nó hoạt động trên TryAPL .

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

Đây là một hàm lấy mảng 3 phần tử làm đối số bên phải ( ) và ngày để kiểm tra làm đối số bên trái ( ) của nó , làm số nguyên YYYYMMDDđịnh dạng. Tức là ngày 2014-07-09được biểu diễn dưới dạng số 20140709.

Kiểm tra:

      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

Giải trình:

  • Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵: biến ngày đã cho thành định dạng YMD bằng cách lật (⊂⌽⍵), xoay sang trái 2 lần (⊂2⌽⍵)hoặc không làm gì cả ⊂⍵. Ít nhất một trong số này hiện là một ngày thích hợp ở định dạng YMD, có thể nhiều hơn một nếu ngày đó không rõ ràng.
  • {∧/12 31≥1↓⍵}¨Z: kiểm tra xem mỗi ngày có hợp lệ không: năm (yếu tố đầu tiên) bị hủy và sau đó tháng không được cao hơn 12 và ngày không được cao hơn 31.
  • Z/⍨: lọc các ngày hợp lệ từ Z.
  • {... : cho mỗi ngày hợp lệ:
    • ⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵: nếu năm không cao hơn 99, hãy thêm 1900, sau đó 100 nếu năm thấp hơn 50.
    • (3/100)⊥: giải mã nó như thể nó là một tập hợp các số cơ sở 100. (Năm cao hơn 100, nhưng điều này không quan trọng vì đây là yếu tố đầu tiên.) Điều này đưa ra một số cho mỗi ngày hợp lệ ở cùng định dạng với đối số bên trái.
  • ⍺≤: cho mỗi ngày, xem nếu nó không nhỏ hơn . Điều này sẽ đưa ra một vectơ nhị phân trong đó 1 phương tiện OKvà 0 có nghĩa spoiled.
  • 100×(+/÷⍴): chia tổng của vectơ nhị phân cho chiều dài của nó và nhân với 100.

Lưu 7 byte (và đánh bại K bằng một lề đẹp) bằng cách mắc kẹt và tạo một hàm bên trong ngầm:{100×(+/÷⍴)⍺≤((3/100)⊥⊢+(99≥⊃)×3↑1900+100×50>⊃)¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⌽⍵)(2⌽⍵)⍵}
Adám

0

Java: 349 Ký tự (3 w / o dấu cách)

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

Dưới đây là một lớp chứa có thể được sử dụng để kiểm tra nó, bao gồm cả một phiên bản (hơi) bị khử của phương thức:

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+"%");
   }   
}

Đây là vòng golf mã đầu tiên của tôi và tôi nghĩ rằng tôi đã hiểu tại sao tôi thường không thấy nhiều người chơi golf Java.


1
Bạn cần chấp nhận một int[]đối số, không phải ba ints.
Joey

ok, tôi đã sửa nó
Shieldgenerator7

0

C # 287 byte

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);}}}

Lần đầu tiên chơi golf, tìm kiếm lời khuyên. Đáng chú ý, loại bỏ byte do không gian tên.

Lạm dụng thực tế là chỉ cần một chức năng, không phải là một chương trình thực tế. Ngoài ra, chức năng luôn dẫn đến một ngoại lệ chưa được bắt gặp.

Bị đánh cắp

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

Toán học , 118

Sử dụng mã của m.buettner làm điểm khởi đầu Tôi có một vài cải tiến:

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

Golf có thể là một hàm lấy danh sách ba Int làm đối số.
thuật toán

@alerskymshark Cảm ơn. Tôi không biết làm thế nào tôi bỏ lỡ điều đó. Đang cập nhật ...
Mr.Wizard
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.