Optimasi Alarm

28

Jam Alarm saya

Saya orang Amerika, dan begitu juga jam alarm (digital) saya. Untuk mengatur alarm, itu dimulai pada waktu sebelumnya. Menekan tombol jam memindahkannya satu jam, dan menekan tombol menit bergerak naik satu menit. Menekan kedua tombol pada saat yang sama mengatur ulang ke tengah malam (12:00 pagi), dan dihitung sebagai dua tombol yang ditekan.

Ketika jam melebihi batasnya (12), reset ke 1 dan matikan lampu AM / PM. Ketika menit melebihi batasnya (59), mereka mengatur ulang ke 0, tanpa mempengaruhi jam.

Tugas

Tugas Anda adalah, diberi waktu mulai dan waktu target, untuk menampilkan jumlah tombol yang optimal yang diperlukan untuk mengatur alarm saya ke waktu target.

Anda dapat mengambil input dalam format apa pun yang paling cocok untuk Anda. Satu-satunya data yang perlu program Anda adalah jam dan menit, untuk kedua input. Itu berarti bahwa Anda, misalnya, dapat mengambil data sebagai milidetik sejak zaman, dan mengekstrak jam dan menit, tetapi Anda tidak dapat menyandikan apa pun ke tahun, bulan, detik, dll. Perhatikan bahwa saat Anda dapat, misalnya, input menggunakan "Waktu militer" (atau waktu reguler untuk sebagian besar dunia), tetapi itu tidak mengubah cara jam saya bekerja.

Contohnya

1:15 pm -> 2:30 am

Anda dapat menekan kedua tombol ke bawah untuk mengatur ulang hingga pukul 12:00 pagi, lalu naik menjadi 02:30, yang merupakan 2+2+30 = 34penekanan tombol. Anda juga bisa menambah hingga 02:30, yang akan menjadi 13+15 = 28penekanan tombol. Karena itu, output Anda 28.

3:58 am -> 4:02 am

Anda dapat mengatur ulang dan menambah, yang merupakan 2+4+2 = 8penekanan tombol. Anda juga bisa menambahkan, yang merupakan 1+4 = 5penekanan tombol. Karena itu, output Anda 5.

10:55 pm -> 1:00 am

Anda dapat mengatur ulang dan menambah, yang merupakan 2+1 = 3penekanan tombol. Anda juga bisa menambahkan, yang merupakan 3+5=8penekanan tombol. Karena itu, output Anda 3.

1:00 am -> 1:59 pm

Anda bisa mengatur ulang dan menambah, tetapi itu akan menjadi tiga penekanan lebih dari sekadar menambah. Karena itu, output Anda 12+59 = 71.

Uji Kasus

Current  Target   = Output
1:15pm   2:30am   = 28
3:58am   4:02am   = 5
10:55pm  1:00am   = 3
1:00am   1:59pm   = 71
12:00am  12:00am  = 0
6:51pm   12:00am  = 2
2:01pm   11:00pm  = 25
2:01pm   11:01pm  = 9
12:59am  12:01am  = 2
11:50am  12:00pm  = 11
Stephen
sumber
Sandbox
Stephen
13
Sial! Menekan kedua tombol itu akan menyetel ulang jam alarm saya (Eropa) menjadi 0:00 juga ... Bertahun-tahun ini terlalu sering menekan tombol ... O_o
Arnauld
8
"waktu militer (atau waktu reguler untuk sebagian besar dunia)" ... istilah yang Anda cari adalah "waktu 24 jam".
Jakob
12
@ Jakob Tidak, istilah yang dia cari adalah "waktu reguler". Orang Amerika menggunakan waktu yang tidak teratur, tanggal tidak teratur, unit tidak teratur, dll.
Neil
1
@LangkahHen saya di Inggris dan tidak tahu apa yang Anda maksud dengan "waktu militer" sampai Jakob menjelaskannya. Waktu 24 jam masuk akal bagi saya
Darren H

Jawaban:

5

Sekam , 16 byte

