Alphabétiser les entiers

19

Alphabétiser les entiers

Pour un ensemble donné de nombres, mettez-les dans l'ordre alphabétique lorsqu'ils sont épelés (c'est-à-dire 1: un, 2: deux, 90: quatre-vingt-dix, 19: dix-neuf). Votre code devrait fonctionner pour la plage [-999999, 999999]. La sortie doit avoir un délimiteur entre les nombres. Un espace fonctionnera, tout comme un espace et une virgule comme indiqué dans les exemples ci-dessous. L'entrée peut être un tableau d'entiers, une chaîne de nombres délimités ou comme bon vous semble. Tous les entiers sont supposés être uniques.

Les chiffres ne sont pas coupés d'un trait aux fins de ce défi et les espaces sont classés par ordre alphabétique avant tout autre caractère. Les nombres négatifs sont supposés être exprimés en utilisant le mot minus. Par exemple, fourprécéderait four thousandet le nombre -40serait trié à l'aide de la chaîne minus forty. Supposons que tous les nombres seront uniquement composés de mots numériques et pas de conjonctions (par exemple, utiliser à la two thousand forty twoplace de two thousand and forty two).


Cas de test

Entiers à un chiffre:

Contribution:

1, 2, 3, 4, 5

Production:

5, 4, 1, 3, 2

Entiers à plusieurs chiffres:

Contribution:

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

Production:

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

Espaces entre les mots, sans tirets, virgules ou "et":

Contribution:

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

Production:

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

N'oubliez pas qu'il s'agit de , donc le code avec le moins d'octets gagne. Aucune échappatoire autorisée!

wubs
la source
Voici le lien vers la publication sandbox correspondante.
wubs
L'entrée contiendra-t-elle jamais plus d'un seul entier?
ETHproductions
@ETHproductions Non, ce ne sera pas le cas. Je le préciserai dans la question.
wubs
8
Bienvenue chez PPCG. Joli avatar. : D Belle première question.
AdmBorkBork
@TimmyD Merci! J'ai hâte de pouvoir PowerShell tout ce que je peux ici.
wubs

Réponses:

5

JavaScript (ES6), 189 179 186 octets

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'idée de base est de convertir chaque numéro d'entrée en une chaîne courte qui est dans la position lexographique correcte par rapport à toutes les autres paires de chaînes de nombres. Voici le dictionnaire utilisé: (N'exécutez pas l'extrait; il est juste utilisé pour masquer la longue liste.)

Cela crée un moyen très concis de mapper chaque nombre à sa position lexographiquement correcte. C'est ce que fait la qfonction récursive :

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]

Au 0début de la chaîne est de s'assurer que par exemple 100 ( one hundred, converti en PK0) est trié avant 101( one hundred one, converti en PKP). Cela crée un scénario étrange où 0 ( zero) est trié à l'avant du tableau, donc pour contourner cela, dans la fonction de tri, nous trions d'abord les zéros à droite avec !x-!y||(....

ETHproductions
la source
On dirait que ça ne marche pas [1100, 1000]. Je m'attendrais à ce que la sortie soit 1000 (one thousand), 1100 (one thousand one hundred), mais la sortie est du même ordre que l'entrée.
lait
@milk Hmm ... Je ne sais pas pourquoi cela se produit, mais je vais y réfléchir.
ETHproductions du
@milk Ah, 1000est analysé comme one thousand zero; Je vais arranger ça momentanément. Doit-on soutenir 0seul? C'est un cas unique qui ajoutera environ 15 octets à mon code.
ETHproductions
11

Informer 7, 214 201 118 octets

Inform 7 est un langage absolument horrible pour le golf, donc je voulais lui donner une chance ici.

L'indentation doit utiliser des caractères tab ( \t), mais HTML n'aime pas ceux-ci. Inversement, Inform n'aime pas les espaces pour l'indentation, vous devrez donc remplacer les espaces par des tabulations si vous copiez-collez le code d'ici pour le tester. Ou copiez-collez simplement à partir de la source Markdown.

Golfé:

À X:
    répéter dans le tableau 1:
        maintenant l'entrée Q est "[entrée R en mots]";
    trier le tableau 1 dans l'ordre Q;
    dire "[R dans le tableau 1]".

L'entrée doit être une table Inform, comme ceci (avec \tentre les colonnes):

Tableau 1
R (nombre) Q (texte)
-1002
5
435012
4
23
81
82

Production:

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

