Alfabetyczne liczby całkowite


19

Alfabetyczne liczby całkowite

Dla danego zestawu liczb ułóż je w kolejności alfabetycznej, gdy zostaną przeliterowane (tj. 1: jeden, 2: dwa, 90: dziewięćdziesiąt, 19: dziewiętnaście). Twój kod powinien działać dla zakresu [-999999, 999999]. Dane wyjściowe muszą mieć ogranicznik między liczbami. Spacja będzie działać, podobnie jak spacja i przecinek, jak pokazano w poniższych przykładach. Dane wejściowe mogą być tablicą liczb całkowitych, ciągiem liczb rozdzielanych lub w zależności od potrzeb. Zakłada się, że wszystkie liczby całkowite są unikalne.

Liczby nie są dzielone według celów tego wyzwania, a spacje są alfabetycznie przed innymi znakami. Przyjmuje się, że liczby ujemne są wyrażane za pomocą słowa minus. Na przykład fourpoprzedza, four thousanda liczba -40jest sortowana za pomocą łańcucha minus forty. Załóżmy, że wszystkie liczby będą się składać wyłącznie ze słów liczbowych i bez spójników (np. Użyj two thousand forty twozamiast two thousand and forty two).


Przypadki testowe

Liczby całkowite jednocyfrowe:

Wejście:

1, 2, 3, 4, 5

Wynik:

5, 4, 1, 3, 2

Wielocyfrowe liczby całkowite:

Wejście:

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

Wynik:

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

Odstępy między słowami, bez myślników, przecinków lub „i”:

Wejście:

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

Wynik:

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

Pamiętaj, to jest , więc wygrywa kod z najmniejszą liczbą bajtów. Niedozwolone są luki!


Oto link do odpowiedniego postu w piaskownicy.
wubs,

Czy dane wejściowe będą zawierać więcej niż jedną liczbę całkowitą?
ETHproductions

@ETHproductions Nie, nie będzie. Sprecyzuję to w pytaniu.
wubs,

8
Witamy w PPCG. Niezły awatar. : D Ładne pierwsze pytanie.
AdmBorkBork,

@TimmyD Dzięki! Z niecierpliwością czekam na PowerShell-ing wszystko, co mogę tutaj.
wubs,

Odpowiedzi:


5

JavaScript (ES6), 189 179 186 bajtów

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>

Podstawową ideą jest konwersja każdej liczby wejściowej na krótki ciąg znaków, który ma prawidłową pozycję leksykalną w porównaniu do wszystkich innych par ciągów liczbowych. Oto użyty słownik: (Nie uruchamiaj fragmentu; służy on tylko do ukrywania długiej listy).

Stwarza to bardzo zwięzły sposób przyporządkowania każdej liczby do jej poprawnej leksykograficznie pozycji. Tak właśnie qdziała funkcja rekurencyjna :

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]

