Trier les numéros de série épelés

17

Étant donné une liste de deux ou plusieurs numéros de série épelés de longueur égale supérieure à deux, par exemple

[[ "three" , "one"  , "four"  ],
 [ "one"   , "five" , "nine"  ],
 [ "two"   , "six"  , "five"  ],
 [ "three" , "five" , "eight" ]]

trier la liste par les nombres que les mots représentent:

[[ "one"   , "five" , "nine"  ],
 [ "two"   , "six"  , "five"  ],
 [ "three" , "one"  , "four"  ],
 [ "three" , "five" , "eight" ]]

Vous devrez peut-être orthographier les chiffres en minuscules ou en majuscules, mais pas en les mélangeant.

Cas de test

[["three","one","four"],["one","five","nine"],["two","six","five"],["three","five","eight"]]
donne
[["one","five","nine"],["two","six","five"],["three","one","four"],["three","five","eight"]]

[["two","seven"],["one","eight"],["two","eight"],["one","eight"],["two","eight"],["four","five"]]
donne
[["one","eight"],["one","eight"],["two","seven"],["two","eight"],["two","eight"],["four","five"]]

[["one","four","one","four","two"],["one","three","five","six","two"],["three","seven","three","zero","nine"]]
donne
[["one","three","five","six","two"],["one","four","one","four","two"],["three","seven","three","zero","nine"]]

[["zero","six","one"],["eight","zero","three"],["three","nine","eight"],["eight","seven","four"],["nine","eight","nine"],["four","eight","four"]]
donne
[["zero","six","one"],["three","nine","eight"],["four","eight","four"],["eight","zero","three"],["eight","seven","four"],["nine","eight","nine"]]

Adam
la source
Je ne sais pas si j'ai bien compris, non ["three","one","four"] === 314?
Nit
@Nit Oui, c'est vrai.
2018 à
@Nit Par les chiffres qu'ils énoncent. Par exemple [314,159,265,358][159,265,314,358].
2018 à
Peut-on supposer une certaine capitalisation arbitraire des nombres?
dylnan
@dylnanYou may require the numbers to be spelled in lower or upper, but not mixed, case.
totallyhuman

Réponses:

14

Husk , 9 8 octets

Ö†€¨tfṡn

Essayez-le en ligne!

Algorithme "inspiré" par la réponse récursive de Stax (je viens de changer un peu la chaîne de recherche), allez le voter!

L'astuce consiste à mapper chaque lettre à sa position dans la chaîne tfsen(compressée à la fin de ce programme). Les listes de cosses sont basées sur 1 et les éléments manquants renvoient 0, nous obtenons donc ce mappage:

"one"        [0,5,4]
"two"        [1,0,0]
"three"      [1,0,0,4,4]
"four"       [2,0,0,0]
"five"       [2,0,0,4]
"six"        [3,0,0]
"seven"      [3,4,0,4,5]
"eight"      [4,0,0,0,1]
"nine"       [5,0,5,4]

Comme vous pouvez le constater, les listes sont parfaitement ordonnées.


Pour être clair, voici comment fonctionne la comparaison de liste dans Husk (et dans de nombreuses autres langues):

  1. Si l'une des deux listes est vide, c'est la plus petite.
  2. Si les premiers éléments des deux listes sont différents, celui dont le premier élément est le plus petit est la liste la plus petite.
  3. Sinon, jetez le premier élément des deux listes et revenez au point 1.
Leo
la source
Si je ne me trompe pas, le "w" peut également être supprimé, car il n'est utile que de comparer "deux" à "trois", mais vous avez déjà "h". Je ne sais pas si cela vous aide. Je n'ai pas encore compris comment intégrer ce fait dans un programme stax qui est en fait encore plus petit.
récursif le
... si ce n'était que des lettres, cela pourrait être tfrsenmais je suppose que le fait d'avoir des mots comme withet senaide à la compression.
Jonathan Allan
Merci les gars, vous m'avez inspiré pour trouver une chaîne encore plus courte: D
Leo
Donc, c'est comme remplacer les virgules par un point décimal après la première virgule?
Strawberry
@Strawberry Pas vraiment, [1,0,0]est considéré comme plus petit que [1,0,0,0](mais pour ce programme, cela ne ferait aucune différence)
Leo
10

