A data é alfabética?

8

Escreva uma função ou programa que aceite uma data (como uma string no YYYY-MM-DDformato) como entrada e retorne um valor verdadeiro se essa data for "alfabética" e um valor falsey se não for.

Uma data alfabética é uma data cujo mês, dia e ano estão em ordem alfabética quando expressos como uma sequência de caracteres (e quando considerados especificamente na ordem M - D - Y). Por exemplo, 26 de setembro de 2018 é uma data alfabética:

September 26th 2018 -> September twenty-sixth two thousand eighteen

September
Twenty-sixth
Two thousand eighteen

Outra maneira de pensar nesse desafio: "os elementos de uma determinada data são lexicamente classificados?"

Notas:

  • 2018 é representado como "dois mil e dezoito", não "vinte e dezoito" ou "dois zero um oito". Por outro exemplo, o ano de 1456 seria representado como "mil quatrocentos e cinquenta e seis", não "catorze e cinquenta e seis".
  • 26 é representado como "vigésimo sexto", não "vinte e seis".
  • Cada elemento da data é considerado como um todo. É por isso que 2018 não falha automaticamente, embora o "e" nos dezoito venha antes do "t" em dois.

As seguintes datas não são alfabéticas:

  • 2 de setembro de 2018 (o "segundo" deve estar à frente de "setembro")
  • 30 de abril de 4000 ("quatro mil" deve estar à frente de "trigésimo")

Regras adicionais:

  • Você receberá a data como uma string, formatada como YYYY-MM-DD. O ano sempre terá quatro dígitos e o mês e o dia sempre terão dois dígitos cada. O preenchimento zero não é representado na conversão de cadeia (por exemplo, '2000-01-01' é 'primeiro de janeiro de dois mil' como seria de esperar).
  • Você pode presumir que as datas sempre serão válidas (no dia 30 de fevereiro, no dia 1 de Smarch) e que o valor do ano será positivo (sem datas BC), mas a data poderá estar distante no futuro ("nos dois anos nove mil...").
  • Você deve retornar um valor verdadeiro ou falso, não necessariamente um booleano Trueou False. Se você fizer isso em JavaScript e querem voltar '0'e 0isso é bom. Claro, se você quiser retornar um booleano, sinta-se à vontade.
  • As brechas padrão são proibidas.
  • Isto é code-golf

Mais exemplos de datas alfabéticas

  • 2066-01-02 (segundo de janeiro de dois mil e sessenta e seis)
  • 1000-04-08 (oitavo de abril, mil)
  • 6000-08-01 (primeiro de agosto, seis mil)

Mais exemplos de datas não alfabéticas

  • 1066-01-02 (segundo de janeiro, mil e sessenta e seis)
  • 1000-04-07 (sétimo de abril, mil)
  • 8000-08-01 (oito de agosto, oito mil)
souldeux
fonte
2
Tempo ruim de Smarch .
AdmBorkBork 26/09
@ Arnauld Hum, não? Parece que o dia 09/09/2018 é falso, enquanto o dia 26/09/2018 é verdadeiro (quando fornecido como na pergunta).
Erik the Outgolfer
@EriktheOutgolfer Right. Eu interpretei totalmente o desafio. (Talvez ela deve ser reformulada como é a data lexically classificadas? Ou algo parecido.)
Arnauld
@ Arnauld Alterei o primeiro parágrafo e incluí uma linha com a redação sugerida um pouco mais adiante, espero que seja para o deleite dos futuros leitores. Obrigado!
souldeux 26/09/18
1
O ano é sempre o número escrito. 1444 é mil quatrocentos e quarenta e quatro. 1991 é mil novecentos e noventa e um.
souldeux 27/09/18

Respostas:

1

05AB1E , 66 62 58 bytes

0ì'-¡ÀDΣ2£<•88ΛηΣλšëÇñ0é≠>sîä&ζp°Lć®-αÅ®`•21вŽqT32в£Nèsè}Q

Experimente on-line ou verifique todos os exemplos mencionados no desafio .

Explicação:

0ì         # Prepend a "0" before the (implicit) input
           #  i.e. "2018-09-26" → "02018-09-26"
  '-¡     '# Then split on "-"
           #  i.e. "02018-09-26" → ["02018","09","26"]
     À     # Rotate it once to the left (so [0yyyy,MM,dd] becomes [MM,dd,0yyyy])
           #  i.e. ["02018","09","26"] → ["09","26","02018"]
