Переставити число в алфавітному порядку


24

Давши невід'ємне ціле число ( n), створіть функцію, яка повертається nв алфавітному порядку відповідно до буквального написання кожної цифри в n.

Приклади:

Input: 101
>> one, zero, one
>> one, one, zero
Output: 110

Input: 31948
>> three, one, nine, four, eight
>> eight, four, nine, one, three
Output: 84913

Input: 5544
>> five, five, four, four
>> five, five, four, four
Output: 5544

Input: 1234567890
Output: 8549176320

Примітка: операції в прикладі є лише ілюстративними і їх не потрібно включати у висновок. Повертається лише алфавітно-відсортований номер.

Це код-гольф, тому найкоротший код у байтах виграє.

Редагувати: вхід може бути зроблений у будь-якому бажаному форматі, який найкраще відповідає вашій мові, а вихід може бути зроблений аналогічно, повернувшись із функції або друкуючи. Вхід завжди буде натуральним числом (включаючи 0) і не буде містити провідних 0.

Відповідна запис OEIS (A057846), знайдена в @DomHastings


1
Чи можу я також прийняти число як рядок і вивести рядок?
ThreeFx

1
@nimi 00....
TuxCrafting

5
Ви можете уточнити, що введення є в десятковій формі, або ви отримаєте кілька зухвалих відповідей, використовуючи одинакові ...
Martin Ender

6
Це трохи заплутано: ви писали в коментарях, що очікуєте числовий тип як введення та вихід функції, але також, що добре друкувати результат замість цього. Отже, якщо результат є 849, чи означає це , що нам дозволяється друкувати число, 849а не рядок "849"? IMO - це просто громіздкий формат вводу-виводу (погано!), Який є ідеальним завданням.
Лінн

1
Провідні нулі значні чи ні? наприклад, що дає 001результат? Якщо вони значущі, а результату немає 1, то для більшості мов потрібні рядки як вхідні дані для простого факту, це грубо, непрактично і, як правило, неможливо попросити аналізатора зберегти провідні нулі в базових 10 буквальних числах.
кіт

Відповіді:


12

Perl 6 ,  32  28 байт

{+[~] .comb.sort: *.Str.uniname}
{+[~] .comb.sort: *.uniname}

Пояснення:

{
  # turn the following into a Numeric
  +

  # fold the following list using string concatenation operator
  [~]

    # split $_ into individual characters
    # (implicit method call on implicit parameter)
    .comb

    .sort:
    *.uniname # sort by the Unicode name of the character (digit)
}

Тест:

#! /usr/bin/env perl6
use v6.c;
use Test;

my @tests = (
  101 => 110,
  31948 => 84913,
  5544 => 5544,
  1234567890 => 8549176320,
);

# give the lambda a lexical name for clarity
my &int-sort = {+[~] .comb.sort: *.uniname}

plan 3 * @tests;

for @tests -> $_ ( :key($input), :value($expected) ) {
  put '';
  isa-ok $input, Int, "input ($input) is an Int";

  my $output = int-sort $input;

  is $output, $expected, .gist;
  isa-ok $output, Int, "output ($output) is an Int"
}
1..12

ok 1 - input (101) is an Int
ok 2 - 101 => 110
ok 3 - output (110) is an Int

ok 4 - input (31948) is an Int
ok 5 - 31948 => 84913
ok 6 - output (84913) is an Int

ok 7 - input (5544) is an Int
ok 8 - 5544 => 5544
ok 9 - output (5544) is an Int

ok 10 - input (1234567890) is an Int
ok 11 - 1234567890 => 8549176320
ok 12 - output (8549176320) is an Int


8

JavaScript (ES6), 54

Редагуйте таку ж кількість символів, але уникаючи глобальної змінноїz

Введення / виведення у вигляді рядків

n=>[...n].sort((a,b)=>n[a]-n[b],n='9487216503').join``

Тест

f=n=>[...n].sort((a,b)=>n[a]-n[b],n='9487216503').join``

function test() {
  O.textContent=f(I.value)
}

test()
<input id=I type=number value=31948 oninput='test()'>
<pre id=O></pre>


2
Любіть це, використовуючи вхідні цифри як індекси рядка z...
Дом Гастінгс

6

Haskell, 62 51 44 байт

