อายุเท่าไหร่


29

เขียนโปรแกรมสั้น ๆ ซึ่งใช้เวลาเป็นวินาทีในการแสดงอายุและแสดงผลการประมาณเวลานั้นเป็นภาษาอังกฤษ

โปรแกรมของคุณจะต้องแสดงเวลาที่แม่นยำน้อยที่สุดซึ่งผ่านไปแล้วโดยใช้เมตริกต่อไปนี้และความยาวเป็นวินาที:

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

ตัวอย่าง

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

ดังที่คุณเห็นด้านบนหลังจากเวลาพูด 1 วัน (60 * 60 * 24 = 86400 วินาที) เราจะไม่ส่งออกนาทีหรือชั่วโมงอีกต่อไปแต่จะมีเพียงวันจนกว่าเราจะผ่านเวลาหนึ่งสัปดาห์ และอื่น ๆ

พิจารณาระยะเวลาที่กำหนดให้เป็นอายุ ตัวอย่างเช่นหลังจาก 119 วินาทีผ่านไป 1 นาทีไม่ใช่ 2

กฎระเบียบ

  • ไม่มีข้อกำหนดสำหรับ 0 หรืออินพุตเชิงลบ
  • ปฏิบัติตามพหูพจน์ที่เหมาะสม ทุกการวัดที่มากกว่า 1 จะต้องมีคำsต่อไปนี้
  • คุณไม่สามารถใช้ไลบรารีที่มีอยู่แล้วซึ่งทำหน้าที่ฟังก์ชั่นของโปรแกรมทั้งหมด
  • นี่คือรหัสกอล์ฟโปรแกรมที่สั้นที่สุดชนะคะแนนอินเทอร์เน็ต
  • มีความสุข!

3
ฉันไม่เข้าใจวิธีที่เราเลือกหน่วยหรือจำนวนเงิน เราจะปัดเศษหรือไม่
xnor

1
@ xnor เราแบ่งจำนวนเต็มและใช้ค่าที่ไม่เป็นศูนย์ที่เล็กที่สุดพร้อมกับหน่วยของมัน (อาจเป็นพหูพจน์) ดังนั้น 59 -> "59 วินาที" และ 86401 -> "1 วัน"
Jonathan Allan

5
ยินดีต้อนรับสู่ PPCG! ความท้าทายแรกที่ดี สำหรับการอ้างอิงในอนาคตมีsandboxซึ่งเป็นประโยชน์สำหรับการรับความคิดเห็นก่อนโพสต์ไปยังหน้าหลัก
Jonathan Allan

4
โปรดทราบว่าDo X โดยไม่ต้อง Yเป็นกำลังใจเช่นเดียวกับความต้องการโปรแกรมที่ไม่สามารถสังเกตได้
user202729

1
เราควรปัดเศษตัวเลขอย่างไร? ควร 119 วินาทีเป็น 1 นาทีหรือ 2 นาที? ประมาณ 90
user202729

คำตอบ:


8

เยลลี่ 62 ไบต์

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

โปรแกรมเต็มรูปแบบการพิมพ์ผล
(ลิงก์แบบ monadic จะส่งคืนรายการจำนวนเต็มตามด้วยอักขระ)

ลองออนไลน์!

อย่างไร?

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 ตัวอักษร

ขอบคุณ @gastropher สำหรับการลดรหัส ฉันลืมว่า C อนุญาตให้ใช้พารามิเตอร์โดยนัยโดยใช้ฟังก์ชัน K & R-style! นอกจากนี้ยังต้องขอบคุณ @gmatht สำหรับความคิดในการใส่ตัวอักษรเข้ามาแทนที่อาร์เรย์ ฉันขยายไปถึงตัวละครด้วยการใช้ประโยชน์จากตัวละคร / char16_tสายอักขระที่เหยียดหยาม ! คอมไพเลอร์ดูเหมือนจะไม่ชอบ\1ในรูปของ☺

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");}

ลองออนไลน์!

โซลูชันดั้งเดิม

ฉันแบ่งอาร์เรย์เป็นเส้นแยกกันเพื่อให้มองเห็นส่วนที่เหลือของโซลูชันได้ง่ายขึ้น

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":"");}

ลองออนไลน์!

ดำเนินการตัวหารตามลำดับจากใหญ่ไปหาน้อยที่สุดเราจะได้หน่วยที่มีเวลามากที่สุด โปรแกรมทำงานผิดปกติหากคุณให้ 0 วินาที แต่เนื่องจากข้อกำหนดไม่รวมค่านี้อย่างชัดเจนฉันถือว่ามันเป็นที่ยอมรับ


เทคนิคบางอย่างสามารถใช้เพื่อลดขนาดให้เหลือ 183 ไบต์: ลองออนไลน์!
Gastropner

1
ขออภัยมีข้อผิดพลาดเกิดขึ้น ขนาดที่เหมาะสมที่ 180 ไบต์: ลองออนไลน์!
Gastropner

@gastropner ฉันคิดว่าอันสุดท้ายมีบั๊กด้วยเช่นกัน '(d <1)' ควรเป็น '(d <2)' ... หรือ '(d <= 1)' แต่อย่าให้บ้าไปเลย
gmatht

@gmatht คุณพูดถูก!
Gastropner

ตกลงสุดท้ายฉันสัญญา 164 ไบต์
Gastropner