D          # Duplicate this list
 Σ         # Sort this list by:
  2£       #  Leave only the first 2 digits of the current item
           #  (which is why the prepended 0 was there at the start for the year)
           #   i.e. "09" → "09"
           #   i.e. "02018" → "02"
    <      #  Decrease it by 1 to make it 0-indexed
           #   i.e. "09" → 8
  88ΛηΣλšëÇñ0é≠>sîä&ζp°Lć®-αÅ®`•21в
           #  Push the list [7,3,7,0,7,7,7,0,13,10,10,0,4,12,17,6,4,17,15,2,9,17,2,19,17,6,4,17,15,2,9,19,19,19,19,19,19,19,19,19,19,17,17,11,20,18,5,5,16,14,1,8]
   ŽqT32в  #  Push the list [12,31,9]
         £ #  Split the first list into parts of that size: [[7,3,7,0,7,7,7,0,13,10,10,0],
           #    [4,12,17,6,4,17,15,2,9,17,2,19,17,6,4,17,15,2,9,19,19,19,19,19,19,19,19,19,19,17,17],
           #    [11,20,18,5,5,16,14,1,8]]
   Nè      #  Then only leave the relevant list of the three based on the sort-index
     s     #  Swap to get the earlier integer at the top of the stack again
      è    #  And use it to index into the list
           #   i.e. [7,3,7,0,7,7,7,0,13,10,10,0] and 8 → 13
 }         # Close the sort
  Q        # And check if the sorted list is equal to the duplicated list,
           # so whether the order is still [MM,dd,0yyyy] after sorting
           # (and output the result implicitly)               

Consulte esta minha dica do 05AB1E (seção Como compactar listas inteiras? ) Para entender por que •88ΛηΣλšëÇñ0é≠>sîä&ζp°Lć®-αÅ®`•21вé [7,3,7,0,7,7,7,0,13,10,10,0,4,12,17,6,4,17,15,2,9,17,2,19,17,6,4,17,15,2,9,19,19,19,19,19,19,19,19,19,19,17,17,11,20,18,5,5,16,14,1,8]e ŽqT32вé [12,31,9].

Explicação geral adicional:

A função de classificação irá classificar os três tipos (dia, mês, ano), ao mesmo tempo, onde vamos retornar um valor truthy somente se M < D < Y(onde estes D, Me Ysão os valores que já recuperados a partir das listas comprimido).

Por que essas três listas mencionadas acima? Se colocarmos todas as palavras em ordem, categorizadas por tipo, teremos a seguinte ordem:

Sorting nr      Type        Which?

0               Month       April, August, December
1               Year        eight thousand
2               Day         eighteenth, eighth, eleventh
3               Month       February
4               Day         fifteenth, fifth, first
5               Year        five thousand, four thousand
6               Day         fourteenth, fourth
7               Month       January, July, June, March, May
8               Year        nine thousand
9               Day         ninteenth, ninth
10              Month       November, October
11              Year        one thousand
12              Day         second
13              Month       September
14              Year        seven thousand
15              Day         seventeenth, seventh
16              Year        six thousand
17              Day         sixteenth, sixth, tenth, third, thirteenth, thirtieth, thirty-first
18              Year        three thousand
19              Day         twelfth, twentieth, twenty-first through twenty-ninth
20              Year        two thousand

Se analisarmos cada tipo individualmente e sua ordem original (mil, dois mil etc. por anos; janeiro, fevereiro etc. por meses; e primeiro, segundo etc. por dias), os números de classificação mencionados acima serão nestas ordens:

Years:  [11,20,18,5,5,16,14,1,8]
Months: [7,3,7,0,7,7,7,0,13,10,10,0]
Days:   [4,12,17,6,4,17,15,2,9,17,2,19,17,6,4,17,15,2,9,19,19,19,19,19,19,19,19,19,19,17,17]
Kevin Cruijssen
fonte
9

JavaScript (ES6), 101 bytes

Guardado 4 bytes graças a @Shaggy

Retorna ou .01

s=>'_414044406550'[[,m,d]=s.split`-`,+m]<(d=`_268328715819832871${6e12-12}`[+d])&d<'_6A9338704'[s[0]]

Experimente online! ou Teste todas as datas! (inclui algumas entradas inválidas)

Quão?

Cada mês, cada dia e cada ano são mapeados para um ID em ( , e respectivamente), de acordo com a tabela a seguir. Depois testamos se temos e .[0..10]MDYM<DD<Y

A última parte da cadeia de pesquisa para as IDs dia é ligeiramente compactado usando ${6e12-12}, que se expande para 5999999999988(19 ° a 31 r ).

  M | Month                D | Day                  Y | Year (millennium)
----+----------------    ----+----------------    ----+-------------------
  0 | April                1 | eighth               0 | eight thousand
  0 | August               1 | eleventh           ----+-------------------
  0 | December             1 | eighteenth           3 | four thousand
----+----------------    ----+----------------      3 | five thousand
  1 | February             2 | first              ----+-------------------
----+----------------      2 | fifth                4 | nine thousand
  4 | January              2 | fifteenth          ----+-------------------
  4 | March              ----+----------------      6 | one thousand
  4 | May                  3 | fourth             ----+-------------------
  4 | June                 3 | fourteenth           7 | seven thousand
  4 | July               ----+----------------    ----+-------------------
----+----------------      5 | ninth                8 | six thousand
  5 | October              5 | nineteenth         ----+-------------------
  5 | November           ----+----------------      9 | three thousand
----+----------------      6 | second             ----+-------------------
  6 | September          ----+----------------     10 | two thousand
                           7 | seventh
                           7 | seventeenth
                         ----+----------------
                           8 | third
                           8 | sixth
                           8 | tenth
                           8 | thirteenth
                           8 | sixteenth
                           8 | thirtieth
                           8 | thirty-first
                         ----+----------------
                           9 | twelfth
                           9 | twentieth
                           9 | twenty-*
Arnauld
fonte
104 bytes
Shaggy
@ Shagy Oops ... Isso m=foi, é claro, completamente inútil. Obrigado. :)
Arnauld
1
Aquilo foi rápido! Bem feito. O "teste todas as datas" e a tabela ilustrativa são especialmente apreciados.
souldeux 27/09/18