Przyrostowy format czasu gry

18

Przyrostowy format czasu gry

Cel

Gry przyrostowe często mają stoper odliczający dni, godziny, minuty i sekundy do zakończenia zadania. W zależności od dostępnego miejsca można je sformatować jako:

2d 13h
23h 59m 48s
14m
3h 0m 0s

Celem tego kodu golfa jest napisanie funkcji lub programu, który wykonuje to formatowanie.

Wejścia

  • Łączna liczba sekund.
  • Maksymalna liczba segmentów do wydrukowania.

Wynik

  • Segmenty obejmują:
    • 0 tygodni
    • 0 dni
    • 0 godzin
    • 0 minut
    • 0 sekund
  • Każdy segment jest oddzielony pojedynczą spacją.
  • Wyświetlane segmenty muszą być ciągłe. Na przykład nie będziesz wyświetlać godzin i sekund bez wyświetlania minut, nawet jeśli minut jest zero.
  • Wartości jednocyfrowe nie mają zer wiodących, chociaż wartość zero musi być pokazana jako 0.
  • Wartości są zaokrąglane w dół.
  • Pierwszy wyświetlany segment to pierwsza wartość niezerowa.

Przypadki testowe

seconds  segments  output
     0      1      0s
   123      1      2m
   123      2      2m 3s
   123      3      2m 3s
 82815      3      23h 0m 15s
307891      2      3d 13h
307891      4      3d 13h 31m 31s
604800      1      1w
604800      6      1w 0d 0h 0m 0s

Zwycięski

Rozwiązanie o najniższej liczbie bajtów w ciągu tygodnia zyska „akceptację”.

Edycje

  • Wyjaśniono, który segment jest pierwszy, jak pokazano w przykładach.
  • Dodano przypadek testowy 4 zgodnie z żądaniem.
Hand-E-Food
źródło
Jaka jest oczekiwana wydajność 307891 1? 0wlub 1w.
jnovacho
1
@jnovacho Czy nie byłoby 3d? „Pierwszy wyświetlany segment to pierwsza wartość niezerowa”
Luigi
@Ligiigi True. Tęskniłem za tym.
jnovacho
Czy jestem jedynym, który myśli, że jest to pytanie „czy ktoś mógłby napisać ten kod dla mnie”?
fho
To nie jest tak naprawdę codzienne zadanie w golfa kodowego. Mówię: idź z tym: D
Geobits,

Odpowiedzi:

7

CJam (migawka), 41 38 bajtów

q~"<<^X^G"{imd\}%W%"wdhms":s.+_{0=}#><S*

W powyższym zastosowano notację karetką, ponieważ dwóch znaków nie można wydrukować.

Dzięki @ Sp3000 za grę w golfa z 2 bajtów.

Testowanie

Najnowsza stabilna wersja (0.6.5) zawiera błąd, który może powodować {}#zwracanie liczb całkowitych zamiast długich. Całkiem paradoksalnie można to obejść, rzutując na liczbę całkowitą (i ).

Aby uruchomić to z kodem za pomocą interpretera online, kliknij ten link bezpośredni lub skopiuj kod z tej pasty .

Możesz też pobrać i zbudować najnowszą migawkę, wykonując następujące polecenia:

hg clone http://hg.code.sf.net/p/cjam/code cjam-code
cd cjam-code/
ant

Możesz utworzyć plik CJam w następujący sposób:

base64 -d > game-time.cjam <<< cX4iPDwYByJ7aW1kXH0lVyUid2RobXMiOnMuK197MD19Iz48Uyo=

Jak to działa