Cette fonction parcourt le tableau une fois, en ajoutant une représentation textuelle de chaque numéro dans une nouvelle colonne. Ensuite, il trie les lignes du tableau en fonction de la colonne de texte; dans Inform, les chaînes sont triées lexicographiquement. Enfin, il imprime la colonne d'origine dans la nouvelle commande. De manière pratique, le format "brut mais parfois utile" d' Inform 7 pour l'impression des colonnes du tableau se révèle être séparé par des virgules, exactement comme demandé.

Non golfé, avec passe-partout indiquant comment appeler la fonction:

Pour imprimer les chiffres par ordre alphabétique:
    répéter dans le tableau des nombres triables:
        maintenant l'entrée de nom est "[l'entrée d'index en mots]";
    trier le tableau des nombres triables dans l'ordre des noms;
    dites "[la colonne d'index du tableau des nombres triables]".

Tableau des nombres triables
index (nombre) nom (texte)
-1002
5
435012
4
23
81
82

Il y a une pièce.
Lorsque la lecture commence: imprimez les chiffres dans l'ordre alphabétique.
Draconis
la source
1
Je suis légèrement confus par cela. Une wordsréférence des versions épelées des nombres est-elle intégrée à Inform 7?
Pavel
1
@Pavel Effectivement! "(nombre) en mots" renvoie une chaîne avec une représentation textuelle du nombre. Il utilise commodément "moins" pour les nombres négatifs, et bien qu'il place des tirets entre les mots, il le fait de manière cohérente et alphabétise les tirets avant toutes les lettres (donc le résultat final est le même).
Draconis
2
+1 pour le choix de la langue. Je devrais vérifier, mais je soupçonne qu'il reste des opportunités de golf; par exemple, l'analyseur a-t-il vraiment besoin de tous "les" articles? Et il faudrait demander au PO, mais je ne vois aucune raison évidente pour laquelle «et» ne serait pas un délimiteur valide. Même si ce n'est pas le cas, un seul espace est explicitement autorisé, donc say "[R entry] "devrait suffire.
Ilmari Karonen
Je dirais que le "et" à la fin est très bien. Je n'ai pas dit que les délimiteurs devaient être uniformes, c'est donc une réponse parfaitement acceptable. Si je pouvais donner des points pour la réponse la plus intéressante, je vous la donnerais. J'apprécie vraiment la lisibilité de cette langue, même au golf. Bon travail!
wubs
J'ai enfin eu la chance de jouer un peu avec Inform7, et j'ai réussi à re-jouer votre entrée à seulement 118 octets. Étant donné que la publication du code Inform dans les commentaires ne fonctionne pas très bien, je suis allé de l'avant et l'ai modifié directement dans votre réponse. J'espère que cela ne vous dérange pas, n'hésitez pas à revenir en arrière et / ou à modifier mes modifications comme vous le souhaitez si vous le faites.
Ilmari Karonen
4

Mathematica, 67 octets

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

Fonction sans nom prenant une liste d'entiers comme argument et renvoyant une liste d'entiers comme valeur. #~IntegerName~"Words"est une fonction intégrée qui change un entier en son nom en anglais. IntegerNamea parfois des virgules et des tirets dans sa sortie, donc l' StringReplaceappel se débarrasse de ceux-ci. (Malheureusement, le tiret est en fait le caractère à 3 octets, 8208, en UTF-8.) SortByTrie ensuite la liste d'origine par ordre alphabétique en fonction de la valeur du nom entier modifié.

Une belle coïncidence: IntegerNameutilise negativeau lieu de minusdans sa sortie - mais aucun mot apparaissant dans les noms des numéros autorisés n'est alphabétiquement entre ces deux mots, donc aucun remplacement n'est nécessaire!

(Pointe du chapeau à ngenisis pour me le rappeler Sortby.)

Greg Martin
la source
Gloire! J'étais très près d'obtenir cette solution, mais ce tiret me donnait des maux de tête!
ngenisis
Votre réponse ici utilise-t-elle réellement le trait d'union correct? Si je copie ce que vous avez ici dans Mathematica, il ne remplace pas les tirets IntegerName. La documentation Wolfram indique qu'il s'agit du caractère unicode 2010 .
ngenisis
Probablement pas, alors - j'ai essayé d'obtenir le trait d'union correct dans cette réponse, mais on dirait que je n'ai pas réussi.
Greg Martin
J'ai coupé votre réponse de moitié;)
J. Antonio Perez
Et puis certains ... vous apportez des modifications inutiles à la chaîne.
J. Antonio Perez
4

Bash + GNU utils + bsdgames, 52

  • 4 octets enregistrés grâce à @izabera.
sed 's/.*/echo `echo &|number`:&/e'|sort|sed s/.*://

