¡Vaya, hombre, esta fecha de vencimiento no escribe los meses con letras! No puedo decir si caducará el 10 de marzo o el 3 de octubre ... Espera, no, no importa, el año dice 2012. (callejón oops ladrillo de queso medio usado en el basurero como un profesional)
Entonces, supongamos por un momento que estás demasiado ocupado para tratar de razonar cuando se supone que este frasco de marinara caducará. Solo quiere la versión de Cliff Notes: ¿qué tan probable es que esté vencida? ¡Escribamos un código!
Usted sabe que los fabricantes imprimen la fecha como un triple ordenado de enteros, en uno de tres formatos:
YEAR MONTH DAY
MONTH DAY YEAR
DAY MONTH YEAR
Y usted sabe que algunas fechas solo pueden interpretarse de una o dos maneras, no las tres: la 55 en 55-11-5
tiene que ser un año, lo que significa que esta caja particular de Twinkies expiró el 5 de noviembre de 1955. El año a veces se da en cuatro dígitos y no dos, lo que puede descartar algunas opciones. Sin embargo, cuando son dos dígitos, 50..99 significa 1950..1999 y 0..49 significa 2000..2049.
Su trabajo es escribir un programa o función que tome una matriz de enteros que sea una fecha válida en al menos una de las interpretaciones anteriores, y genere un porcentaje de probabilidad de que todavía sea buena. El porcentaje de probabilidad es simplemente el porcentaje de interpretaciones válidas de la fecha que son posteriores o posteriores a la fecha de hoy.
La matriz de enteros será el [Int]
tipo de longitud de su idioma tres si es un argumento para una función, y se dará como enteros con guiones, barras o espacios separados (puede elegir) si se usa como entrada en STDIN para un programa completo. *
La "fecha de hoy" puede ser la fecha real de hoy, tal como se obtiene a través de una función de fecha, o la fecha dada en un argumento adicional para la función o parámetro adicional en STDIN. Puede ser en segundos de época de Unix, otro triple año-mes-día ingresado en una de las tres formas anteriores, u otra forma más conveniente.
¡Tengamos algunos ejemplos! La entrada de la fecha de vencimiento estará en un estilo separado por guiones, y suponga para los ejemplos a continuación que la fecha de hoy es el 5 de julio de 2006.
14-12-14
- Ambas interpretaciones válidas para esto (DMY e YMD) son equivalentes, 14 de diciembre de 2014. El resultado es 100 porque este producto definitivamente sigue siendo bueno.8-2-2006
- El último número es un año, seguro, ya que tiene cuatro dígitos. Esto podría ser el 8 de febrero (caducado) o el 2 de agosto (aún bueno). La salida es 50 .6-7-5
- ¡Esto podría ser cualquier cosa! La interpretación del "5 de julio de 2006" sigue siendo buena (solo por un día), pero las dos restantes corresponden a 2005 y deben descartarse lo más rápido posible. La salida es 33 .6-5-7
- Aquí, dos de cada tres interpretaciones son seguras. Puede redondear su decimal hacia arriba o hacia abajo, por lo que 66 o 67 están bien.12-31-99
- Bien, este es inequívocamente desde el cambio de siglo (los años del 50 al 99 son 19XX, y el 31 no puede ser un mes). Un gran 0 gordo , y realmente deberías limpiar tu refrigerador con más frecuencia.
Puede asumir con seguridad que cualquier entrada que no cumpla con los estándares anteriores no está al tanto de las reglas de salida anteriores.
No hay solicitudes web ni lagunas estándar. Se permiten bibliotecas de manejo de fechas. Este es el código de golf: que gane el programa más corto.
* Si está utilizando brainfuck o algún lenguaje con discapacidad similar al tipo de datos, puede suponer que los valores ASCII de los primeros tres caracteres de entrada son los enteros de la fecha. Esto excluye la lógica del año de cuatro dígitos, claro, pero creo que estaríamos demasiado asombrados al ver una solución a esto en Brainfuck para desacreditarlo.
Respuestas:
k4
(90)(88)(87)(82)Invoque con
x
of.z.D
(un incorporado) para compararlo con el día de hoy, o con una fecha literal de su elección de lo contrario:Esto es básicamente un puerto de la solución Python de @ Alex-l, con algunos trucos de golf agregados:
fuente
"012201210"
, ya que#
toma sus elementos de forma cíclica. De hecho, puede guardar una segunda carbón de esta manera mediante el canje de los dos últimos casos:3 3#.:'"0122102"
.{c*(+/~d<x)%3-+/^d:{"D"$"."/:$|z,y,x+(c*19+x<50)*x<c::100}.'y@/:3 3#.:'$21020101}
.Ruby, 115 caracteres.
Esto define una función
f
que toma dos argumentos: una matriz que contiene la entrada y la fecha "de hoy".Ejemplos:
fuente
Python 2.7 - 172
Yo uso el módulo de fecha y hora para la validez y la comparación de fechas. Si
date
no puede hacer una fecha y hora válida de la entrada, se elevaValueError
. De esta maneras
es la suma de las fechas no vencidas yt
es el número total de fechas válidas. Estoy aprovechando el hecho de queTrue == 1
para propósitos de adición e indexación en Python. También guardo un personaje usando 25 * (76,80) en lugar de (1900,2000).Tenga en cuenta que las líneas en el segundo nivel de sangría usan un carácter de tabulación, no 2 espacios.
Agregue esto al final para probar:
fuente
PowerShell,
183173168Entrada como a
int[]
través de parámetros, p. Ej.try
/catch
, siempre que no sepa si la salida en stderr está permitida o no.+"-1"
en la fecha, que se interpreta como.AddDays(-1)
un cambio de la fecha actual en un día, para que podamos comparar con ayer (en lugar de solo hoy). Esto resuelve el problema de que obtenemos una fecha con 0:00 como hora, pero necesitamos compararla con una fecha con la hora de hoy.fuente
R, 269
Esperaba que esto fuera fácil en R, pero los años de un solo dígito fueron una bola curva bastante grande. Siento que esto podría ser mucho mejor de lo que es.
lubridate
es un paquete de CRAN, es posible que deba instalarlo coninstall.packages("lubridate")
.Uso:
f(c(d1,d2,d3))
dondec(d1,d2,d3)
es un vector de enteros.Por ejemplo,
f(c(6,10,14))
devoluciones0.3333333
.El
lubridate
paquete tiene una serie de funciones de contenedor para analizar fechas en diferentes órdenes. Los uso para ver qué formatos producen fechas válidas, descartar las inválidas y luego ver cuáles aún no se han producido.fuente
Mathematica,
163153164 bytes( editar: fechas fijas fuera del rango 1950-2049)
Esto define una función que puede llamar como
Actualmente, el porcentaje no está redondeado (esperando que el OP se aclare).
Aquí es un poco larga explicación que debe ser comprensible sin ningún conocimiento Mathematica (nota que
&
hace que todo lo que queda de ella una función anónima, cuyos parámetros se conocen como#
,#2
,#3
...):Esto define una función, que convierte 3 parámetros
a,b,c
en 3 listas{{a,b,c},{c,b,a},{c,a,b}
. Tenga en cuenta que##
es solo una secuencia de todos los parámetros.Aplicado a la fecha de caducidad, esto proporciona una lista de
{y,m,d}
cada una de las tres posibles permutaciones.Esta es una función anónima que toma tres parámetros
a,b,c
y devuelve una lista de los tres, donde el primero se ha convertido a un año según las reglas dadas: los números entre50
y99
(módulo100
) se convierten en un año del siglo XX, los números entre0
y49
( módulo100
) se convierten en un año del siglo XXI, todos los demás quedan. Aquí,##2
hay una secuencia de parámetros que comienza con el segundo, es decirb,c
.Aplicado a cada uno de los tres resultados anteriores, esto solo canoniza los formatos del año. Llamemos a esto
canonicalDates
para acortar la siguiente expresión:Esto filtra las interpretaciones no válidas.
DateList@d
realiza una{y,m,d,h,m,s}
representación completa de varios formatos de fecha. Interpretará las listas en el mismo orden, pero el problema es que puede pasar cosas como{8,2,2006}
en cuyo caso se calculará8 years + 2 months + 2006 days
. Por lo tanto, verificamos que los primeros tres elementos de la lista devuelta sean idénticos a la entrada (que solo puede suceder si el mes y el día están en los rangos apropiados).Para acortar las siguientes líneas, me referiré al resultado de esa expresión a partir
validDates
de ahora:Otra función anónima que toma una fecha y devuelve la diferencia en días hasta hoy (obtenida de
Date[]
).Asigne eso en las interpretaciones de fechas válidas.
Otra función anónima que, dada una lista (
#
), devuelve el porcentaje de números no positivos en esa lista. El.
no es una multiplicación, sino solo el dígito decimal, para evitar números racionales como resultado (obtendría cosas como en100/3
lugar de33.333
, en realidad no sé si eso es un problema).Aplicado a la lista de diferencias de fechas, esto nos da la fracción de interpretaciones que aún no han expirado.
fuente
JavaScript (E6)
159164172Editar Gracias a nderscore por las sugerencias y por empujarme a pensar de nuevo. Reorganizó D evitando parámetros y cortando algunos caracteres.
Editar 2 Otro truco de nderscore, 2 funciones fusionadas en 1. Luego, dos paréntesis eliminaron las expresiones separadas por comas en una. Legibilidad cercana a 0. Nota de advertencia: no redondear podría ahorrar otros 2 caracteres (| 0).
Prueba en la consola FireFox
Salida:
Sin golf
Nota: la función D intenta crear una fecha con un año, mes y día determinados, pero devuelve falso si la fecha creada no es la que se pretendía (! = Día o mes)
fuente
C # en LINQPad -
446408272 BytesTercera edición: Gracias a Le Canard fou por señalar que DateTime.Today es correcto, no DateTime.Now. Segunda edición: ¡ Gracias VisualMelon por esta solución inteligente!
Editar: ¡ Gracias a podiluska y edc65 por ayudarme a acortar el código! También noté que mi solución no era correcta si la entrada del año era de 4 bytes, por lo tanto, incluí la solución para ese problema. El puntaje para esta solución es 408 Bytes.
Aunque no estoy superando ninguna de las respuestas anteriores, todavía quería compartir mi solución C #. Cualquier ayuda / sugerencia es apreciada! ;)
Versión formateada y sin golf:
Traté de hacer una solución donde la parte "DateTime. TryParse" no se repite como en esta solución, pero fue 21 bytes más.
Solución sin repetir "DateTime. TryParse": 467 bytes
Versión sin golf:
fuente
int s=0;int a=d[2];int b=d[1];int e=d[0];
->int s=0,a=d[2],b=d[1],e=d[0];
DateTime.TryParse
llamadas fue mi primer instinto, lo reemplacé con una lambda que también devolvió el valor a q. También realicé algunos otros pasos ( pastebin ) para obtener 328 caracteres:void g(int[]d){var q=new List<DateTime>();var p=".";int a=d[2],b=d[1],e=d[0],y;DateTime c;y=(a<100)?(a>49)?1900+a:2000+a:a;Action<string>z=(x)=>{if(DateTime.TryParse(x,out c))q.Add(c);};z(e+p+b+p+y);z(b+p+e+p+y);y=(e<100)?(e>49)?1900+e:2000+e:e;z(a+p+b+p+y);(q.Where(i=>i>=DateTime.Now).Count()*100/(q.Any()?q.Count:1)).Dump();}
Action<string>
antes, así que pude aprender algo de ti;) pude obtener tu respuesta a 318 caracteres reemplazándolaq.Where(i=>i>=DateTime.Now).Count
porq.Count(i=>i>=DateTime.Now
. ¡También eliminé los corchetesx
para poder guardar 2 personajes más!Haskell,
171165 caracteresEl nombre de la función es
%
. Ejecute con la fecha de prueba como una tupla en orden canónico (a, m, d) con el año real, y el sello del cartón como una tupla de tres números:fuente
Erlang, 146
La función de prueba sería:
Sin golf
Esta solución se basa en la comprensión de la lista. Toma prestado el truco del módulo para el año de la solución Haskell. También se utiliza
calendar:valid_date/1
para manejar fechas imposibles debido a la cantidad de días en un mes determinado (por ejemplo, "29-2-2" solo puede estar en formato YMD). Además, Today está endate()
formato Erlang (una tupla YMD).fuente
APL (85)
Esto utiliza algunas de las nuevas funciones de Dyalog APL 14, pero no bibliotecas externas. Para variar, funciona en TryAPL .
Esta es una función que toma la matriz de 3 elementos como
⍵
argumento del lado derecho ( ), y la fecha para verificar como⍺
argumento del lado izquierdo ( ), como un entero deYYYYMMDD
formato. Es decir, la fecha2014-07-09
se representa como el número20140709
.Prueba:
Explicación:
Z←(⊂⌽⍵),(⊂2⌽⍵),⊂⍵
: convierte la fecha dada en formato YMD volteándola(⊂⌽⍵)
, girándola a la izquierda 2(⊂2⌽⍵)
o simplemente sin hacer nada⊂⍵
. Al menos uno de estos ahora es una fecha adecuada en formato YMD, tal vez más de uno si la fecha es ambigua.{∧/12 31≥1↓⍵}¨Z
: prueba si cada fecha es válida: el año (primer elemento) se descarta, y luego el mes no debe ser superior a 12 y el día no debe ser superior a 31.Z/⍨
: filtra las fechas válidas deZ
.{
...}¨
: para cada fecha válida:⍵+(99≥⊃⍵)×3↑1900+100×50>⊃⍵
: si el año no es superior a 99, agregue 1900, luego 100 si el año es inferior a 50.(3/100)⊥
: descifrarlo como si fuera un conjunto de números de base 100. (El año es superior a 100, pero esto no importa, ya que es el primer elemento). Esto proporciona un número para cada fecha válida en el mismo formato que el argumento izquierdo.⍺≤
: para cada fecha, vea si no es menor que⍺
. Esto dará un vector binario donde 1 significaOK
y 0 significaspoiled
.100×(+/÷⍴)
: divide la suma del vector binario por su longitud y multiplica por 100.fuente
{100×(+/÷⍴)⍺≤((3/100)⊥⊢+(99≥⊃)×3↑1900+100×50>⊃)¨Z/⍨{∧/12 31≥1↓⍵}¨Z←(⌽⍵)(2⌽⍵)⍵}
Java: 349 caracteres (3 sin espacios)
Aquí hay una clase que contiene que se puede usar para probarlo, incluida una versión (ligeramente) desadaptada del método:
Esta es mi primera ronda de golf de código, y creo que descubrí por qué generalmente no veo a muchos golfistas de Java.
fuente
int[]
argumento, no tresint
s.C # 287 bytes
Golf por primera vez, en busca de consejos. Notablemente, eliminando bytes debido al espacio de nombres.
Abusar del hecho de que solo se requiere una función, no un programa real. Además, la función siempre da como resultado una excepción no detectada.
Sin golf
fuente
Mathematica , 118
Usando el código de m.buettner como punto de partida, tengo algunas mejoras:
fuente