q~        e# Read an evaluate the input.
"<<^X^G"  e# Push the string corresponding to the array [60 60 24 7
{         e# For each character:
  i       e#   Replace it by its code point.
  md      e#   Push divisor and residue of the division by that code point.
  \       e#   Swap their order.
}%
W%        e# Reverse the resulting array.
"wdhms":s e# Push ["w" "d" "h" "m" "s"].
.+        e# Perform vectorized concatenation.
_         e# Push a copy.
{0=}#     e# Find the index of the first pair with positive integer.
>         e# Remove the preceding pairs.
<         e# Truncate to the number of pairs specified in the input.
S*        e# Join, separating by spaces.
Dennis
źródło
6

Java, 197 191 bajtów

String p(int s,int m){String a[]={s%60+"s",(s/=60)%60+"m",(s/=60)%24+"h",(s/=24)%7+"d",(s/7)+"w"},b="",z="";for(s=5;s>0&&a[--s].charAt(0)=='0';);for(;s>=0&&--m>=0;z=" ")b+=z+a[s--];return b;}

Właśnie zauważyłem, że Java obsługuje deklarację podobną do String a[]. To pozwoliło mi wyciągnąć deklarację bi zdo tej samej linii, co uratowało mnie od Stringponownego pisania .

ECS
źródło
1
Jak ;z=" ")- bardzo sprytny.
OldCurmudgeon
5

C, 134 127 110 104 103 bajtów

Nowa wersja:

a,e=5;f(n,x){for(;e;n%=a)a=(int[]){1,60,3600,86400,604800}[--e],x>e?printf("%u%c ",n/a,"smhdw"[e]):0;}

Poprzednia wersja:

#define p(a) x>--e?printf("%u%c ",n/a,"smhdw"[e]):0;n%=a;
e=5;f(n,x){p(604800)p(86400)p(3600)p(60)p(1)}
openaddr
źródło
4

Pyth, 39 43 bajtów

jd_>vz+V?u?GeGPG+m%~/QddCM"<<"Q)Q]0"smhdw

edycja: +4 znaki, bo zapomniałem 0s przypadku testowego.

Obejmuje to 2 znaki niedrukowalne. Uzyskaj aktualny kod i wypróbuj go online: Demonstracja

Wyjaśnienie:

                                         z = 1st input line (segments, as string)
                                         Q = 2nd input line (time, as int)
                         "<<.."          string with 4 chars
                       CM                convert to ASCCI-values => [60,60,24,7]
                m                        map each d of ^ to:
                   /Qd                     Q / d 
                  ~                        update Q, but use the old value for
                 %  Q d                    Q mod d
                                         this gives [sec, min, hour, day]
               +               Q         add Q (week)
        u                       )        apply the following expression to G, 
                                         starting with G = [s,m,h,d,w], until
                                         G stops changing:
         ? eG                              if eG != 0:
          G                                  update G with G (stop changing)
                                           else:
             PG                              update G with G[-1]
                                         this gets rid of trailing zeros
      +V                         "smhdw  vectorized add with "smhdw"
   >vz                                   only use the last eval(z) items
  _                                      reverse order
jd                                       join by spaces and print
Jakube
źródło
3

Python 2.7 - 181 178 174 bajtów

Moja pierwsza próba gry w golfa.

def I(s,M):
 z=[0]*5;j=0
 for i in [604800,86400,3600,60,1]:z[j],s=s/i,s%i;j+=1
 l=[z.index(n)for n in z if n][0]
 return" ".join([str(i)+n for n,i in zip('wdhms',z)][l:l+M])
f. produkty
źródło
1
Świetna pierwsza próba! Lepsze niż niektóre z moich szóstych prób ...;) Możesz odciąć 3 bajty, zmieniając if n!=0na just if n.
kirbyfan64sos
O tak, zapomniałem, że 0 oznacza False. Dzięki.
f.rodrigues
2

Julia, 158 bajtów

Jestem pewien, że może to być krótsze przy bardziej sprytnym podejściu, ale na razie to właśnie mam.

(s,g)->(j=0;p=cell(5,1);for i=[604800,86400,3600,60,1] p[j+=1],s=s÷i,s%i end;z=findfirst(p);z>0?join([string(p[i],"wdhms"[i])for i=z:min(z+g-1,5)]," "):"0s")

