Сортировать по тому, что описывают пары цифр

17

Учитывая положительное целое число, мы можем сформировать новое число, которое описывается его цифрами, взятыми попарно (с добавлением начального 0 для чисел с нечетным числом цифр).

Например:

  • 1234 можно прочитать как один 2, три 4 с, так что для 1234 выводится 2444.

  • 643 имеет нечетное число цифр, поэтому добавляется начальный ноль, чтобы сделать его четным. Тогда 0643 можно прочитать как: ноль 6 с, четыре 3 с, следовательно, результат будет 3333.

(Это OEIS A056967 ).

Задача: по массиву натуральных чисел отсортировать их по значению, описанному парой цифр, в порядке возрастания. Порядок не имеет значения между входными числами, которые приводят к одному и тому же значению.

Ввод : массив / список / набор натуральных чисел. Начальные нули на входе не допускаются и вводятся в виде строк / списков цифр / и т. Д. не допускаются - входные данные должны быть настолько близки к целочисленному / числовому типу, насколько ваш язык способен использовать.

Выход : массив, отсортированный вышеупомянутым способом, возвращаемый любым из обычных способов (функция возвращает значение / STDOUT / выкрикивая в пустоту / и т.д.). Вы можете распечатать их по отдельности, вернуть их в виде чисел, строк или списков цифры.

Контрольные примеры

Input 
Output

[19, 91, 2345, 2023]
[19, 2023, 2345, 91]

[25257, 725, 91, 5219, 146125, 14620512]
[725, 5219, 14620512, 91, 146125, 25257]

[123130415 3335 91 111111111 528 88]
[528, 111111111, 123130415, 3335, 88, 91]

[1 21 33 4 5]
[1 4 5 21 33]

[3725, 10, 2537, 1, 1225, 2512]
[10, 1, 1225, 2512, 2537, 3725]

[125, 26, 1115, 1024] 
[1115, 1024, 125, 26]

(В 4-м тестовом случае 1, 4 и 5 все оцениваются в 0, и поэтому могут быть отсортированы между собой в любом порядке. Аналогично в пятом тестовом случае 10 и 1 оба оценивают в 0, и поэтому могут быть отсортированы в либо заказ.)

(Связанный: Скажите, что вы видите , Один 1, Два 1, Один 2 Один 1

Спасибо Кевину Круйссену за помощь в прояснении вопроса в Песочнице.

sundar - Восстановить Монику
источник
2
Можем ли мы взять список списков цифр в качестве входных данных? Можем ли мы вывести список списков цифр?
г-н Xcoder
@ Mr.Xcoder Ввод должен быть в виде списка целых чисел, а не списков цифр. Выводом может быть список списков цифр, если это как-то удобнее.
sundar - Восстановить Монику
как указано @mnel, мой ответ не будет работать для чисел выше 10 цифр. законно ли хранить его как есть, или я должен изменить его по цене 32 байта.
JayCe
@JayCe Если я правильно понимаю, ограничение заключается в том, что это предел целочисленного типа в R - потому что strtoiвозвращает целое число - правильно? Если так, то все нормально, это законно, как есть.
sundar - Восстановить Монику
ты прав! сохранит это как есть.
JayCe

Ответы:

5

APL (Dyalog) , 26 байтов

Спасибо ngn за сохранение 1 байта :)

{⍵[⍋⌽↑,⍨⌿⍴⌿0 10⊤⍵⊤⍨⍴⍨100]}

Попробуйте онлайн!

Вдохновение взять от Дзайма и Нгн

H.PWiz
источник
100⊥⍣¯1⊢⍵-> ⍵⊤⍨⍵/100работает на 26.
JSLIP
Я действительно не хочу WSFULL в данных тестовых случаях
H.PWiz
26 возможно с MAXWS = 1M
ngn
100⊥⍣¯1⊢⍵->⍵⊤⍨⍴⍨100
нгн
1
@ H.PWiz, а вот другое решение для 26 байтов:{⍵[⍋⌽↑,⍨⌿⍴⌿⊃⊥⍣¯1/10 100⍵]}
ngn
3

