Alfabetizar Inteiros

19

Alfabetizar Inteiros

Para um determinado conjunto de números, coloque-os em ordem alfabética quando estiverem escritos (por exemplo, 1: um, 2: dois, 90: noventa, 19: dezenove). Seu código deve funcionar para o intervalo [-999999, 999999]. A saída deve ter um delimitador entre os números. Um espaço funcionará, assim como um espaço e uma vírgula, conforme mostrado nos exemplos abaixo. A entrada pode ser uma matriz de números inteiros, uma sequência de números delimitados ou o que você achar melhor. Todos os números inteiros são considerados únicos.

Os números não são hifenizados para os propósitos deste desafio e os espaços são alfabetizados antes de qualquer outro caractere. Os números negativos são assumidos para ser expressa usando a palavra minus. Por exemplo, fourprecederia four thousande o número -40seria classificado usando a sequência minus forty. Suponha que todos os números sejam compostos apenas por palavras numéricas e sem conjunções (por exemplo, use em two thousand forty twovez de two thousand and forty two).


Casos de teste

Inteiros de um dígito:

Entrada:

1, 2, 3, 4, 5

Resultado:

5, 4, 1, 3, 2

Inteiros com vários dígitos:

Entrada:

-1002, 5, 435012, 4, 23, 81, 82

Resultado:

81, 82, 5, 4, 435012, -1002, 23

Espaços entre palavras, sem hífens, vírgulas ou "e":

Entrada:

6, 16, 60, 64, 600, 6000, 60000, 60004, 60008, 60204, 60804

Resultado:

6, 600, 6000, 16, 60, 64, 60000, 60008, 60804, 60004, 60204

Lembre-se, isso é , portanto o código com o menor número de bytes vence. Não são permitidas brechas!

wubs
fonte
Aqui está o link para a postagem da sandbox relevante.
wubs
A entrada conterá mais de um de um único número inteiro?
ETHproductions
@ETHproductions Não, não será. Vou especificar isso na pergunta.
wubs
8
Bem-vindo ao PPCG. Bom avatar. : D Nice primeira pergunta.
AdmBorkBork
@TimmyD Thanks! Estou ansioso pelo PowerShell - tudo o que posso por aqui.
wubs

Respostas:

5

JavaScript (ES6), 189 179 186 bytes

let f =

a=>a.sort((x,y)=>!x-!y||(X=q(x),Y=q(y),X>Y)-(X<Y),q=n=>n<0?"L"+q(-n):n>999?q(n/1e3)+"Z"+q(n%1e3):n>99?q(n/100)+"K"+q(n%100):n>19?"  cYHFVSCO"[n/10|0]+q(n%10):"0PdaIGTQAMWDbXJEURBN"[n|0])

let g = a => console.log(`[${f(a)}]`)

g([1,2,3,4,5])
g([-1002,5,435012,4,23,81,82])
g([0,1000,1100])
<input id=I value="1 2 3 4 5"><button onclick="g(I.value.match(/\d+/g)||[])">Run</button>

A idéia básica é converter cada número de entrada em uma sequência curta que esteja na posição lexográfica correta em comparação com todos os outros pares de sequência numérica. Aqui está o dicionário usado: (Não execute o snippet; é usado apenas para ocultar a lista longa.)

Isso cria uma maneira muito concisa de mapear cada número para sua posição lexograficamente correta. É isso que a qfunção recursiva faz:

q(-X)        => "L" + q(X)
q(XYYY)      => q(X) + "Z" + q(YYY)
q(XYY)       => q(X) + "K" + q(YY)
q(XY >= 20)` => "  cYHFVSCO"[X] + q(Y)
q(X)         => "0PdaIGTQAMWDbXJEURBN"[X]

O 0início da string é para garantir que, por exemplo, 100 ( one hundredconvertido em PK0) seja classificado antes 101( one hundred oneconvertido em PKP). Isso cria um cenário ímpar, em que 0 ( zero) é classificado na frente da matriz, para contornar isso, na função de classificação, primeiro ordenamos os zeros à direita !x-!y||(....

ETHproductions
fonte
Parece que não funciona [1100, 1000]. Eu esperaria que a saída fosse 1000 (one thousand), 1100 (one thousand one hundred), mas a saída é da mesma ordem que a entrada.
milk
@ leite Hmm ... não sei por que isso acontece, mas vou dar uma olhada.
ETHproductions
@ leite Ah, 1000está sendo analisado como one thousand zero; Eu vou consertar isso momentaneamente. Devemos apoiar 0por conta própria? É um caso único que adicionará mais ou menos 15 bytes ao meu código.
ETHproductions
11

Informar 7, 214 201 118 bytes

O Inform 7 é uma linguagem absolutamente terrível para o golfe, então eu queria dar uma chance aqui.

O recuo deve usar \tcaracteres tab ( ), mas o HTML não gosta deles. Por outro lado, o Inform não gosta de espaços para recuo, portanto, você precisará substituir os espaços por tabulações se copiar e colar o código daqui para testá-lo. Ou apenas copie e cole da fonte Markdown.

Golfe:

Para X:
    repita na Tabela 1:
        agora a entrada Q é "[entrada R em palavras]";
    classifique a Tabela 1 em ordem Q;
    diga "[R na Tabela 1]".

A entrada deve ser uma tabela Inform, da seguinte forma (com \tentre as colunas):

tabela 1
R (número) Q (texto)
-1002
5
435012
4
23
81
82

Resultado:

81, 82, 5, 4, 435012, -1002, 23

Esta função percorre a tabela uma vez, adicionando uma representação textual de cada número em uma nova coluna. Em seguida, classifica as linhas da tabela de acordo com a coluna de texto; no Inform, as strings são classificadas lexicograficamente. Por fim, imprime a coluna original no novo pedido. Convenientemente, o formato "bruto, mas às vezes útil" do Inform 7 para imprimir colunas da tabela é separado por vírgula, exatamente como solicitado.

Ungolfed, com clichê mostrando como chamar a função:

Para imprimir os números em ordem alfabética:
    repita na Tabela de Números Classificáveis:
        agora a entrada do nome é "[a entrada do índice em palavras]";
    classifique a tabela de números classificáveis ​​em ordem de nome;
    diga "[a coluna do índice na Tabela de Números Classificáveis]".

Tabela de Números Classificáveis
nome do índice (número) (texto)
-1002
5
435012
4
23
81
82

Há um quarto.
Quando a reprodução começar: imprima os números em ordem alfabética.
Draconis
fonte
11
Estou um pouco confuso com isso. É wordsuma referência das versões detalhadas dos números, incorporadas ao Inform 7?
Pavel
11
@Pavel Indeed! "(número) em palavras" retorna uma string com uma representação textual do número. Ele usa convenientemente "menos" para números negativos e, embora coloque hífens entre as palavras, o faz de maneira consistente e coloca em ordem alfabética os hífens antes de todas as letras (para que o resultado final seja o mesmo).
Draconis
2
+1 para a escolha do idioma. Eu teria que verificar, mas suspeito que ainda existem algumas oportunidades de golfe; por exemplo, o analisador realmente exige todos esses artigos "the"? E você teria que perguntar ao OP, mas não vejo nenhuma razão óbvia para que "e" não seja um delimitador válido. Mesmo se não, um único espaço é explicitamente permitido, portanto, apenas say "[R entry] "deve ser suficiente.
Ilmari Karonen
Eu diria que o "e" no final está bom. Eu não disse que os delimitadores tinham que ser uniformes, então essa é uma resposta perfeitamente aceitável. Se eu pudesse dar pontos para a resposta mais interessante, eu daria a você. Eu realmente gosto da legibilidade dessa linguagem, mesmo que joguei golfe. Bom trabalho!
wubs 2/12/16
Finalmente tive a chance de jogar um pouco com o Inform7 e consegui re-jogar sua entrada com apenas 118 bytes. Como a publicação do código Inform nos comentários não funciona muito bem, fui adiante e editei-o diretamente na sua resposta. Espero que você não se importe, fique à vontade para reverter e / ou ajustar minhas edições da maneira que desejar.
Ilmari Karonen
4

Mathematica, 67 bytes

SortBy[#,#~IntegerName~"Words"~StringReplace~{","->"","-"->""}&]&

Função sem nome, tendo uma lista de números inteiros como argumento e retornando uma lista de números inteiros como seu valor. #~IntegerName~"Words"é um interno que altera um número inteiro para seu nome em inglês. IntegerNameàs vezes tem vírgulas e hífens em sua saída, então a StringReplacechamada se livra deles. (Infelizmente, o hífen é realmente o caractere de 3 bytes, 8208, em UTF-8.) Em seguida, SortByclassifica a lista original em ordem alfabética de acordo com o valor do nome inteiro modificado.

Uma boa coincidência: IntegerNameusa em negativevez de minusem sua saída - mas nenhuma palavra que apareça nos nomes de nenhum dos números permitidos está alfabeticamente entre essas duas palavras; portanto, nenhuma substituição é necessária!

(Gorjeta para ngenisis por me lembrar Sortby.)

Greg Martin
fonte
Parabéns! Cheguei muito perto de obter esta solução, mas esse traço estava me dando dores de cabeça!
Ngenisis
Sua resposta aqui realmente usa o hífen correto? Se eu copiar o que você tem aqui no Mathematica, ele não substituirá os hífens IntegerName. A documentação da Wolfram diz que é o caractere unicode 2010 .
Ngenisis
Provavelmente não, então - tentei obter o hífen correto nesta resposta, mas parece que não obtive sucesso.
Greg Martin
Eu cortei sua resposta ao meio;)
J. Antonio Perez
E então alguns ... você faz modificações desnecessárias na string.
J. Antonio Perez
4

Bash + utilitários GNU + bsdgames, 52

  • 4 bytes salvos graças ao @izabera.
sed 's/.*/echo `echo &|number`:&/e'|sort|sed s/.*://

E / S são linhas delimitadas por nova linha.

  • A primeira expressão sed substitui cada número numérico por um comando shell que exibe a forma da palavra do número (conforme fornecido pelo utilitário bsdgamesnumber ), seguida por uma :forma numérica do número.
  • Isto é então sorted.
  • Em seguida, a segunda sedtira os caracteres iniciais até e inclusive o :, deixando a forma numérica classificada conforme necessário.

numberlida corretamente com "menos" e sua saída é próxima o suficiente do formato especificado para que sortfuncione conforme necessário. Ele produz "quarenta e quatro" em vez de "quarenta e quatro", mas isso não deve importar da perspectiva da classificação.

O pacote bsdgames pode precisar de instalação:

sudo apt-get install bsdgames

Os utilitários sede sortjá estão quase certamente na sua distribuição.

Trauma Digital
fonte
-t:é inútil e você pode usarnumber<<<&
izabera
@izabera Sim - obrigado - eu removi o -t:. No entanto, o erecurso val do sed executa comandos usando sh, portanto, recursos do bash como <<<não funcionam.
Digital Trauma
funciona bem contanto que seu sh seja bash: P
izabera 2/16/16
@izabera Não - se o bash começou, shele tenta emular o Posix sh o máximo possível, o que significa que bashismos como <<<estão desativados. sedO erecurso val do GNU inicia comandos com /bin/sh -c ...e não /bin/bash -c .... Você já tentou isso?
Digital Trauma
bash nunca desliga <<<, nem mesmo no modo posix
izabera
1

Python + flexão, 97 91 89 bytes

from inflect import*
a={x:engine().number_to_words(x)for x in words}
sorted(a,key=a.get)

Utilizou a inflectbiblioteca para transformar a wordsmatriz de números inteiros em sua representação fonética / string. Armazenado em um dicionário de pares k / v em que as chaves eram a representação numérica e os valores eram a representação em cadeia. Retornou a lista de chaves conforme classificada por valores.

EDIT: Salvo 5 e 3 bytes, graças a ETHproductions e Alex.S!

9814072356
fonte
Bem-vindo ao PPCG! Você pode jogar golfe removendo espaços ; por exemplo, a segunda linha pode ser a={x:inflect.engine().number_to_words(x)for x in words}.
ETHproductions
Você pode salvar dois bytes usando from inflect import*e jogando fora inflect.na segunda linha.
Alex.S
Infelizmente, parece que isso também falha ao classificar corretamente a lista 40, 44, 40000, 40804, 40004, 40204 (que deve permanecer nessa ordem).
Ilmari Karonen
0

Mathematica, 30 bytes

A resposta abaixo gera uma função pura que pega uma lista de números inteiros como entrada e os classifica pelo nome alfabético. Exatamente o que o médico pediu;)

SortBy[#~IntegerName~"Words"&]

Aqui está a versão não destruída:

SortBy[IntegerName[#, "Words"]&]

E aqui está um exemplo de uso:

SortBy[#~IntegerName~"Words"&][{0,1,2,3,4,5,6,7,8,9,10}]

O que também pode ser escrito como

SortBy[#~IntegerName~"Words"&]@{0,1,2,3,4,5,6,7,8,9,10}

Eles produzem saídas idênticas - no mathematica, f[x]é equivalente a f@x.

Outputs: {8, 5, 4, 9, 1, 7, 6, 10, 3, 2}

Há uma resposta muito mais longa que outro usuário postou no Mathematica. Essa resposta tenta corrigir algumas pequenas diferenças entre a maneira como o mathematica alphebatiza os números para melhor se adaptar à maneira como os números declarados do OP devem ser alfabetizados, no entanto, as coisas que eles corrigem não afetam a ordem de classificação, e minha resposta é idêntica à deles:

MyF = SortBy[#~IntegerName~"Words"&];
TheirF = SortBy[#, #~IntegerName~"Words"~ StringReplace~{"," -> "", "-" -> ""} &] &;
MyF[Range[-999999, 999999]] == TheirF[Range[-999999, 999999]]
(*Outputs True*)
J. Antonio Perez
fonte
Uma ótima investigação! - infelizmente, eles não dão a mesma ordem. TheirFclassifica corretamente 888 antes de 880.000, enquanto MyFnão. Provavelmente, o problema está na cópia e colagem do hífen estranho: sua versão TheirFprovavelmente está substituindo hífens normais (dos quais não existem), enquanto a versão real substitui o hífen Unicode estranho de 3 bytes. (Ele ainda seria interessante ver se a remoção vírgulas é necessário.)
Greg Martin
Eu testei no intervalo [999999]. Parece que eliminar as vírgulas é desnecessário, mas substituir "[Hífen]" por "" é definitivamente necessário.
Ngenisis
0

Lisp comum, 113 bytes

Nenhuma biblioteca externa necessária.

(print(mapcar #'cdr(sort(loop for i in x collect(cons(format()"~r"i)i))(lambda(y z)(string-lessp(car y)(car z))))))

Saída se xfor '(1 2 3 4 5):

(5 4 1 3 2)
atormentar
fonte