Tworzy to nienazwaną funkcję, która akceptuje dwie liczby całkowite jako dane wejściowe i zwraca ciąg znaków. Aby to nazwać, nadaj mu nazwę, np f=(s,g)->....

Niegolfowane + wyjaśnienie:

function f(s, g)
    # Initialize an array and an index
    p = cell(5, 1)
    j = 0

    # Loop over the number of seconds in a week, day, hour,
    # minute, and second
    for i in [604800, 86400, 3600, 60, 1]
        # Set the jth element in p to be the quotient and s
        # to be the remainder of i into s
        p[j+=1], s = s ÷ i, s % i
    end

    # Get the index of the first nonzero value in p
    z = findfirst(p)

    if z > 0
        # We start the string at the first nonzero value
        # and continue until we hit the desired number of
        # units (z+g-1) or the maximum number of units (5),
        # whichever comes first. The appropriate unit is
        # appended to each value and the values are then
        # joined with a space.
        join([string(p[i], "wdhms"[i]) for i in z:min(z+g-1,5)], " ")
    else
        # If there are no nonzero values in p, we just
        # have 0 seconds
        "0s"
    end
end

Przykłady:

julia> f(82815, 6)
"23h 0m 15s"

julia> f(604800, 4)
"1w 0d 0h 0m"
Alex A.
źródło
1

Scala, 147 bajtów

def p(s:Int,i:Int)=List(s/604800+"w",s/86400%7+"d",s/3600%24+"h",s/60%60+"m",s%60+"s").dropWhile(k=>k.head=='0'&&k.tail!="s").take(i).mkString(" ")
użytkownik42083
źródło
1

rs , 367 bajtów

^(\d+)/(_)^^(\1)
(_*) (\d)/\1!\2
_{60}/#
#{60}/@
@{24}/:
:{7}/;
(_+)/(^^\1)s
(#+)/(^^\1)m
(@+)/(^^\1)h
(:+)/(^^\1)d
(;+)/(^^\1)w
([a-z])/\1 
w ((\d+[^\dd])|!)/w 0d \1
d ((\d+[^\dh])|!)/d 0h \1
h ((\d+[^\dm])|!)/h 0m \1
(m|^) ?!/\1 0s!
!(\d+)/!(_)^^(\1)
#
+#(\d+)([a-z]) ?(.*)!(_*)/\1\2 #\3!\4@
#/
(@+)/ (_)^^((^^\1))
!(_+) \1(_*)/!\2
_+ _+/
+\d+[a-z] ?!_/!
 *!/
^$/0s

Demo na żywo i wszystkie przypadki testowe.

Niechlujny, niechlujny, niechlujny ...

Wykonanie przypadków testowych w Chrome na Androida zajmuje około 3-7 sekund. Czy nie używać trybu debugowania, które można zamrozić przeglądarkę w tym przypadku, ponieważ wszystkie wyjścia, które mają zostać wydrukowane.

kirbyfan64sos
źródło
Co to jest rs? -----
Caleb Paul
@Wideshanks Dodałem link w tytule. Jest to napisana przeze mnie reguła językowa.
kirbyfan64sos
0

DO#, 239 237 170 164 bajtów

Nie jest to tak kompaktowe jak inne rozwiązania, ale nie mogę stawić czoła temu wyzwaniu, nie sami sobie tego zadając.

Ta najnowsza iteracja została zainspirowana odpowiedzią ESC .

Wcięte dla jasności:

string G(int s,int n){
    int[]x={s%60,(s/=60)%60,(s/=60)%24,(s/=24)%7,s/7};
    for(s=5;x[--s]==0&s>0;);
    var o="";
    while(n-->0&s>=0)
        o+=" "+x[s]+"smhdw"[s--];
    return o.Trim();
}
Hand-E-Food
źródło