Stax , 24 22 17 16 14 octets

▄Ωφ▐╧Kìg▄↕ñ▼!█

Exécuter et déboguer

Ce programme prend des tableaux de chiffres épelés en minuscules pour la saisie. La sortie est séparée par des sauts de ligne.

one five nine
two six five
three one four
three five eight

Ce programme trie les entrées en utilisant l'ordre obtenu sous une transformation spécifique. Chaque caractère de chaque mot est remplacé par son index dans la chaîne "wo thif sen". Les tableaux d'origine sont triés par cet ordre. Ensuite, les résultats sont imprimés après avoir rejoint un espace.

Les espaces ne servent à rien, mais permettent en fait une plus grande compression dans le littéral de chaîne.

récursif
la source
Quel encodage Stax utilise-t-il? C'est 32 octets en UTF-8.
OldBunny2800 le
5
CP437 modifié, comme l'explique le lien hypertexte "octets".
récursif le
Existe-t-il un algorithme / méthode standard pour créer une telle chaîne? Le concept a-t-il un nom?
Itai
@Itai: Il semble que ce serait le cas, mais je ne sais pas ce que c'est.
récursif
6

Gelée , 12 octets

OḌ%⁽Т%147µÞ

Un lien monadique.

Essayez-le en ligne! ... ou voir la suite de tests

Comment?

La conversion des chiffres en ordinaux puis à partir de la base 10 puis la prise de modules par 4752 puis 147 donne un ordre croissant:

 zero            , one         , two         , three               , four
[122,101,114,111],[111,110,101],[116,119,111],[116,104,114,101,101],[102,111,117,114]
 133351          , 12301       , 12901       , 1276511             , 114384
 295             , 2797        , 3397        , 2975                , 336
 1               , 4           , 16          , 35                  , 42

 five            , six         , seven               , eight               , nine
[102,105,118,101],[115,105,120],[115,101,118,101,110],[101,105,103,104,116],[110,105,110,101]
 113781          , 12670       , 1263920             , 1126456             , 121701
 4485            , 3166        , 4640                , 232                 , 2901
 75              , 79          , 83                  , 85                  , 108

Cela peut ensuite être utilisé comme une fonction clé pour trier:

OḌ%⁽Т%147µÞ - Link: list of lists of lists of characters
          µÞ - sort (Þ) by the mondadic chain to the left (µ):
O            -   ordinals of the characters
 Ḍ           -   convert from base 10
   ⁽Т       -   literal 4752
  %          -   modulo
      %147   -   modulo by 147
Jonathan Allan
la source
C'est quelques merveilleux modules que vous avez trouvés ici, je suppose que cela a été minutieux.
Erik the Outgolfer le
Pas si minutieux - j'ai d'abord regardé le binaire.
Jonathan Allan
Comme, vous avez forcé les modulos brutalement, non?
Erik the Outgolfer le
Oui, mais c'était rapide.
Jonathan Allan
6

Python , 62 octets

lambda m:sorted(m,key=lambda r:[int(s,36)%6779%531for s in r])

Essayez-le en ligne! ... ou voir la suite de tests

Remarque:

lambda m:sorted(m,key=lambda r:[map("trfsen".find,s)for s in r])

qui fonctionne en Python 2 (mais pas 3) est plus long de deux octets.

Jonathan Allan
la source
1
Comment avez-vous découvert les nombres magiques?
mbomb007
1
Juste une boucle imbriquée vérifiant l'augmentation stricte des résultats. Bien que j'aie peut-être restreint la longueur des chiffres de l'intérieur étant donné l'extérieur.
Jonathan Allan
5

APL (Dyalog Classic) , 12 octets

'nesft'∘⍒⌷¨⊂

Essayez-le en ligne!

Voici comment j'ai trouvé un argument de gauche approprié pour dyadique (j'ai essayé et longueur 6 en premier):

A←⊖a←↑'zero' 'one' 'two' 'three' 'four' 'five' 'six' 'seven' 'eight' 'nine'
{(aa[⍵⍒a;])∧Aa[⍵⍒A;]:⎕←⍵}¨,⊃∘.,/5⍴⊂∪∊a
ngn
la source
3

Perl 6 , 37 octets

