WymowaSort ™


24

Wszyscy znamy różne fantazyjne algorytmy sortowania, ale żaden z nich nie podaje liczb w sposób łatwy do wymówienia. Aby temu zaradzić, proponuję użycie WymowaSort ™, najbardziej naturalnego sposobu sortowania list liczb.

Wymowa

Oficjalne zasady wymawiania liczb (w tym wyzwaniu) są takie, że cyfry wymawiane są jeden po drugim, a powstały ciąg jest sortowany w kolejności leksykograficznej. Jako przykład oznacza to, że liczba 845jest wymawiana "eight four five"i powinna być odpowiednio posortowana.

Liczby ujemne

Liczby ujemne wymawia się, dodając słowo "minus". Dlatego -23wymawia się jako "minus two three". Zauważ, że powoduje to, że liczby ujemne kończą się na środku wyniku, dokładnie między liczbami zaczynającymi się od 4(czterech) i 9(dziewięciu).

Tytułem przewodnika, oficjalna kolejność słów dla WymowaSort ™ to:

  • osiem
  • pięć
  • cztery
  • minus
  • dziewięć
  • jeden
  • siedem
  • sześć
  • trzy
  • dwa
  • zero

To jest,

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

Wkład

Lista liczb całkowitych z zakresu , zawierająca maksymalnie 100 elementów. Wprowadzanie jako lista ciągów jest niedozwolone. Jeśli twój język nie obsługuje wprowadzania jako listy, dozwolone jest podawanie danych jako oddzielnych liczb całkowitych.[-999,999]

Dane wejściowe nie będą zawierać żadnych nieprawidłowych liczb ani żadnej liczby rozpoczynającej się od 0 (z wyjątkiem samej liczby 0). Dane wejściowe na ogół nie będą sortowane, można je podać w dowolnej kolejności.

Wydajność

Te same liczby całkowite, w kolejności WymowaSort ™. Zauważ, że liczby powinny być konwertowane tylko na ich wymowy, aby uzyskać sortowanie, dane wyjściowe nie powinny zawierać żadnych ciągów.

Przykłady

W przykładach środkowy krok (owinięty w nawiasy) służy jedynie jako wskazówka i nie jest częścią wyniku.

[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]

Istnieje również skrypt do weryfikacji wyników .


5
Dlaczego „jeden” (wymawiane „wygrał”) nie pojawia się po dwóch i przed zerem?
Ben Miller - Przywróć Monikę

3
@BenMiller Nie pamiętam, czy to ty skomentowałeś w piaskownicy, ale ten komentarz dał mi deja vu. Aby odpowiedzieć na to pytanie, zastanawiałem się nad tym, ale poszedłem z ortografią, aby uniknąć dyskusji na temat ortografii (np. „Dwa” wobec „też”, „wygrał” lub „wan”)
maxb

17
Jest to więc bardziej „sortowanie pisowni” niż „sortowanie wymowy” :-)
Paŭlo Ebermann

3
bummer. Miałem nadzieję, że zostaną posortowane według stopnia trudności w wymowie ...
NH.

2
To wyzwanie naprawdę należy zmienić, ponieważ sortowanie tutaj nie ma praktycznie nic wspólnego z wymową. Byłoby to o wiele bardziej skomplikowane, gdyby było oparte na wymowie (np. Cztery mogłyby pojawić się przed piątą, jeśli posortujesz monofoniczny ⟨ɔː⟩ przed dyftongiem ⟨aɪ⟩, ale pięć przed czterema, jeśli posortujesz pochodną ⟨a⟩ przed o -prowadzono ⟨ɔ⟩ - o ile mi wiadomo, nie ma ustalonego porządku sortowania wymowy, ani w IPA, ani w żadnym innym schemacie).
Janus Bahs Jacquet

Odpowiedzi:


8

05AB1E (starsza wersja) , 15 bajtów

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

Wypróbuj online!

Wyjaśnienie

Σ                 # sort by
 ε                # apply to each
             sk   # index of the element in
  •Koéa₃•         # "85409176320"
         '-3ǝ     # with "-" inserted at index 3

Wydaje się, że występuje błąd w skompresowanej liczbie całkowitej •ĆU‘•. Dodaje nowy wiersz podczas mapowania / sortowania z dowolnego powodu. Σ•ĆU‘•"54-ÿ"sSkmogłabym być 15-bajtową alternatywą, nad którą pracowałem, gdyby nie ten dziwny błąd. Gdybym zmienił •ĆU‘•literał 9176320 ,
działałby

1
@KevinCruijssen: To dziwne. Twój byłby 14 z …54-ìparzystym
Emigna

