Legalizar data revertida

18

Entrada:

Um Data (contendo dd, MMe yyyy). Um objeto de data ou três inteiros separados também são válidos como entrada.

Resultado:

Cada parte ( dd, MMe yyyy) revertida individualmente e depois arredondada para a data válida mais próxima.

Por exemplo (no formato dd-MM-yyyy):
21-10-2016torna - se12-01-6102

Regras do desafio:

  • Apenas dd, MM, yyyyé válida, mas a ordem e que separam-símbolos que você usa é a sua própria escolha.
    Então, esses são alguns exemplos de formato válidos: dd-MM-yyyy; MM/dd/yyyy; yyyy MM dd; ddMMyyyy, Etc.
    E estes são alguns exemplos de formato inválidos: dd MMM yyyy; dd-MM-'yy; etc.
  • Você também pode optar por inserir apenas um objeto Date se o seu idioma suportar ou três parâmetros inteiros separados, em vez da string que representa uma data.
  • Indique qual formato de data você usou! (E a entrada e a saída devem estar no mesmo formato.) Também é permitido gerar um objeto Date, desde que ele possa lidar com todos os casos de teste e a regra de desafio abaixo.
  • A transição do calendário juliano para o gregoriano é ignorada para esse desafio. Portanto, 1582é apenas um ano invertido válido para 2851.
    Consulte Informações / dicas do desafio para todos os anos, meses e dias válidos.
  • Como você não pode ter fevereiro como revertido em qualquer outro mês, não precisa se preocupar com anos bissextos.

Todos os anos, meses e dias revertidos:

  • O ano sempre pode ser revertido sem problemas, passando de 0001 (revertido de 1000) a 9999 (permanece 9999). (Portanto, 0000não é uma entrada válida e também não há casos de teste.)
  • Os únicos meses que você reverterá são: janeiro (revertido de outubro / 10); Outubro (revertido de janeiro / 01); Novembro (permanece novembro / 11); e dezembro (revertido a cada dois meses / 02- 09, 12).
  • Os únicos dias que você terá revertido são: 01 (revertido de 10), 02 (revertido de 20), 03 (revertido de 30), 10 (revertido de 01), 11 ( revertido de ), 11 (permanece 11), 12 (revertido de 21), 13 (revertido de 31) , 20 (revertido de 02), 21 (revertido de 12), 22 (restante 22), 30 (revertido de 03ou o mesmo que 31 de novembro!), 31 (revertido de 04- 09/ 13-19/ 23- 29).

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta, para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e declarações de retorno / saída, programas completos. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código.
  • Além disso, adicione uma explicação, se necessário.

Casos de teste ( dd-MM-yyyycomo formato):

21-07-2016   ->   12-12-6102
12-11-1991   ->   21-11-1991
01-01-2000   ->   10-10-0002
27-08-1875   ->   31-12-5781
18-12-2010   ->   31-12-0102
13-01-1981   ->   31-10-1891
04-11-1671   ->   30-11-1761  // Semi-tricky case, since November has 30 days
28-11-2036   ->   30-11-6302  // Semi-tricky case, since November has 30 days
14-06-1855   ->   31-12-5581
30-10-9999   ->   03-01-9999
01-01-2851   ->   10-10-1582
Kevin Cruijssen
fonte
@ LegionMammal978 Não, 21-07-2016é revertido 12-70-6102e arredondado para 12-12-6102. Não tenho certeza como você obter o resultado ##-10-6107..
Kevin Cruijssen
@KevinCruijssen Ok, eu pensei que era o mês que terminava 70, com o ano aumentando.
LegionMammal978
A 10-10-2saída é válida no terceiro caso?
18746 Luis Mendo
@LuisMendo Yeah sure. Vi outras pessoas fazerem isso também. O desafio é mais reverter e arredondar as datas corretamente do que o formato de entrada ou saída.
Kevin Cruijssen 27/07
Seria aceitável pegar três strings e esperar zeros à esquerda?
JustinM - Restabelece Monica

Respostas:

3

Convexo , 23 bytes

A contagem de bytes assume a codificação CP-1252.

qS/Wf%_1=:=31^sCs¶.e<S*

O formato de E / S é dd mm yyyy.

Experimente online!

