Berapa usianya kira-kira?


29

Tulis program singkat yang menghasilkan jumlah detik positif yang mewakili suatu umur, dan menghasilkan perkiraan waktu itu dalam bahasa Inggris.

Program Anda harus menampilkan jumlah waktu paling tidak tepat yang telah berlalu, di antara metrik berikut dan panjangnya dalam detik:

second = 1
minute = 60
hour   = 60 * 60
day    = 60 * 60 * 24
week   = 60 * 60 * 24 * 7
month  = 60 * 60 * 24 * 31
year   = 60 * 60 * 24 * 365

Contohnya

input      : output
1          : 1 second
59         : 59 seconds
60         : 1 minute
119        : 1 minute
120        : 2 minutes
43200      : 12 hours
86401      : 1 day
1815603    : 3 weeks
1426636800 : 45 years

Seperti yang dapat Anda lihat di atas, setelah waktu mengatakan, 1 hari (60 * 60 * 24 = 86400 detik), kami tidak lagi mengeluarkan menit atau jam , tetapi hanya beberapa hari sampai kami melampaui waktu satu minggu , dan seterusnya.

Pertimbangkan lamanya waktu yang diberikan untuk menjadi usia. Misalnya, setelah 119 detik, 1 menit berlalu , bukan 2.

Aturan

  • Tidak ada spesifikasi untuk 0 atau input negatif.
  • Ikuti pluralisasi yang tepat. Setiap ukuran lebih besar dari 1 harus menyertakan kata sberikut.
  • Anda tidak dapat menggunakan perpustakaan yang sudah ada sebelumnya yang melayani fungsi dari seluruh program.
  • Ini adalah kode golf, program terpendek memenangkan poin internet.
  • Selamat bersenang-senang!

3
Saya tidak mengerti bagaimana kami memilih unit atau jumlah. Apakah kita bulat?
xnor

1
@ xnor kita integer membagi dan menggunakan nilai bukan nol terkecil bersama dengan unitnya (mungkin jamak). Karenanya 59 -> "59 detik" dan 86401 -> "1 hari".
Jonathan Allan

5
Selamat datang di PPCG! Tantangan pertama yang bagus. Untuk referensi di masa mendatang ada kotak pasir yang berguna untuk mendapatkan umpan balik sebelum memposting ke utama.
Jonathan Allan

4
Perhatikan bahwa Do X tanpa Y tidak disarankan, serta persyaratan program yang tidak dapat diamati .
user202729

1
Bagaimana seharusnya kita membulatkan angka? Haruskah 119 detik menjadi 1 menit atau 2 menit? Bagaimana dengan 90?
user202729

Jawaban:


8

Jelly , 62 byte

TṀị
“¢<<ð¢‘×\×€0¦7,31,365F⁸:µç“ɲþḣ⁹ḢṡṾDU¤µQƝṁ⁼ẹ»Ḳ¤ṭÇK;⁸Ç>1¤¡”s

Program lengkap mencetak hasilnya.
(Sebagai tautan monadik, ia mengembalikan daftar bilangan bulat diikuti oleh karakter)

Cobalah online!

Bagaimana?

TṀị - Link 1: list of integers, K; list, V  e.g. [86401,1440,24,1,0,0,0], ["second","minute","hour","day","week","month","year"]
T   - truthy indexes of K                        [1,2,3,4]
 Ṁ  - maximum                                    4
  ị - index into V                               "day"

“¢<<ð¢‘×\×€0¦7,31,365F⁸:µç“...»Ḳ¤ṭÇK;⁸Ç>1¤¡”s - Main link: integer, N  e.g. 3599
“¢<<𢑠                                      - list of code-page indices = [1,60,60,24,1]
        \                                     - cumulative reduce with:
       ×                                      -  multiplication = [1,60,3600,86400,86400]
             7,31,365                         - list of integers = [7,31,365]
            ¦                                 - sparse application...
           0                                  - ...to index: 0 (rightmost)
         ×€                                   - ...of: multiplication for €ach = [1,60,3600,86400,[604800,2678400,31536000]]
                     F                        - flatten = [1,60,3600,86400,604800,2678400,31536000]
                      ⁸                       - chain's left argument, N    3599
                       :                      - integer divide         [3599,59,0,0,0,0,0]
                        µ                     - start a new monadic chain, call that X
                                ¤             - nilad followed by links as a nilad:
                          “...»               -   compression of "second minute hour day week month year"
                               Ḳ              -   split at spaces = ["second","minute","hour","day","week","month","year"]
                         ç                    - call the last link (1) as a dyad - i.e. f(X,["second","minute","hour","day","week","month","year"])
                                              -                             "minute"
                                  Ç           - call the last link (1) as a monad - i.e. f(X,X)
                                              -                             59
                                 ṭ            - tack                        [59,['m','i','n','u','t','e']]
                                   K          - join with spaces            [59,' ','m','i','n','u','t','e']
                                           ”s - literal character '
                                          ¡   - repeat...
                                         ¤    - ...number of times: nilad followed by link(s) as a nilad:
                                     ⁸        -   chain's left argument, X  [3599,59,0,0,0,0,0]
                                      Ç       -   call the last link (1) as a monad - i.e. f(X,X)
                                              -                             59
                                       >1     -   greater than 1?           1
                                    ;         - concatenate                 [59,' ','m','i','n','u','t','e','s']
                                              - implicit print - smashes to print  "59 minutes"

