Сортуйте за тим, що описують пари цифр


17

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

Наприклад:

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

  • 643 має непарну кількість цифр, тому для додавання парного нуля додається початковий нуль. Тоді 0643 можна читати як: нуль 6s, чотири 3s, отже, вихід буде 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 обидва оцінюють до 0s, і так можна сортувати в або замовлення.)

(Пов'язане: Скажіть, що бачите , Один 1, Два 1, Один 2 Один 1

Дякуємо Кевіну Круїссену за допомогу в уточненні питання в пісочниці.


2
Чи можна взяти список списків цифр як вхідний? Чи можемо ми вивести список списків цифр?
Містер Xcoder

@ Mr.Xcoder Введення має бути як список цілих чисел, а не списки цифр. Вихід може бути списком переліків цифр, якщо це якось зручніше.
sundar

як вказував @mnel, моя відповідь не буде працювати для чисел, що перевищують 10 цифр. чи законно зберігати його таким, яким він є, чи варто змінювати його ціною 32 байти.
JayCe

@JayCe Якщо я правильно розумію, обмеження полягає в тому, що це межа типу цілого числа в R - тому що strtoiповертає ціле число - правильно? Якщо так, це добре, це законно, як є.
sundar - Відновлення Моніки

Ви праві! збереже його як є.
JayCe

Відповіді:


5

APL (Dyalog) , 26 байт

Дякую ngn за збереження 1 байта :)

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

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

Натхнення беру з dzaima і СПП


100⊥⍣¯1⊢⍵-> ⍵⊤⍨⍵/100працює на 26.
jslip

Я не дуже хочу WSFULLs на даних тестових випадках
H.PWiz

26 можливо з MAXWS = 1M
ngn

100⊥⍣¯1⊢⍵->⍵⊤⍨⍴⍨100
ngn

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=""))))]

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

Відповідь досить копітка - але це працює на всіх тестових випадках. Побудує вихід з числа цифр і сортує вхід відповідно до цього.


Я розмістив свій підхід на іншій відповіді, оскільки я працював над цим сьогодні вдень, але мене перервали. Просто запевняю, що я не отримав натхнення від ваших без кредитів;)
digEmAll

@digEmAll ніяких турбот :) - Насправді я думаю, що я взяв назву vзмінної з інших ваших відповідей - я ніколи vраніше не використовував . І приємного використання intToUtf8!
JayCe

аха, я справді ревную до моїх назв змінних однієї букви! Ні, серйозно ... приїжджаючи зі StackOverflow кожного разу, коли я публікую "подібну" альтернативу, це відчувається як крадіжка;)
digEmAll

strtoi поверне NA для цілих чисел, що перевищують 10 цифр (as.numeric neće)
mnel,

@mnel дякую за вказівку! Я перевірив сундар, і оскільки це обмеження цілого типу, я можу залишити його таким, яким є :)
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'

[!1:0]Трюк реально добре - ніколи не бачив його раніше.
JayCe

@sundar: пояснення додано;)
digEmAll

1
Приємно. Я знав, що ті [!1:0]хлопці ховають щось акуратне. Я розігрувався з цим і підказками про R golfing, намагаючись отримати число з цифр арифметично (без as.double), але придумав лише версію 132 байтів: TIO
sundar - Відновити Моніку

@sundar: Я не думав про арифметичний підхід ... я врятував 11 байт, дякую!
digEmAll

2

Піт , 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.

2

Желе , 10 байт

ṚẋƝm2ṚFḌµÞ

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

Перевірте тестовий набір!

Як це працює

ṚẋƝm2ṚFḌµÞ Monadic link / Повна програма. | Приклад: [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]]
     Ṛ Реверс. | [[5, 5]]
      F Згладьте. | [5, 5]
       Ḍ Перетворити з десяткових в цілі числа. | 55

Це, безумовно, збіг обставин: 2537і 3725не представляють однакової кількості.
Ерік Аутгольфер

Чи можете ви надати мені тестовий випадок, який би сприйняв це, і я додам це питання?
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 байт

Збережено байт завдяки ов

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]

Основну функціональність забезпечує оператор infix, (?)який відслідковує множник 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

Діалог APL, 41 39 36 35 31 30 29 байт

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

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

-2 спасибі корови
4 (плюс -4 за ідею базової конверсії) завдяки ngn
-2 спасибі H.PWiz


⊃,/може стати
Kritixi Lithos

@Cowsquack Я знав, що забуваю вбудований: p
dzaima

{⍺⍴⍨⍎⍵}->⍴⍨∘⍎
ngn

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

ось ще одна хитрість для -1 байта - треніфікуйте {⍵[⍋F ⍵]}як⊂⌷¨⍨∘⍋F
ngn

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()довга через рядки та пов’язані з ними функції, ви можете зберегти багато байтів, просто прочитавши останні дві цифри та побудувавши результат таким чином: 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.
Анньо

Хороша ідея - я думаю, що робота над цілими значеннями робить це зовсім іншим підходом, тож варто розглянути питання про розміщення відповіді? :)
Фелікс Палмен

Запропонувати b-~sprintf(b+1,"%d",x)%2замістьb+!(sprintf(b+1,"%d",x)&1)
roofcat

@Annyo пропонують x/10%10замістьx%100/10
roofcat


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

Я вважаю, що |Ȯ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

Attache , 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





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);}

Приймає список довжин як параметр і сортує цей вхідний список (без повернення нового списку).

Спробуйте в режимі он-лайн (ПРИМІТКА. 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, +""щоб перетворити число в String. Слід виправити зараз. :)
Кевін Круїссен

1
Приємно. Я не очікував цього від Java. :)
sundar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.