Legalisasikan Tanggal Terbalik


18

Memasukkan:

Tanggal (mengandung dd, MMdan yyyy). Objek-tanggal, atau tiga bilangan bulat terpisah juga valid sebagai input.

Keluaran:

Setiap bagian ( dd, MMdan yyyy) secara individual dikembalikan dan dibulatkan ke tanggal valid terdekat.

Misalnya (dalam format dd-MM-yyyy):
21-10-2016menjadi12-01-6102

Aturan tantangan:

  • Hanya dd, MM, yyyyberlaku, tetapi urutan dan yang terpisah-simbol yang Anda gunakan adalah pilihan Anda sendiri.
    Jadi ini adalah beberapa contoh format yang valid: dd-MM-yyyy; MM/dd/yyyy; yyyy MM dd; ddMMyyyy, Dll
    Dan ini adalah beberapa contoh format yang tidak valid: dd MMM yyyy; dd-MM-'yy; dll.
  • Anda juga dapat memilih untuk hanya memasukkan objek-Tanggal jika bahasa Anda mendukungnya atau tiga parameter integer terpisah, alih-alih string yang mewakili tanggal.
  • Harap sebutkan format tanggal yang Anda gunakan! (Dan input dan output harus dalam format yang sama.) Ia juga diizinkan untuk mengeluarkan objek-Tanggal, selama ia dapat menangani semua kasus uji dan aturan tantangan di bawah ini.
  • Transisi Julian ke Kalender Gregorian diabaikan untuk tantangan ini. Jadi 1582ini hanya tahun terbalik yang valid untuk 2851.
    Lihat Info / tips Tantangan untuk semua tahun, bulan, dan hari yang valid.
  • Karena Anda tidak dapat memiliki Februari sebagai terbalik dari bulan lainnya, Anda tidak perlu khawatir tentang tahun kabisat.

Semua tahun, bulan, dan hari terbalik:

  • Tahun selalu dapat dibalik tanpa masalah, mencapai dari 0001 (terbalik 1000) ke 9999 (tetap 9999). (Jadi 0000bukan input yang valid, dan juga tidak ada test case untuknya.)
  • Satu-satunya bulan Anda akan dibalik adalah: Januari (terbalik dari Oktober / 10); Oktober (terbalik dari Januari / 01); November (tetap November / 11); dan Desember (terbalik dari setiap bulan lainnya / 02- 09, 12).
  • Satu-satunya hari Anda akan membalikkan adalah: 01 (terbalik dari 10), 02 (terbalik dari 20), 03 (terbalik dari 30), 10 (terbalik dari 01), 11 (tetap 11), 12 (terbalik dari 21), 13 (terbalik dari 31) , 20 (terbalik dari 02), 21 (terbalik dari 12), 22 (tetap 22), 30 (terbalik dari 03atau sama dengan 31 untuk November!), 31 (terbalik dari 04- 09/ 13-19/ 23- 29).

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa saja'.
  • Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat dan mengembalikan pernyataan / keluaran, program lengkap. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda.
  • Juga, silakan tambahkan penjelasan jika perlu.

Kasus uji ( dd-MM-yyyysebagai format):

21-07-2016   ->   12-12-6102
12-11-1991   ->   21-11-1991
01-01-2000   ->   10-10-0002
27-08-1875   ->   31-12-5781
18-12-2010   ->   31-12-0102
13-01-1981   ->   31-10-1891
04-11-1671   ->   30-11-1761  // Semi-tricky case, since November has 30 days
28-11-2036   ->   30-11-6302  // Semi-tricky case, since November has 30 days
14-06-1855   ->   31-12-5581
30-10-9999   ->   03-01-9999
01-01-2851   ->   10-10-1582

@ LegionMammal978 Tidak, 21-07-2016dikembalikan 12-70-6102yang dibulatkan menjadi 12-12-6102. Tidak yakin bagaimana Anda mendapatkan hasilnya ##-10-6107..
Kevin Cruijssen

@KevinCruijssen Oke, saya pikir itu adalah bulan yang 70melilit, dengan tahun semakin bertambah.
LegionMammal978

Apakah 10-10-2keluaran yang valid dalam kasus ketiga?
Luis Mendo

@LuisMendo Ya tentu. Saya telah melihat orang lain melakukannya juga. Tantangannya adalah tentang membalikkan dan membulatkan tanggal dengan benar daripada format in- atau output.
Kevin Cruijssen

Apakah bisa diterima untuk mengambil tiga string, dan mengharapkan nol di depan?
JustinM

