Eu tinha uma idéia genial para facilitar a vida profissional - uma contagem regressiva para uma data específica que conta apenas dias úteis.
A tarefa básica é criar uma contagem regressiva para uma data específica que inclua apenas os dias úteis na contagem regressiva.
Como o dia útil conta segunda , terça , quarta , quinta e sexta - feira .
A Entrada deve ser uma data específica no formato padrão europeu "não oficial" dd.MM.yyyy
e deve ser hoje ou um dia no futuro.
A saída deve ser apenas o número de dias restantes.
Como é código-golfe, o código mais curto vence.
Caso de teste:
Today | Input | Output
10.12.2018 | 17.12.2018 | 5
02.10.2018 | 16.10.2018 | 10
Se eu perdi algumas coisas na pergunta, por favor me perdoe - é a minha primeira pergunta :)
EDITAR:
- Você pode usar
false
como saída em vez de0
<- mas não é bonito - Não há necessidade de respeitar o horário de verão
Respostas:
05AB1E ,
130128133131124123 bytesEstou maluco ..
Para o idioma de golfe 05AB1E, não importa se a entrada está com
.
ou-
. No entanto, 05AB1E não possui nenhum built-in para objetos ou cálculos de data. O único construído em relação às datas que possui é o ano / mês / dia / hora / minutos / segundos / microssegundos de hoje.Portanto, por causa disso, quase todo o código que você vê são cálculos manuais para ir para o dia seguinte e calcular o dia da semana.
+5 bytes devido a uma parte que esqueci na fórmula de Zeller (ano-1 para os meses de janeiro e fevereiro).
Experimente online ou Experimente online com uma data emulada e especificada automaticamente de 'hoje' .
Explicação:
Parede de entrada de texto.
Em geral, o código segue o seguinte pseudocódigo:
1)
Date currentDate = today;
faz parte do programa 05AB1E:2)
Integer counter = 0;
e 3)Start an infinite loop:
são diretas no programa 05AB1E:4)
If(currentDate is NOT a Saturday and currentDate is NOT a Sunday):
é a primeira parte difícil com cálculos manuais. Como 05AB1E não possui data embutida, teremos que calcular o dia da semana manualmente.A fórmula geral para fazer isso é:
Onde, para os meses de março a dezembro:
[1, 31]
)[3, 12]
)E para os meses de janeiro e fevereiro:
[1, 31]
)[13, 14]
)Resultando no dia da semanah , em que 0 = sábado, 1 = domingo, ..., 6 = sexta-feira.
Fonte: congruência de Zeller
Podemos ver isso nesta parte do programa 05AB1E:
5)
Counter += 1;
é direto novamente:6)
currentDate += 1; // Set currentDate to the next day in line
é novamente mais complexo, porque temos que fazer isso manualmente. Portanto, isso será expandido para o seguinte pseudocódigo:Fontes:
Algoritmo para determinar se um ano é um ano bissexto.(EDIT: não é mais relevante, pois uso um método alternativo para verificar os anos bissextos que salvaram 7 bytes.)Algoritmo para determinar o número de dias em um mês.
6a)
Integer isLeapYear = ...;
é feito assim no programa 05AB1E:Também usado em nesta minha resposta 05AB1E , para que alguns anos de exemplo sejam adicionados para ilustrar as etapas.
6b)
currentDate.month == 2 ?
e 6c)28 + isLeapYear
são feitos assim:6d)
:
e 6e)31 - (currentDate.month - 1) % 7 % 2;
são feitos assim:6f)
If(currentDate.day < daysInCurrentMonth):
é feito assim:6g)
nextDate.day += 1;
é feito assim:6h)
Else:
e 6i)nextDate.day = 1;
são feitas da seguinte maneira:6j)
If(currentDate.month < 12):
:6k)
nextDate.month += 1;
:6l)
Else:
, 6m)nextDate.month = 1;
e 6n)nextDate.year += 1;
são feitos da seguinte maneira:E finalmente às 8)
If(currentDate == parsed input-string):
e 9)Stop the infinite loop, and output the counter
:fonte
Excel 24 bytes
Pressupõe entrada na célula A1
Usa a função interna. Infelizmente, a função inclui hoje e a data final. Desde então, o OP esclareceu para não contar hoje, então adiciono um ao NOW para não contar hoje.
Para endereçar comentários no formato de número, novamente, este é o padrão do Excel:
fonte
10.12.2018
é uma string quando mantida em uma célula e não em uma data. A solução óbvia, mas muito tempo para corrigir este seria mudarA1
aDATE(RIGHT(A1,4),MID(A1,4,2),LEFT(A1,2))
sua soluçãoHKCU\Control Panel\International\sDecimal
cadeia de registro. Em uma instalação padrão do Windows nos EUA, é MM / dd / aaaa. Na maioria dos países da UE, esse seria o padrão.R , 76 bytes
Também dê uma olhada nesta resposta R de 72 bytes que também é independente da localidade.
Experimente online!
weekdays
fornece dias de texto da semana; portanto, contamos os dias na sequência entre hoje e a entrada que não contémS
e adicionamos um ao resultado.fonte
Java 10,
233232226 bytesDate sempre me lembra como Java é realmente detalhado ..
NOTA: Agora existem duas respostas Java mais curtas (abaixo de 175 bytes), uma com uso inteligente de métodos descontinuados de versões anteriores do Java por @LukeStevens e outra usando as
java.time.LocalDate
novidades desde o Java 8 por @ OlivierGrégoire .Experimente online.
Explicação:
fonte
e=s.clone()
?Calendar s=Calendar.getInstance(),e=s.getInstance()
, que infelizmente acaba sendo exatamente do mesmo tamanho.C
realmente não é necessária. Era de uma parte antiga do código onde eu também usavaC
em outro lugar. Foi capaz de golf 1 byte usandovar s=Calendar.getInstance();var e=s.getInstance();
tão obrigado. :)java.time
.JavaScript (ES6),
116103 bytesExperimente online!
Quão?
.toJSON()
método:YYYY-MM-DD
YYYY-MM-DD
DD.MM.YYYY
D.getDay()
fonte
MATL , 24 bytes
Experimente online!
Você meio que conseguiu :-)
Explicação
fonte
16.10.2018
hoje (segunda-feira01-10-2018
) resultaria em11
amanhã em10
etc.Wolfram Language (Mathematica) ,
6456 bytesExperimente online!
DayCount[x,y,"Weekday"]
conta o número de dias da semana entrex
ey
.As entradas
x
ey
podem ser muitas coisas, incluindo uma fantasiaDateObject
como a retornada porToday
, ou uma string no formato (infelizmente)mm.dd.yyyy
.Minha tentativa anterior tentou ativar o
dd.mm.yyyy
entrada em umaDateObject
, dizendo ao Mathematica como analisá-la; a nova solução simplesmente reorganiza a string para colocar dia e mês na ordem que o Mathematica espera.Vale ressaltar que a solução de 28 bytes
DayCount[Today,#,"Weekday"]&
não só funciona perfeitamente para um formato de entrada mês-dia-ano, mas também lida corretamente com entradas inequívocas de dia-mês-ano como31.12.2018
, o que não poderia significar "o 12º dia do 31º dia mês". Por isso, é correto mais de 60% das vezes :)fonte
Perl 6 , 61 bytes
Experimente online!
fonte
R, 72 caracteres
Uma variação na resposta fornecida por @ngm, que evita que o grepl salve alguns caracteres e funcione em locais que não sejam em inglês.
sum(strftime(seq(Sys.Date(),as.Date(scan(,""),"%d.%m.%Y"),1),'%u')<6)+1
fonte
Java (OpenJDK 8) ,
174166165 bytesCom um pouco de inspiração na resposta de Kevin e uma boa análise através da API obsoleta do Date, consegui obter uma solução Java mais sucinta.
-8 bytes graças à análise inventiva da data regex de Kevin
-1 bytes graças à inteligente operação bit a bit de Nevay
Experimente online!
Explicação
fonte
d=d[0].split
obsoleto e obsoleto.parse
com o formato padrãoMM/dd/yyyy
. Um pequeno erro na sua postagem, você tem emimport java.text.*;
vez doimport java.util.*;
código e// Required import for both Calendar and Date
da explicação (mesmo que não useCalendar
).java.text
reparado agora! Obrigado!d=d[0].split
varargs, alterar a entrada para uma String regular, removerd=d[0].split("\\.");
e alterard[1]+"/"+d[0]+"/"+d[2]
parad.replaceAll("(..).(..).","$2/$1/")
salva 7 bytes .r+=new Date(s).getDay()%6<1?0:1,s+=864e5);
paras+=864e5)r+=new Date(s).getDay()%6<1?0:1;
. :)r-=-new Date(s).getDay()%6>>-1;
Vermelho , 72 bytes
Experimente online!
Leva a data no formato dd-mm-aaaa, por exemplo 31-10-2018 (também funciona com 10 de outubro de 2018)
Entrada estrita:
Vermelho , 97 bytes
Experimente online!
Bônus:
Retorna uma lista das datas / dias da semana dos dias úteis até a data especificada:
Vermelho , 235 bytes
Experimente online!
fonte
JavaScript,
8785 bytesRetorna
false
para0
.Experimente online ou verifique os próximos 31 dias
fonte
Python 2 ,
163156149147 bytesExperimente online!
-7 com agradecimentos a @mypetlion
-7 mais com graças a @ovs
+30 devido ao formato de entrada muito restritivo, que eu notei apenas antes de postar meu código anterior, que recebeu entrada como por exemplo
(2018,11,1)
:-(fonte
(0,1)[t.weekday()<5]
. Os booleanos Python são uma subclasseint
eTrue, False
podem ser usados em operações aritméticas como1,0
. Substitua porc+=t.weekday()<5
para salvar 7 bytes.Java (JDK 10) , 171 bytes
Experimente online!
Créditos
fonte
(.*)\\.(.*)\\.(.*)
para(..).(..).(.*)
.replaceAll
técnica, sua resposta também pode ser alterada em 7 bytes, portanto a sua ainda é um pouco mais longa. ;)JavaScript (Node.js) ,
168160139133 bytes35 bytes a menos graças a Quintec e Kevin Cruijssen
Experimente online!
fonte
f=
-lo à contagem de bytes (e no TIO você pode colocá-lo no cabeçalho), e é por isso que a @Quintec afirmou que é 139 bytes em vez de 141 bytes. Além disso, você pode mudarif((d.getDay()+1)%7>1)n++;
paran+=-~d.getDay()%7>1;
a golf-lo para 133 bytes .-~i
é a mesma.(i+1)
Além disso, se você ainda não o viu, pode ser interessante ler dicas de golfe em JavaScript e dicas de golfe em <todos os idiomas> . :)Python3 & Numpy, 96 bytes
I couldn't get smaller than the boring pre-made solution...
Try it online!
fonte
PowerShell,
10799 bytes-8 bytes thanks to mazzy
Try it online!
Performs a regex
-split
on the input$args
, stores the values into$d
ays,$m
onths, and$y
ears, respectively. Then, enters afor
loop, initializing$a
to today's date. The loop continues while$a
is-l
esst
han our input target date. Each iteration we're adding1
days
to$a
, and checking whether the currentD*k
(short forDayOfWeek
) is in the range1..5
(i.e., Monday to Friday). That Boolean result is accumulated into$o
and once we're out of the loop that value is left on the pipeline and output is implicit.fonte
$d,$m,$y=$args-split'\.';for($a=date;$a-lt(date "$y-$m-$d");$a=$a|% *ys 1){$o+=($a|% D*k)-in1..5};$o
for(...){...}
and$o
can be removed, so we're now below 100!Python 2,
147143141140 bytesTry it online!
Takes a string, e, which represents the end date in the format "dd.MM.YYYY". Optionally also takes the start date, but this is expected to be a datetime.date.
The start date, s, is defaulted to today's date as a datetime.date object in order to disregard time. The end time is parsed into a datetime.datetime object then converted to a date, since datetime.date objects do not have a parse method and datetimes cannot be added to/subtracted from dates. Iterates through every day in (start, end] and adds 1 to the total if its weekday number is < 5. ([0-4] are [Mon-Fri], [5-6] are [Sat-Sun]).
Datetime parsing is the worst, you guys.
EDIT: Stole ElPedro's map(int,thing) trick to save 4 bytes.
EDIT 2: ELECTRIC BOOGALOO: Saved 2 bytes by making it an anonymous function. (Thanks Aaron!)
EDIT 3: xrange -> range. (Thanks again Aaron!)
fonte
f=
from lambda expressions hererange
rather thanxrange
it should still work just fine.PHP, 66 bytes
empty output for
0
; insert+
betweenecho
and$r
to fix.Run as pipe with
-nr
or try it online.60 bytes with unary output:
fonte
PHP (with Carbon), 107 bytes
fonte
IBM/Lotus Notes Formula - 99 bytes
Takes input from a date/time field
i
. The input format ofi
is set to.
separated so there is no need to convert the input. Notes can take a date input with any separator as long as you tell it before what it is going to be (hope that's not cheating!). Formula is in computed numeric fieldo
on the same form.Interesting aside: Ever since
@For
and@While
were introduced into the Formula language in (I think) R6 by the great Damien Katz the only use I have found for them is code golfing. I have never used them in a production app.There is no TIO available for formula so here is a screenshot taken on 02.10.2018:
fonte
Ruby, 81 bytes
Try it online!
fonte
K4, 40 bytes
Solution:
Explanation:
Calculate the difference between the dates, use modulo 7 to ignore weekends, sum up.
Notes:
"D"$,/|"."\:x
fonte
C (clang),
209208205 bytesCompiler flags
-DU=u=localtime(&b)
-DW=tm_wday
-DY=tm_year
-DT=tm_yday
(52 bytes).Try it online!
-1 byte thanks to @JonathanFrech
fonte
?i++:0
->&&++i
.q,
5279 bytesin q, each date has an underlying integer value, based on how many days have passed since the start of the millenium. Applying 'mod 7' to this, you get unique values for each day of the week (0 for Saturday, 6 for Friday). So when 2 > x mod 7, don't increment the counter, to avoid counting weekends.
EDIT: Missed strict date format, editing
EDIT2: Included
fonte
{sum 1<mod[d+til("D"$x 10 vs 67893401)-d:.z.d]7}
for 48 bytes without resorting to K verbs.