Esta é uma porta direta da minha resposta CJam . O Convex baseia-se fortemente no CJam e, portanto, a única diferença é o uso do operador do Convex, que agrupa os dois principais elementos da pilha em uma lista, economizando um byte [...].

Martin Ender
fonte
8

CJam, 24 bytes

qS/Wf%[_1=:=31^sCs].e<S*

O formato de E / S é dd mm yyyy.

Experimente online!

Contagem de mesmos bytes, formato de E / S mm dd yyyy:

qS/Wf%_0=:=1231^s2/.e<S*

Experimente online!

Explicação

qS/     e# Read input, split around spaces.
Wf%     e# Reverse each component.
[       e# Set marker for new list.
  _1=   e#   Duplicate reversed strings, extract reversed month.
  :=    e#   Check for equality of the characters. This gives 1 for
        e#   November (11) and 0 for everything else.
  31^   e#   XOR the result with 31, giving 30 for November and 31
        e#   for everything else.
  s     e#   Convert the result to a string, "30"/"31".
  Cs    e#   Push 12, convert to string, "12".
]       e# Wrap "30"/"31" and "12" in a list.
.e<     e# Element-wise minimum. This clamps the day and month to their
        e# respective maxima.
S*      e# Join the result with spaces.

A outra versão funciona da mesma forma, exceto que começamos a partir do número inteiro 1230ou 1231antes de convertê-lo para ["12" "30"] ou ["12" "31"].

Martin Ender
fonte
2
Os idiomas com data built-in ...
Leaky Nun
1
@LeakyNun Isso não usa uma data incorporada e não vejo como isso ajudaria.
Martin Ender
Então, como você sabe que há 30 dias em novembro?
Freira vazada
2
@LeakyNun Vou adicionar uma explicação mais tarde, mas 1=obtém o mês invertido, :=verifica se seus dígitos são iguais e ^reduz o resultado para 31, dando 30 por mês 11e 31 para todo o resto.
Martin Ender
Ah, eu não li as especificações ... #
Leaky Nun
5

Pitão, 55 53 46 43 41 bytes

