Berapa lama lagi?

21

Berapa lama lagi?

Baru-baru ini, saya membuat pizza menggunakan penghitung waktu 5 menit di ponsel saya. Ketika seseorang masuk dan bertanya kepada saya berapa lama yang tersisa, pada awalnya saya bingung bagaimana menjawab pertanyaan itu. Anda tahu, jika penghitung waktu saat ini adalah jam 3:47, pada saat saya membacakan 'Tiga menit empat puluh tujuh detik' dengan keras, waktu akan berubah. Oleh karena itu, saya harus mencari waktu yang timer akan mencapai hanya karena saya selesai membaca itu.

Ini adalah tantangan Anda: untuk mengotomatisasi proses ini. Diberi waktu dalam format apa pun yang sesuai (":" dibatasi, atau sebagai argumen menit dan kedua), mengeluarkan waktu paling awal dari momen saat ini yang akan mengambil jumlah waktu yang sama untuk dibacakan karena waktu yang diperlukan pengatur waktu untuk mendapatkan untuk. Kami mengasumsikan bahwa setiap suku kata membutuhkan waktu 1 detik untuk membacanya.

Aturan lebih lanjut

  • Anda harus menghitung 'menit' dan 'detik' sebagai dua suku kata masing-masing, serta 'dan' di antara mereka.
  • Pizza tidak akan pernah membutuhkan lebih dari 59:59 untuk memasak.
  • '11 menit dan 0 detik 'bukan 10 suku kata: Anda harus menyederhanakan menjadi '11 menit' (yaitu 5 suku kata). Sama halnya dengan menit: '0 menit dan 7 detik' juga hanya dihitung sebagai 4 suku kata.
  • Program Anda dapat memberikan output dalam format apa pun: array [minutes, seconds], atau bahkan sebagai <minutes> minutes and <seconds> seconds(teks biasa dituliskan).
  • Celah standar berlaku.
  • Ini adalah , jadi jawaban tersingkat dalam byte menang.

Uji kasus

Semua input sebagai (minutes, seconds)

(4, 47) = (4, 38) (Four MiNutes And ThirTy Eight SeConds - 9 syllables/seconds)
(1, 1) = (0, 56) (FifTy-Six SeConds - 5 syllables/seconds)
(59, 57) = (59, 46) (FifTy Nine Minutes And Forty Six SeConds - 11 syllables/seconds)
(0, 10) = null/error/0 (no positive answer)

Referensi jumlah suku kata

Untuk referensi, berikut adalah jumlah suku kata di setiap nomor hingga 59.

0,0 (does not need to be counted)
1,1
2,1
3,1
4,1
5,1
6,1
7,2
8,1
9,1
10,1
11,3
12,1
13,2
14,2
15,2
16,2
17,3
18,2
19,2
20,2
21,3
22,3
23,3
24,3
25,3
26,3
27,4
28,3
29,3
30,2
31,3
32,3
33,3
34,3
35,3
36,3
37,4
38,3
39,3
40,2
41,3
42,3
43,3
44,3
45,3
46,3
47,4
48,3
49,3
50,2
51,3
52,3
53,3
54,3
55,3
56,3
57,4
58,3
59,3
Geza Kerecsenyi
sumber
Untuk kasus uji pertama Anda, apakah 4:37 juga akan menjadi output yang valid, karena itu akan membutuhkan 10 suku kata untuk dikatakan?
Quinn
1
@ Quinn, spesifikasi menyatakan bahwa kita harus menampilkan waktu paling awal .
Shaggy
1
@Shaggy whoops, jadi terima kasih - saat saya menyortir jawaban, saya pikir pizza saya akan hangus
Quinn
Apakah kita boleh berasumsi bahwa input dapat diisi, yaitu 4 menit dan 43 detik dapat dimasukkan sebagai "04:43"?
Vedvart1
1
@ Vedvart1 OK, tidak apa-apa
Geza Kerecsenyi

Jawaban:

4

JavaScript (ES6),  112 106  105 byte

Versi yang lebih pendek berdasarkan saran dari @EmbodimentofIgnorance
6 byte lebih disimpan oleh @DaniilTutubalin

(minutes)(seconds)[minutes, seconds]0

m=>d=F=s=>m|s?(g=n=>n&&(n%10!=7)-7+(n-11?n<13?2:n<21|n%10<1:0))(m)+g(s)^~d?F(s?s-1:m--&&59,d=-~d):[m,s]:0

Cobalah online!


JavaScript (ES6),  126  119 byte

(minutes)(seconds)[minutes, seconds]0

m=>d=F=s=>m|s?(g=n=>n&&2+(30774612>>2*n%(n>12?20:26)&3)+(n>12)+(n>19))(m)+g(s)+!!(m*s)^d?F(s?s-1:m--&&59,d=-~d):[m,s]:0

Cobalah online!

Berkomentar

m =>                  // m = minutes
d =                   // d = delta in seconds between the initial time and the current time,
                      //     initialized to a non-numeric value (zero-ish)