Як запропонував @nimi, використання розуміння списку коротше, ніж функції складання:

f x=0+read[a|a<-"8549176320",b<-show x,a==b]

Для довідки моя версія:

f n=read.(=<<)(\x->filter(==x)$show n)$"8549176320"

Версія pointfree трохи довша:

f=flip(read.)"8549176320".(=<<).flip(filter.(==)).show

Відразу: відфільтруйте цифри у правильному порядку, а потім з'єднайте результат.


5

Pyth, 12 10 байт

ox`C" Ȁ\0

Не впевнений, чи можна далі грати в гольф. Вхідні дані повинні бути укладені в лапки.

2 байти збережено завдяки @isaacg!

У пітонічному псевдокоді:

                Q = input()
o          Q    sort(Q, key = lambda N:
  `C" Ȁ\0        repr(base256toDec(" Ȁ\0"))
 x        N         .index(N)     # 8 being absent from the number yields -1
                )

Перевірте це тут .


@busukxuan Я також отримую 14 байт : p.
Аднан

@Adnan повернутися до чисел тоді. Здається, немає способу стиснути ці цифри ...
busukxuan

2
Збережіть 2 байти, замінивши 549176320наC" »Ä\0
isaacg

@isaacg Дякую! Я кілька разів намагався перетворити його на базу 256, але результат був неправильним. Як ти це зробив правильно?
busukxuan

1
Вам слід уникнути нульових байтів, замінивши їх на \0. Мабуть, це проблема, з якою ви стикалися.
isaacg

4

Perl, 37 байт

36 байт код + 1 байт командного рядка (-F)

say sort{8549176320=~/$b.*$a/||-1}@F

Приклад використання:

echo -n "04823" | perl -F -M5.010 entry.pl


3

Желе, 11 байт

“U1°ŀ”OṾf@€

Спробуйте тут.

Пояснення

“U1°ŀ”O       Get the Unicode ordinals of “U1°ŀ”
                (all of which are coincidentally single bytes
                in the Jelly code page!)
              The result is [85, 49, 176, 320].
       Ṿ      Uneval. This gets us the string “85,49,176,320”.
        f@€   For each char in this string, extract all chars
                from the first command line argument that
                equal it.

3

Математика 35 78 47 байт

31 байт збережено завдяки пропозиції LIAMnYP!

