Que semana é essa?


8

O dia da semana e o mês do ano parecem receber muita atenção, mas ninguém parece se importar com a semana do ano. Acredito que é hora de mudar isso, portanto, seu trabalho é escrever um programa ou função que, quando determinada data, gera um número inteiro entre 1 e 53, correspondente à semana atual do ano.

Para os propósitos deste desafio, diremos que o primeiro domingo do ano marca o início do ano; portanto, o único caso em que 1º de janeiro é considerado a semana 1 é quando cai em um domingo.

  • A entrada pode ser qualquer formato de data que não inclua explicitamente o número da semana (basta especificar o formato na sua resposta) para datas entre 1JAN1900e 31DEC2100.
  • A saída é um número inteiro entre 1 e 53
  • Você pode usar qualquer método padrão para fornecer entrada / saída.

Casos de teste

17MAY2017 -> 20

3JAN2013 -> 53

1JAN2017 -> 1

17MAY1901 -> 19

31DEC2100 -> 52

7JUL2015 -> 27
  • Isso é portanto todas as regras padrão de golfe se aplicam e o código mais curto (em bytes) vence.

5
As semanas ISO seriam mais padrão; O IIRC é baseado na primeira quinta-feira de um ano.
Neil

Podemos usar outros formatos de entrada de data (por exemplo, 07/07/2015)? Pode 7JUL2015ser 07JUL2015?
21717 Stephen

@ Stephenos Sim, tudo bem. 7/7/2015, 2015-07-07também são válidos.
J_Lard 17/05

2
@ Neil: Não corresponder exatamente à definição padrão é uma coisa boa aqui, torna menos provável que o problema possa ser resolvido através de um built-in, ao mesmo tempo em que não é mais difícil resolver sem ele.

4
Nota para as pessoas que usam %U: Como aponta o @J_Lard, é preciso ter cuidado se a semana 0 é a semana 52 ou 53 do ano anterior. É a semana 53 em 2001, 2007, 2013, 2018, 2024, 2029 e se repete em um ciclo de 28 anos. Outros anos é a semana 52.
Neil

Respostas:


2

Ohm , 12 33 bytes

EDIT : Corrigidos os casos de borda para "% U".

IΩDÖ?┼╓y≤s"-12-31"C"%F"╓₧Ω
"%U"╓&

Assume que a entrada pode ser um carimbo de data / hora. Explicação para vir.

Experimente online!


1
A semana 0 é diferente em anos como 1995 e 2023.
Neil

@ Neil Isso é verdade, mas o desafio diz que a resposta deve estar entre 1 e 53, e eu estou basicamente fazendo a mesma coisa que todas as outras respostas.
Nick Clifford

Desculpe, eu misturei meus anos. Enfim, são 52 em alguns anos e 53 em outros.
Neil

@ Neil Lá vamos nós.
Nick Clifford

1
De fato, isso fornece respostas corretas para, por exemplo, 1º de janeiro de 2018 e 2019. #
Neil

6

MATL , 50 bytes

Obrigado a @Neil e @NickClifford por apontarem um erro, agora corrigido

ZO1)TThXJYOXIGYO&:8XO!s310=sJ4B-YOIq&:8XO!s310=sX\

Experimente online!Ou verifique todos os casos de teste .

Explicação

Isso usa as três funções de conversão de data / hora que existem no MATL:

  • XO: converte data e hora em formato de string;
  • YO: converte data e hora em número de série;
  • ZO: converte data e hora em vetor de componentes.

Determinar se a semana "0" deve se tornar 52 ou 53 foi caro, porque o MATL não pode definir funções que podem ser chamadas para reutilizar a 8XO!s310=speça. Reutilização por meio de loop com uma ramificação economiza apenas um byte e complica a explicação, provavelmente não vale a pena.

Além disso, pode-se obter algo inserindo a data como uma matriz [ano, mês, dia]; mas eu não usaria as três funções de data :-)

Considere a entrada '17MAY2017'como um exemplo.

       % Implicit input
       % STACK: '17MAY2017'
ZO     % Convert to date vector
       % STACK: [2017 5 17]
1)     % Get first entry: year
       % STACK: 2017
TTh    % Append [1 1]
       % STACK: [2017 1 1]
XJ     % Copy to clipboard J
YO     % Convert to date number
       % STACK: 736696
XI     % Copy to clipboard I
GYO    % Push input again. Convert to date number
       % STACK: [736696 736832]
&:     % Binary range
       % STACK: [736696 736697 736698 ... 736832]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: ['Sun'; 'Mon'; 'Tue'; ... ; 'Wed']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: [310 298 302 ...  288]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: [1 0 0 ... 0]
s      % Sum of array. If is 0, it needs to be transformed into 52 or 53,
       % depending on the number of Sundays the previous year contains.
       % STACK: 20