F = s =>              // F is a recursive function taking s = seconds
  m | s ? (           // if either m or s is not 0:
    g = n =>          //   g is a helper function taking an integer n in [0..59]
      n &&            //     return 0 if n = 0
      2 + (           //     otherwise, start with 2 for either 'mi-nutes' or 'se-conds'
        30774612 >>   //     add the base number of syllables (0 to 3) corresponding to n
        2 * n %       //     using a bitmask of 13 entries x 2-bit:
                      //       12 11 10  9  8  7  6  5  4  3  2  1  0
                      //       01 11 01 01 01 10 01 01 01 01 01 01 00
        (n > 12 ? 20  //     using n MOD 10 if n is greater than 12
                : 26) //     or just n otherwise
        & 3           //     isolate the two least significant bits
      ) +             //   
      (n > 12) +      //     add 1 syllable for '-teen' or '-ty' if n is greater than 12
      (n > 19)        //     add 1 more syllable for 'x-ty' if n is greater than 19
  )(m) +              //   invoke g for the minutes
  g(s) +              //   invoke g for the seconds
  !!(m * s)           //   add 1 syllable for 'and' if both m and s are non-zero
  ^ d ?               //   if the result is not equal to the delta:
    F(                //     otherwise, do a recursive call:
      s ? s - 1       //       decrement s if it's not 0,
        : m-- && 59,  //       or decrement m and restart with s = 59
      d = -~d         //       increment the delta
    )                 //     end of recursive call
  :                   //   else:
    [m, s]            //     success: return [m, s]
:                     // else:
  0                   //   failure: return 0
Arnauld
sumber
Bisakah Anda menambahkan penjelasan?
Geza Kerecsenyi
@GezaKerecsenyi Selesai. :-)
Arnauld
Terima kasih. Itu sebagian besar 30774612>>2*n%(n>12?20:26)&3bagian saya bingung tentang.
Geza Kerecsenyi
1
g=x=>x&&(x%10==7)+(x==11?6:x<13?4:x<21|x%10<1?5:6)mungkin berfungsi (belum diuji sejak Internet sedang tidak aktif dan menggunakan telepon saya)
Perwujudan Ketidaktahuan
1
@DaniilTutubalin Keren. Saya menyimpan byte lain dari sana dengan g()mengembalikan hasil yang berlawanan dan XOR'ing dengan ~d.
Arnauld
2

Python 3 , 287 285 byte

m=int(input())
s=int(input())
y=lambda w:3+(w[-1]=='7')-(w[-1]=='0')-(w[0]in'01')*(1+(w[0]=='0'))+(w=='11')-(w=='12')
z=lambda m,s:(2+y(f'{m:02d}'))*(m!=0)+(2+y(f'{s:02d}'))*(s!=0)+(m!=0!=s)
q=lambda t: (m-(t+60-s-1)//60,(s-t)%60)
print([q(t) for t in range(s+60*m) if z(*q(t))==t][0])

Cobalah online!

Ini bukan solusi yang sangat pintar - itu sebagian besar striaghtforward. Mengambil 'm: s' m dan s sebagai input terpisah (tidak perlu diisi), dan output (m, s). Melempar kesalahan jika tidak ada output yang valid.

Program ini sangat bergantung pada casting boolean secara implisit ke 0 dan 1. Baris pertama mengambil input. Baris kedua mendefinisikan fungsi lambda y yang memberikan suku kata dalam angka - ia mengasumsikan basis 3 suku kata, kemudian menambahkan 1 jika berakhir dengan 7, mengurangi 1 jika berakhir dengan 0, dan mengurangi 1 jika itu dalam 10 dan 2 jika dalam satu digit. Dua belas dan sebelas disesuaikan secara manual di akhir. Baris ketiga adalah lambda untuk suku kata dalam keseluruhan ekspresi. Akhirnya, baris keempat memberi waktu setelah t detik. Baris kelima adalah output - ini membangun array dari semua waktu yang memenuhi masalah, dan output yang pertama.

EDIT 1: Terima kasih kepada Matthew Anderson di komentar, 2 byte dicukur dengan mengambil input secara terpisah.

Vedvart1
sumber
1
Jika Anda mengambil input pada dua baris terpisah:, m=int(input()) s=int(input())Anda dapat menyimpan 2 byte.
Matthew Anderson
1

Jelly , 46 byte

ḅḶbɗ60Ṛµ“÷ṢḣxE⁻Ṇ⁹ƬƝwɼỤṡl’ḃ4+2;0⁸ịS+ṬS$’)=JTị⁸Ḣ

Cobalah online!

Tautan monadik mengambil sebagai argumennya waktu [minutes, seconds]dan mengembalikan waktu yang tepat untuk mengatakan sebagai [minutes, seconds]atau [seconds]jika kurang dari satu menit.

Nick Kennedy
sumber
0

CJam , 102 byte

60:X;q~\X*+:W_{;(__X%\X/{_196656821516111872\_A%K+e<_{(2*m>3&3.5+}{\;}?@}2*+i+\X*+_W=!2$0<-}g;_X%\X/S@

Cobalah online!

Hanya mencari biner angka-sihir tua yang membosankan, tidak ada yang bisa dilihat di sini.

JosiahRyanW
sumber