8

C, 194 180 144 128 karakter

Terima kasih kepada @gastropher untuk pengurangan kode. Saya lupa bahwa C memungkinkan untuk parameter implisit menggunakan fungsi K&R! Juga terima kasih kepada @gmatht untuk ide menempatkan literal di dalam bukan array. Saya memperluas itu ke karakter dengan menyalahgunakan memanfaatkan karakter luas / char16_tstring! Compiler sepertinya tidak suka \1dalam bentuk ☺.

f(t,c,d){for(c=7;!(d=t/L"\1<ฐ\1•▼ŭ"[--c]/(c>2?86400:1)););printf("%d %.6s%s\n",d,c*6+(char*)u"敳潣摮業畮整潨牵 慤y†敷步 潭瑮h敹牡",(d<2)+"s");}

Cobalah online!

Solusi asli

Saya membagi array menjadi garis-garis terpisah untuk membuatnya lebih mudah untuk melihat sisa solusi.

char *n[]={"second","minute","hour","day","week","month","year"};
int o[]={1,60,3600,86400,604800,2678400,31536000};
f(int t){int c=7,d;while(!(d=t/o[--c]));printf("%d %s%s\n",d,n[c],d>1?"s":"");}

Cobalah online!

Menjalankan pembagi secara berurutan dari yang terbesar ke yang terkecil, kami mendapatkan satuan waktu yang paling kasar. Program keliru jika Anda memberikannya 0 detik, tetapi karena spesifikasi secara eksplisit mengecualikan nilai ini, saya anggap itu dapat diterima.


Beberapa trik dapat digunakan untuk membuatnya hingga 183 byte: Cobalah online!
gastropner

1
Maaf, yang itu memperkenalkan bug. Proper satu dengan 180 byte: Cobalah secara online!
gastropner

@gastropner Saya pikir yang terakhir memiliki bug juga. '(d <1)' harus '(d <2)' ... atau '(d <= 1)', tetapi jangan menjadi gila.
gmatht

@ gmatht Anda benar!
gastropner

OK, yang terakhir, aku janji. 164 byte
gastropner


5

Stax , 54 byte

▀♂♂┼╕Qá◙à*ä∙Φò►⌠╨Ns↔║►πîÇ∙cI≡ªb?δ♪9gΓ╕┬≥‼⌡Öå01:♪EoE╘≡ë

Jalankan dan debug itu

Berikut ini adalah representasi ascii yang tidak dibongkar, tidak disatukan, dari program yang sama.

                            stack starts with total seconds
c60/                        push total minutes to stack
c60/                        ... hours 
c24/                        ... days
Yc7/                        ... weeks
y31/                        ... months
y365/                       ... years
L                           make a list out of all the calculated time units
`)sQP(dr'pk,oV4?_HIFD?x`j   compressed literal for singular forms of unit names
\                           zip totals with names
rF                          foreach pair of total and name (in reverse orer)
  h!C                       skip if the current total is falsey (0)
  _J                        join the total and unit name with a space
  's_1=T+                   concat 's' unless the total is one

Setelah eksekusi, karena tidak ada output lain, bagian atas tumpukan dicetak secara implisit.

Jalankan yang ini


5

JavaScript (ES6), 131 byte

n=>[60,60,24,7,31/7,365/31,0].map((v,i)=>s=n<1?s:(k=n|0)+' '+'second,minute,hour,day,week,month,year'.split`,`[n/=v,i])|k>1?s+'s':s

Cobalah online!


Saya tidak mengetahui sintaksis yang Anda gunakan (split ,). Saya belajar sesuatu yang baru. Solusi bagus
Makotosan

1
@Makotosan Perhatikan bahwa apa yang sebenarnya diteruskan ke splitarray [',']. Oleh karena itu, ini hanya berfungsi dengan fungsi yang memaksa pemaksaan pada string.
Arnauld

3

Java 8, 197 195 157 byte