J      % Paste from clipboard J
       % STACK: 20, [2017 1 1]
4B-    % Push [1 0 0] and subtract element-wise
       % STACK: 20, [2016 1 1]
YO     % COnvert to date number
       % STACK: 20, 736330
I      % Paste from clipboard I
       % STACK: 20, 736330, 736696
q      % Subtract 1
       % STACK: 20, 736330, 736695
&:     % Binary range
       % STACK: 20, [736330 736331 736332 ... 736695]
8XO    % Convert to date string with format 'ddd': day of week
       % STACK: 20, ['Fri'; 'Sat'; 'Sun'; ... ; 'Sat']
!s     % Sum of each row (chars are interpreted as code points)
       % STACK: 20, [289 296 310 ... 296]
310=   % Compare with 310 (sum of 'Sun')
       % STACK: 20, [0 0 1 ... 0]
s      % Sum of array
       % STACK: 20, 52
X\     % 1-based modulo
       % STACK: 20
       % Implicit display

2
Parabéns por 50k! Eu estou bem aqui atrás de você :)
Digital Trauma

1
2 pontos para ir ... e boom! Parabéns!
Jonathan Allan

Isso funciona com os casos extremos apontados por Neil? Eu sei que ele não usa %U, mas eu só quero ter certeza.
Nick Clifford

Isso parece pensar que 1º de janeiro de 2019 está na semana 53, mas é apenas na semana 52.
Neil

@ Neil Sim, você está correto. Curiosamente, os outros casos de teste estão corretos.
J_Lard 17/05

4

JavaScript (ES6), 82 80 bytes

Toma entrada como (year,month,day).

let f =

(y,m,d)=>-~((((x=new Date(y,m-1,d))-new Date(y,0,1))/864e5+372-x.getDay())/7%53)

console.log(f(2017, 5,17)) // 20
console.log(f(2013, 1, 3)) // 53
console.log(f(2017, 1, 1)) // 1
console.log(f(1901, 5,17)) // 19
console.log(f(2100,12,31)) // 52
console.log(f(2015, 7, 7)) // 27


4

JavaScript (Firefox 34+), 70 bytes

with(new Date())y.value=getFullYear(),m.value=getMonth()+1,d.value=getDate()+1
f=
(y,m,d)=>new Date(y,--m,d-new Date(y,m,d).getDay()).toLocaleFormat`%U`
<div oninput=w.value=f(y.value,m.value,d.value)><input id=y type=number><input id=m type=number min=1 max=12><input id=d type=number min=1 max=31><input id=w readonly placeholder=Output>

Funciona localizando o primeiro dia da semana que contém a data especificada e, em seguida, localizando o número da semana desse dia (que nunca é zero).


+1 para with. Sempre +1 para with!
Shaggy

2

Python 2, 70 64 bytes

Entrada => (year,month,day)

from datetime import*;lambda*v:int(date(*v).strftime('%U'))or 53

print(f(2017, 5,17)) #20
print(f(2013, 1, 3)) #53
print(f(2017, 1, 1)) #1
print(f(1901, 5,17)) #19
print(f(2100,12,31)) #52
print(f(2015, 7, 7)) #27

-6 bytes, graças a @ovs


2

JavaScript (somente Firefox), 77 bytes

Toma data como string: ie Jan 1, 2017

s=>+new Date(s)[k='toLocaleFormat']`%U`||new Date(s.slice(-4)-1,11,31)[k]`%U`

Boa tentativa, mas a "semana 0" nem sempre é a mesma semana (1995 e 2023 são diferentes).
Neil

Desculpe, casos de teste errados. Eu devo postar um comentário adequado sobre a questão.
194 Neil

@ Neil Deve ser corrigido.
powelles


2

C #, 138 123 121 bytes

namespace System.Globalization{d=>CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d,(CalendarWeekRule)1,(DayOfWeek)0);}

Acontece que há um construído para isso, embora seja bastante grande ...

namespace System.Globalization
{
    Func<DateTime, int> f = d =>
        CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(d, (CalendarWeekRule)1, (DayOfWeek)0);
 }

1

Powershell, 260 + 8 = 268 bytes

+8 bytes por causa do -DateTime bandeira


Aceita argumento como "day month year"formato.

function W([datetime]$DateTime = (Get-Date)) {
$cultureInfo = [System.Globalization.CultureInfo]::CurrentCulture
$cultureInfo.Calendar.GetWeekOfYear($DateTime,$cultureInfo.DateTimeFormat.CalendarWeekRule,$cultureInfo.DateTimeFormat.FirstDayOfWeek)
}

Não é especialista em PowerShell, não pode jogar golfe


Caso de teste

>W -DateTime "11 March 2015"
11
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.