*.sort:{('digit 'X~$_)».parse-names}

Essayez-le

Étendu:

*\     # WhateverCode lambda (this is the parameter)
.sort:
{  # block with implicit parameter 「$_」
  (
    'digit ' X~ $_  # concatenate 'digit ' to each named digit
  )».parse-names    # call .parse-names on each
}

Le bloc de code prendra une valeur du formulaire ("three","one","four")et le traduira en ("3","1","4")une valeur .sortfacilement utilisable.

Brad Gilbert b2gills
la source
3

APL (Dyalog) , 38 octets

{⍵[⍋(531∘⊥⍤1)(531|6779|369+⎕A⍳⊢)¨↑⍵]}

Essayez-le en ligne!

Basé sur la formidable solution de Jonathan Allan .

Uriel
la source
1
@JonathanAllan J'ai édité un crédit pendant la première heure de changement. Je n'ai aucune idée pourquoi il est resté inchangé. réparé maintenant
Uriel
1
31:, ⊂⌷¨⍨∘⍋(531⊥531|6779|36⊥9+⎕A⍳⊢)¨mais vous pouvez le faire beaucoup plus simplement en moins de la moitié de votre nombre d'octets actuel.
Adám
@ Adám donc, vous tolérez les entrées et sorties dans différents formats (mixtes vs non mélangés)?
2018
@ngn Bien sûr. Mais la solution que j'ai en tête a totalement mélangé les E / S.
2018
3

Rubis, 48 ​​octets

->x{x.sort_by{|y|y.map{|s|s.to_i(35)**2%47394}}}