Jawaban:


3

Cembung , 23 byte

Hitungan byte mengasumsikan pengkodean CP-1252.

qS/Wf%_1=:=31^sCs¶.e<S*

Format I / O adalah dd mm yyyy.

Cobalah online!

Ini adalah port langsung dari jawaban CJam saya . Cembung sangat didasarkan pada CJam, dan oleh karena itu satu-satunya perbedaan adalah penggunaan operator Cembung yang membungkus dua elemen tumpukan teratas dalam daftar, menghemat satu byte lebih [...].


8

CJam, 24 byte

qS/Wf%[_1=:=31^sCs].e<S*

Format I / O adalah dd mm yyyy.

Cobalah online!

Jumlah byte yang sama, format I / O mm dd yyyy:

qS/Wf%_0=:=1231^s2/.e<S*

Cobalah online!

Penjelasan

qS/     e# Read input, split around spaces.
Wf%     e# Reverse each component.
[       e# Set marker for new list.
  _1=   e#   Duplicate reversed strings, extract reversed month.
  :=    e#   Check for equality of the characters. This gives 1 for
        e#   November (11) and 0 for everything else.
  31^   e#   XOR the result with 31, giving 30 for November and 31
        e#   for everything else.
  s     e#   Convert the result to a string, "30"/"31".
  Cs    e#   Push 12, convert to string, "12".
]       e# Wrap "30"/"31" and "12" in a list.
.e<     e# Element-wise minimum. This clamps the day and month to their
        e# respective maxima.
S*      e# Join the result with spaces.

Versi lain berfungsi sama, kecuali bahwa kita mulai dari integer 1230atau 1231sebelum mengubahnya menjadi ["12" "30"] atau ["12" "31"].


2
Bahasa dengan tanggal bawaan ...
Leaky Nun

1
@ LeakyNun Ini tidak menggunakan tanggal bawaan dan saya tidak melihat bagaimana itu akan membantu.
Martin Ender

Lalu bagaimana Anda tahu bahwa ada 30 hari di bulan November?
Leaky Nun

2
@ LeakyNun Saya akan menambahkan penjelasan nanti, tetapi 1=mendapatkan bulan yang dibalik, :=memeriksa apakah angka- ^angkanya sama dan mengubah hasilnya menjadi 31, memberi 30 untuk bulan 11dan 31 untuk yang lainnya.
Martin Ender

Oh, saya tidak membaca spesifikasi ...
Leaky Nun

5

Pyth, 55 53 46 43 41 byte

