Escreva uma função ou programa que leva entradas de string, totalmente escrito, os nomes dos meses Inglês em caso de título: January
, February
, March
, etc. (null / CR / LF encerrado OK, delimitado com alguns caracteres não-alfa se assim preferir) e quer
compara duas entradas, retornando um valor Truthy se a segunda entrada for maior (na ordem do mês) que a primeira. Valores iguais resultam em um valor de Falsey
ou classifica uma sequência arbitrária (lista, sequência delimitada etc.) em ordem cronológica
(O ponto crucial do desafio é definir um método / expressão que dê a classificação lexicográfica correta. Alguns idiomas podem ter uma resposta mais curta com um ou outro)
Você não pode usar nenhum método interno de análise de tempo (por exemplo strptime
) para converter o nome do mês em um número ou em um mapeamento pré-definido de nomes de meses. Use as propriedades das próprias strings, uma tabela de consulta parcimoniosa que você definir ou algo inteligente.
Exemplo
Exemplos de funcionamento, embora o primeiro seja proibido pelas regras ...
import datetime
def is_later_month(a, b):
'''
Example of prohibited code because it relies on language
features about how to parse month names
'''
return datetime.strptime(a, '%B') < datetime.strptime(b, '%B')
As versões abaixo estão OK, porque codificamos essas informações
months = {
'January': 1, 'February': 2, 'March': 3,
'April': 4, 'May': 5, 'June': 6,
'July': 7, 'August': 8, 'September': 9,
'October': 10, 'November': 11, 'December': 12,
}
def is_later_month(a, b):
"""
Returns True/False when comparing two months.
"""
return months[a] < months[b]
Ou você pode fazer uma função de classificação
months = {'as above...'}
def sort_months(l):
"""
Sorts list and returns it. Different input and output than the above,
but equally valid. Sorting versus comparing might be shorter in your
favorite language.
"""
return sorted(l, key=lambda x: months[x])
Testes de exemplo
assert is_later_month('January', 'February')
assert is_later_month('January', 'December')
assert is_later_month('November', 'December')
assert not is_later_month('July', 'July')
assert not is_later_month('October', 'September')
months
que fosse uma lista de todos os nomes de meses, eu gostaria de proibirmonths[x] < months[y]
como resposta. A lista de nomes de meses possui alguns recursos mais peculiares (duração variável, semelhança) que facilitam / dificultam o desafio em relação a cadeias geradas aleatoriamente.Respostas:
Geléia , 19 bytes
Este é um link monádico que pega uma lista como argumento e a classifica. Experimente online!
fundo
O Jelly usa indexação modular baseada em 1. Se repetirmos os nomes dos meses com frequência suficiente para obter 11 caracteres, obteremos a seguinte matriz.
Na 11 ª coluna (última), todos os personagens são diferentes, então nós podemos usá-los para identificar a ordem dos meses.
Como funciona
fonte
código de máquina x86,
2625 bytesHexdump:
Código de montagem:
A seguinte função hash coloca os nomes dos meses na ordem correta (encontrada pela força bruta):
É aplicado aos primeiros 4 bytes (32 bits) da sequência de entrada, organizados em ordem little-endian. Em seguida, comparando o resultado e usando
SALC
para definir o registro de resultados (al):fonte
Gelatina , 15 bytes
Nenhum link de intérprete online aqui, porque este é um envio lento . O programa usa a função de hash
354^(input interpreted as base 32 int) % 991
como a chave de classificação, que fornece resultados na ordem correta. O programa não terminará tão cedo porque os resultados da exponenciação são gigantescos - para "setembro", um número com 0,24 quatrilhão de dígitos precisa ser calculado!Explicação da geléia:
Script de prova de conceito do Python - observe o uso de
pow
para exponenciação modular, que é muito mais eficiente:fonte
Python,
646157 bytesO lambda leva dois meses como entrada e os compara. Teste em Ideone .
Graças a @ljeabmreosn por jogar fora 3 bytes e abrir caminho para mais 3!
fonte
s[10%len(s)]
para o(4*s)[10]
trabalho?Python,
8171 byteshttps://repl.it/CluN/1
Compara o índice
m
da segunda e terceira letras de dois meses.Versão de 83 bytes para classificar uma lista de meses:
fonte
Ruby, 58 bytes
Usa o truque de classificação do mês da resposta do @ atlasologist .
A função de comparação é um pouco mais longa, com 63 bytes
fonte
J,
6665 bytesUsa o fato de que f (m) = 2 * (ord (m [0]) + ord (m [-1])) // len (m) é uma função válida no domínio limitado dos 12 meses:
Uso:
(De maneira alguma essa é a melhor idéia, mas eu não queria roubar o truque de ninguém!)
Aqui está uma versão mais curta usando o método @ atlasologist :
J, 63 bytes
Uso:
E uma versão muito mais curta usando o método inteligente de @ Dennis :
J, 34 bytes
fonte
Haskell, 74 bytes
Meu primeiro código de golfe, yay! A idéia geral deste é inspirada na resposta principal em Jelly, e no fato de que, quando os nomes dos meses são alternados, o décimo primeiro caractere é sempre único.
Aqui está uma versão não destruída para ver como funciona:
A
e
função representa a função décimo primeiro char (infelizmente não é possível retirar 4 bytes devido à restrição de monomorfismo, eu acho) e a#
função infix corresponde àinOrder
função.Uma solução pequena e elegante, mas pode haver maneiras de eliminar mais bytes (eu encontrei alguns enquanto escrevia isso!)
fonte
e s=head.drop 10$cycle s
como você fez na sua explicação usando.
em vez de$
:e=head.drop 10.cycle
. No entanto usando o operador de índice de lista!!
é ainda menor:e=(!!10).cycle
Java,
133123Golfe:
Eu estava procurando por uma técnica inteligente, como na resposta do montador, mas estava demorando muito para descobrir, então eu segui a mesma técnica que todos os outros usavam.
Ungolfed:
fonte
substring
em vez secharAt
"" +
pois não existem mais dados brutoschar
.Linguagem de máquina ARM no Linux
4440 bytesEu usei uma função hash diferente do que anatolyg da solução e tentou instruções uso polegar para salvar alguns bytes (embora soprou 8 bytes que entram modo polegar).
Você pode fazer isso em um dispositivo Raspberry Pi ou Android com GNURoot.
Para executar, digite algo como
A versão atual agora lida com o caso de igualdade (e outros) corretamente.
fonte
bfac
faz?ite ge
executa condicionalmente a próxima instrução (movge r0, #0
) ser3 >= r0
, caso contrário, a instrução a seguir é executada (movlt r0, #1
). Eu acho que há espaço para derrubar um par de bytes aqui, mas eu não tive tempo para trabalhar neste :-)Perl 6 , 55 bytes
Seria necessário mais alguns bytes para as versões de comparação:
Teste:
fonte
Haskell, 118 caracteres
Usa o fato de que o nome de cada mês é único em seu primeiro e quarto caracteres (ou em 3 de maio) para definir um tipo de dados que pode ser analisado e comparado automaticamente pelo idioma. A função 'r' converte uma string pegando os quatro primeiros caracteres (ou menos) e depois escolhendo o primeiro e o último. Então 'a # b' é um operador para comparar os valores:
Provavelmente poderia ser feito de maneira mais eficiente, mas eu queria tentar fazer isso usando um tipo de dados útil para representar os meses.
fonte
PowerShell,
968863 bytespor exemplo
Agora, o segundo desafio é classificar uma lista em ordem; versões anteriores fizeram a comparação do teste de dois meses:
Com base nos dois segundos caracteres no nome do mês.
fonte
Python
8382 bytesTeste: https://repl.it/repls/TimelyDecimalBrowsers
Obtém a soma dos 3 primeiros caracteres e cria um único caractere para pesquisar.
fonte
Javascript, 118 bytes
Poderia ser mais jogado, provavelmente se livrando
c
e usandoarray.map
, mas é isso que tenho por enquanto ...fonte
for(i=0;i<12;)c.push(p[[4,3,7,0,8,6,5,1,11,10,9,2][i++]]);
Bash, 101 bytes
isso é função como is_later
teste
fonte
k4, 29
Um porto da resposta da @ Dennis's Jelly .
Este é o classificador, não o comparador; Curiosamente, o comparador é trivialmente implementável pelo mesmo algoritmo e apenas um byte a mais:
fonte
Bash + coreutils,
94 bytes93 bytesEsta é uma tentativa de criar uma transformação que classifique lexicograficamente. Se você olhar atentamente para a chave de transformação
FMAyulgSOND
poderá ver os meses de fevereiro a dezembro (janeiro fica vazio após a transformação; ela é puxada para cima usando 'B' como separador). A reversão, truncamento e remoção de letras sem chave permitem que esse truque seja realizado.90 bytes usando localidade C
... onde ␉ é o caractere de tabulação.
80 bytes usando localidade C
... usando o método @ atlasolog. Limite para ser uma maneira de usar essa abordagem para trabalhar com mais localidades.
Teste / Uso
saídas:
fonte