n->(n<60?n+" second":(n/=60)<60?n+" minute":(n/=60)<24?n+" hour":(n/=24)<7?n+" day":n<31?(n/=7)+" week":n<365?(n/=31)+" month":(n/=365)+" year")+(n>1?"s":"")

-38 byte terima kasih kepada @ OlivierGrégoire .

Penjelasan:

Cobalah online.

n->               // Method with long parameter and String return-type
  (n<60?          //  If `n` is below 60:
    n             //   Output `n`
    +" second"    //   + " second"
   :(n/=60)<60?   //  Else-if `n` is below 60*60
    n             //   Integer-divide `n` by 60, and output it
    +" minute"    //   + " minute"
   :(n/=60)<24?   //  Else-if `n` is below 60*60*24:
    n             //   Integer-divide `n` by 60*60, and output it
    +" hour"      //   + " hour"
   :(n/=24)<7?    //  Else-if `n` is below 60*60*24*7:
    n             //   Integer-divide `n` by 60*60*24, and output it
    +" day"       //   + " day"
   :n<31?         //  Else-if `n` is below 60*60*24*31:
    (n/=7)        //   Integer-divide `n` by 60*60*24*7, and output it
    +" week"      //   + " week"
   :n<365?        //  Else-if `n` is below 60*60*24*365:
    (n/=31)       //   Integer-divide `n` by 60*60*24*31, and output it
    +" month"     //   + " month"
   :              //  Else:
    (n/=365)      //   Integer-divide `n` by 60*60*24*365, and output it
    +" year")     //   + " year"
   +(n>1?"s":"")  //  And add a trailing (plural) "s" if (the new) `n` is larger than 1

1
157 byte . Saya baru saja memasukkan nomor Anda ke yang lebih pendek dan bergerak /=di mana saja diperlukan.
Olivier Grégoire

Favorit pribadi: n->{for(int t=60,d[]={1,t,t*=60,t*=24,t*7,t*31,t*365},x=7;;)if(n>=d[--x])return(n/=d[x])+" "+"second,minute,hour,day,week,month,year".split(",")[x]+(n>1?"s":"");}(162 byte), mungkin dasar yang bagus untuk bermain golf.
Olivier Grégoire

Simpan 9 byte menggunakan n/7+bukan (n/=7)+dll.
Neil

@Neil Aku takut itu tidak akan berhasil. Misalnya, jika inputnya adalah 2678400, output harusnya 1 monthbukan 1 months(tunggal, bukan jamak).
Kevin Cruijssen

Oh, halus, terima kasih sudah memberi tahu saya.
Neil

2

Kotlin , 205 203 196 byte

x->val d=86400
with(listOf(1 to "second",60 to "minute",3600 to "hour",d to "day",d*7 to "week",d*31 to "month",d*365 to "year").last{x>=it.first}){val c=x/first
"$c ${second+if(c>1)"s" else ""}"}

Cobalah online!


2

T-SQL , 306 byte (281 byte tanpa I / O)

DECLARE @n INT=1
DECLARE @r VARCHAR(30)=TRIM(COALESCE(STR(NULLIF(@n/31536000,0))+' year',STR(NULLIF(@n/2678400,0))+' month',STR(NULLIF(@n/604800,0))+' week',STR(NULLIF(@n/86400,0))+' day',STR(NULLIF(@n/3600,0))+' hour',STR(NULLIF(@n/60,0))+' minute',STR(@n)+' second'))IF LEFT(@r,2)>1 SET @r+='s'
PRINT @r

Dua kesalahan ketik kecil: TRIMtidak didefinisikan, ini mungkin seharusnya LTRIM. Antara weekdan day, Anda memiliki + , mungkin harus,
Stephan Bauer

Memang, alih-alih + harus menjadi ,dan saya memperbaikinya sekarang. Namun, TRIMfungsi ini didefinisikan sejak SQL Server 2017. Terima kasih.
Razvan Socol

2

R , 157 byte

function(n,x=cumprod(c(1,60,60,24,7,31/7,365/31)),i=cut(n,x),o=n%/%x[i])cat(o," ",c("second","minute","hour","day","week","year")[i],"if"(o>1,"s",""),sep="")

Cobalah online!

cutberguna, karena membagi rentang menjadi factors, yang disimpan secara internal sebagai integers, yang berarti kita dapat menggunakannya sebagai indeks array juga. Kita mungkin bisa melakukan sesuatu yang sedikit lebih pintar dengan nama periode waktu, tetapi saya belum bisa mengetahuinya dulu.


2

APL + WIN, 88 119 byte