Abuse le fait que "zero".to_i(35)0 (puisque 'z' n'est pas un chiffre valide en base 35), il est donc beaucoup plus facile de forcer brutalement une formule pour les neuf autres chiffres.

histocrate
la source
2

Rubis , 47 octets

->x{x.sort_by{|y|y.map{|s|s.to_i(32)%774%538}}}

Essayez-le en ligne!

Utilise le fait que l'utilisation d'une base inférieure au chiffre maximum donne un résultat de zéro (comme souligné par l'histocrate dans sa réponse )

Jonathan Allan
la source
2

Python 2 , 85 81 80 octets

Utilise simplement les deux premières lettres de chaque mot pour déterminer le nombre, puis trie chaque liste en utilisant cette fonction d'indexation comme clé.

lambda _:sorted(_,key=lambda L:['zeontwthfofisiseeini'.find(s[:2])/2for s in L])

Essayez-le en ligne!

Enregistré 4 octets, merci à Jonathan Allan

mbomb007
la source
Une compréhension de la liste des boucles dans la fonction clé est de 4 octets plus courte.
Jonathan Allan, le
1

05AB1E , 27 octets

Σ“¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“#skJ

Essayez-le en ligne!


Σ                           # Sort input by...
 “¡×€µ‚•„í†ìˆÈŒšï¿Ÿ¯¥Š“     # "zero one two three four five size seven eight nine"
                       #    # Split on spaces.
                        sk  # Find index of each input...
                          J # Join up.
Urne de poulpe magique
la source
25 octets
Kaldo
@Kaldo ah ... encodant les 2 premières lettres de chacune? Je pense que cela devrait être sa propre réponse.
Urne de poulpe magique
1

Haskell , 133 122 109 107 107 106 octets

import Data.List
sortOn$abs.read.(>>=show.head.(`elemIndices`words"ze on tw th fo fi si se ei ni").take 2)

Non golfé:

import Data.List

nums = ["ze","on","tw","th","fo","fi","si","se","ei","ni"]

lookup' :: Eq a => a -> [a] -> Int
lookup' v = head . elemIndices v

wordToInt :: String -> Int
wordToInt (x:y:_) = lookup' [x,y] nums

wordsToInt :: [String] -> Int
wordsToInt = read . concatMap (show . wordToInt)

sortN :: [[String]] -> [[String]]
sortN = sortOn wordsToInt
user9549915
la source
1

Java (JDK 10) , 132 octets

l->{l.sort((a,b)->s(a)-s(b));}
int s(String[]a){int v=0;for(var s:a)v=v*99+"zeontwthfofisiseini".indexOf(s.substring(0,2));return v;}

Essayez-le en ligne!

Olivier Grégoire
la source
0

Ruby , 64 octets

->a{a.sort_by{|b|b.map{|n|"zeontwthfofisiseeini".index n[0,2]}}}

Essayez-le en ligne!

Un lambda acceptant un tableau 2D de chaînes et renvoyant un tableau 2D de chaînes.

Le ferroutage de la réponse Python 2 de mbomb007 pour -26 octets de ce que j'allais publier.

benj2240
la source
0

Retina 0.8.2 , 38 octets

T`z\o\wit\hfsen`d
O`
T`d`z\o\wit\hfsen

Essayez-le en ligne! Le lien inclut une suite de tests. Fonctionne en remplaçant temporairement les lettres zowithfsenpar leur position dans cette chaîne, ce qui permet de trier lexicalement les chiffres.

Neil
la source
0

Gelée , 30 28 27 octets

w@€“¡¦ẇṆb~ṇjṚØ%ĖġṘḥḞṾṇJḌ»µÞ

Essayez-le en ligne!

-1 merci à Jonathan Allan.

Recherche l'index de chaque chiffre dans la chaîne 'onetwo ... nine' puis trie en utilisant ceci comme une fonction clé avec Þ. Il n'est pas nécessaire d'inclure 'zero'au début, car la recherche des deux premiers caractères de 'zero'échouera et 0sera renvoyée à la place d'un index, ce qui rend 'zero'lexicographiquement "précoce".

dylnan
la source
Utiliser une compression de «un deux ... neuf» est un octet de moins
Jonathan Allan
@JonathanAllan Ah, merci. Je n'avais pas pensé à vérifier ça. La compression a 'zeontw...ni'fini par être plus longue.
dylnan
... plus "... les deux premières lettres".
Jonathan Allan
0

Python 3, 141 octets

print(sorted(eval(input()),key=lambda l:int(''.join([str("zero one two three four five six seven eight nine".split().index(i))for i in l]))))

Essayez-le en ligne!

hakr14
la source
131 octets
caird coinheringaahing
0

C (clang) , 229 octets

y,j,k,t[9];char *s="zeontwthfofisiseeini";r(char **x){for(j=y=k=0;k+1<strlen(*x);k+=j,y=y*10+(strstr(s,t)-s)/2)sscanf(*x+k,"%2[^,]%*[^,]%*[,]%n",t,&j);return y;}c(*x,*y){return r(x)-r(y);}f(*x[],l){qsort(&x[0],l,sizeof(x[0]),c);}

Essayez-le en ligne!

Il n'y a aucun moyen simple d'envoyer un tableau de tableau de chaînes aux fonctions C, donc dans l'esprit du code-golf, j'ai pris une liberté mineure dans le format d'entrée.

f()accepte un tableau de pointeurs vers des chaînes, où chaque chaîne est un nombre, représenté par des chiffres épelés séparés par des virgules en minuscules. De plus, il a besoin d'un nombre de chaînes dans le tableau dans le deuxième paramètre. J'espère que c'est acceptable.

f()remplace les pointeurs en place dans l'ordre trié à l'aide de qsort().
r()lit le numéro d'entrée dans une chaîne numérique séparée par des virgules. Il compare uniquement les deux premiers caractères pour identifier le numéro.
c()est la fonction de comparaison

GPS
la source
1
207 octets
Plafond
@ceilingcat Pouvez-vous s'il vous plaît expliquer strstr("i"-19,t)-"zeontwthfofisiseeini"? Est-ce spécifique au compilateur ou standard?
GPS
Cela repose sur le fait qu'il n'y a pas d'autres modèles .rodataqui ressemblent à cela 0x69 0x00et que le compilateur place l'adresse de "i"fin"zeo..."
plafondcat
pensé ainsi .. est-il possible de s'assurer que le compilateur fait cela? Je sais que les règles ici permettraient cela, mais pourrais-je en dépendre vraiment?
GPS
Mon instinct est d'éviter cela dans le "monde réel" mais cela fonctionnera probablement bien si vos fragments de chaîne sont suffisamment uniques. Il peut en fait y avoir un cas d'utilisation légitime peut-être lié aux canaris empilés, mais je pourrais aussi simplement halluciner.
plafondcat