In ordine alfabetico numeri interi


19

In ordine alfabetico numeri interi

Per un determinato set di numeri, inseriscili in ordine alfabetico quando sono indicati (ovvero 1: uno, 2: due, 90: novanta, 19: diciannove). Il tuo codice dovrebbe funzionare per l'intervallo [-999999, 999999]. L'output deve avere un delimitatore tra i numeri. Uno spazio funzionerà, così come uno spazio e una virgola, come mostrato negli esempi seguenti. L'input può essere una matrice di numeri interi, una stringa di numeri delimitati o comunque si ritenga opportuno. Si presume che tutti i numeri interi siano univoci.

I numeri non sono sillabati ai fini di questa sfida e gli spazi sono alfabetizzati prima di qualsiasi altro personaggio. Si presume che i numeri negativi siano espressi usando la parola minus. Ad esempio, fourprecederebbe four thousande il numero -40verrebbe ordinato usando la stringa minus forty. Supponiamo che tutti i numeri siano composti esclusivamente da parole numeriche e nessuna congiunzione (ad esempio, utilizzare two thousand forty twoinvece di two thousand and forty two).


Casi test

Numeri interi a una cifra:

Ingresso:

1, 2, 3, 4, 5

Produzione:

5, 4, 1, 3, 2

Numeri interi a più cifre:

Ingresso:

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

Produzione:

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

Spazi tra parole, senza trattini, virgole o "e":

Ingresso:

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

Produzione:

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

Ricorda, questo è , quindi vince il codice con il minor numero di byte. Non sono ammesse scappatoie!


Ecco il link al post sandbox pertinente.
Hub

L'input conterrà mai più di un singolo numero intero?
ETHproductions

@ETHproductions No, non lo farà. Lo specificherò nella domanda.
Hub

8
Benvenuti in PPCG. Bel avatar. : D Bella prima domanda.
AdmBorkBork,

@TimmyD Grazie! Non vedo l'ora di PowerShell tutto ciò che posso qui.
Hub

Risposte:


5

JavaScript (ES6), 189 179 186 byte

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>

L'idea di base è quella di convertire ciascun numero di input in una stringa breve che si trova nella posizione lessicale corretta rispetto a tutte le altre coppie di stringhe di numeri. Ecco il dizionario utilizzato: (Non eseguire lo snippet; è solo usato per nascondere la lunga lista.)

Questo crea un modo molto conciso di mappare ciascun numero nella sua posizione lessicale dal punto di vista lessicale. Ecco cosa fa la qfunzione ricorsiva :

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]

