Aww, teman, tanggal kadaluwarsa ini tidak menulis bulan dengan surat! Saya tidak tahu apakah akan kedaluwarsa pada tanggal 10 Maret atau 3 Oktober ... Tunggu, tidak, tidak apa-apa, tahun ini mengatakan tahun 2012. (lorong oop bata keju yang sudah setengah digunakan ke tempat sampah seperti pro)
Jadi anggaplah sejenak bahwa Anda terlalu sibuk untuk mencoba mencari tahu kapan toples marinara ini seharusnya berakhir. Anda hanya ingin versi Cliff Notes: seberapa besar kemungkinan bahwa itu sudah lewat jatuh tempo? Mari kita menulis beberapa kode!
Anda tahu bahwa pabrikan mencetak tanggal sebagai tiga kali lipat bilangan bulat, dalam salah satu dari tiga format:
YEAR MONTH DAY
MONTH DAY YEAR
DAY MONTH YEAR
Dan Anda tahu bahwa beberapa tanggal hanya dapat diartikan dalam satu atau dua cara, bukan ketiganya: tanggal 55 55-11-5
harus satu tahun, artinya kotak Twinkies khusus ini kedaluwarsa 5 November 1955. Tahun ini kadang-kadang diberikan dalam empat digit dan bukan dua, yang dapat mengesampingkan beberapa opsi. Namun ketika dua digit, 50..99 berarti 1950..1999 dan 0..49 berarti 2000..2049.
Tugas Anda adalah menulis program atau fungsi yang mengambil array bilangan bulat yang merupakan tanggal yang valid dalam setidaknya satu dari interpretasi di atas, dan menghasilkan persen kemungkinan itu masih bagus. Persentase peluang hanyalah persentase interpretasi yang valid dari tanggal yang ada pada atau lebih lambat dari tanggal hari ini.
Array bilangan bulat akan menjadi [Int]
jenis bahasa Anda yang panjangnya tiga jika itu adalah argumen untuk suatu fungsi, dan diberikan sebagai bilangan bulat dash, slash-, atau spasi (Anda bisa memilih) jika digunakan sebagai input pada STDIN ke sebuah program lengkap. *
"Tanggal hari ini" dapat menjadi tanggal aktual hari ini, seperti yang diperoleh melalui fungsi tanggal, atau tanggal yang diberikan dalam argumen tambahan untuk fungsi atau paramater tambahan di STDIN. Mungkin dalam detik Unix, triple tahun tahun bulan dimasukkan dalam salah satu dari tiga cara di atas, atau cara lain yang lebih nyaman.
Mari kita punya beberapa contoh! Input tanggal kedaluwarsa akan berada dalam gaya yang dipisahkan dengan tanda hubung, dan menganggap untuk contoh di bawah ini bahwa tanggal hari ini adalah 5 Juli 2006.
14-12-14
- Kedua interpretasi yang valid untuk ini (DMY dan YMD) adalah setara, 14 Desember 2014. Outputnya adalah 100 karena produk ini pasti masih bagus.8-2-2006
- Angka terakhir adalah satu tahun, pasti, karena memiliki empat digit. Ini bisa berupa 8 Februari (kedaluwarsa) atau 2 Agustus (masih bagus). Outputnya adalah 50 .6-7-5
- Ini bisa apa saja! Penafsiran "5 Juli 2006" masih bagus (hanya untuk satu hari), tetapi dua yang tersisa keduanya pada tahun 2005 dan harus dilemparkan secepat mungkin. Outputnya adalah 33 .6-5-7
- Di sini, dua dari tiga interpretasi aman. Anda dapat membulatkan desimal Anda ke atas atau ke bawah, sehingga 66 atau 67 keduanya baik-baik saja.12-31-99
- Oke, yang ini jelas dari pergantian abad (tahun 50-99 adalah 19XX, dan 31 tidak mungkin sebulan). Lemak besar 0 , dan Anda benar-benar harus membersihkan lemari es Anda lebih sering.
Anda dapat dengan aman berasumsi bahwa input apa pun yang tidak memenuhi standar di atas tidak diketahui oleh aturan output di atas.
Tidak ada permintaan web atau celah standar. Pustaka penanganan tanggal diizinkan. Ini kode golf: semoga program terpendek menang.
* Jika Anda menggunakan brainfuck atau bahasa dengan cacat data sejenis, Anda dapat mengasumsikan nilai ASCII dari tiga karakter pertama yang dimasukkan adalah bilangan bulat untuk tanggal tersebut. Ini tidak termasuk logika empat digit tahun, tentu, tapi saya pikir kita akan terlalu kaget dengan melihat solusi untuk ini di Brainfuck untuk membuat Anda sedikit kecewa.
Jawaban:
k4
(90)(88)(87)(82)Memanggil dengan
x
dari.z.D
(a builtin) untuk dibandingkan dengan hari ini, atau tanggal literal pilihan Anda sebaliknya:Ini pada dasarnya adalah port dari solusi Python @ Alex-l, dengan beberapa trik golf ditambahkan:
sumber
"012201210"
, karena#
mengambil itemnya secara siklis. Bahkan, Anda dapat menyimpan char kedua cara ini dengan menukar dua kasus terakhir:3 3#.:'"0122102"
.{c*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(c*19+x<50)*x<c::100}.'y@/:3 3#.:'$21020101}
.Ruby, 115 karakter
Ini mendefinisikan fungsi
f
yang mengambil dua argumen: array yang berisi input, dan tanggal "hari ini".Contoh:
sumber
Python 2.7 - 172
Saya menggunakan modul datetime untuk validitas dan perbandingan tanggal. Jika
date
tidak dapat membuat datetime yang valid dari input, itu memunculkanValueError
. Cara inis
adalah jumlah dari tanggal yang tidak kedaluwarsa dant
merupakan jumlah total dari tanggal yang valid. Saya mengambil keuntungan dari fakta bahwaTrue == 1
untuk keperluan penambahan dan pengindeksan dengan Python. Saya juga menyimpan karakter dengan menggunakan 25 * (76,80), bukannya (1900.2000).Perhatikan baris di lekukan kedua menggunakan karakter tab, bukan 2 spasi.
Tambahkan ini ke akhir untuk menguji:
sumber
PowerShell,
183173168Input sebagai
int[]
via parameter, mistry
/catch
, selama saya tidak tahu apakah output pada stderr diizinkan atau tidak.+"-1"
pada tanggal, yang ditafsirkan sebagai.AddDays(-1)
menggeser tanggal saat ini dengan satu hari, sehingga kita dapat membandingkannya dengan kemarin (bukan hanya hari ini). Ini menyelesaikan masalah bahwa kita mendapatkan tanggal dengan 0:00 sebagai waktu tetapi perlu membandingkan dengan tanggal dengan waktu mulai hari ini.sumber
R, 269
Saya mengharapkan ini mudah di R, tetapi tahun-tahun satu digit adalah bola lengkung yang cukup besar. Saya merasa ini bisa jauh lebih baik dari itu.
lubridate
adalah paket dari CRAN, Anda mungkin perlu menginstalnyainstall.packages("lubridate")
.Penggunaan: di
f(c(d1,d2,d3))
manac(d1,d2,d3)
adalah vektor bilangan bulat.misalnya
f(c(6,10,14))
pengembalian0.3333333
.The
lubridate
paket memiliki serangkaian fungsi wrapper untuk parsing tanggal dalam urutan yang berbeda. Saya menggunakan ini untuk melihat format mana yang menghasilkan tanggal yang valid, membuang yang tidak valid, dan kemudian melihat mana yang belum terjadi.sumber
Mathematica,
163153164 byte( sunting: tanggal tetap di luar rentang 1950 - 2049)
Ini mendefinisikan fungsi yang bisa Anda panggil
Saat ini, persentase tidak bulat (menunggu OP untuk mengklarifikasi).
Berikut adalah penjelasan sedikit panjang yang harus dimengerti tanpa pengetahuan Mathematica (catatan yang
&
membuat segalanya yang tersisa dari itu fungsi anonim yang parameter yang disebut sebagai#
,#2
,#3
...):Ini mendefinisikan fungsi, yang mengubah 3 parameter
a,b,c
menjadi 3 daftar{{a,b,c},{c,b,a},{c,a,b}
. Perhatikan bahwa##
ini hanyalah urutan dari semua parameter.Diterapkan pada tanggal kedaluwarsa, ini memberikan daftar
{y,m,d}
untuk masing-masing dari tiga kemungkinan permutasi.Ini adalah fungsi anonim yang mengambil tiga parameter
a,b,c
dan mengembalikan daftar ketiganya, di mana yang pertama telah dikonversi menjadi tahun sesuai aturan yang diberikan: angka di antara50
dan99
(modulo100
) diubah menjadi tahun abad ke-20, angka di antara0
dan49
( modulo100
) berubah menjadi tahun abad ke-21, semua yang lain dibiarkan begitu saja. Di sini,##2
adalah urutan parameter dimulai dengan yang kedua, yaitub,c
.Diterapkan pada masing-masing dari tiga hasil sebelumnya, ini hanya mengkanonis format tahun. Sebut ini
canonicalDates
untuk mempersingkat ekspresi berikut:Ini memfilter interpretasi yang tidak valid.
DateList@d
membuat{y,m,d,h,m,s}
representasi penuh dari berbagai format tanggal. Ini akan menginterpretasikan daftar dalam urutan yang sama, tetapi tangkapannya adalah bahwa Anda dapat meneruskannya hal-hal seperti{8,2,2006}
dalam hal mana ia akan menghitung8 years + 2 months + 2006 days
. Jadi kami memeriksa bahwa tiga elemen pertama dari daftar yang dikembalikan identik dengan input (yang hanya dapat terjadi jika bulan dan hari dalam rentang yang sesuai).Untuk mempersingkat baris berikut, saya akan merujuk pada hasil dari ekspresi itu
validDates
mulai sekarang:Fungsi anonim lain yang mengambil tanggal dan mengembalikan perbedaan dalam hari ke hari ini (diperoleh dari
Date[]
).Petakan itu ke interpretasi tanggal yang valid.
Namun fungsi anonim lain yang, diberikan daftar (
#
), mengembalikan persentase angka non-positif dalam daftar itu. Ini.
bukan perkalian tetapi hanya angka desimal, untuk menghindari bilangan rasional sebagai hasilnya (Anda akan mendapatkan hal-hal seperti100/3
bukannya33.333
- Saya tidak benar-benar tahu apakah itu masalah).Diterapkan pada daftar perbedaan tanggal, ini memberi kita sebagian kecil interpretasi yang belum kedaluwarsa.
sumber
JavaScript (E6) 159
164 172Sunting Terima kasih kepada nderscore untuk petunjuk dan untuk mendorong saya untuk berpikir lagi. D diatur ulang menghindari parameter dan memotong beberapa karakter.
Sunting 2 Trik lain oleh nderscore, 2 fungsi digabung menjadi 1. Kemudian dua tanda kurung dihapus menggabungkan ekspresi yang dipisahkan koma menjadi satu. Keterbacaan dekat 0. Sidenote: Tidak membulatkan dapat menyimpan 2 karakter lain (| 0).
Tes di konsol FireFox
Keluaran:
Tidak disatukan
Fungsi NB D mencoba membuat Tanggal dengan tahun, bulan, hari tertentu tetapi menghasilkan false jika tanggal yang dibuat bukan yang diinginkan (! = Hari atau bulan)
sumber
C # dalam LINQPad -
446408272 BytesSunting Ketiga: Terima kasih kepada Le Canard karena telah menunjukkan bahwa DateTime. Hari ini benar, bukan DateTime. Sekarang. Sunting Kedua: Terima kasih VisualMelon untuk solusi pintar ini!
Sunting: Terima kasih kepada podiluska dan edc65 karena membantu saya mempersingkat kode! Saya juga memperhatikan bahwa solusi saya tidak benar jika input tahun panjangnya 4 byte, oleh karena itu saya menyertakan perbaikan untuk masalah itu. Skor untuk solusi ini adalah 408 Bytes.
Meskipun saya tidak mengalahkan jawaban sebelumnya, saya masih ingin membagikan solusi C # saya. Bantuan / saran sangat dihargai! ;)
Versi yang diformat dan tidak disunat:
Saya mencoba membuat solusi di mana "DateTime.TryParse" -Part tidak diulang seperti dalam solusi ini, tapi itu 21 byte lebih lama.
Solusi tanpa mengulangi "DateTime.TryParse": 467 Bytes
Versi tidak disatukan:
sumber
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];
DateTime.TryParse
panggilan adalah insting pertama saya, menggantinya dengan lambda yang juga mengembalikan nilai q. Juga dilakukan beberapa langkah lain ( pastebin ) untuk mendapatkan 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();}
Action<string>
sebelumnya, jadi saya bisa belajar sesuatu dari Anda;) saya bisa mendapatkan jawaban Anda ke 318 karakter dengan menggantiq.Where(i=>i>=DateTime.Now).Count
denganq.Count(i=>i>=DateTime.Now
. Saya juga menghapus tanda kurungx
sehingga saya dapat menyimpan 2 karakter lagi!Haskell,
171165 karakterNama fungsinya adalah
%
. Jalankan dengan tanggal tes sebagai tupel dalam urutan kanonik (y, m, d) dengan tahun aktual, dan cap karton sebagai tupel dengan tiga angka:sumber
Erlang, 146
Fungsi tes adalah:
Tidak disatukan
Solusi ini bergantung pada pemahaman daftar. Ia meminjam trik modulo untuk tahun ini dari solusi Haskell. Ini juga digunakan
calendar:valid_date/1
untuk menangani tanggal yang tidak mungkin karena jumlah hari dalam bulan tertentu (mis. "29-2-2" hanya bisa dalam format YMD). Hari ini juga dalamdate()
format Erlang (tuple YMD).sumber
APL (85)
Ini menggunakan beberapa fungsi baru Dyalog APL 14, tetapi tidak ada perpustakaan eksternal. Untuk perubahan, ini berfungsi di TryAPL .
Ini adalah fungsi yang mengambil array 3-elemen sebagai
⍵
argumen sisi kanan ( ), dan tanggal untuk memeriksa sebagai⍺
argumen sisi kiri ( ), sebagai bilangan bulatYYYYMMDD
format. Yaitu, tanggal2014-07-09
direpresentasikan sebagai angka20140709
.Uji:
Penjelasan:
Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵
: ubah tanggal yang diberikan ke dalam format YMD dengan membalik(⊂⌽⍵)
, memutarnya ke kiri sebanyak 2(⊂2⌽⍵)
, atau hanya tidak melakukan apa-apa⊂⍵
. Setidaknya salah satu dari ini sekarang merupakan tanggal yang tepat dalam format YMD, mungkin lebih dari satu jika tanggalnya tidak jelas.{∧/12 31≥1↓⍵}¨Z
: tes jika setiap tanggal valid: tahun (elemen pertama) dijatuhkan, dan bulannya harus tidak lebih dari 12 dan hari harus tidak lebih tinggi dari 31.Z/⍨
: filter tanggal yang valid dariZ
.{
...}¨
: untuk setiap tanggal yang valid:⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵
: jika tahun tidak lebih tinggi dari 99, tambahkan 1900, lalu 100 jika tahun lebih rendah dari 50.(3/100)⊥
: decode seolah-olah itu adalah seperangkat angka dasar-100. (Tahun lebih tinggi dari 100, tetapi ini tidak masalah karena ini adalah elemen pertama.) Ini memberikan angka untuk setiap tanggal yang valid dalam format yang sama dengan argumen kiri.⍺≤
: untuk setiap tanggal, lihat apakah jumlahnya tidak lebih kecil dari⍺
. Ini akan memberikan vektor biner di mana 1 berartiOK
dan 0 berartispoiled
.100×(+/÷⍴)
: bagi jumlah vektor biner dengan panjangnya dan kalikan dengan 100.sumber
{100×(+/÷⍴)⍺≤((3/100)⊥⊢+(99≥⊃)×3↑1900+100×50>⊃)¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⌽⍵)(2⌽⍵)⍵}
Java: 349 Karakter (3 tanpa ruang)
Berikut ini adalah kelas yang berisi yang dapat digunakan untuk mengujinya, termasuk versi (sedikit) dari metode ini:
Ini adalah babak pertama saya golf kode, dan saya pikir saya tahu mengapa saya biasanya tidak melihat banyak pegolf Jawa.
sumber
int[]
argumen sebagai, bukan tigaint
.C # 287 byte
Pertama kali bermain golf, mencari saran. Khususnya, menghapus byte karena namespace.
Menyalahgunakan fakta bahwa hanya fungsi yang diperlukan, bukan program yang sebenarnya. Juga, fungsi selalu menghasilkan pengecualian tanpa tertangkap.
Tidak disatukan
sumber
Mathematica , 118
Menggunakan kode m.buettner sebagai titik awal, saya memiliki beberapa peningkatan:
sumber