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!


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||(....


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.

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.)


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.


-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!


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*)

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)
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.