5

Stax , 54 ไบต์

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

เรียกใช้และแก้ไขข้อบกพร่อง

ต่อไปนี้เป็นการนำเสนอโปรแกรมที่ยังไม่ได้บรรจุ ungolfed และ ascii ของโปรแกรมเดียวกัน

                            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

การดำเนินการต่อไปนี้เนื่องจากไม่มีเอาต์พุตอื่นด้านบนของสแต็กจะถูกพิมพ์โดยปริยาย

เรียกใช้อันนี้


5

JavaScript (ES6), 131 ไบต์

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

ลองออนไลน์!


ฉันไม่ทราบถึงไวยากรณ์ที่คุณใช้ (แยก,) ฉันเรียนรู้สิ่งใหม่ ทางออกที่ดี
Makotosan

1
หมายเหตุ @Makotosan ว่าสิ่งที่จะถูกส่งจริงจะเป็นอาร์เรย์split [',']ดังนั้นสิ่งนี้จะใช้งานได้เฉพาะกับฟังก์ชั่นที่บังคับให้ใช้กับสตริง
Arnauld

3

Java 8, 197 195 157 ไบต์

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 ไบต์ขอบคุณที่@ OlivierGrégoire

คำอธิบาย:

ลองออนไลน์

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 ไบต์ ฉันเพิ่งเล่นกอล์ฟหมายเลขของคุณให้สั้นลงและเคลื่อนที่/=ไปตามที่ต้องการ
Olivier Grégoire

รายการโปรดส่วนตัว: 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 ไบต์) อาจเป็นฐานที่ดีสำหรับการเล่นกอล์ฟ
Olivier Grégoire

บันทึก 9 ไบต์โดยใช้n/7+แทน(n/=7)+เป็นต้น
Neil

@ ไม่มีฉันกลัวว่าจะไม่ทำงาน ตัวอย่างเช่นถ้าใส่เป็น2678400ผลผลิตที่ควรจะ1 monthแทน1 months(เอกพจน์พหูพจน์แทน)
Kevin Cruijssen

โอ้อ่อนโยนขอบคุณที่แจ้งให้เราทราบ
Neil


2

T-SQL , 306 ไบต์ (281 ไบต์โดยไม่มี 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

สองความผิดพลาดเล็ก ๆ : ไม่ได้กำหนดไว้นี้อาจเป็นไปได้ควรจะเป็นTRIM LTRIMระหว่างweekและdayคุณมี+ ควรเป็น,
เตฟานบาวเออ

อันที่จริงแทนที่จะ+ เป็นควร,และฉันแก้ไขที่ตอนนี้ อย่างไรก็ตามTRIMฟังก์ชั่นถูกกำหนดตั้งแต่ SQL Server 2017 ขอบคุณ
Razvan Socol

2

R , 157 ไบต์

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="")

ลองออนไลน์!

cutมีประโยชน์เนื่องจากมันแบ่งช่วงเป็นfactors ซึ่งถูกเก็บไว้ภายในเป็นintegers ซึ่งหมายความว่าเราสามารถใช้มันเป็นดัชนีอาร์เรย์ได้เช่นกัน เราอาจทำอะไรที่ฉลาดกว่านี้กับชื่อช่วงเวลาได้บ้าง แต่ฉันยังไม่สามารถเข้าใจได้


2

APL + WIN, 88 119 ไบต์

ฉบับดั้งเดิมพลาดสัปดาห์และเดือนที่ชี้โดย Phil H; (

แจ้งอินพุตหน้าจอของจำนวนวินาที

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'

คำอธิบาย

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

มีคนกินสัปดาห์และเดือนหรือไม่
Phil H

@PhilH Cookie สัตว์ประหลาด? ;) ขอบคุณ ตอบแก้ไขตาม
เกรแฮม

มันดูเรียบร้อยเกินไปแม้แต่สำหรับ APL! นอกจากนี้คุณนับจำนวนไบต์เป็นอย่างไร ฉันนับ 119 ตัวอักษรมากกว่าไบต์ ...
ฟิล H

@PhilH ฉันไม่เข้าใจความคิดเห็นของคุณก่อนเราเห็นด้วยกับ 119 ไบต์ซึ่งฉันเปลี่ยนไปในการแก้ไขคำตอบและเหนือคุณไม่ได้บอกว่าคุณกำลังถามคำถามจำนวนไบต์ที่เท่าไหร่
Graham


1

แบตช์ 185 ไบต์

@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 ไบต์

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]

ลองออนไลน์!

บันทึก 2 ไบต์ขอบคุณ Jonathan Allan


1
if n/xบันทึกเป็นไบต์
Jonathan Allan

1
การกลับรายการคำสั่งซื้อและการจัดทำดัชนีด้วย0บันทึกรายการอื่น
Jonathan Allan




0

Perl 6 / Rakudo 138 ไบต์

ฉันแน่ใจว่าจะมีอีกต่อไป แต่ตอนนี้

{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"!!"")}

อธิบาย:

{ # 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

งานกำลังดำเนินการ

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 ไบต์

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","")))}

ลองออนไลน์!

นี่คือการใช้รูปแบบเวลาแทนการคำนวณทางคณิตศาสตร์เพียงเพื่อนรกของมัน บางทีคนอื่นอาจทำให้ขนาดเล็กลงได้ไหม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.