Formato de tiempo de juego incremental

18

Formato de tiempo de juego incremental

Objetivo

Los juegos incrementales a menudo tienen un temporizador de cuenta regresiva que expresa los días, horas, minutos y segundos hasta que se complete una tarea. Dependiendo del espacio disponible, pueden formatearse como:

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

El objetivo de este código de golf es escribir una función o programa que realice este formateo.

Entradas

  • El número total de segundos.
  • El número máximo de segmentos a la salida.

Salida

  • Los segmentos incluyen:
    • 0 semanas
    • 0 días
    • 0h horas
    • 0m minutos
    • 0 segundos
  • Cada segmento está separado por un solo espacio.
  • Los segmentos mostrados deben ser contiguos. Por ejemplo, no mostrará horas y segundos sin mostrar minutos, incluso si hay cero minutos.
  • Los valores de un solo dígito no tienen ceros a la izquierda, aunque un valor de cero debe mostrarse como 0.
  • Los valores se redondean hacia abajo.
  • El primer segmento que se muestra es el primer valor distinto de cero.

Casos de prueba

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

Victorioso

La solución de recuento de bytes más baja en una semana ganará "aceptación".

Ediciones

  • Se aclaró qué segmento es primero, como se muestra en los ejemplos.
  • Se agregó el caso de prueba 4 según la solicitud.
Hand-E-Food
fuente
¿Para qué se espera la salida 307891 1? 0wo 1w.
jnovacho
1
@jnovacho ¿No sería así 3d? "El primer segmento que se muestra es el primer valor distinto de cero"
Luigi
@Luigi True. Me he perdido eso.
jnovacho
¿Soy el único que piensa que esta es una pregunta de "alguien podría escribir este código por mí"?
fho
No todos los días una tarea de código de golf podría ser útil. Yo digo ve con eso: D
Geobits

Respuestas:

7

CJam (instantánea), 41 38 bytes

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

Lo anterior usa notación de intercalación, ya que dos de los caracteres no se pueden imprimir.

Gracias a @ Sp3000 por jugar golf en 2 bytes.

Pruebas

La última versión estable (0.6.5) tiene un error que puede hacer {}#que se devuelvan números enteros en lugar de largos. Paradójicamente, esto se puede eludir al convertir a entero ( i).

Para ejecutar esto con código con el intérprete en línea, haga clic en este enlace permanente o copie el código de esta pasta .

Alternativamente, puede descargar y construir la última instantánea ejecutando los siguientes comandos:

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

Puede crear el archivo CJam de esta manera:

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

Cómo funciona

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
fuente
6

Java, 197191 bytes

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

Acabo de notar que Java admite declaraciones como String a[]. Esto me permitió extraer la declaración de by zen la misma línea, lo que me salvó de Stringvolver a escribir .

ECS
fuente
1
Como el ;z=" ")- muy inteligente.
OldCurmudgeon
5

C, 134 127 110 104 103 bytes

Nueva versión:

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

Versión previa:

#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
fuente
4

Pyth, 39 43 bytes

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

editar: +4 caracteres, porque olvidé el 0scaso de prueba.

Esto incluye 2 caracteres no imprimibles. Obtenga el código real y pruébelo en línea: Demostración

Explicación:

                                         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
fuente
3

Python 2.7 - 181 178 174 bytes

Mi primer intento de jugar al golf.

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.rodrigues
fuente
1
Gran primer intento! Mejor que algunos de mis sextos intentos ...;) Puede cortar 3 bytes cambiando if n!=0a solo if n.
kirbyfan64sos
Ah sí, olvidé que 0 se evalúa como Falso. Gracias.
f.rodrigues
2

Julia, 158 bytes

Estoy seguro de que esto podría ser más corto con un enfoque más inteligente, pero esto es lo que tengo por ahora.

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

Esto crea una función sin nombre que acepta dos enteros como entrada y devuelve una cadena. Para llamarlo, asígnele un nombre, p. Ej.f=(s,g)->... .

Ungolfed + explicación:

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

Ejemplos:

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

julia> f(604800, 4)
"1w 0d 0h 0m"
Alex A.
fuente
1

Scala, 147 bytes

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(" ")
usuario42083
fuente
1

rs , 367 bytes

^(\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

Demostración en vivo y todos los casos de prueba.

Desordenado, desordenado, desordenado ...

Tarda entre 3 y 7 segundos en ejecutar los casos de prueba en Chrome para Android. No , no utilice el modo de depuración, que puede congelar su navegador en este caso debido a que toda la producción que se imprime.

kirbyfan64sos
fuente
¿Qué es rs? -----
Caleb Paul
@ Wideshanks Agregué un enlace en el título. Es un lenguaje basado en expresiones regulares que escribí.
kirbyfan64sos
0

C #, 239 237 170 164 bytes

Esto no es tan compacto como otras soluciones, pero no puedo plantear este desafío sin tener una puñalada por mí mismo.

Esta última iteración se inspiró en la respuesta de ESC .

Sangrado por claridad:

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
fuente