APJ_Mczd = HhS, 12sH = GhS, sGC @. "❤❤ó» "H%"% 02d% 02d% s "[GHeJ 
APJ_Mczd = hS, 12sH = hS, sGC @." ❤❤ó »î" H% "% 02d% 02d% s" [GHeJ 
APJ_Mcz \ -% "% 02d% 02d% s" [hS, sGx31q11sHhS, 12sHeJ 
APJ_Mczdjd [> 2+ \ 0hS, sGx31q11sH> 2+ \ 0hS, 12sHeJ
APJ_Mczdjd. [L \ 02 [`hS, sGx31q11sH`hS, 12sHeJ

onde ❤❤havia dois não imprimíveis, respectivamente U + 001C e U + 001F.

Suíte de teste.

Freira Furada
fonte
3

Python 3, 82 bytes

lambda x:[min(x[0][::-1],['31','30'][x[1]=='11']),min(x[1][::-1],'12'),x[2][::-1]]

Uma função anônima que recebe entrada, via argumento, da data como uma lista de cadeias de caracteres do formulário ['dd', 'mm', 'yyyy']e retorna a data reversa validada no mesmo formato.

Como funciona

Python compara caracteres e seqüências de caracteres por seus pontos de código Unicode. Isso significa que qualquer comparação em dois ou mais números inteiros retorna o mesmo que a comparação nesses números inteiros como seqüências de caracteres. Portanto, chamar mindois números inteiros como sequências retorna o menor número inteiro como sequência; tomando a parte da data invertida como um argumento e o valor máximo como outro, o dia e o mês são fixados no intervalo desejado. As partes da data são revertidas pela indexação com as etapas de -1( [::-1]) e o valor máximo para o mês é alterado de '31'para '30'se o mês for novembro, indexando em uma lista com o resultado booleano de uma condicional.

Experimente no Ideone

TheBikingViking
fonte
2

Dyalog APL , 32 33 bytes

⍕¨{⍵-3↑31 11≡2↑⍵}31 12 1E4⌊⍎∊⍕⌽¨⎕

E / S é uma lista de três cadeias ( 'dd' 'mm' 'yyyy').

TryAPL , mas observe que (solicitação de entrada) foi substituída por e toda a linha delimitada em {... }para ativar o teste on-line, e (executar expressão) foi substituída por 2⊃⎕VFI(verificar e corrigir entrada) porque a execução de código arbitrário está bloqueada .

Adão
fonte
2

C # 314 305 299 249 232 223 Bytes

using System.Linq;string f(int d,int m,int y){Func<int,string>r=i=>string.Concat((""+i).PadLeft(2,'0').Reverse());Func<string,int,string>x=(j,k)=>int.Parse(j)>k?""+k:j;return x(r(d),m==11?30:31)+"-"+x(r(m),12)+"-"+r(y);}

Agradeço a @KevinCruijssen por apontar que eu poderia reduzir minha declaração de variável, que também tornou a string de aliasing capaz de salvar alguns bytes.

Economizou 50 bytes armazenando a função de reversão para reutilização e outros 13, fazendo o mesmo para o arredondamento e removendo as declarações da variável.

A última atualização faz com que a cadeia de aliasing não seja mais uma proteção de bytes.

Versão Ungolfed:

using System.Linq;
    string dateReverse(int day, int month, int year)
{
    //setup a resuable function to reverse
    Func<int, string> reverse = intToReverse => string.Concat((""+intToReverse).PadLeft(2, '0').Reverse());

    //another function for rounding
    Func<string, int, string> round = (strToRound, maxVal) => int.Parse(strToRound) > maxVal ? "" + maxVal : strToRound;

    //Join the strings into the "dd-mm-yyyy" date format
    return 
        //Round down the day value, if november cap to 30 otherwise cap to 31
        round(reverse(day), month == 11 ? 30 : 31) + "-" +

        //Round the month down
        round(reverse(month), 12) + "-" +

        //we can use the reverse function here too and pad left just won't do anything
        reverse(year);
}

Teste aqui

JustinM - Restabelecer Monica
fonte
Você pode ignorar o espaço entre using System.Linq;e a função, então isso é -1 byte. Além disso, você var n=...;var e=...;pode obter 1 byte de golfe usando este byte: string n=...,e=...;não é muito, mas ainda -2 bytes. ;)
Kevin Cruijssen 27/07
Boa captura desse espaço, embora pareça que minha contagem de bytes realmente não contava, por isso, abro isso até um problema de copiar e colar. Também acho que usando esse estilo de declaração variável poderei ganhar mais alguns bytes alterando a string.
JustinM - Restabelecer Monica
2

Javascript, 106 105 94 bytes

d=>d.split`,`.map((a,b,r)=>(e=[...a].reverse().join``,f=!b?r[1]==11^31:b<2&&12,f&&f<e?f:e))+''

Conjunto de testes (rev. 3)


Explicação

d=>d.split`,`                 // split into sections by `,`

.map((a,b,r)=>(               // map each section

e=[...a].reverse().join``,    // spread a date section into array and reverse and 
                              // join with `` to get string result

f=!b?r[1]==11^31              // if section being mapped is day (section 0), 
                              // then max (f) is 30 for November(month 11) or else 31

:b<2&&12,                     // if part being mapped is month (section 1), then max (f) is 12

f&&f<e?f:e))                  // if there is a max (f)
                              // and the max (f) is less than the reversed string (e),
                              // then return the max (f), 
                              // else return the reversed string (e)

+''                           // join all the sections back together with `,` 
                              // (concatenating [] with a string will do this)

Obrigado a @KevinCruijssen por economizar 1 byte para b==1a b<2. Obrigado @ Neil por salvar 11 bytes, sugerindo literal e ,separador de modelo ES6 .

CShark
fonte
Eu sou muito ruim em JS, então me corrija se eu disser algo errado, mas não posso b==1jogar b<2para salvar um byte? Não pode mais ser 0, pois você já verificou isso na !b?parte do código. Parece funcionar no seu conjunto de testes quando eu o troco.
Kevin Cruijssen 27/07
@KevinCruijssen sim, você está certo, obrigado! Eu apenas a ignorei. Eu não fiz golfe em javascript por muito olhar para que eu perca as coisas assim às vezes
CShark
* Eu quis dizer 'por muito tempo', e não 'por muito olhar'
CShark
2
Ao direcionar o ES6, você pode usar seqüências de caracteres de modelo para encurtar seu código - em join``vez de, join('')por exemplo -, mas pode economizar um pouco mais usando ,como separador, o que permite que você +''junte os três valores.
315 Neil
@ Neil você quer dizer ,como o separador na entrada?
CShark
1

Ruby, 92 84 + 1 ( -psinalizador) = 93 85 bytes

Usa -como separador.

d,m,y=chomp.split(?-).map &:reverse
$_=[[d,m=="11"?"30":"31"].min,[m,"12"].min,y]*?-
Value Ink
fonte
1

Pyke, 29 bytes

F_bw-o^tDI]SX(mhj_Xjth~%R@]Sh

Experimente aqui!

Eu definitivamente posso ver isso sendo jogável

Azul
fonte
0

Python 2, 154 bytes

z=input().split("-");r=[x[::-1]for x in z];z[1]=r[1]if r[1]<'12'else '12';z[0]=r[0]if r[0]<'31'else '30'if z[1]=='11'else '31';z[2]=r[2];print "-".join(z)

Toma a entrada como uma sequência, portanto, as aspas precisam ser especificadas na entrada, por exemplo, "11-04-2016".

Jeremy
fonte
Apenas uma melhoria básica desde que eu não sou um golfista Python: z=[x[::-1]for x in z];z[1]=min(z[1],'12');z[0]=min(z[0],['31','30'][z[1]=='11']);print"-".join(z). Basicamente, você não precisa usar rnada e minrealiza muitas das coisas que deseja fazer.
Value Ink
0

05AB1E , 24 bytes

#íÐÅsË31^12‚øεßт+¦}sθªðý

Porto de @MartinEnder resposta CJam 's , assim também as entradas e saídas como uma string no formato dd MM yyyy.

Experimente online ou verifique todos os casos de teste .

Explicação:

#                         # Split the (implicit) input by spaces
                          #  i.e. "04 11 1671" → ["04","11","1671"]
                          #  i.e. "20 01 2000" → ["20","01","2000"]
 í                        # Reverse each string
                          #  i.e. ["04","11","1671"] → ["40","11","1761"]
                          #  i.e. ["20","01","2000"] → ["02","10","0002"]
  Ð                       # Triplicate this list
   Ås                     # Pop one of them, and push it's middle element (the months)
                          #  i.e. ["40","11","1761"] → "11"
                          #  i.e. ["02","10","0002"] → "10"
     Ë                    # Check if the digits are the same (1 for 11; 0 otherwise)
                          #  i.e. "11" → 1 (truthy)
                          #  i.e. "10" → 0 (falsey)
      31^                 # Bitwise-XOR with 31 (30 for November, 31 for other months)
                          #  i.e. 1 → 30
                          #  i.e. 0 → 31
         12              # Pair it with 12
                          #  i.e. 30 → [30,12]
                          #  i.e. 31 → [31,12]
            ø             # Zip/transpose; swapping rows and columns
                          # (implicitly removes year)
                          #  i.e. ["40","11","1761"] and [30,12] → [["40",30],["11",12]]
                          #  i.e. ["02","10","0002"] and [31,12] → [["02",31],["10",12]]
             ε    }       # Map each pair to:
              ß           # Get the minimum (implicitly converts to integer unfortunately)
                          #  i.e. [["40",30],["11",12]] → [30,11]
                          #  i.e. [["02",31],["10",12]] → [2,10]
               т+         # Add 100
                          #  i.e. [30,11] → [130,111]
                          #  i.e. [2,10] → [102,110]
                 ¦        # Remove the first character
                          #  i.e. [130,111] → ["30","11"]
                          #  i.e. [102,110] → ["02","10"]
                   s      # Swap so the triplicated list is at the top of the stack again
                    θ     # Pop and only leave it's last element (the year)
                          #  i.e. ["40","11","1761"] → "1761"
                          #  i.e. ["02","10","0002"] → "0002"
                     ª    # Append it to the list
                          #  i.e. ["30","11"] and "1761" → ["30","11","1761"]
                          #  i.e. ["02","10"] and "0002" → ["02","10","0002"]
                      ðý  # Join the list by spaces (and output implicitly)
                          #  i.e. ["30","11","1761"] → "30 11 1761"
                          #  i.e. ["02","10","0002"] → "02 10 0002"
Kevin Cruijssen
fonte