PronunciationSort ™

24

Todos conhecemos diferentes algoritmos de classificação sofisticados, mas nenhum deles fornece números de uma maneira fácil de pronunciar. Para remediar isso, proponho o uso do PronunciationSort ™, a maneira mais natural de classificar listas de números.

Pronúncia

As regras oficiais para pronunciar números (neste desafio) é que os dígitos são pronunciados um por um, e a sequência resultante é classificada em ordem lexicográfica. Como exemplo, isso significa que o número 845é pronunciado "eight four five"e deve ser classificado de acordo.

Números negativos

Os números negativos são pronunciados acrescentando a palavra "minus". Assim, -23é pronunciado como "minus two three". Observe que isso faz com que os números negativos terminem no meio da saída, entre os números que começam com 4(quatro) e 9(nove).

Como guia, a ordem oficial das palavras para o PronunciationSort ™ é:

  • oito
  • cinco
  • quatro
  • menos
  • nove
  • 1
  • Sete
  • seis
  • três
  • dois
  • zero

Isso é,

8, 5, 4, -, 9, 1, 7, 6, 3, 2, 0

Entrada

Uma lista de números inteiros no intervalo , contendo no máximo 100 elementos. A entrada como uma lista de strings não é permitida. Se o seu idioma não suportar entrada como lista, é permitido fornecer entrada como números inteiros separados.[-999,999]

A entrada não conterá nenhum número inválido ou qualquer número começando com um 0 (exceto o próprio número 0). A entrada geralmente não será classificada, pode ser fornecida em qualquer ordem.

Saída

Os mesmos números inteiros, na ordem PronunciationSort ™. Observe que os números devem ser convertidos apenas em suas pronúncias para obter a classificação; a saída não deve conter nenhuma string.

Exemplos

Para os exemplos, a etapa do meio (entre parênteses) serve apenas como guia e não faz parte da saída.

[1, 2, 3] -> (['one', 'two', 'three']) -> [1, 3, 2]
[-1, 0, 1, 2] -> (['minus one', 'zero', 'one', 'two']) -> [-1, 1, 2, 0]
[-100, 45, 96] -> (['minus one zero zero', 'four five', 'nine six']) -> [45, -100, 96]
[11, 12, 13, 134, 135] -> (['one one', 'one two', 'one three', 'one three four', 'one three five']) -> [11, 13, 135, 134, 12]

Há também um script para verificar seus resultados .

maxb
fonte
5
Por que "um" (pronunciado "venceu") não vem depois de dois e antes de zero?
Ben Miller - Restabelece Monica
3
@ BenMiller Não me lembro se foi você quem comentou na sandbox, mas esse comentário me deu deja vu. Para respondê-lo aqui, eu o contemplava, mas segui a ortografia para evitar discussões ortográficas (por exemplo, "dois" vs "também", "vencido" ou "wan")
maxb 27/09/18
17
Por isso, é realmente mais "que soletra tipo" do que "tipo pronúncia" :-)
Paulo Ebermann
3
vadio. Eu esperava que eles fossem classificados pela dificuldade em pronunciar ...
NH.
2
Esse desafio realmente deve ser renomeado, pois a classificação aqui praticamente não tem nada a ver com pronúncia. Seria imensamente mais complexo se fosse baseado em pronúncia (por exemplo, quatro podem vir antes das cinco se você classificar o monofita ⟨ɔː⟩ antes do ditongo ⟨aɪ⟩, mas cinco antes das quatro se você classificar ⟨a⟩ derivado antes de o - derivado ⟨ɔ⟩ - não existe, pelo que sei, ordem de classificação estabelecida para a pronúncia, nem no IPA nem em qualquer outro esquema).
Janus Bahs Jacquet

Respostas:

8

05AB1E (herdado) , 15 bytes

Σε•Koéa₃•'-3ǝsk

Experimente online!

Explicação

Σ                 # sort by
 ε                # apply to each
             sk   # index of the element in
  •Koéa₃•         # "85409176320"
         '-3ǝ     # with "-" inserted at index 3