R , 141 байт

(s<-scan(,""))[order(strtoi(sapply(s,function(x)paste(strrep((m=matrix(c(if(nchar(x)%%2)0,el(strsplit(x,""))),2))[2,],m[1,]),collapse=""))))]

Попробуйте онлайн!

Довольно трудоемкий ответ - но он работает на всех тестовых примерах. Создает вывод пары цифр и сортирует вход в соответствии с этим.

Jayce
источник
Я опубликовал свой подход в другом ответе, так как я работал над ним сегодня днем, но меня прервали. Просто чтобы заверить вас, я не получил от вас вдохновения без кредитов;)
digEmAll
@digEmAll не беспокойтесь :) - На самом деле, я думаю, что я взял имя vдля переменной из ваших других ответов - я никогда не использовал vраньше. И хорошее использование intToUtf8 !
JayCe
ахах, я действительно завидую своим именам переменных из одной буквы! Нет, серьезно ... приходя из StackOverflow каждый раз, когда я выкладываю "похожую" альтернативу, это похоже на воровство;)
digEmAll
strtoi вернет NA для целых чисел более 10 цифр (as.numeric не будет)
mnel
@mnel спасибо за указание! Я проверил с помощью sundar, и так как это ограничение целочисленного типа, я могу оставить все как есть :)
JayCe
3

R , 120 байт

(v=scan())[order(sapply(v,function(n,e=nchar(n))sum((a=rep((x=n%/%10^(0:(e-1-e%%2))%%10)[!0:1],x[!1:0]))*10^seq(a=a))))]

Попробуйте онлайн!

  • -11 байт благодаря «арифметическому» предложению @sundar!

Разоблаченный код с объяснением:

# define a function G which takes a number 'n' and uncompress it multiplied by 10
# e.g. 2735 -> 775550, 61345 -> 355550 etc.
G=function(n){
  e = nchar(n)                   # get the n.of digits in the compressed number

  x = n%/%10^(0:(e-1-e%%2))%%10  # split 'n' into vector of digits reversed adding 
                                 # trailing zero if 'e' is odd (e.g. 123 -> c(0,3,2,1))

  even = x[!0:1]                 # take only the odd elements of 'x' (= even digits)
  odd  = x[!1:0]                 # take only the even elements of 'x' (= odd digits)
                                 # N.B. :
                                 # these tricks work because !0:1 is c(TRUE,FALSE)
                                 # and V[c(TRUE,FALSE)] exploits the fact that R 
                                 # automatically recycles the logical indexes up to the
                                 # length of the vector V

  a = rep(even,odd)              # repeat each value in 'even' 'odd' times obtaining the
                                 # uncompressed number as digits vector. Note that in
                                 #  case of single digit 'n', 'a' will be an empty vector

  sum(a*10^seq(a=a))             # multiplies 'a' * 10^(1:length(a)) and sum 
                                 # obtaining the uncompressed number multiplied by 10
                                 # N.B. in case of empty 'a', we get 0
}

v = scan()                       # take vector v from stdin

w = sapply(v,G(n))               # apply G to all numbers of 'v'

v[order(w)]                      # use the uncompressed values as weights to sort 'v'
digEmAll
источник
[!1:0]Трюк реально хорошо - никогда не видел его раньше.
JayCe
@sundar: объяснение добавлено;)
digEmAll
1
Ницца. Я знал, что эти [!1:0]парни прячут что-то аккуратное. Я играл с этим и с советами по игре в гольф R, пытаясь получить число из цифр арифметически (без as.double), но только придумал 132-байтовую версию: TIO
sundar - Восстановите Monica
@sundar: я не думал о арифметическом подходе ... я спас 11 байтов, спасибо!
digEmAll
2

Pyth , 14 байт