L' 0inizio della stringa è garantire che ad esempio 100 ( one hundred, convertito in PK0) sia ordinato prima 101( one hundred one, convertito in PKP). Questo crea uno scenario dispari in cui 0 ( zero) viene ordinato nella parte anteriore dell'array, quindi per ovviare a questo, nella funzione di ordinamento ordiniamo innanzitutto gli zero a destra con !x-!y||(....


Sembra che non funzioni [1100, 1000]. Mi aspetto che l'output sia 1000 (one thousand), 1100 (one thousand one hundred), ma l'output è nello stesso ordine dell'input.
latte

@milk Hmm ... Non sono sicuro del perché questo accada, ma lo esaminerò.
ETHproductions

@milk Ah, 1000viene analizzato come one thousand zero; Lo riparerò momentaneamente. Dobbiamo sostenere 0da soli però? È un caso unico che aggiungerà circa 15 byte al mio codice.
ETHproductions

11

Informare 7, 214 201 118 byte

Inform 7 è un linguaggio assolutamente terribile per il golf, quindi volevo dargli una possibilità qui.

Il rientro dovrebbe usare i caratteri tab ( \t), ma a HTML non piacciono quelli. Al contrario, Inform non ama gli spazi per il rientro, quindi dovrai sostituire gli spazi con le schede se copi e incolli il codice da qui per testarlo. O semplicemente copia e incolla dall'origine Markdown.

golfed:

Alla X:
    ripetere attraverso la tabella 1:
        ora la voce Q è "[R voce in parole]";
    ordina la tabella 1 in ordine Q;
    dì "[R in Tabella 1]".

L'input dovrebbe essere una tabella Inform, in questo modo (con \ttra le colonne):

Tabella 1
R (numero) Q (testo)
-1002
5
435012
4
23
81
82

Produzione:

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

Questa funzione viene eseguita una volta nella tabella, aggiungendo una rappresentazione testuale di ciascun numero in una nuova colonna. Quindi ordina le righe della tabella in base alla colonna di testo; in Inform, le stringhe sono ordinate lessicograficamente. Infine, stampa la colonna originale nel nuovo ordine. Convenientemente, il formato "grezzo ma a volte utile" di Inform 7 per la stampa delle colonne della tabella risulta essere separato da virgola, esattamente come richiesto.

Ungolfed, con boilerplate che mostra come chiamare la funzione:

Per stampare i numeri in ordine alfabetico:
    ripeti la tabella dei numeri ordinabili:
        ora la voce del nome è "[la voce dell'indice in parole]";
    ordina la tabella dei numeri ordinabili nell'ordine dei nomi;
    dire "[la colonna dell'indice nella Tabella dei numeri ordinabili]".

Tabella dei numeri ordinabili
indice (numero) nome (testo)
-1002
5
435012
4
23
81
82

C'è una stanza
Quando inizia la riproduzione: stampa i numeri in ordine alfabetico.

1
Sono leggermente confuso da questo. È wordsun riferimento delle versioni esplicite dei numeri, integrato in Inform 7?
Pavel,

1
@Pavel Indeed! "(numero) in parole" restituisce una stringa con una rappresentazione testuale del numero. Usa convenientemente "meno" per i numeri negativi, e mentre mette i trattini tra le parole, lo fa in modo coerente e alfabetizza i trattini prima di tutte le lettere (quindi il risultato finale è lo stesso).
Draconis,

2
+1 per la scelta della lingua. Dovrei controllare, ma sospetto che ci siano ancora alcune opportunità di golf; per esempio, il parser richiede davvero tutti quegli "i" articoli? E dovresti chiedere al PO, ma non vedo alcun motivo ovvio per cui "e" non siano un delimitatore valido. Anche in caso contrario, un singolo spazio è esplicitamente consentito, quindi say "[R entry] "dovrebbe bastare.
Ilmari Karonen,

Direi che "e" alla fine va bene. Non ho detto che i delimitatori dovevano essere uniformi, quindi questa è una risposta perfettamente accettabile. Se potessi dare dei punti per la risposta più interessante, te la darei. Mi piace molto la leggibilità di questa lingua, anche giocando a golf. Bel lavoro!
Wubs

Finalmente ho avuto la possibilità di giocare un po 'con Inform7 e sono riuscito a ri-golfare la tua voce fino a soli 118 byte. Dato che pubblicare il codice Inform nei commenti non funziona molto bene, sono andato avanti e l'ho modificato direttamente nella tua risposta. Spero che non ti dispiaccia, sentiti libero di ripristinare e / o modificare le mie modifiche come preferisci.
Ilmari Karonen,

4

Mathematica, 67 byte

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

Funzione senza nome che prende un elenco di numeri interi come argomento e restituisce un elenco di numeri interi come valore. #~IntegerName~"Words"è un built-in che cambia un numero intero con il suo nome in inglese. IntegerNamea volte ha virgole e trattini nel suo output, quindi la StringReplacechiamata si libera di quelli. (Purtroppo il trattino è in realtà il carattere a 3 byte, 8208, in UTF-8). Quindi SortByordina l'elenco originale in ordine alfabetico in base al valore del nome intero modificato.

Una bella coincidenza: IntegerNameusa negativeinvece che minusnel suo output - ma nessuna parola che appare nei nomi di nessuno dei numeri consentiti è in ordine alfabetico tra quelle due parole, quindi non è necessaria alcuna sostituzione!

(Punta del cappello alla ngenisi per avermelo ricordato Sortby.)


Complimenti! Mi avvicinai molto a questa soluzione, ma quel trattino mi faceva venire il mal di testa!
ngenisis,

La tua risposta qui utilizza effettivamente il trattino corretto? Se copio quello che hai qui in Mathematica, non sostituisce i trattini da IntegerName. La documentazione di Wolfram afferma che è un carattere Unicode 2010 .
ngenisis,

Probabilmente no, quindi — ho cercato di ottenere il trattino corretto in questa risposta, ma sembra che non ci sia riuscito.
Greg Martin,

Ho dimezzato la tua risposta;)
J. Antonio Perez il

E poi alcuni ... apporti modifiche inutili alla stringa.
J. Antonio Perez,

4

Bash + GNU utils + bsdgames, 52

  • 4 byte salvati grazie a @izabera.
sed 's/.*/echo `echo &|number`:&/e'|sort|sed s/.*://