Versi asli ketinggalan minggu dan bulan seperti yang ditunjukkan oleh Phil H; (

Meminta input layar dari jumlah detik

a←⌽<\⌽1≤b←⎕÷×\1 60 60 24 7,(31÷7),365÷31⋄b,(-(b←⌊a/b)=1)↓∊a/'seconds' 'minutes' 'hours' 'days' 'weeks' 'months' 'years'

Penjelasan

b←⎕÷×\1 60 60 24 7,(31÷7),365÷31 prompts for input and converts to years, days, hours, minutes, seconds

a←⌽<\⌽1≤b identify largest unit of time and assign it to a

a/'years' 'days' 'hours' 'minutes' 'seconds' select time unit

(-(b←⌊a/b)=1)↓∊ determine if singular if so drop final s in time unit

b, concatenate number of units to time unit from previous steps

Apakah seseorang memakan minggu dan bulan?
Phil H

@PhilH Cookie monster? ;) Terima kasih. Jawaban diedit sesuai.
Graham

Itu terlihat terlalu rapi, bahkan untuk APL! Juga, bagaimana Anda menghitung byte? Saya menghitung 119 karakter daripada byte ...
Phil H

@PhilH Saya tidak mengerti komentar Anda terlebih dahulu, kami sepakat pada 119 byte yang saya ubah pada mengedit jawaban dan di atas Anda tidak mengatakan berapa banyak byte yang Anda tanyakan
Graham


1

Batch, 185 byte

@for %%t in (1.second 60.minute 3600.hour 43200.day 302400.week, 1339200.month, 15768000.year)do @if %1 geq %%~nt set/an=%1/%%~nt&set u=%%~xt
@if %n% gtr 1 set u=%u%s
@echo %n%%u:.= %

1

Python 2 , 146 144 byte

lambda n,d=86400:[`n/x`+' '+y+'s'*(n/x>1)for x,y in zip([365*d,31*d,7*d,d,3600,60,1],'year month week day hour minute second'.split())if n/x][0]

Cobalah online!

2 byte disimpan berkat Jonathan Allan


1
if n/xmenghemat satu byte.
Jonathan Allan

1
Membalik urutan dan mengindeks dengan 0menyimpan yang lain.
Jonathan Allan

1

PHP , 183 byte

<?$a=[second=>$l=1,minute=>60,hour=>60,day=>24,week=>7,month=>31/7,year=>365/31];foreach($a as$p=>$n){$q=$n*$l;if($q<=$s=$argv[1])$r=($m=floor($s/$q))." $p".($m>1?s:"");$l=$q;}echo$r;

Cobalah online!


1

Julia 0,6 , 161 byte

f(n,d=cumprod([1,60,60,24,7,31/7,365/31]),r=div.(n,d),i=findlast(r.>=1),l=Int(r[i]))="$l $(split("second minute hour day week month year",' ')[i])$("s"^(l>1*1))"

Cobalah online!



0

Perl 6 / Rakudo 138 byte

Saya yakin masih ada yang harus dilakukan, tetapi untuk sekarang

{my @d=(365/31,31/7,7,24,60,60);$_/=@d.pop while @d&&$_>@d[*-1];$_.Int~" "~ <year month week day hour minute second>[+@d]~($_>1??"s"!!"")}

Menjelaskan:

{ # bare code block, implicit $_ input
    my @d=(365/31,31/7,7,24,60,60); # ratios between units
    $_ /= @d.pop while @d && $_ > @d[*-1]; # pop ratios off @d until dwarfed
    $_.Int~   # implicitly output: rounded count
        " "~  # space
        <year month week day hour minute second>[+@d]~ # unit given @d
        ($_>1??"s"!!"")  # plural
}

0

R, 336

Sedang dalam proses

function(x){
a=cumprod(c(1,60,60,24,7,31/7,365/31))
t=c("second","minute","hour","day","week","month")
e=as.data.frame(cbind(table(cut(x,a,t)),a,t))
y=x%/%as.integer(as.character(e$a[e$V1==1]))
ifelse(x>=a[7],paste(x%/%a[7],ifelse(x%/%a[7]==1,"year","years")),
ifelse(y>1,paste(y,paste0(e$t[e$V1==1],"s")),paste(y,e$t[e$V1==1])))}

0

R , 246 byte

f=function(x,r=as.integer(strsplit(strftime(as.POSIXlt(x,"","1970-01-01"),"%Y %m %V %d %H %M %S")," ")[[1]])-c(1970,1,1,1,1,0,0),i=which.max(r>0)){cat(r[i],paste0(c("year","month","week","day","hour","minute","second")[i],ifelse(r[i]>1,"s","")))}

Cobalah online!

Ini menggunakan format waktu alih-alih arithemtics, hanya untuk itu. Mungkin orang lain bisa membuat ini lebih kecil?

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.