APJ_Mczd = HHS, 12sH = GHS, SGC @. "❤❤ó» î "H%" % 02d% 02d% s "[GHeJ 
APJ_Mczd = hS, 12sH = hS, SGC @." ❤❤ó »î" H% "% 02d% 02d% s" [GHeJ 
APJ_Mcz \ -% "% 02d% 02d% s" [hS, sGx31q11sHhS, 12sHeJ 
APJ_Mczdjd [> 2+ \ 0hS, sGx31q11sH> 2+ \ 0hS, 12sHeJ
APJ_Mczdjd. [L \ 02 [`hS, sGx31q11sH`hS, 12sHeJ

di mana ❤❤ada dua unsintables, masing-masing U + 001C dan U + 001F.

Suite uji.


3

Python 3, 82 byte

lambda x:[min(x[0][::-1],['31','30'][x[1]=='11']),min(x[1][::-1],'12'),x[2][::-1]]

Fungsi anonim yang mengambil input, melalui argumen, tanggal sebagai daftar string formulir ['dd', 'mm', 'yyyy']dan mengembalikan tanggal terbalik yang divalidasi dalam format yang sama.

Bagaimana itu bekerja

Python membandingkan karakter dan string dengan titik kode Unicode mereka. Ini berarti bahwa setiap perbandingan pada dua atau lebih bilangan bulat mengembalikan sama dengan perbandingan pada bilangan bulat tersebut sebagai string. Oleh karena itu, memanggil mindua bilangan bulat sebagai string mengembalikan integer terkecil sebagai string; dengan mengambil bagian-tanggal terbalik sebagai satu argumen dan nilai maksimum sebagai yang lain, hari dan bulan dijepit ke rentang yang diinginkan. Bagian-tanggal dibalik dengan mengindeks dengan langkah-langkah-1 ( [::-1]), dan nilai maksimum untuk bulan diubah dari '31'menjadi '30'jika bulan adalah November dengan mengindeks ke dalam daftar dengan hasil Boolean dari kondisional.

Cobalah di Ideone


2

Dyalog APL , 32 33 byte

⍕¨{⍵-3↑31 11≡2↑⍵}31 12 1E4⌊⍎∊⍕⌽¨⎕

I / O adalah daftar tiga string ( 'dd' 'mm' 'yyyy').

TryAPL , tetapi perhatikan bahwa (prompt untuk input) telah diganti dengan dan seluruh baris terlampir dalam {... }untuk mengaktifkan pengujian online, dan (jalankan ekspresi) telah diganti dengan 2⊃⎕VFI(verifikasi dan perbaiki input) karena eksekusi kode arbitrer diblokir .


2

C # 314 305 299 249 232 223 Bytes

using System.Linq;string f(int d,int m,int y){Func<int,string>r=i=>string.Concat((""+i).PadLeft(2,'0').Reverse());Func<string,int,string>x=(j,k)=>int.Parse(j)>k?""+k:j;return x(r(d),m==11?30:31)+"-"+x(r(m),12)+"-"+r(y);}

Terima kasih kepada @KevinCruijssen karena menunjukkan bahwa saya dapat mempersingkat deklarasi variabel saya, yang juga membuat string aliasing dapat menghemat beberapa byte.

Menyimpan 50 byte menyimpan fungsi pembalikan untuk digunakan kembali dan 13 lainnya dengan melakukan hal yang sama untuk pembulatan dan menghapus deklarasi variabel.

Pembaruan terakhir membuat string aliasing tidak lagi menjadi byte saver.

Versi Tidak Serigala:

using System.Linq;
    string dateReverse(int day, int month, int year)
{
    //setup a resuable function to reverse
    Func<int, string> reverse = intToReverse => string.Concat((""+intToReverse).PadLeft(2, '0').Reverse());

    //another function for rounding
    Func<string, int, string> round = (strToRound, maxVal) => int.Parse(strToRound) > maxVal ? "" + maxVal : strToRound;

    //Join the strings into the "dd-mm-yyyy" date format
    return 
        //Round down the day value, if november cap to 30 otherwise cap to 31
        round(reverse(day), month == 11 ? 30 : 31) + "-" +

        //Round the month down
        round(reverse(month), 12) + "-" +

        //we can use the reverse function here too and pad left just won't do anything
        reverse(year);
}

Uji di sini


Anda dapat mengabaikan ruang di antara using System.Linq;dan fungsinya, jadi itu -1 byte. Juga, var n=...;var e=...;bisa di-golf dengan 1 byte menggunakan ini sebagai gantinya: string n=...,e=...;Ini tidak banyak, tetapi masih -2 byte. ;)
Kevin Cruijssen

Bagus menangkap ruang itu, meskipun sepertinya jumlah byte saya sebenarnya tidak menghitungnya, sangat sakit sampai masalah copy paste. Juga saya pikir menggunakan gaya deklarasi variabel saya akan dapat memenangkan beberapa byte lagi dengan aliasing string.
JustinM

2

Javascript, 106 105 94 byte

d=>d.split`,`.map((a,b,r)=>(e=[...a].reverse().join``,f=!b?r[1]==11^31:b<2&&12,f&&f<e?f:e))+''

Test suite (rev. 3)


Penjelasan

d=>d.split`,`                 // split into sections by `,`

.map((a,b,r)=>(               // map each section

e=[...a].reverse().join``,    // spread a date section into array and reverse and 
                              // join with `` to get string result

f=!b?r[1]==11^31              // if section being mapped is day (section 0), 
                              // then max (f) is 30 for November(month 11) or else 31

:b<2&&12,                     // if part being mapped is month (section 1), then max (f) is 12

f&&f<e?f:e))                  // if there is a max (f)
                              // and the max (f) is less than the reversed string (e),
                              // then return the max (f), 
                              // else return the reversed string (e)

+''                           // join all the sections back together with `,` 
                              // (concatenating [] with a string will do this)

Terima kasih @KevinCruijssen untuk menyimpan 1 byte untuk b==1ke b<2. Terima kasih @Neil untuk menyimpan 11 byte dengan menyarankan literal dan ,pemisah template ES6 .


Saya sangat buruk di JS, jadi perbaiki saya jika saya mengatakan sesuatu yang salah, tetapi tidak b==1bisa di-golf b<2untuk menghemat byte? Tidak boleh 0 lagi, karena Anda sudah memeriksanya di !b?bagian kode. Tampaknya berfungsi di ruang tes Anda ketika saya mengubahnya.
Kevin Cruijssen

@KevinCruijssen ya, Anda benar, terima kasih! Saya hanya mengabaikannya. Saya belum pernah bermain golf di javascript untuk waktu yang lama jadi saya kehilangan hal-hal seperti itu kadang
CShark

* Maksud saya 'sangat lama', bukan 'sangat kelihatan'
CShark

2
Saat Anda menargetkan ES6, Anda dapat menggunakan string template untuk mempersingkat kode Anda - join``alih - alih join('')misalnya - tetapi Anda dapat menyimpan sedikit lebih banyak dengan menggunakan ,sebagai pemisah Anda, yang memungkinkan Anda +''untuk menggabungkan ketiga nilai bersama-sama.
Neil

@Neil maksudmu ,sebagai pemisah dalam input?
CShark

1

Ruby, 92 84 + 1 ( -pbendera) = 93 85 byte

Digunakan -sebagai pemisah.

d,m,y=chomp.split(?-).map &:reverse
$_=[[d,m=="11"?"30":"31"].min,[m,"12"].min,y]*?-


0

Python 2, 154 byte

z=input().split("-");r=[x[::-1]for x in z];z[1]=r[1]if r[1]<'12'else '12';z[0]=r[0]if r[0]<'31'else '30'if z[1]=='11'else '31';z[2]=r[2];print "-".join(z)

Mengambil input sebagai string, jadi tanda kutip perlu ditentukan dalam input, misalnya "11-04-2016".


Hanya perbaikan dasar karena saya tidak pegolf Python: z=[x[::-1]for x in z];z[1]=min(z[1],'12');z[0]=min(z[0],['31','30'][z[1]=='11']);print"-".join(z). Pada dasarnya, Anda tidak perlu menggunakan rsama sekali, dan minmenyelesaikan banyak hal yang ingin Anda lakukan.
Nilai Tinta

0

05AB1E , 24 byte

#íÐÅsË31^12‚øεßт+¦}sθªðý

Port of CJam @MartinEnder menjawab , demikian juga input dan output sebagai string dalam format dd MM yyyy.

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

#                         # Split the (implicit) input by spaces
                          #  i.e. "04 11 1671" → ["04","11","1671"]
                          #  i.e. "20 01 2000" → ["20","01","2000"]
 í                        # Reverse each string
                          #  i.e. ["04","11","1671"] → ["40","11","1761"]
                          #  i.e. ["20","01","2000"] → ["02","10","0002"]
  Ð                       # Triplicate this list
   Ås                     # Pop one of them, and push it's middle element (the months)
                          #  i.e. ["40","11","1761"] → "11"
                          #  i.e. ["02","10","0002"] → "10"
     Ë                    # Check if the digits are the same (1 for 11; 0 otherwise)
                          #  i.e. "11" → 1 (truthy)
                          #  i.e. "10" → 0 (falsey)
      31^                 # Bitwise-XOR with 31 (30 for November, 31 for other months)
                          #  i.e. 1 → 30
                          #  i.e. 0 → 31
         12              # Pair it with 12
                          #  i.e. 30 → [30,12]
                          #  i.e. 31 → [31,12]
            ø             # Zip/transpose; swapping rows and columns
                          # (implicitly removes year)
                          #  i.e. ["40","11","1761"] and [30,12] → [["40",30],["11",12]]
                          #  i.e. ["02","10","0002"] and [31,12] → [["02",31],["10",12]]
             ε    }       # Map each pair to:
              ß           # Get the minimum (implicitly converts to integer unfortunately)
                          #  i.e. [["40",30],["11",12]] → [30,11]
                          #  i.e. [["02",31],["10",12]] → [2,10]
               т+         # Add 100
                          #  i.e. [30,11] → [130,111]
                          #  i.e. [2,10] → [102,110]
                 ¦        # Remove the first character
                          #  i.e. [130,111] → ["30","11"]
                          #  i.e. [102,110] → ["02","10"]
                   s      # Swap so the triplicated list is at the top of the stack again
                    θ     # Pop and only leave it's last element (the year)
                          #  i.e. ["40","11","1761"] → "1761"
                          #  i.e. ["02","10","0002"] → "0002"
                     ª    # Append it to the list
                          #  i.e. ["30","11"] and "1761" → ["30","11","1761"]
                          #  i.e. ["02","10"] and "0002" → ["02","10","0002"]
                      ðý  # Join the list by spaces (and output implicitly)
                          #  i.e. ["30","11","1761"] → "30 11 1761"
                          #  i.e. ["02","10","0002"] → "02 10 0002"
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.