Gli I / O sono linee delimitate da newline.

  • La prima espressione sed sostituisce ogni numero numerico con un comando shell che genera la forma della parola del numero (come data dall'utilità bsdgamesnumber ), seguita da una :forma numerica del numero.
  • Questo è quindi sorted.
  • Quindi la seconda sedstriscia conduce i caratteri fino a e includendo il :, lasciando la forma numerica ordinata come richiesto.

numbergestisce correttamente "meno" e il suo output è abbastanza vicino al formato specifico che sortfunziona come richiesto. Produce "quarantaquattro" invece di "quarantaquattro", ma questo non dovrebbe importare dal punto di vista dell'ordinamento.

Il pacchetto bsdgames potrebbe richiedere l'installazione:

sudo apt-get install bsdgames

Le utility sede sortsono quasi certamente già nella tua distribuzione.


-t:è inutile e puoi usarenumber<<<&
izabera il

@izabera Sì, grazie. Ho rimosso il file -t:. Tuttavia, la efunzione val di sed esegue i comandi utilizzando sh, quindi le funzionalità bash come <<<non funzioneranno.
Digital Trauma,

funziona bene fintanto che sh è bash: P
izabera,

@izabera No - se bash è iniziato nel shtentativo di emulare Posix sh il più possibile, il che significa che i bashismi come quelli <<<sono disattivati. sedLa efunzione val di GNU avvia i comandi con /bin/sh -c ...e non /bin/bash -c .... Hai provato questo?
Digital Trauma,

bash non si spegne mai <<<, nemmeno in modalità
posix

1

Python + inflect, 97 91 89 byte

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

Ha usato la inflectlibreria per trasformare l' wordsarray di numeri interi nella loro rappresentazione fonetica / stringa. Memorizzato in un dizionario di coppie k / v in cui le chiavi erano la rappresentazione numerica e i valori erano la rappresentazione in forma di stringa. Restituito l'elenco di chiavi come ordinato per valori.

EDIT: 5 e 3 byte salvati, grazie a ETHproductions e Alex.S!


Benvenuti in PPCG! Puoi giocare a golf rimuovendo gli spazi ; per esempio, la seconda riga può essere a={x:inflect.engine().number_to_words(x)for x in words}.
ETHproductions

È possibile salvare due byte usando from inflect import*e gettando inflect.nella seconda riga.
Alex.S,

Ahimè, sembra che anche questo non riesca a ordinare correttamente l'elenco 40, 44, 40000, 40804, 40004, 40204 (che dovrebbe rimanere in quell'ordine).
Ilmari Karonen,

0

Mathematica, 30 byte

La risposta di seguito mostra una funzione pura che prenderà un elenco di numeri interi come input e li ordinerà in base al loro nome alfabetico. Proprio quello che il medico ha ordinato;)

SortBy[#~IntegerName~"Words"&]

Ecco la versione ungolfed:

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

Ed ecco un esempio di utilizzo:

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

Che potrebbe anche essere scritto come

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

Producono output identici - in matematica, f[x]è equivalente a f@x.

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

C'è una risposta molto più lunga che un altro utente ha pubblicato in Mathematica. Quella risposta cerca di correggere alcune piccole differenze tra il modo in cui la matematica alfabatizza i numeri per adattarsi meglio al modo in cui i numeri dichiarati OP dovrebbero essere alfabatizzati, tuttavia le cose per cui correggono non influiscono sull'ordinamento e la mia risposta risulta identica alla loro:

MyF = SortBy[#~IntegerName~"Words"&];
TheirF = SortBy[#, #~IntegerName~"Words"~ StringReplace~{"," -> "", "-" -> ""} &] &;
MyF[Range[-999999, 999999]] == TheirF[Range[-999999, 999999]]
(*Outputs True*)

Una grande indagine! Sfortunatamente, in realtà non danno lo stesso ordine. TheirFordina correttamente 888 prima di 880.000, mentre MyFnon lo fa. Probabilmente il problema è con il copia-incolla dello strano trattino: la tua versione TheirFsostituisce probabilmente i trattini normali (di cui non ce ne sono), mentre la versione attuale sostituisce lo strano trattino Unicode a 3 byte. (Sarebbe comunque interessante vedere se è necessario rimuovere le virgole.)
Greg Martin

L'ho provato su Range [999999]. Sembra che non sia necessario eliminare le virgole, ma è assolutamente necessario sostituire "[Trattino]" con "".
ngenisis,

0

Lisp comune, 113 byte

Non sono necessarie librerie esterne.

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

Uscita se xè '(1 2 3 4 5):

(5 4 1 3 2)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.