Emigna
fonte
Parece haver um erro no número inteiro compactado •ĆU‘•. Ele adiciona uma nova linha durante o mapeamento / classificação por qualquer motivo. Σ•ĆU‘•"54-ÿ"sSkpoderia ter sido uma alternativa de 15 bytes que eu estava trabalhando, se não fosse por esse bug estranho .. Se eu mudar •ĆU‘•para o literal 9176320 ele funciona muito bem ..
Kevin Cruijssen
11
@KevinCruijssen: Isso é estranho. O seu seria 14 com …54-ìpar
Emigna 27/09/18
@KevinCruijssen: Você poderia fazer Σ•RT‹•Á…54-ìsSkpor 15
Emigna 27/09/18
•t∍ýJ•'-ìÁÁtambém funcionaria
Emigna 27/09/18
8

Haskell , 57 bytes

import Data.List
sortOn$map(`elemIndex`"54-9176320").show

Experimente online!

Vincent
fonte
11
Isso é tão limpo e legível! Definitivamente o vencedor em termos de facilidade de entendimento.
Stephen Belden
8

Geléia ,  15  13 bytes

ṾV€ị“Þ⁽3Z6»µÞ

Experimente online!

Um link monádico que aceita uma lista de números inteiros que produz uma lista de números inteiros.

Quão?

Classifica pelos valores ordinais dos dígitos dos números inteiros (onde -é um "dígito" de -1) convertidos em seqüências de caracteres usando os caracteres no índice modular e com base em 1 na sequência mágica "murgeon lix".

A classificação é efetivamente alfabética onde um espaço é considerado menor que qualquer letra.

A seqüência mágica "murgeon lix" foi encontrada inspecionando os dicionários de Jelly usados ​​na compactação. Não há palavras de 11 letras que satisfaçam os requisitos (e nada mais que isso mediante a duplicação). como um espaço classifica antes das letras, a próxima escolha mais óbvia é uma palavra de comprimento sete, seguida por um espaço seguido de uma palavra de comprimento três. "murgeon" e "lix" é a única combinação satisfatória, embora sem espaço outros possam ser possíveis (por exemplo, “£Py:ƥ»"murgeonalix", que funciona para a mesma contagem de bytes)

ṾV€ị“Þ⁽3Z6»µÞ - Link: list of integers
            Þ - sort by:
           µ  -   the monadic link: -- i.e. do this for each integer, then sort by that