oir9c.[Z2jNT2T

Попробуй это здесь! | Тестирование! | 12 байтов со списком цифр ввода / вывода

Как это устроено?

oir9c.[Z2jNT2T – Full program.
o              – Sort the input list by the results of the following code (variable: N).
         jNT   – Cast the current element to a list of digits.
     .[Z2      – Pad it on the left with 0s to the nearest multiple of 2.
    c       2  – Split in pieces of length 2.
  r9           – Run length decode.
 i           T – Cast the list of digits to a base 10 integer.
Мистер Xcoder
источник
2

Желе , 10 байт

ṚẋƝm2ṚFḌµÞ

Попробуйте онлайн!

Проверьте набор тестов!

Как это устроено

ṚẋƝm2ṚFḌµÞ Монадическая ссылка / Полная программа. | Пример: [25257, 725, 91, 5219, 146125, 14620512]
        Сортировать входной список по результату монадической ссылки: | Пример: 725
Ṛ Продвиньте N в его массив цифр и переверните его. | [5, 2, 7]
 ẋƝ Для каждых двух последовательных цифр x, y повторите xy раз. | [[5, 5], [2, 2, 2, 2, 2, 2, 2]]
   м2 Модульная 2. Возьмите все остальные элементы этого массива. | [[5, 5]]
     Verse Обратный. | [[5, 5]]
      F Flatten. | [5, 5]
       Ḍ Преобразовать из десятичного в целое. | 55
Мистер Xcoder
источник
Это определенно совпадение: 2537и 3725не представляют одно и то же число.
Эрик Outgolfer
Не могли бы вы дать мне контрольный пример, который бы это уловил, и я добавлю это к вопросу?
sundar - Восстановить Монику
@sundar Как сказал Эрик [2537, 3725]. Я никогда не сомневался, что это совпадение, поэтому я включил эту записку в ответ
г-н Xcoder
@ Mr.Xcoder Testcase добавлено, спасибо.
sundar - Восстановить Монику
2

Perl 6 , 53 байта

*.sort(+*.flip.comb.rotor(2).map({[x] $_}).join.flip)

Попробуйте онлайн!

Анонимно Любая лямбда, которая берет список значений и сортирует его по описанию пар чисел.

В этом случае я меняю номер на противоположный, затем делаю rotorсписок на два, чтобы получить каждую пару чисел. Это исключит первую цифру для чисел нечетной длины, но, поскольку это преобразуется в 0умноженное на это число, все в порядке. Кроме того, он выравнивает значения для [x]правильного использования .

Джо Кинг
источник
2

Haskell , 89 88 байт

Сохраненный байт благодаря ovs

import Data.List
(%)=mod
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%10
sortOn(1?)

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

> sortOn(1?)[19, 91, 2345, 2023]
[19,2023,2345,91]

Основные функциональные возможности обеспечиваются оператором инфикса, (?)который отслеживает множитель mи оставшиеся входные данные RLE n. (?)непрерывно вычитает 10 из, в nто время как есть десятки цифр, из которых нужно вычитать, и при этом она выталкивает еще одну копию последней цифры в начало вывода (через множитель m, который увеличивается на 10 каждый раз). Когда место в десятках исчерпано, последние две цифры отбрасываются, и процесс повторяется до тех пор, пока число не уменьшится до 0. Наконец, мы используем оператор (с начальным множителем 1) в качестве ключа сортировки.

азотистый
источник
1
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%10на байт короче.
овс
2

Шелуха , 10 байт

ÖödṁΓ*C_2d

Попробуйте онлайн!

объяснение

ÖödṁΓ*C_2d    Full function
Ö             Sort the input list by the result of...
 ö            The composition of these four functions:
         d      Convert to a list of digits
      C_2       Split into length-2 sublists starting at the end
   ṁ            Map the following function and concatenate the results:
    Γ*            Repeat the list tail X times, where X is the list head
  d             Convert back to an integer
София Лехнер
источник
2

Dyalog APL, 41 39 36 35 31 30 29 байт

f←⊂⌷¨⍨∘⍋{10⊥∊⍴⌿0 10100⊥⍣¯1⊢⍵}¨

Попробуйте онлайн!

-2 благодаря Cows quack
-4 (плюс -4 за базовую идею преобразования) благодаря ngn
-2 благодаря H.PWiz

dzaima
источник
⊃,/может стать
Kritixi Lithos
@ Cowsquack Я знал, что забыл встроенный: p
dzaima
{⍺⍴⍨⍎⍵}->⍴⍨∘⍎
СПП
@ngn, конечно, я никогда не смогу вспомнить все, что происходит на тренировке
dzaima
вот еще один трюк для -1 байта - тренируй {⍵[⍋F ⍵]}как⊂⌷¨⍨∘⍋F
нгн
2

C (gcc) (32-битные системы), 188 177 176 байт

char*p,*q,c[99],b[99]="0";i;d(x){for(p=b+!(sprintf(b+1,"%d",x)&1),q=c;i=*p++;++p)for(i-=48;i--;*q++=*p);*q=0;atoi(c);}m(int*a,int*b){return d(*a)-d(*b);}s(l,c){qsort(l,c,4,m);}

Попробуйте онлайн!

на amd64надстройке флаг -m32для компиляции.

Использование : s(x,n);где xуказывает на массив целых чисел для сортировки и nявляется длиной этого массива.

Второй тест дает неверный результат, потому что преобразование 25257дает 2222277777переполнение 32-битного целого числа - добавлен 5-й тест без этого числа.

Объяснение:

char*p,                                     // d(): input pointer
    *q,                                     // d(): output pointer
    c[99],                                  // d(): output buffer
    b[99]="0";                              // d(): input buffer
                                            //      (fixed first char 0)
i;                                          // d(): repeat counter

d(x){                                       // conversion function
    for(
            p=b+!(sprintf(b+1,"%d",x)&1),   // print number in decimal to
                                            // input buffer, starting at second
                                            // character, initialize input
                                            // pointer to first or second char
                                            // depending on the length of the
                                            // number
            q=c;                            // initialize output pointer
            i=*p++;                         // set repeat counter to digit and
                                            // point to next digit, stop when
                                            // NUL character is found
            ++p)                            // point to next digit after loop
        for(i-=48;i--;*q++=*p);             // inner loop, append current digit
                                            // i-48 ('0') times to output buffer
    *q=0;                                   // terminate output with NUL
    atoi(c);                                // convert to number, 'return' not
                                            // needed as atoi() leaves result
                                            // on the stack
}

m(int*a,int*b){                             // comparison function for qsort
    return d(*a)-d(*b);                     // return difference of converted
}                                           // values

s(l,c){                                     // sorting function
    qsort(l,c,4,m);                         // only "wrap" qsort, assuming
}                                           // sizeof(int) is 4
Феликс Палмен
источник
Ваша функция d()длинна из-за строк и функций, связанных с ними, вы можете сохранить много байтов, просто прочитав последние 2 цифры и сформировав вывод следующим образом: o;u;i;d(x){for(u=1,o=0;x;x/=100)for(i=0;i++<x%100/10;o+=x%10*u,u*=10);x=o;}m(int*a,int*b){u=d(*a)-d(*b);}s(l,c){qsort(l,c,4,m);}вы также будете сохранять байты, избегая объявления и инициализации chars.
Annyo
Хорошая идея - я думаю, что работа с целочисленными значениями делает этот подход совершенно другим, поэтому вы должны рассмотреть вопрос о публикации ответа? :)
Феликс Пальмен
Предлагаю b-~sprintf(b+1,"%d",x)%2вместоb+!(sprintf(b+1,"%d",x)&1)
floorcat
@Annyo предлагает x/10%10вместоx%100/10
потолок кошка
1

Брахилог , 18 байт

{↔ġ₂ẹ{Ċj₎|Ȯt}ˢ↔c}ᵒ

Попробуйте онлайн!

объяснение

Множество мелочей, необходимых для учета трех разных случаев: нечетное количество цифр, пара по 0 раз и нормальные пары.

{               }ᵒ     Order the Input according to the output of this predicate
 ↔                       Reverse the number
  ġ₂                     Group into pairs; the last digit is alone if there are
                           an odd number of them
    ẹ{      }ˢ           For each group:
      Ċ                    If there are two elements
       j₎                  Juxtapose the first one as many times as the second
                             element (won't work if the second element is 0)
         |                 Else
          Ȯ                If there is one element (odd number of digits)
           t               just take that element
                           (Else don't select anything, i.e. 0 repetitions)
              ↔c         Reverse and concatenate back into an integer
Fatalize
источник
Я думаю, что |Ȯtэто ненужно, и фактически делает его сортировку неправильной: это эквивалентно заполнению 1 вместо 0, поэтому, учитывая [125, 26, 1], сортирует его как [1, 26, 125] вместо [1 , 125, 26].
sundar - Восстановить Монику
1

Perl 5 , 76 байт

Функция вместо однострочника на этот раз.

Совершенно прямо: gсортирует входные данные численно, используя hдля преобразования чисел. hделает это с помощью регулярного выражения s/(.)(.)/$2x$1/gre(которое, вероятно, достаточно читабельно). И 0левый отступ делается с 0 x("@_"=~y///c%2)."@_"(где y///cкраткий способ записи length, xоператор повтора и .конкатенация).

sub h{(0 x("@_"=~y///c%2)."@_")=~s/(.)(.)/$2x$1/gre}sub g{sort{h($a)-h$b}@_}

Попробуйте онлайн!

Я ожидаю увидеть некоторые короткие ответы Perl, хотя!

папа
источник
1

Сетчатка , 44 байта

^.?((..)*)$
$1 $&
%)`\G(\d)(.)
$1*$2
N`
.+ 

Попробуйте онлайн! Генерировать ключ сортировки в начале строки сложнее, но короткая стадия сортировки приводит к общей экономии 3 байта. Объяснение:

%)`

Примените первые два этапа на каждой линии в отдельности.

^.?((..)*)$
$1 $&

Совпадение и копирование четного числа завершающих цифр.

\G(\d)(.)
$1*$2

Замените каждую пару цифр их описанным значением. \G\dВызывает матч до остановки в пространстве.

N`

Сортировать численно.

.+ 

Удалить ключи сортировки.

Нил
источник
Это умный трюк для сортировки по ключу. Хороший.
sundar - Восстановить Монику
1

05AB1E , 20 19 байтов

ΣDgÉi¦}2ôε`sиJ}J0ìï

Исправлена ​​ошибка в +1 байт, а затем добавлялось в -2 байта благодаря @sundar .

Попробуйте онлайн или проверьте все тесты .

Можно определенно играть в гольф .. Не слишком рад этому ...

Объяснение:

Σ                    # Sort by:
 Dg                  #  Duplicate the current number, and take it's length
                     #   i.e. 25257 → 5
                     #   i.e. 4 → 1
   Éi }              #  If this length is odd:
     ¦               #   Remove the first digit
                     #    i.e. 25257 → '5257'
                     #    i.e. 4 → ''
       2ô            #  Then split the number in pieces of 2
                     #   i.e. '5257' → ['52','57']
                     #   i.e. '' → []
         ε    }      #  And map each to:
          `          #   Push both digits to the stack
                     #    i.e. '52' → '5' and '2'
           s         #   Swap them
            и        #   Repeat the first digit the second digit amount of times
                     #    i.e. '2' and '5' → ['2','2','2','2','2']
             J       #   Join the list of digits together
                     #    i.e. ['2','2','2','2','2'] → '22222'
               J     #  Join all numbers back together again
                     #   i.e. ['','22222','77777'] → '2222277777'
                     #   i.e. [] → ''
                0ì   #  Prepend a 0 (because `Σ` will put all '' at the back)
                     #   i.e. 2222277777 → '02222277777'
                     #   i.e. '' → '0'
                  ï  #  Cast it to an integer, because sorting is done string-wise by
                     #  default despite 05AB1E's interchangeability of strings and numbers;
                     #  and it's also to remove all leading zeros
                     #   i.e. '02222277777' → 2222277777
                     #   i.e. '0' → 0
Кевин Круйссен
источник
1

Атташе , 50 байт

SortBy!N@Flip##~`&&>PadRight&0&2=>Chop&2@Flip@List

Попробуйте онлайн!

объяснение

SortBy!N@Flip##~`&&>PadRight&0&2=>Chop&2@Flip@List      anonymous function, argument: [a1..aN]
SortBy!                                                 sort the given array by grading f[ai]
                                                        e.g. 42513
                                              List      digits of ai
                                                        e.g. [4, 2, 5, 1, 3]
                                         Flip@          flip the digits around
                                                        e.g. [3, 1, 5, 2, 4]
                                  Chop&2@               chop into groups of 2
                                                        e.g. [[3, 1], [5, 2], [4]]
                    PadRight&0&2=>                      pad each group to size 2 with 0's
                                                        e.g. [[3, 1], [5, 2], [0, 4]]
                  &>                                    using each sub array as arguments...
               ~`&                                      ...repeat the 2nd the 1st amount of times
                                                        e.g. [[1, 1, 1], [2, 2, 2, 2, 2], []]
             ##                                         then:
         Flip                                           reverse the groups
                                                        e.g. [[2, 2, 2, 2, 2], [1, 1, 1]]
       N@                                               then convert it to an number
                                                        e.g. 22222111
Конор О'Брайен
источник
1

Japt, 13 байт

ñ_ì_ò2n)®rçì

Попробуйте или запустите все тесты


объяснение

ñ_                :Sort by passing each integer through a function
  ì_              :  Split to an array of digits, pass it through the following function and implicitly convert back to an integer
    ò2n)          :    Starting from the end of the array, split at every second element
        ®         :    Map
         rç       :      Reduce X & Y by repeating X Y times
           Ã      :    End mapping
            ¬     :    Join
мохнатый
источник
0

Java 11, 204 189 байт

L->{L.sort((a,b)->Long.compare(s(a+""),s(b+"")));}long s(String s){var r="";for(int l=s.length(),i=l%2;i<l;)r+=s.split("")[++i].repeat(s.charAt(i++-1)-48);return r.isEmpty()?0:new Long(r);}

Принимает List of Longs в качестве параметра и сортирует этот input-List (без возврата нового List).

Попробуйте онлайн (ПРИМЕЧАНИЕ: String.repeat(int)эмулируется, repeat(String,int)потому что Java 11 еще не на TIO. Число байтов остается тем же.)

Объяснение:

L->{                     // Method with ArrayList<Long> parameter and no return-type
  L.sort(                //  Sort the list by:
   (a,b)->Long.compare(  //   Using a builtin Long-comparator with:
     s(a+""),s(b+"")));} //   The correctly formatted values as described in the challenge

long s(String s){        // Separated method with String parameter and long return-type
  var r="";              //  Temp-String, starting empty
  for(int l=s.length(),  //  The length of the input-String
      i=l%2;i<l;)        //   If the length is even:
                         //    Loop `i` in the range [0,`l`) (in steps of 2)
                         //   Else (the length is odd):
                         //    Loop `i` in the range [1,`l`) (in steps of 2) instead
    r+=                  //   Append the result-String with:
      s.split("")[++i].  //    The digit at index `i+1`
      .repeat(s.charAt(i++-1)-48);
                         //    Repeated the digit at index `i` amount of times
  return r.isEmpty()?    //  If the temp-String is empty:
          0              //   Return 0
         :               //  Else:
          new Long(r);}  //   Convert the temp-String to a long and return it
Кевин Круйссен
источник
Привет, вызов явно запрещает ввод строки, извините! (Я испытываю желание разрешить это для Java, но это не будет справедливо в других ответах.)
sundar - Восстановить Монику
@sundar Ах, пропустил это требование; мой плохой .. К счастью, это просто исправить, просто добавив 2x, +""чтобы преобразовать число в строку. Должно быть исправлено сейчас. :)
Кевин Круйссен
1
Ницца. Я не ожидал этого от Java. :)
sundar - Восстановить Монику