Na 0początku łańcucha ma zapewnić, że np. 100 ( one hundredprzekonwertowane na PK0) zostanie posortowane przed 101( one hundred oneprzekonwertowane na PKP). Stwarza to dziwny scenariusz, w którym 0 ( zero) jest sortowane na początku tablicy, więc aby to obejść, w funkcji sortowania najpierw sortujemy zera za pomocą !x-!y||(....


Wygląda na to, że to nie działa [1100, 1000]. Oczekiwałbym, że dane wyjściowe będą 1000 (one thousand), 1100 (one thousand one hundred), ale dane wyjściowe są tej samej kolejności co dane wejściowe.
mleko

@ mleko Hmm ... Nie jestem pewien, dlaczego tak się dzieje, ale przyjrzę się temu.
ETHproductions

@ mleko Ah, 1000jest analizowane jako one thousand zero; Zaraz to naprawię. Czy jednak musimy wspierać 0samodzielnie? To wyjątkowy przypadek, który doda około 15 bajtów do mojego kodu.
ETHproductions

11

Poinformuj 7, 214 201 118 bajtów

Inform 7 to absolutnie okropny język do gry w golfa, więc chciałem dać temu szansę.

Wcięcie powinno używać \tznaków tab ( ), ale HTML ich nie lubi. I odwrotnie, Inform nie lubi spacji dla wcięć, więc będziesz musiał zastąpić spacje tabulatorami, jeśli skopiujesz i wkleisz kod z tego miejsca, aby go przetestować. Lub po prostu skopiuj i wklej ze źródła Markdown.

Gra w golfa:

Do X:
    powtórz przez tabelę 1:
        teraz wpis Q to „[wpis R w słowach]”;
    sortuj tabelę 1 w kolejności Q;
    powiedz „[R w tabeli 1]”.

Dane wejściowe powinny być tabelą Inform, taką jak ( \tmiędzy kolumnami):

Tabela 1
R (liczba) Q (tekst)
-1002
5
435012
4
23
81
82

Wynik:

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

Ta funkcja jest uruchamiana raz w tabeli, dodając tekstową reprezentację każdej liczby w nowej kolumnie. Następnie sortuje wiersze tabeli zgodnie z kolumną tekstową; w Inform, ciągi są sortowane leksykograficznie. Na koniec drukuje oryginalną kolumnę w nowej kolejności. Dogodnie, „surowy, ale czasem użyteczny” format Inform 7 do drukowania kolumn tabeli okazuje się być oddzielony przecinkami, dokładnie zgodnie z żądaniem.

Nie golfowany, z płytą grzewczą pokazującą, jak wywołać funkcję:

Aby wydrukować liczby w kolejności alfabetycznej:
    powtórz w Tabeli liczb sortowalnych:
        teraz nazwa to „[wpis indeksu słownie]”;
    posortuj tabelę numerów sortowalnych według nazw;
    powiedz „[kolumna indeksu w tabeli liczb sortowalnych]”.

Tabela liczb do sortowania
indeks (numer) nazwa (tekst)
-1002
5
435012
4
23
81
82

Jest pokój.
Kiedy rozpocznie się gra: wydrukuj liczby w kolejności alfabetycznej.

1
Trochę mnie to zagubiło. Czy wordsodniesienie do przeliterowanych wersji liczb jest wbudowane w Inform 7?
Pavel

1
@Pavel Rzeczywiście! „(liczba) słownie” zwraca ciąg znaków z tekstową reprezentacją liczby. Dogodnie używa „minus” dla liczb ujemnych i chociaż umieszcza łączniki między słowami, robi to konsekwentnie i alfabetycznie łączniki przed wszystkimi literami (więc wynik końcowy jest taki sam).
Draconis,

2
+1 za wybór języka. Muszę jednak sprawdzić, ale podejrzewam, że zostały jeszcze pewne możliwości gry w golfa; na przykład, czy analizator składni naprawdę wymaga wszystkich tych „artykułów”? I trzeba by zapytać OP, ale nie widzę żadnego oczywistego powodu, dla którego „i” nie byłyby prawidłowym separatorem. Nawet jeśli nie, jedno miejsce jest wyraźnie dozwolone, więc say "[R entry] "powinno wystarczyć.
Ilmari Karonen,

Powiedziałbym, że „i” na końcu jest w porządku. Nie powiedziałem, że separatory muszą być jednolite, więc jest to całkowicie akceptowalna odpowiedź. Gdybym mógł dać punkty za najciekawszą odpowiedź, dałbym to tobie. Bardzo podoba mi się czytelność tego języka, nawet golfa. Dobra robota!
wubs

W końcu miałem okazję zagrać trochę z Inform7 i udało mi się ponownie zagrać w golfa na twoim wejściu do zaledwie 118 bajtów. Ponieważ zamieszczanie kodu Inform w komentarzach nie działa zbyt dobrze, poszedłem do przodu i bezpośrednio go edytowałem. Mam nadzieję, że nie masz nic przeciwko, przywróć i / lub popraw moje zmiany w dowolny sposób, jeśli chcesz.
Ilmari Karonen,

4

Mathematica, 67 bajtów

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

Nienazwana funkcja przyjmująca listę liczb całkowitych jako argument i zwracająca listę liczb całkowitych jako wartość. #~IntegerName~"Words"jest wbudowanym, który zmienia liczbę całkowitą na nazwę w języku angielskim. IntegerNameczasami ma w przecinku przecinki i myślniki, więc StringReplacepołączenie się ich pozbywa. (Niestety, myślnik jest w rzeczywistości 3-bajtowym znakiem 8208 w UTF-8). Następnie SortBysortuje oryginalną listę alfabetycznie według wartości zmodyfikowanej nazwy całkowitej.

Niezły zbieg okoliczności: IntegerNameużywa negativezamiast minusw danych wyjściowych - ale żadne słowo pojawiające się w nazwach dowolnych dozwolonych liczb nie występuje alfabetycznie między tymi dwoma słowami, więc nie jest wymagana zamiana!

(Czapka dla ngenisis za przypomnienie mi Sortby.)


Sława! Bardzo zbliżyłem się do tego rozwiązania, ale ta myśl sprawiła mi ból głowy!
ngenisis,

Czy twoja odpowiedź tutaj faktycznie używa poprawnego łącznika? Jeśli skopiuję to, co tu masz, do Mathematiki, nie zastąpi to łączników IntegerName. Dokumentacja Wolfram mówi, że jest to znak Unicode 2010 .
ngenisis,

Prawdopodobnie więc nie… Próbowałem uzyskać poprawny łącznik w tej odpowiedzi, ale wygląda na to, że mi się nie udało.
Greg Martin

Przetnąłem twoją odpowiedź na pół;)
J. Antonio Perez

A potem ... wprowadzasz niepotrzebne modyfikacje łańcucha.
J. Antonio Perez,

4

Bash + GNU utils + bsdgames, 52

  • 4 bajty zapisane dzięki @izabera.