§▼ṁ→(Σz%e24 60z-

Cobalah online!

Membawa argumen sebagai dua daftar [jam, menit], untuk waktu mulai dan berakhir, dalam format 24 jam.

Saya cukup senang tentang seberapa banyak saya bisa bermain golf yang satu ini, saya merasa menarik bagaimana argumen dikelola dalam komposisi fungsi ini.

Fungsi yang menghitung berapa banyak penekanan tombol yang kita butuhkan jika reset tidak diizinkan adalah sebagai berikut:

Σz%e24 60z-
         z-    elementwise subtract the two times
 z%e24 60      take the hours difference modulo 24 and the minutes difference modulo 60
Σ              sum the two resulting numbers

Bagian yang menarik adalah bahwa karena sisa solusi ini hanya dapat berfungsi dengan satu daftar sebagai argumen, yang satu ini akan diterapkan sebagian pada argumen pertama dari keseluruhan program, "memakannya" dan hanya menyisakan argumen kedua yang terlihat baik untuk dirinya sendiri maupun sisa program.

Selanjutnya, kita menghitung berapa banyak penekanan tombol yang kita butuhkan jika kita mereset waktu ke 0:00

ṁ→    take the sum of each element of the list increased by 1

Seperti yang dikatakan sebelumnya, ini hanya beroperasi pada argumen kedua (waktu terakhir), dan menghitung hours+minutes+2, hanya dengan cara golf.

Akhirnya, §▼adalah bagian yang meneruskan argumen kedua ke kedua fungsi, dan mengembalikan yang lebih rendah dari dua hasil.

Leo
sumber
8

JavaScript (ES6), 73 56 54 52 50 byte

Menggunakan format 24 jam. Mengambil input sebagai 4 bilangan bulat yang mewakili jam & menit setiap kali.

(g,l,h,m)=>Math.min(2+h+m,(h-g+24)%24+(m-l+60)%60)

Cobalah

Masukkan waktu dalam format 24 jam, dengan :pemisah.

o.innerText=(f=

(g,l,h,m)=>Math.min(2+h+m,(h-g+24)%24+(m-l+60)%60)

)(+(x=(i.value="01:00").split`:`)[0],+x[1],+(y=(j.value="13:59").split`:`)[0],+y[1]);oninput=_=>o.innerText=f(+(x=i.value.split`:`)[0],+x[1],+(y=j.value.split`:`)[0],+y[1])
label,input{font-family:sans-serif;font-size:14px;height:20px;line-height:20px;vertical-align:middle}input{margin:0 5px 0 0;width:100px;}
<label for=i>Current: </label><input id=i type=time><label for=j>Target: </label><input id=j type=time><pre id=o>


Penjelasan

(Akan segera diperbarui.)

(g,l,h,m)=>

Fungsi anonim mengambil bilangan bulat sebagai argumen melalui parameter g, l, h& m, di mana g& lmasing-masing adalah, jam & menit dari waktu saat ini dan h& madalah jam & menit dari target waktu.

2+h+m

Pertama, kami menghitung berapa banyak penekanan tombol yang diperlukan jika kami hanya mengatur ulang jam, yang hanya 2 (untuk reset) ditambah jam target dan menit target.

h-g+24*(h<g)

Selanjutnya kita menghitung berapa banyak penekanan tombol yang diperlukan untuk mencapai jam target. Kami melakukan ini dengan mengurangi jam saat ini dari jam target. Namun, jika jam saat ini kurang dari target, ini akan memberi kita angka negatif sehingga kami memperbaiki bahwa dengan menambahkan 24 dikalikan dengan memeriksa jika h<g(yang mengembalikan boolean tetapi secara implisit dilemparkan ke bilangan bulat 1, jika benar, atau 0jika salah oleh operasi matematika.

+m-l+60*(m<l)

Kami menggunakan rumus yang sama untuk menghitung jumlah penekanan untuk mendapatkan dari menit saat ini ke menit target dan menambahkannya ke penekanan jam.

Math.min()

Akhirnya, kami mendapatkan minimal 2 angka untuk memberi kami hasil kami.

Shaggy
sumber
1
Bisakah kamu melakukannya (h-g+24)%24+(m-l+60)%60?
Arnauld
7

Pyth , 29 byte

Tantangan ini jelas tidak menguntungkan bahasa golf, itu sebabnya begitu lama. Di sisi lain, ini ditingkatkan oleh fakta bahwa Pyth berbasis Python, sehingga kita dapat menyalahgunakan modulus negatifnya.

hS,+%-eQ@Q1 60%-@Q2hQ24+2s>Q2

Test Suite. Angka dalam Pyth tidak mendukung angka nol di depan.

Tuan Xcoder
sumber
5

Jelly , 19 byte

_⁵%24µ+⁴_⁶%60µ«³+⁴¤

Cobalah online!

Input sebagai 4 bilangan bulat (jam akhir, menit akhir, jam mulai, menit mulai)

HyperNeutrino
sumber
@ETHproductions ಠ_ಠ
HyperNeutrino
3

C # (.NET Core) , 56 byte

(H,M,h,m)=>Math.Min(((h+24-H)%24)+((m+60-M)%60),(2+h+m))

Cobalah online!

Sangat mirip dengan jawaban Javascript. Bools dalam C # tidak mudah dikonversi ke angka, jadi alih-alih [diff]+24*(H<h)saya melakukan ([diff]+24)%24yang secara efektif melakukan hal yang sama.

Kamil Drakari
sumber
Anda dapat menghapus tanda kurung sekitar 2+h+m-2 byte.
Kevin Cruijssen
Saya telah membuat port jawaban Anda di Java 8 , dan perhatikan Anda dapat menambahkan empat byte tambahan dengan menghapus lebih banyak tanda kurung, diakhiri dengan ini(H,M,h,m)=>Math.Min((h+24-H)%24+(m+60-M%60),2+h+m)
Kevin Cruijssen
1
Tidakkah Anda harus berhasil System.Math.Min?
LiefdeWen
3

Haskell, 41 byte

(a#b)c d=min(a+b+2)$mod(a-c)24+mod(b-d)60

Cukup mudah. Mengambil input sebagai empat argumen menggunakan waktu 24 jam: jam akhir, menit akhir, jam mulai, menit mulai.

Silvio Mayolo
sumber
2

Python 3 , 43 byte

lambda a,b,c,d:min((c-a)%24+(d-b)%60,2+c+d)

Cobalah online!

Input sebagai 4 bilangan bulat (jam mulai, menit mulai, jam akhir, menit akhir)

HyperNeutrino
sumber
@StepHen Whoops. Memperbaiki mudah.
HyperNeutrino
Gagal2 01 11 00 ? Dalam jawaban Anda, bagaimana Anda menentukan apakah waktu itu AMatau PM, jika Anda tidak menganggapnya sebagai input?
Tn. Xcoder
@ Mr.Xcoder; Saya mendapatkan 13input itu menggunakan TIO, yang benar (reset + 11 <9 + 59).
Shaggy
2
Apakah %selalu mengembalikan angka positif dengan Python?
Shaggy
4
@ Shaggy selalu mengembalikan tanda sisi kanan %. 1%24= 1, 1%-24= -23. Ini sangat membantu untuk pertanyaan ini.
Stephen
2

Java 8, 54 50 byte

(h,m,H,M)->Math.min((H-h+24)%24+(M-m+60)%60,H+M+2)

Port dari jawaban #KamilDrakari C # (setelah saya main golf 2 6 byte).

Penjelasan:

Coba di sini.

(h,m,H,M)->       // Method with four integer parameter and integer return-type
  Math.min(       //  Return the lowest of the following two:
                  //   The hours:
   (H-h           //    Second hours - first hours inputs
       +24)       //    +24 so we won't have negative numbers
           %24    //    mod-24 to get the hours
   +              //   And add the minutes:
    (M-m          //    Second minutes - first minutes inputs
         +60)     //    +60 so we won't have negative numbers
             %60  //    mod-60 to get the minutes
    ,H+M          //  And compare it to the second hours + second minutes inputs
        +2)       //   +2 for the added +24 and +60 to get the positive modulo arguments
Kevin Cruijssen
sumber
1

Perl 5 , 71 +2 (-ap) = 73 byte

($w,$x,$y,$z)=@F;$_=($r=2+$y+$z)>($c=($y-$w+24)%24+($z-$x+60)%60)?$c:$r

Cobalah online!

Mengambil input dalam format 24 jam (waktu militer), dipisahkan oleh spasi, waktu mulai pertama, waktu akhir kedua: HH MM hh mm

Xcali
sumber
1

Retina , 106 byte

\d+
$*
 (1*):(1*)
 24$*1$1:60$*1$2#11$1$2
(1*):(1* )\1(1{24})?
$2
(1*) (1*):\1(1{60})?
$2
(1+)#(?!\1)

\G1

Cobalah online! Tautan termasuk kasus uji. Mengambil input sebagai arus dan waktu yang diinginkan dalam waktu 24 jam reguler dengan ruang yang memisahkan dua kali. Penjelasan:

\d+
$*

Konversikan ke unary.

 (1*):(1*)
 24$*1$1:60$*1$2#11$1$2

Ini melakukan dua hal; itu menambah 24 jam dan 60 menit ke jam dan menit yang diinginkan, dan itu juga menambahkan 2 ke jumlah jam dan menit yang diinginkan asli, yaitu jumlah tombol yang ditekan untuk mengatur menggunakan reset.

(1*):(1* )\1(1{24})?
$2

Kurangi jam saat ini dari jam yang diinginkan, dan kurangi 24 yang kita tambahkan jika kita bisa.

(1*) (1*):\1(1{60})?
$2

Demikian pula untuk menit-menitnya. Ini juga menambahkan dua hasil bersama.

(1+)#(?!\1)

Jika jumlah penekanan yang diatur menggunakan waktu saat ini lebih dari jumlah penekanan yang diatur menggunakan reset, hapuslah.

\G1

Konversi angka yang tersisa pertama kembali ke desimal.

Neil
sumber