Les E / S sont des lignes délimitées par des sauts de ligne.

  • La première expression sed remplace chaque nombre numérique par une commande shell qui génère la forme verbale du nombre (comme indiqué par les bsdgamesnumber utilitaire ), suivie de :puis la forme numérique du nombre.
  • C'est alors sort éd.
  • Ensuite, la seconde sedbande menant les caractères jusqu'au et y compris le :, laissant la forme numérique triée comme requis.

number gère correctement "moins", et sa sortie est suffisamment proche du format spécifique que le sort fonctionne comme requis. Il affiche "quarante-quatre" au lieu de "quarante-quatre", mais cela ne devrait pas avoir d'importance du point de vue du tri.

Le package bsdgames peut nécessiter une installation:

sudo apt-get install bsdgames

Les utilitaires sedet sortsont presque certainement déjà dans votre distribution.

Traumatisme numérique
la source
-t:est inutile et vous pouvez utilisernumber<<<&
izabera
@izabera Oui - merci - j'ai supprimé le -t:. Cependant, la efonction val de sed exécute des commandes en utilisant sh, donc les fonctionnalités bash comme <<<ne fonctionneront pas.
Digital Trauma
cela fonctionne bien tant que votre sh est bash: P
izabera
@izabera Nope - si bash est démarré car shil essaie d'émuler autant que possible Posix sh, ce qui signifie que les bashismes tels que <<<sont désactivés. sedLa efonction val de GNU démarre les commandes avec /bin/sh -c ...et non /bin/bash -c .... Avez-vous essayé cela?
Traumatisme numérique
bash ne s'éteint jamais <<<, même pas en mode posix
izabera
1

Python + flexion, 97 91 89 octets

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

Utilisé la inflectbibliothèque pour transformer le wordstableau d'entiers en leur représentation phonétique / chaîne. Stocké dans un dictionnaire de paires k / v où les clés étaient la représentation numérique et les valeurs étaient la représentation sous forme de chaîne. Renvoyé la liste des clés triées par valeurs.

EDIT: 5 et 3 octets enregistrés, grâce à ETHproductions et Alex.S!

9814072356
la source
Bienvenue chez PPCG! Vous pouvez jouer au golf en supprimant les espaces ; par exemple, la deuxième ligne peut être a={x:inflect.engine().number_to_words(x)for x in words}.
ETHproductions
Vous pouvez enregistrer deux octets en utilisant from inflect import*et en jetant sur inflect.la deuxième ligne.
Alex.S
Hélas, il semble que cela ne parvienne pas non plus à trier correctement la liste 40, 44, 40000, 40804, 40004, 40204 (qui devrait rester dans cet ordre).
Ilmari Karonen
0

Mathematica, 30 octets

La réponse ci-dessous génère une fonction pure qui prendra une liste d'entiers en entrée et les triera par leur nom alphabétique. Juste ce que le docteur à prescrit ;)

SortBy[#~IntegerName~"Words"&]

Voici la version non golfée:

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

Et voici un exemple d'utilisation:

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

Qui pourrait aussi s'écrire

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

Ils produisent des sorties identiques - en mathématique, f[x]équivaut à f@x.

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

Il y a une réponse beaucoup plus longue qu'un autre utilisateur a posté dans Mathematica. Cette réponse essaie de corriger quelques petites différences entre la façon dont mathématique alphebatise les nombres pour mieux se conformer à la façon dont les nombres déclarés OP doivent être alphebatisés, cependant les choses qu'ils corrigent n'affectent pas l'ordre de tri, et ma réponse renvoie de manière identique à la leur:

MyF = SortBy[#~IntegerName~"Words"&];
TheirF = SortBy[#, #~IntegerName~"Words"~ StringReplace~{"," -> "", "-" -> ""} &] &;
MyF[Range[-999999, 999999]] == TheirF[Range[-999999, 999999]]
(*Outputs True*)
J. Antonio Perez
la source
Une belle enquête! - malheureusement, ils ne donnent pas le même ordre. TheirFtrie correctement 888 avant 880 000, mais MyFpas. Le problème est probablement lié au copier-coller du trait d'union étrange: votre version de TheirFremplace probablement les tirets normaux (dont il n'y en a pas), tandis que la version actuelle remplace l'étrange trait d'unicode 3 octets. (Il serait toujours intéressant de voir si la suppression des virgules est nécessaire.)
Greg Martin
Je l'ai testé sur la gamme [999999]. Il semble inutile d'éliminer les virgules, mais remplacer "[Trait d'union]" par "" est absolument nécessaire.
ngenisis
0

Lisp commun, 113 octets

Aucune bibliothèque externe nécessaire.

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

Sortie si xest '(1 2 3 4 5):

(5 4 1 3 2)
Harry
la source