FromDigits@SortBy[IntegerDigits@#,IntegerName]&

IntegerDigitsрозбиває число на цифри, які потім сортуються відповідно до їх імен англійською мовою. FromDigitsзбирає цифри в число базової-10.


FromDigits@SortBy[IntegerDigits@#,IntegerName]&[1234567890]

8549176320


Використовуючи "SortBy", у вас немає проблеми з перетворенням слів у цифри. FromDigits@SortBy[IntegerName]@IntegerDigits@#&
LLlAMnYP

Також Interpreterболісно повільно, тому це додатковий бонус.
LLlAMnYP

Фантастичне вдосконалення.
DavidC

11 байт у Mtmca, коли б це не виникло.
Майкл Стерн

3

С, 142 141 117

Передати параметр long long *до f(); функція змінює параметр:

f(long long*n){char*c="8549176320",g[10]={0};for(;*n;*n/=10)++g[*n%10];for(;*c;++c)for(;g[*c-48]--;*n=*n*10+*c-48);}

long longПотрібно, оскільки останній тестовий випадок переповнюється intпри сортування.


2

Python 2 - 95 байт

def s(n):
    l=list("8549176320")
    return "".join(sorted(list(n),key=lambda x: l.index(x)))

Спроба подальшого гольфу ... Я вважаю, що рядок 2 є непотрібним, і це може стати 1 лямбда.

EDIT: 49 версія версії в коментарях, thx для xnor та vaultah для допомоги.


lambda n:''.join(sorted(`n`,key="8549176320".find))
vaultah

4
@vaultah Приємне рішення, ви повинні розмістити його! Я думаю, що ви можете опустити 8так, що findдає -1.
xnor

1
о, це розумно @xnor. Найкоротший, що я отримав, це lambda n: "".join(sorted(n,key="549176320".find)), що насправді схоже на те, що ви запропонували, vaultah. Ви повинні розмістити його!
Джеремі

1
@Jeremy Ви повинні відредагувати цю версію у своєму дописі.
DJMcMayhem

2
Принаймні позбудьтесь зайвого пробілу ... Відступ можна зробити за допомогою одного простору. Також це недійсно, оскільки в ОП було вказано, що вихід повинен бути числовим типом.
Мего

2

- Oracle 11 (SQL): 164 байти

  SELECT LISTAGG(DECODE(s,0,'zero',TO_CHAR(TO_DATE(s,'j'),'jsp')),',')WITHIN GROUP(ORDER BY 1)FROM(SELECT SUBSTR(&1,level,1)s FROM dual CONNECT BY LEVEL<=LENGTH(&1));

Довга форма та пояснення

  SELECT LISTAGG(DECODE(s,0,'zero',TO_CHAR(TO_DATE(s,'j'),'jsp')),',') WITHIN GROUP (ORDER BY 1)
  FROM ( SELECT SUBSTR(&1,level,1)s FROM dual
           CONNECT BY LEVEL <= LENGTH(&1)
        );

Отримайте вхід як параметр сценарію:

  SELECT &1 FROM dual

"Створити" рядки за допомогою з'єднання на основі довжини введення:

  CONNECT BY LEVEL <= LENGTH(&1)

Викопуйте кожну цифру з рядка для кожної позиції:

  SELECT SUBSTR(&1,level,1)s FROM dual

Перетворіть цифру в дату Джуліана та поверніться до Char, щоб отримати правопис:

  TO_CHAR(TO_DATE(s,'j'),'jsp')

Перевірка на нуль - спеціальний випадок.

  DECODE(s,0,'zero'

Використовуйте функцію LISTAGG для об'єднання рядків у єдиний список рядків, розділених комами, впорядкованих за алфавітом

  LISTAGG(DECODE(s,0,'zero',TO_CHAR(TO_DATE(s,'j'),'jsp')),',') WITHIN GROUP (ORDER BY 1)

Завжди цікаво намагатися налаштувати SQL на такі речі ... :) дійсно перевіряє мої знання про помилку ...



1

Ракетка, 142 130 байт

(λ(n)(string->number(list->string(sort(string->list(~a n))char<? #:key(λ(m)(string-ref "9487216503"(-(char->integer m)48)))))))

З них конверсій більше , ніж майже половина довжини ( 76 64 байт).


(+ 1 answer)для Ракетки!
кіт

@cat Для мене корисно продовжувати практикувати Ракетку, оскільки це спосіб зберегти знання з функціонального програмування під час роботи над цими жахливо процедурними застарілими програмами Java (і трохи менш застарілими Python), які мені залишили мої колеги. Я міг би розійтися про те, як наявність об'єктів не обов'язково робить програму орієнтованою на об'єкт, але замість цього я просто тримати проблеми з гольфом подалі від Ракетки.
Стівен Х.

Хм ... я, безумовно, співчуваю, і можна і весело писати функціональний Python, але Java просто Fawful. Можливо, ви можете змусити ваших начальників дозволити вам використовувати Scala для реалізації та Java як клей. :)
кіт

До речі, якщо вам подобається Forth і ваші очі трохи втомлюються від читання Lisp зсередини, вам слід перевірити Фактор , який є Lisp та CLOS, але в поштовій формі і не маскує Forth-y.
кіт

1

TSQL, 260 байт

Використовується перевернутий сортування міхура, щоб уникнути зміни довжини, щоб зберегти кілька байт

Гольф:

DECLARE @ varchar(99)=101

,@i INT=99,@j INT=98WHILE @i>1SELECT
@=IIF(CHARINDEX(x,'598327614')>CHARINDEX(y,'598327614'),STUFF(STUFF(@,@j,1,x),@i,1,y),@),@i-=IIF(@j=1,1,0),@j=IIF(@j=1,@i,@j-1)FROM(SELECT
SUBSTRING(@,@i,1)x,SUBSTRING(@,@j,1)y)z
PRINT @

Безголівки:

DECLARE @s BIGINT=1234567890

DECLARE @ char(99)=@s,@i INT=99,@j INT=98
WHILE @i>1
  SELECT 
    @=IIF(CHARINDEX(x,'236719458')>CHARINDEX(y,'236719458'),
        STUFF(STUFF(@,@j,1,x),@i,1,y),@), 
    @i-=IIF(@j=1,1,0),
    @j=IIF(@j=1,@i,@j-1)
  FROM(SELECT SUBSTRING(@,@i,1)x,SUBSTRING(@,@j,1)y)z
PRINT CAST(@ as bigint)

Наполягаючи на використанні цілих типів як введення та виводу, додано 37 байт


DECLARE @ varchar(99)=1010.o 101перетворюється на рядок автоматично?
кіт

Також stuffє об'єктивно жахливою назвою функції. squashабо shoveабо packкраще: P
кіт

@cat так, він перетворюється в рядок автоматично, але це було б обманом згідно опису. Я згоден, речі - це дурне ім'я
t-clausen.dk

1
Я маю на увазі, ми можемо просто називати кожну функцію, stuffтому що саме це роблять функції: вони роблять щось. Тоді ваш код може виглядати такstuff(stuff(4, 5, stuff), stuff(stuff()).(stuff())()); stuff(stuff)
кіт

1

ClojureScript, 45 байт

#(apply str(sort-by(vec"9487216503")(str %)))

Використовується деяка гнучка конвертація string-> int від витоку Javascript через, тому це недійсне Clojure.


1

Жар-птиця, 317 байт

Гольф:

select list(s,'')from(with recursive q as(select 1 p,substring(:a from 1 for 1)s from rdb$database q union all select q.p+1 p,substring(:a from q.p+1 for 1)s from q where q.p<char_length(:a))select s from q order by iif(s=8,0,iif(s=5,1,iif(s=4,2,iif(s=9,3,iif(s=1,4,iif(s=7,5,iif(s=3,7,iif(s=2,8,iif(s=0,9,6))))))))))

Безголівки:

select list(s, '')
from (
   with recursive q as (
      select 1 as p, substring(:a from 1 for 1) s
      from rdb$database q
      union all
      select q.p + 1 as p, substring(:a from q.p + 1 for 1) as s
      from q
      where q.p < char_length(:a)
   )
   select s
   from q
   order by iif(s = 8, 0,
               iif(s = 5, 1,
                  iif(s = 4, 2,
                     iif(s = 9, 3,
                        iif(s = 1, 4,
                           iif(s = 7, 5,
                              iif(s = 3, 7,
                                 iif(s = 2, 8,
                                    iif(s = 0, 9, 6)))))))))
)

У Firebird немає розділених функціональних можливостей. Натомість я створив рекурсивний запит, щоб отримати наступний символ знову і знову. Потім перебирайте їх під час сортування за власним замовленням. Нарешті об'єднайте ці результати разом у список. Замініть роздільник комами за замовчуванням на порожній. Я міг би зберегти 11 байт, створивши нову макетну таблицю замість, rdb$databaseале вважав, що це може суперечити правилам.


1

ZX Spectum, код машини, 53 48 47 45 44 байт

    org 49200 ; #c030

; table converts ascii to alfabetical order
; start from BASIC with any number as : PRINT "1234567890" AND USR 49208

convtab defb 249 ; zero defb 244 ; one defb 248 ; two defb 247 ; three defb 2+205 ; four defb 1+205 ; five defb 246 ; six defb 245 ; seven ; defb 0 ; eight ; defb 3 ; nine ; last 2 conversions hidden in call-command

start Call #2bf1    ; fetch stackindex
    call #2ab2 ; store back
    ld h,#c0    ; set highbyte of table


Sort Push de
loop ld b,d
    ld c,e
    inc de
    ld a,(bc)   ; fetch number
    Ld l,a
    ld a,(de)
    cp 34       ; endmarker "
    Jr z,exit   ; end reached?
    push hl     ; save number
    ld l,a
    Ld a,(hl)   ; convert second number
    pop hl
    cp (hl)     ; compare numbers
    jr nc,loop  ; in order, no swap
swap ld a,(bc)  ; swap original numbers
    ld l,a
    ld a,(de)
    ld (bc),a
    ld a,l
    ld (de),a
Exit pop de
    Ret z
    jr sort     ; check number for order


З сортуванням Gnome його можна скоротити, а таблиця може бути на 1 байт коротше. Приходить нова версія ...
Йоган Коельман

Сортування Gnome тут довше, але інші оптимізації.
Йоган Коельман

0

Фактор, 128

[ 10 base> [ 48 - ] { } map-as dup [ number>text ] map zip [ second first ] sort-with [ first ] map [ 48 + ] ""map-as 10 >base ]

Ура для вбудованих! : D


0

PHP, 126 байт

Наскільки я знаю, php не має вбудованих програм, які б справді допомогли в цьому (найкраще, що я міг би зробити за допомогою usort (str_split ()), був на 5 байт довше), тому єдине, що я радий у цій відповіді - це ігри, що граються за допомогою $ i, щоб зберегти пару байт на ітерації.

<?php for($i=-1;$i<9;)$a[++$i]=preg_replace("/[^$i]/","",$argv[1]);array_multisort([9,4,8,7,2,1,6,5,0,3],$a);echo implode($a);

0

APL, 23 байти

{⍎n['8549176320'⍋n←⍕⍵]}

Пояснення:

  • n←⍕⍵: отримати представлення рядка nта зберегти йогоn
  • '8549176320'⍋: знайти перестановку подібних nтипів, nзаданих наказом8549176320 .
  • n[... ]: переупорядкуватиn цю перестановку
  • : оцініть результат (щоб перетворити його на число)

Оскільки рядки вводу / виводу можуть бути рядками, ви можете видалити та . Перетворити в tradfn видалення {і }та підставивши для . Нарешті, видаліть їх 0як незареєстровані в кінці:n['854917632'⍋n←⍞]
Adám

0

Clojure, 53 байти

Ну, ідея розуміння списку з рішення Haskell здається найкоротшою:

#(apply str(for[p"8549176320"b(str %):when(= p b)]p))

Мій оригінальний підхід на 1 байт довший:

#(apply str(sort-by(zipmap"549176320"(range))(str %)))

Ви можете ознайомитися з обома функціями в Інтернеті тут: https://ideone.com/afac5n


0

Загальна Лісп, 104

(lambda(n)(#1=parse-integer(sort(format()"~A"n)'string<= :key(lambda(u)(format()"~R"(#1#(string u)))))))

Безумовно

(lambda (n)
  (parse-integer
   (sort (format nil "~A" n)
         #'string<=
         :key (lambda (u) (format nil "~R" (parse-integer (string u)))))))

Перетворити ціле число у рядок, сортувати символи, використовуючи string<=порівняння, використовуючи користувацьку :keyфункцію, яка перетворює заданий символ у англійське представлення числового значення, яке він представляє. Зазвичай я б не використовував ключову функцію, яка виконує стільки, скільки ця, але вона коштує менше в байтах, ніж прикрашати / сортувати / не підкреслювати.


0

Пітон 3, 234 байти

Це прямий переклад моєї відповіді "Фактор" , просто для розваги.

def f(n):
 s=list(map(int,str(n)))
 return int("".join(list(map(str,list(map(lambda x:x[1],sorted(list(zip(list(map(lambda t:{0:"zero",1:"one",2:"two",3:"three",4:"four",5:"five",6:"six",7:"seven",8:"eight",9:"nine"}[t],s)),s)))))))))

Семантика оцінки "ледачих" карт та поштових об'єктів - це найтонший, важко знайти, що викликає клопів, справжній екскремент коня у Всесвіті. Іноді, s = map(f, x)не дозволяють sвикористовувати їх належним чином або взагалі.




0

Python 2.7.11, 67 байт

lambda n:''.join(sorted(list(n),key=lambda s:"9487216503"[int(s)]))

Приймає рядок як вхідний і виводить рядок.


0

Python 3, 74 байти

lambda x:''.join(i[1]for i in sorted(['9487216503'[int(j)],j]for j in x))

Можливо, вам вдасться зберегти кілька байтів, використовуючи лямбда
Даніель

0

PHP , 107 байт

function($a){usort($a,function($a,$b){return($z=array_flip([8,5,4,9,1,7,6,3,2,0]))[$a]-$z[$b];});return$a;}

Спробуйте в Інтернеті!

Для налаштування порядку сортування використовується визначена користувачем функція порівняння.

Вихідні дані

101         110
31948       84913
5544        5544
1234567890  8549176320
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.