Ṿ             -     unevaluate  (e.g. -803 -> ['-','8','0','3'])
 V€           -     evaluate each as Jelly code  (e.g. ['-','8','0','3'] -> [-1,8,0,3])
    “Þ⁽3Z6»   -     "murgeon lix" (compression of words in Jelly's dictionary plus a space)
   ị          -     index into (1-indexed & modular) (e.g. [-1,8,0,3] -> "i xr")

@ 15 bytes anteriores :

ṾV€ị“¡Zo⁶’Œ?¤µÞ

Aqui “¡Zo⁶’Œ?¤encontra a primeira permutação de números naturais que residiria no índice 21.340.635 quando todas as permutações dos números são classificadas lexicograficamente - o que é [6,10,9,3,2,8,7,1,5,4,11]. ( “¡Zo⁶’é uma representação de base 250 de 21340635, enquanto Œ?faz o cálculo e ¤agrupa essas instruções)

Jonathan Allan
fonte
Mesmo com a explicação, não me sinto muito inteligente. Solução incrível!
maxb 27/09/18
A versão mais curta também é provavelmente mais fácil de entender!
Jonathan Allan
7

Perl 6 , 30 bytes

*.sort:{TR/0..9-/a5982176043/}

Experimente online!

Porta da solução Ruby da GB.

Versão original de 35 bytes

*.sort: (~*).uninames».&{S/\w*.//}

Experimente online!

Converta cada número em uma string, obtenha o nome Unicode de cada caractere, retire a primeira palavra ("DIGIT" ou "HYPHEN") e depois classifique.

Nwellnhof
fonte
6

JavaScript (SpiderMonkey) , 69 bytes

a=>a.sort((a,b)=>(g=n=>[...n+''].map(c=>':598217604'[c]||3))(a)>g(b))

Experimente online!

Arnauld
fonte
Parece que você pode remover o +'', visto que está recebendo a entrada como uma matriz de seqüências de caracteres.
Shaggy
@ Shaggy Não estou mais usando cordas, pois não tenho certeza se isso é permitido aqui.
Arnauld
Ah ... você está certo. Isso adicionará alguns bytes à minha solução.
Shaggy
6

K (ngn / k) , 21 20 bytes

{x@<"54-9176320"?$x}

Experimente online!

{ } função com argumento x

$ formato como cadeias

""?-263."8"

< calcular permutação ascendente de classificação

x@ o argumento nesses índices

ngn
fonte
6

Python 3, 68 bytes 67 bytes 64 bytes

lambda x:sorted(x,key=lambda y:[*map('54-9176320'.find,str(y))])

Usa a sortedfunção interna com uma lambda anônima para a chave. Codifique a ordem de classificação e compare cada dígito em cada valor na lista de entrada com sua posição na lista de ordem de classificação.

Editar: salvou 1 byte removendo 8da lista de classificação para aproveitar o str.findretorno -1quando o parâmetro não for encontrado. Graças ao maxb.

Edit2: salvou 3 bytes usando a sintaxe de descompactação com estrela em um listliteral, em vez de no listconstrutor

Experimente online!

mypetlion
fonte
11
Você pode remover os 8 primeiros da string? Como Python retorna -1 se a substring não for encontrada.
maxb 27/09/19
@ maxb Boa captura. Editado.
mypetlion
2
A porta Python 2 é 58:lambda x:sorted(x,key=lambda y:map('54-9176320'.find,`y`))
Jonathan Allan
5

Pitão, 17 16 bytes

oxL"54-9176320"`

Experimente online aqui ou verifique todos os casos de teste de uma vez aqui .

oxL"54-9176320"`NQ   Implicit: Q=eval(input())
                     Trailing N, Q inferred
o                Q   Order the elements of Q, as N, using...
               `N      Convert N to string
 xL                    Get the index of each character of that string...
   "54-9176320"        ... in the lookup ordering
                       (if character missing, returns -1, so 8 is still sorted before 5)

Economizou 1 byte graças a @ngn e sua resposta K , omitindo 8 no início da string de dicionário

Sok
fonte
4

Japonês, 19 bytes

ñ_s ®n"54-9176320

Tente

Shaggy
fonte
Ótima solução! Infelizmente, a entrada como uma lista de strings não é permitida.
maxb 27/09/18
Você pode salvar alguns abusando S.n(s): ñ_s ®n"54-9176320(aparentemente S.n(s)é exatamente o mesmo que s.b(S)para Sde comprimento 1, exceto que ele retorna 0no lugar de -1)
ETHproductions
Bom truque, @ETHproductions, obrigado :) Vou ter que lembrar esse para o futuro.
Shaggy
3

Retina 0.8.2 , 36 bytes

T`-d`3:598217604
O`
T`3:598217604`-d

Experimente online! O link inclui o conjunto de testes. Explicação:

T`-d`3:598217604

Traduza o sinal de menos e os dígitos para sua posição em ordem de pronúncia, usando :a 10ª posição.

O`

Classifique em ordem de pronúncia.

T`3:598217604`-d

Traduza o pedido de volta para o sinal de menos e os dígitos originais.

Neil
fonte
3

R , 58 bytes

function(x)x[order(mapply(chartr,"-0-9","dkfjicbhgae",x))]

Experimente online!

Input é uma lista de números que são implicitamente convertidos como string usando chartr. orderem seguida, usa a ordem lexigográfica para recuperar a ordem pela qual a lista original deve ser classificada.

JayCe
fonte
3

Java (JDK 10) , 123 bytes

l->l.sort(java.util.Comparator.comparing(n->{var r="";for(var c:(""+n).split(""))r+=11+"54-9176320".indexOf(c);return r;}))

Experimente online!

Esta é uma implementação Java ingênua. Deve ser muito jogável.

Créditos

Olivier Grégoire
fonte
11
Alterar o .chars-IntStream e .reducepara um ciclo regular de salva 2 bytes: n->{var r="";for(var c:(""+n).split(""))r+=10+"854-9176320".indexOf(c);return r;}. Além disso, mais um byte pode ser salvo alterando 10+"85para 20+"5, pois o .indexOfdígito for 8resultaria em -1. Experimente online 123 bytes
Kevin Cruijssen
2

JavaScript (SpiderMonkey) , 87 73 bytes

a=>a.sort((p,q,F=b=>[...""+b].map(x=>"54-9176320".search(x)))=>F(p)>F(q))

Experimente online!

Obrigado @Arnauld por dizer que o tipo no SpiderMonkey é estável, para que a ||-(F(q)>F(p))peça possa finalmente ser descartada.

Shieru Asakoto
fonte
2

Vermelho , 114 bytes

func[n][g: func[a][collect[foreach c form a[keep index? find"854-9176320"c]]]sort/compare n func[x y][(g x)< g y]]

Experimente online!

Mais legível:

f: func [ n ] [
    g: func [ a ] [
        collect [ 
            foreach c form a [ 
                keep index? find "854-9176320" c
            ]
        ]
    ]
    sort/compare n func [ x y ] [ (g x) < g y ]
]
Galen Ivanov
fonte
2

C ++, 353 bytes

Esta é uma espécie de entrada de comédia, mas eu estava perdendo tempo e escrevi, então não posso deixar de publicá-la ... Desfrute de uma risada e deixe-me saber se há algum poupador de espaço que eu perdi!

#include<algorithm>
#include<iostream>
#include<iterator>
#include<numeric>
#include<string>
using namespace std;auto f(int i){auto s=to_string(i);for(auto&c:s)c='A'+"854-9176320"s.find(c);return s;}int main(){int a[100];auto b=begin(a);auto e=end(a);iota(b,e,-50);sort(b,e,[](int l,int r){return f(l)<f(r);});copy(b,e,ostream_iterator<int>(cout," "));}

Saída:

8 5 4 48 45 44 49 41 47 46 43 42 40 -8 -5 -50 -4 -48 -45 -44 -49 -41 -47 -46 -43 -42 -40 -40 -9 -1 -18 -15 - 14 -19 -11 -17 -16 -13 -12 -10 -7 -6 -3 -38 -35 -34 -39 -31 -37 -36 -33 -32 -30 -2 -28 -25 -24 - 29 -21 -27 -26 -23 -22 -20 9 1 18 15 14 19 11 17 16 13 12 10 7 6 3 38 35 34 39 31 37 36 33 32 30 2 28 25 24 29 21 27 26 23 22 20 0

underscore_d
fonte
Vejo que você também
segue
11
Ei, eu não posso pagar espaços em branco frívolos neste idioma! É engraçado ter que fazer isso, visto que, durante o resto do tempo, poucas coisas me deixam tão irritada quanto abrir o código de outras pessoas, que aparentemente pensam que escrever uma parede monolítica horrível os fará parecer mais inteligentes e / ou são remunerados ativamente para cada nova linha digitada.
Underscore_d
11
Olá! Apertou sua solução para 195 caracteres
Max Yekhlakov
@MaxYekhlakov Legal, obrigado por refletir! Percebo depois de ler um pouco mais; parece que eu não precisava necessariamente fornecer um programa compilável completo, mas apenas as funções que processariam a entrada e a saída especificadas. D'oh!
Underscore_d
2

Mathematica, 68 bytes

SortBy[If[# < 0,"m ",""]<>StringRiffle@IntegerName@IntegerDigits@#&]

Função. Pega uma lista de números inteiros como entrada e retorna a lista classificada como saída. Apenas separa os dígitos de cada número com IntegerDigits, converte cada dígito em "zero", "one"etc., com IntegerName, converte a lista em uma sequência separada por espaços com StringRiffle, precede um "m "se o número for negativo e classifica com base nessa sequência. De fato, essa foi a abordagem mais curta que pude encontrar, pois o Mathematica usa apenas nativamente a classificação lexicográfica para listas do mesmo tamanho; assim, uma abordagem baseada em 854-9176320acaba consumindo mais bytes, pois as funções de string são muito caras.

LegionMammal978
fonte
Sempre confie no mathematica para ter uma combinação de recursos internos. Solução inteligente!
maxb
1

05AB1E , 15 14 bytes

Σ•ĆU‘•…54-ìsSk

-1 byte graças a @Emigna .

Experimente online ou verifique todos os casos de teste .

Explicação:

Σ                 # Sort by:
 •ĆU‘•            #  Push the compressed integer 9176320
      54-        #  Push the string "54-"
          ì       #  Prepend this string before the integer: "54-9176320"
           s      #  Swap so the current number to sort is at the top of the stack
            S     #  Convert it to a list of characters
             k    #  Check for each its index in the string (resulting in -1 for '8')

Veja esta dica 05AB1E meu (seção Como comprimir grandes inteiros ) para entender por que •ĆU‘•é 9176320.

Kevin Cruijssen
fonte