Quanti anni ha all'incirca?


29

Scrivi un breve programma che impieghi un numero positivo di secondi che rappresenti un'età e fornisca una stima di quel tempo in inglese.

Il tuo programma deve generare il tempo meno preciso che è trascorso, tra le seguenti metriche e la loro lunghezza in secondi:

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

Esempi

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

Come puoi vedere sopra, dopo il tempo di dire, 1 giorno (60 * 60 * 24 = 86400 secondi), non vengono più emessi minuti o ore , ma solo giorni fino a quando non superiamo il tempo di una settimana , e così via.

Considera il periodo di tempo indicato come un'età. Ad esempio, dopo 119 secondi, è trascorso 1 minuto , non 2.

Regole

  • Nessuna specifica per 0 o ingressi negativi.
  • Seguire la corretta pluralizzazione. Ogni misura maggiore di 1 deve includere un sseguito alla parola.
  • Non è possibile utilizzare una libreria preesistente che serve alla funzione dell'intero programma.
  • Questo è un codice golf, il programma più corto vince i punti internet.
  • Divertiti!

3
Non capisco come scegliamo un'unità o un importo. Arrotondiamo?
xnor

1
@xnor dividiamo i numeri interi e utilizziamo il più piccolo valore diverso da zero insieme alla sua unità (possibilmente pluralizzata). Quindi 59 -> "59 secondi" e 86401 -> "1 giorno".
Jonathan Allan,

5
Benvenuti in PPCG! Bella prima sfida. Per riferimento futuro c'è un sandbox che è utile per ottenere feedback prima di pubblicare sul main.
Jonathan Allan,

4
Si noti che Do X senza Y è scoraggiato, nonché i requisiti del programma Non osservabile .
user202729

1
Come dovremmo arrotondare i numeri? 119 secondi dovrebbero essere 1 minuto o 2 minuti? Che ne dici di 90?
user202729

Risposte:


8

Gelatina , 62 byte

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

Un programma completo che stampa il risultato.
(Come collegamento monadico restituisce un elenco di un numero intero seguito da caratteri)

Provalo online!

Come?

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 128 caratteri

Grazie a @gastropher per le riduzioni del codice. Ho dimenticato che C consente parametri impliciti usando le funzioni di stile K & R! Grazie anche a @gmatht per l'idea di inserire letterali al posto degli array. L'ho esteso ai personaggi abusando di sfruttare caratteri / char16_tstringhe larghi ! Il compilatore non sembra gradire \1nella sua forma though però.

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

Provalo online!

Soluzione originale

Ho diviso le matrici in linee separate per rendere più semplice la visualizzazione del resto della soluzione.

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

Provalo online!

Eseguendo i divisori in ordine dal più grande al più piccolo, otteniamo l'unità di tempo più grossolana. Il programma si comporta male se gli dai 0 secondi, ma poiché la specifica esclude esplicitamente questo valore, ritengo che sia accettabile.


Alcuni trucchi possono essere utilizzati per ridurlo a 183 byte: provalo online!
Gastropner

1
Spiacente, quello ha introdotto un bug. Uno corretto a 180 byte: provalo online!
Gastropner

@gastropner Penso che anche l'ultimo abbia un bug. '(d <1)' dovrebbe essere '(d <2)' ... o '(d <= 1)', ma non impazzire.
gmatht

@gmatht Hai perfettamente ragione!
Gastropner

OK, l'ultimo, lo prometto. 164 byte.
Gastropner


5

Stax , 54 byte

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

Esegui ed esegui il debug

Ecco la rappresentazione decompressa, ungolfed, ascii dello stesso programma.

                            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

Dopo l'esecuzione, poiché non c'è altro output, la parte superiore della pila viene stampata implicitamente.

Esegui questo


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

Provalo online!


Non ero a conoscenza della sintassi che hai usato (diviso ,). Ho imparato qualcosa di nuovo. Ottima soluzione
Makotosan,

1
@Makotosan Nota che ciò che viene effettivamente passato splitè l'array [',']. Pertanto, questo funziona solo con funzioni che impongono la coercizione a una stringa.
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 grazie a @ OlivierGrégoire .

Spiegazione:

Provalo 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 . Ho appena golfato i tuoi numeri su numeri più brevi e mi sono spostato /=dove necessario.
Olivier Grégoire,

Preferito personale: 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), probabilmente una buona base per giocare a golf.
Olivier Grégoire,

Salva 9 byte usando n/7+invece di (n/=7)+ecc.
Neil

@Neil temo che non funzionerà. Ad esempio, se l'ingresso è 2678400, l'uscita dovrebbe essere 1 monthinvece di 1 months(singolare anziché plurale).
Kevin Cruijssen,

Oh, sottile, grazie per avermelo fatto notare.
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 ""}"}

Provalo online!


2

T-SQL , 306 byte (281 byte senza 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

Due piccoli errori di battitura: TRIMnon è definito, questo potrebbe essere LTRIM. Tra weeke day, hai un + , forse dovrebbe essere un,
Stephan Bauer

Anzi, invece di + dovrebbe essere un ,e l'ho corretto ora. Tuttavia, la TRIMfunzione è definita da SQL Server 2017. Grazie.
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="")

Provalo online!

cutè utile, poiché divide gli intervalli in factors, che sono memorizzati internamente come integers, il che significa che possiamo usarli anche come indici di array. Probabilmente possiamo fare qualcosa di un po 'più intelligente con i nomi dei periodi, ma non riesco ancora a capirlo.


2

APL + WIN, 88 119 byte

La versione originale mancava settimane e mesi, come sottolineato da Phil H;

Richiede l'immissione dello schermo del numero di secondi

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'

Spiegazione

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

Qualcuno ha mangiato settimane e mesi?
Phil H,

@PhilH Cookie monster? ;) Grazie. Risposta modificata di conseguenza.
Graham,

Sembrava troppo pulito, anche per APL! Inoltre, come stai contando i byte? Conto 119 caratteri anziché byte ...
Phil H,

@PhilH Non capisco prima il tuo commento, siamo d'accordo su 119 byte che ho modificato modificando la risposta e sopra non dici quanti byte stai interrogando
Graham


1

Lotto, 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]

Provalo online!

2 byte salvati grazie a Jonathan Allan


1
if n/xsalva un byte.
Jonathan Allan,

1
Invertire l'ordine e indicizzarlo con ne 0salva un altro.
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;

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

Provalo online!



0

Perl 6 / Rakudo 138 byte

Sono sicuro che c'è ancora molto da fare, ma per ora

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

spiegare:

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

Lavoro in corso

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

Provalo online!

Questo sta usando la formulazione del tempo invece degli aritemici, solo per il gusto di farlo. Forse altri potrebbero ridurlo?

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.