@KevinCruijssen: Możesz zrobić Σ•RT‹•Á…54-ìsSkza 15
Emigna

•t∍ýJ•'-ìÁÁdziałałoby również
Emigna


8

Galaretka ,  15  13 bajtów

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

Wypróbuj online!

Łącze monadyczne akceptujące listę liczb całkowitych, która daje listę liczb całkowitych.

W jaki sposób?

Sortuje według wartości porządkowych cyfr liczb całkowitych (gdzie -jest „cyfrą” -1) przekonwertowanych na ciągi znaków przy użyciu znaków o ich 1-modułowym indeksie w magicznym ciągu „murgeon lix”.

Sortowanie jest efektywnie alfabetyczne, gdy spacja jest uważana za mniejszą niż dowolną literę.

Magiczny sznur „murgeon lix” został znaleziony poprzez sprawdzenie słowników Jelly używanych do kompresji. Nie ma słów składających się z 11 liter, które spełniają wymagania (i żadne z nich nie byłyby w przypadku duplikacji). ponieważ spacja sortuje się przed literami, następnym najbardziej oczywistym wyborem jest słowo o długości siedem, po którym następuje spacja, a po nim słowo o długości trzy. „murgeon” i „lix” to jedyna satysfakcjonująca kombinacja, chociaż bez spacji mogą być możliwe inne (np. “£Py:ƥ»„murgeonalix”, który działa dla tej samej liczby bajtów)

Ṿ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")

Poprzednie @ 15 bajtów :

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

Tutaj “¡Zo⁶’Œ?¤znajduje się pierwsza permutacja liczb naturalnych, która znajdowałaby się w indeksie 21 340 640, gdy wszystkie permutacje liczb są sortowane leksykograficznie - co jest [6,10,9,3,2,8,7,1,5,4,11]. ( “¡Zo⁶’jest podstawową reprezentacją 250 21340635, podczas Œ?gdy obliczenia i grupują ¤te instrukcje razem)


Nawet z wyjaśnieniem nie jestem zbyt mądra. Niesamowite rozwiązanie!
maks.

Krótsza wersja jest prawdopodobnie łatwiejsza do zrozumienia!
Jonathan Allan

7

Perl 6 , 30 bajtów

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

Wypróbuj online!

Rozwiązanie portu Ruby dla GB.

Oryginalna 35-bajtowa wersja

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

Wypróbuj online!

Konwertuj każdą liczbę na ciąg, uzyskaj nazwę Unicode każdego znaku, usuń pierwsze słowo („DIGIT” lub „HYPHEN”), a następnie posortuj.


6

JavaScript (SpiderMonkey) , 69 bajtów

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

Wypróbuj online!


Wygląda na to, że możesz usunąć, biorąc pod uwagę +'', że pobierasz dane jako tablicę ciągów.
Shaggy

@Shaggy Już nie biorę strun, ponieważ nie jestem pewien, czy jest to dozwolone tutaj.
Arnauld

Ach ... Masz rację. To doda kilka bajtów do mojego rozwiązania.
Shaggy

6

K (ngn / k) , 21 20 bajtów

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

Wypróbuj online!

{ } funkcja z argumentem x

$ sformatuj jako ciągi znaków

""?-2)63"8"

< obliczyć permutację sortującą rosnąco

x@ argument przy tych indeksach


6

Python 3, 68 bajtów 67 bajtów 64 bajtów

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

Używa wbudowanej sortedfunkcji z anonimową lambda dla klucza. Zakoduj porządek sortowania i porównaj każdą cyfrę w każdej wartości na liście wprowadzania z jej pozycją na liście porządkowania.

Edycja: Zapisano 1 bajt, usuwając 8z listy sortowania, aby skorzystać ze str.findzwrotu, -1gdy parametr nie zostanie znaleziony. Dzięki maxb.

Edycja2: Zapisano 3 bajty, używając składni rozpakowywania oznaczonej gwiazdką w listdosłownym miejscu zamiast listkonstruktora

Wypróbuj online!


1
Czy możesz usunąć pierwsze 8 z ciągu? Ponieważ Python zwraca -1, jeśli nie znaleziono podciągu.
maxb

@maxb Good catch. Edytowany.
mypetlion


5

Pyth, 17 16 bajtów