sed 's/.*/echo `echo &|number`:&/e'|sort|sed s/.*://

I / O to linie rozdzielane znakiem nowej linii.

  • Pierwsze wyrażenie sed zastępuje każdą liczbę liczbową poleceniem powłoki, które wypisuje postać słowa liczby (podaną przez narzędzie bsdgamesnumber ), a :następnie następującą po niej postać liczbową liczby.
  • To jest następnie sorted.
  • Następnie drugie sedpaski prowadzą znaki do znaku włącznie :, pozostawiając postać numeryczną posortowaną według potrzeb.

numberpoprawnie obsługuje „minus”, a jego wynik jest wystarczająco zbliżony do określonego formatu, który sortdziała zgodnie z wymaganiami. Wyprowadza „czterdzieści cztery” zamiast „czterdzieści cztery”, ale z punktu widzenia sortowania nie powinno to mieć znaczenia.

Pakiet bsdgames może wymagać instalacji:

sudo apt-get install bsdgames

Narzędzia sedi sortprawie na pewno są już w twojej dystrybucji.


-t:jest bezużyteczny i możesz użyćnumber<<<&
izabera

@izabera Tak - dzięki - usunąłem -t:. Jednak efunkcja val seda uruchamia polecenia za pomocą sh, więc takie funkcje bash jak <<<nie będą działać.
Cyfrowy uraz

to działa dobrze, dopóki twój sh to bash: P
izabera

@izabera Nope - jeśli bash jest tak rozpoczęty, jak shto tylko możliwe, aby emulować Posix sh, co oznacza, że ​​bashizmy takie jak <<<są wyłączone. GNU sed„s eval funkcja uruchamia polecenia ze /bin/sh -c ...nie /bin/bash -c .... Próbowałeś tego?
Digital Trauma,

bash nigdy się nie wyłącza <<<, nawet w trybie posix
izabera

1

Python + odmiana, 97 91 89 bajtów

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

Wykorzystano inflectbibliotekę do przekształcenia wordstablicy liczb całkowitych w ich reprezentację fonetyczną / łańcuchową. Przechowywane w słowniku par k / v, gdzie klucze były reprezentacją liczbową, a wartości reprezentowały ciąg znaków. Zwrócono listę kluczy posortowaną według wartości.

EDYCJA: Zaoszczędź 5 i 3 bajty dzięki ETHproductions i Alex.S!


Witamy w PPCG! Możesz zagrać w golfa, usuwając spacje ; na przykład druga linia może być a={x:inflect.engine().number_to_words(x)for x in words}.
ETHproductions

Możesz zapisać dwa bajty, używając from inflect import*i wyrzucając inflect.w drugim wierszu.
Alex.S

Niestety wygląda na to, że to również nie sortuje poprawnie listy 40, 44, 40000, 40804, 40004, 40204 (która powinna pozostać w tej kolejności).
Ilmari Karonen,

0

Mathematica, 30 bajtów

Poniższa odpowiedź generuje czystą funkcję, która pobierze listę liczb całkowitych jako dane wejściowe i posortuje je według nazwy alfabetycznej. Właśnie to, co zamówił lekarz;)

SortBy[#~IntegerName~"Words"&]

Oto wersja bez golfa:

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

A oto przykładowe użycie:

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

Które można również zapisać jako

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

Wytwarzają identyczne wyniki - w matematyce f[x]jest równoważne f@x.

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

Istnieje znacznie dłuższa odpowiedź, którą inny użytkownik opublikował w Mathematica. Ta odpowiedź próbuje poprawić niewielkie różnice między sposobem, w jaki matematyka alphebatuje liczby, aby lepiej dostosować się do sposobu, w jaki podane liczby OP powinny być alphebatowane, jednak rzeczy, dla których poprawiają, nie wpływają na porządek sortowania, a moja odpowiedź wychodzi identycznie do ich:

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

Świetne śledztwo! - niestety tak naprawdę nie wydają tego samego zamówienia. TheirFpoprawnie sortuje 888 przed 880 000, podczas gdy MyFnie. Prawdopodobnie problem dotyczy kopiowania i wklejania dziwnego łącznika: Twoja wersja TheirFprawdopodobnie zastępuje zwykłe łączniki (których nie ma), podczas gdy rzeczywista wersja zastępuje dziwny 3-bajtowy łącznik Unicode. (Ciekawe byłoby, czy usunięcie przecinków jest konieczne.)
Greg Martin,

Testowałem to na Range [999999]. Wygląda na to, że wyeliminowanie przecinków jest niepotrzebne, ale zastąpienie „[Łącznika]” przez „” jest zdecydowanie konieczne.
ngenisis

0

Common Lisp, 113 bajtów

Nie są potrzebne biblioteki zewnętrzne.

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

Wyjście, jeżeli xjest '(1 2 3 4 5):

(5 4 1 3 2)
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.