おおよそ何歳ですか?


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秒)の時間の後、分や時間を出力しなくなりましたが、1週間の時間を超えるまでの日数のみが出力されます、 等々。

与えられた時間の長さを年齢と考えてください。たとえば、119秒後、2分ではなく1分が経過しました

ルール

  • 0または負の入力の指定はありません。
  • 適切な複数形に従ってください。1より大きいすべてのメジャーには、s次の単語を含める必要があります。
  • プログラム全体の機能を提供する既存のライブラリを使用することはできません。
  • これはコードゴルフであり、最短プログラムがインターネットポイントを獲得します。
  • 楽しむ!

3
単位または金額の選択方法がわかりません。丸めますか?
-xnor

1
@xnor我々は整数除算し、最小の非ゼロ値とその単位(多元化されている可能性があります)を使用します。したがって、59-> "59秒"および86401-> "1日"。
ジョナサンアラン

5
PPCGへようこそ!素敵な最初の挑戦。将来の参考のために、メインに投稿する前にフィードバックを得るのに役立つサンドボックスがあります。
ジョナサンアラン


1
数字をどのように丸めるべきですか?119秒は1分ですか、2分ですか?90はどうですか?
user202729

回答:


8

ゼリー、62 バイト

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

結果を印刷する完全なプログラム。
(単項リンクとして、整数とそれに続く文字のリストを返します)

オンラインでお試しください!

どうやって?

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スタイルの関数を使用して暗黙的なパラメーターを許可することを忘れていました。また、配列ではなくリテラルを内部に入れるというアイデアを提供してくれた@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バイトまで減らすことができます。オンラインで試してみてください!
ガストロプナー

1
申し訳ありませんが、その1つがバグを導入しました。180バイトで適切なもの:オンラインで試してみてください!
ガストロプナー

@gastropner最後のものにもバグがあると思う。'(d <1)'は '(d <2)' ...または '(d <= 1)'である必要がありますが、狂わないでください。
-gmatht

@gmathtまったくその通りです!
ガストロプナー

最後に、約束します。164バイト。
ガストロプナー


5

スタックス、54 バイト

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

実行してデバッグする

以下は、同じプログラムのアンパック、アンゴルフ、アスキー表現です。

                            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

オンラインでお試しください!


私はあなたが使用した構文(split ,)を知りませんでした。私は何か新しいことを学びました。素晴らしい解決策。
マコトサン

1
@Makotosan実際に渡されるのsplitは配列[',']です。したがって、これは文字列に強制を強制する関数でのみ機能します。
アーナルド

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

@OlivierGrégoireに感謝-38バイト。

説明:

オンラインでお試しください。

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バイト。私はあなたの番号を短い番号に変えて/=、必要な場所を移動しました。
オリビエグレゴワール

個人的なお気に入り: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バイト)、おそらくゴルフに適したベース。
オリヴィエグレゴワール

etcのn/7+代わりに(n/=7)+などを使用して9バイトを節約します
ニール

@Neil私はそれがうまくいかないのではないかと心配しています。たとえば、入力がの2678400場合、出力1 month1 months(複数ではなく単数)の代わりになります。
ケビンクルーッセン

ああ、微妙な、私に知らせてくれてありがとう。
ニール


2

T-SQL、306バイト(I / Oなしの281バイト)

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

2つの小さなタイプミス:TRIMは定義されていませんLTRIM。との間weekday、あなたはを持っている+ 必要があります,
ステファンバウアー

確かに、それの代わりに+ あるべきであり,、私は今それを修正しました。ただし、TRIM関数はSQL Server 2017以降で定義されています。ありがとう。
ラズバンソコル

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

誰かが週と月を食べましたか?
フィルH

@PhilHクッキーモンスター?;)ありがとう。それに応じて回答を編集しました。
グラハム

APLであっても、見栄えが良すぎました!また、どのようにバイトを数えていますか?私は... 119文字ではなくバイト数を数える
フィル・H

私はあなたのコメントを理解していない@PhilH最初、私たちは、私はあなたが疑問視されているどのように多くのバイトを言っていない答えを編集するには、あなたの上に変更さ119バイトに同意
グラハム


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

パイソン2146の 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バイト節約


1
if n/xバイトを保存します。
ジョナサンアラン

1
順序を逆にしてインデックスを作成すると、0別のものが保存されます。
ジョナサンアラン




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.