oxL"54-9176320"`

Spróbuj go online tutaj , lub sprawdzić wszystkie przypadki testowe od razu tutaj .

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)

Zapisano 1 bajt dzięki @ngn i ich odpowiedzi K , pomijając 8 na początku łańcucha słownika


4

Japt, 19 bajtów

ñ_s ®n"54-9176320

Spróbuj


Fajne rozwiązanie! Wprowadzanie jako lista ciągów jest niestety niestety dozwolone.
maxb

Możesz zaoszczędzić trochę przez nadużywanie S.n(s): ñ_s ®n"54-9176320(podobno S.n(s)jest dokładnie taki sam jak w s.b(S)przypadku Sdługości 1, z tym że zwraca 0zamiast -1)
ETHprodukcje

Niezła sztuczka, @ETHproductions, dzięki :) Będę musiał pamiętać o tym na przyszłość.
Shaggy

3

Retina 0.8.2 , 36 bajtów

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

Wypróbuj online! Link zawiera pakiet testowy. Wyjaśnienie:

T`-d`3:598217604

Przetłumacz znak minus i cyfry na ich pozycję w kolejności wymowy, używając :dla 10. pozycji.

O`

Sortuj w kolejności wymowy.

T`3:598217604`-d

Przetłumacz zamówienie z powrotem na oryginalny znak minus i cyfry.



3

R , 58 bajtów

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

Wypróbuj online!

Dane wejściowe to lista liczb, która domyślnie jest konwertowana jako ciąg znaków chartr. ordernastępnie używa kolejności leksykograficznej, aby pobrać kolejność sortowania oryginalnej listy.


3

Java (JDK 10) , 123 bajty

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

Wypróbuj online!

To naiwna implementacja Java. Powinno być dużo gry w golfa.

Kredyty


1
Zmiana .chars-IntStream i .reducedo zwykłego obiegu pozwala zaoszczędzić 2 bajty: n->{var r="";for(var c:(""+n).split(""))r+=10+"854-9176320".indexOf(c);return r;}. Ponadto, można zapisać jeszcze jeden bajt, zmieniając 10+"85na 20+"5, ponieważ .indexOfcyfra for 8spowodowałaby wówczas -1. Wypróbuj online 123 bajty
Kevin Cruijssen


2

Czerwony , 114 bajtów

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

Wypróbuj online!

Bardziej czytelny:

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

2

C ++, 353 bajty

Jest to rodzaj komediowego wpisu, ale marnowałem czas i napisałem go, więc nie mogę tego nie opublikować ... Ciesz się z chichotu i daj mi znać, czy brakuje mi jakichś oszczędnych przestrzeni!

#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," "));}

Wydajność:

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 -9-1 -18 -15 - 14-19-11-11-16-16-13-12-10-107-6-3-338-35-34-39-31-37-36-33-32-30-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


Widzę, że żyjesz również zgodnie z mottem „jeśli nie
nacisnę

1
Hej, nie stać mnie na niepoważne białe znaki w tym języku! Zabawnie jest to robić, ponieważ przez resztę czasu niewiele rzeczy mnie denerwuje, jak otwieranie kodu innych, którzy najwyraźniej myślą, że napisanie przerażającej monolitycznej ściany sprawi, że będą mądrzejsi i / lub aktywnie zadokowani dla każdej nowej linii, którą wpisują.
underscore_d

1
Dzień dobry! Wcisnęliśmy rozwiązanie do 195 znaków
Max Yekhlakov

@MaxYekhlakov Fajnie, dzięki za zastanowienie się! Rozumiem po przeczytaniu nieco więcej; wydaje się, że niekoniecznie dostarczyłem w pełni kompilowalny program, ale tylko funkcje, które przetwarzałyby określone dane wejściowe i wyjściowe. Nie!
underscore_d

2

Mathematica, 68 bajtów

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

Funkcjonować. Pobiera na wejściu listę liczb całkowitych i zwraca posortowaną listę jako wynik. Po prostu oddziela cyfry każdej liczby za pomocą IntegerDigits, konwertuje każdą cyfrę na "zero", "one"itp., Za pomocą IntegerName, konwertuje listę na ciąg znaków oddzielony spacjami StringRiffle, wstawia znak , "m "jeśli liczba jest ujemna, i sortuje na podstawie tego ciągu. Rzeczywiście, było to najkrótsze podejście, jakie udało mi się znaleźć, ponieważ Mathematica natywnie używa sortowania leksykograficznego do list o tej samej długości; dlatego podejście oparte na tym, że 854-9176320zajmuje więcej bajtów, ponieważ funkcje łańcuchowe są tak drogie.


Zawsze ufaj matematyce, że ma kombinację wbudowanych funkcji. Sprytne rozwiązanie!
maks.

1

05AB1E , 15 14 bajtów

Σ•ĆU‘•…54-ìsSk

-1 bajt dzięki @Emigna .

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

Σ                 # 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')

Zobacz moją wskazówkę 05AB1E (rozdział Jak kompresować duże liczby całkowite ), aby zrozumieć, dlaczego tak •ĆU‘•jest 9176320.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.