Сортуйте рядок за заданим упорядкуванням


23

Ваша задача полягає в сортуванні рядка, але замість звичайного алфавітного порядку (abc..xyz) ви будете сортувати рядки за заданим алфавітом.

Ви повинні написати програму або функцію , яка приймає два входи: алфавіт A і рядки S . Обидва будуть містити лише малі англійські літери, і обидва будуть містити принаймні один символ.

Ви повинні переміщувати літери в S так, щоб перша буква, що з’явилася спочатку в A , потім була вказується друга буква A , і т. Д. Можливо, деякі букви в S не відображаються в A , їх слід залишити в кінці та не рухалися по відношенню один до одного.

Тестові приклади:

A       S               Result
axd     haxuizzxaxduxha aaaxxxxdhuizzuh
a       xyz             xyz
abc     dcba            abcd
il      nmiuplliu       iillnmupu
asdf    qwerty          qwerty

Виграє найменше байтів!


Чи можемо ми надрукувати / повернути масив однотонних рядків? Чи можемо ми взяти один рядок і один масив одиночних рядків як вхідний?
Денніс

@Dennis Так, обидва є прекрасними зображеннями рядків.
Павло

Чи можемо ми взяти один або обидва входи як масив окремих символів?
Кудлатий

@Shaggy Рядок - це масив символів, так що так.
Павло

Відповіді:


5

05AB1E , 4 байти

Rvy†

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

Пояснення

R     # Reverse the alphabet
 vy   # For each letter ...
   †  # Push S with the current letter filtered to the front

Розумніший за Σ²sk>.
Чарівна восьминога урна

Дуже погано R€†працювати, як очікувалося :). Іноді це може працювати як менший vyцикл. Гарна людина відповіді.
Чарівна восьминога урна

10

Python 3 , 50 47 46 44 байт

-3 байти завдяки ngn!

-1 байт завдяки mypetlion

lambda a,s:s.sort(key=lambda c:a.find(c)%27)

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

Приймає рядок як алфавіт, а список символів - рядок і сортує список за місцем.

У %27гарантує , що якщо символ не в алфавіті, то повертається індекс поміщає його після того, як інша частина алфавіту.


2
-a[::-1].find(c)->(a+c).find(c)
ngn

1
(a+c).find(c)-> a.find(c)%27щоб зберегти 1 байт
mypetlion

7

Хаскелл, 42 байти

a#s=[c|c<-a,d<-s,c==d]++[c|c<-s,all(/=c)a]

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

a#s=                     -- take alphabet a and string s
        c<-a             -- for all c in a
             d<-s        --   for all d in s
    [c|       c==d]             keep c if c equals d
   ++                    -- append
    [c|c<-s        ]     --   all c of s
         ,all(/=c)a      --   that are not in a 

7

Perl 6 ,  55  43 байт

->\A,\S{[~] S.comb.sort:{%(A.comb.antipairs){$_}//∞}}

Спробуй це

->\A,\S{[~] S.comb.sort:{A.index($_)//∞}}

Спробуй це

Розширено:

-> \A, \S {
  [~]  # reduce using &infix:«~» (shorter than `.join`)

    S.comb.sort: # split into character list and sort by:

      {  # bare block lambda with implicit parameter $_

        A.index( $_ ) # get the position

        //  # if it is undefined (not in `A`)
           # return Inf instead (so it comes at end of result)
      }
}

Оскільки у введенні буде лише до 26 різних символів, а ∞ - 3 байти, ви можете замінити його на 27, і він все одно буде працювати і зберігати байт.
Павло

6

Haskell , 40 34 байт

-6 байтів величезні завдяки Лайконі .

foldr(\c->r(==c)<>r(/=c))
r=filter

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

Перший рядок є виразом , яке приймає два аргументи: S і A .


1
Приємно! Ви навіть можете відмовитися, f=оскільки анонімні функції дозволені.
Лайконі

1
Крім того (<>), тепер у Prelude, тому це можна скоротити до foldr(\c->r(==c)<>r(/=c))34 байт: Спробуйте в Інтернеті!
Лайконі


5

Python 2 , 38 байт

def f(a,s):s.sort(None,a[::-1].find,1)

a має бути рядком, s список рядків довжиною 1. f сортує s на місці.

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

Альтернативна версія, рядок вводу / виводу, 48 байт

lambda a,s:`sorted(s,None,a[::-1].find,1)`[2::5]

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

Як це працює

s.sort(None,a[::-1],1)це скорочення для s.sort(cmp=None,key=a[::-1],reverse=1).

З документів :

reverse - булева величина. Якщо встановлено значення True, то елементи списку сортуються так, ніби кожне порівняння було перетворене.


Сортування TIL може приймати 4 аргументи.
Павло

Тільки в Python 2. Python 3 застарілий cmpі зроблений keyта reverseлише для ключових слів аргументів, тож він list.sortбере лише один позиційний аргумент.
Денніс

4

J , 5 байт

]/:i.

Дієдичне дієслово, беручи алфавіт ліворуч і рядок, відсортований праворуч.

i. знаходить індекси символів рядка в алфавіті, якщо довжина алфавіту не знайдена.

   'axd' i. 'haxuizzxaxduxha'
3 0 1 3 3 3 3 1 0 1 2 3 1 3 0

/: сортує лівий агрумент за порядком, визначеним у правій.

] аргумент жорсткості (рядок)

  'haxuizzxaxduxha' /: 3 0 1 3 3 3 3 1 0 1 2 3 1 3 0
aaaxxxxdhuizzuh

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


4

Python 2 , 35 50 байт

lambda a,s:sorted(s,key=lambda c:-a[::-1].find(c))

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

Бере aі sяк струни; повертає список рядків singelton.

Примітка: О! Набрав 15 байт, щоб виправити ...


Га! Це насправді точно так само, як і мій оригінальний код для моєї відповіді . Великі розуми думають однаково
Джо Кінг

1
@Jo King: Перестаньте контролювати мої думки! :)
Час Браун

4

К (нг / к) , 9 байт

{y@>-x?y}

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

{... }- це функція з аргументами xтаy

x?yзнаходить для кожного елемента в yіндексі його першого виникнення в x; якщо елемент не знайдено в x, вважається його індекс 0N(-2 63 )

-заперечує всі індекси, за винятком того, що він зберігає 0Nнедоторканість, оскільки 2 63 ≡-2 63 (mod 2 64 )

> повертає перестановку сортування, що спадає

y@індекси yз цим


3

Вугілля деревне , 13 байт

Fθ×ι№ηιΦη¬№θι

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

 θ              First input
F               Loop over characters
     η          Second input
      ι         Current character
    №           Count matches
   ι            Current character
  ×             Repeat
                Implicitly print
        η       Second input
       Φ        Filter
           θ    First input
            ι   Current character
          №     Count matches
         ¬      Logical not
                Implicitly print non-matching characters

3

Желе , 4 байти

fⱮ;ḟ

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

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

Як?

fⱮ;ḟ - Link: string; alphabet                                    e.g. smallnotxl; xl
 Ɱ   - map (for each character in the alphabet):                      1=x; 2=l
f    -   filter keep (keep occurrences of this character from string)   x    lll -> xlll
   ḟ - filter discard (discard all alphabet characters from string)   smanot
  ;  - concatenate                                                    xlllsmanot

3

APL (Dyalog Unicode) , 5 байт SBCS

Функція анонімного мовчазного приставки, беручи [string,ordering]за аргумент.

⍋⍨/⌷⊃

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

/ Зменшити за допомогою наступної функції:

  … А  саме версія наступних функцій із аргументованими аргументами:

   класифікуйте правий рядок відповідно до лівого упорядкування (пропущені літери йдуть в кінці)

 використовуйте це для індексації у…

 перший елемент аргументу (тобто рядок)


3

JavaScript (SpiderMonkey), 50 байт

Приймає введення в синтаксис currying (a)(s), де a - рядок, а s - масив символів. Повертає масив символів.

a=>s=>s.sort((b,c)=>(g=c=>-1/a.search(c))(b)-g(c))

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

Як?

Ми визначаємо хелперну функцію g () як:

c => -1 / a.search(c)

який повертає:

  • 1, якщо c не належить до алфавіту
  • значення float у [-Inf, 0) на основі положення c в алфавіті в іншому випадку (-Inf, -1, -1/2, -1/3 тощо)

Сортуємо s [] , обчислюючи g (b) - g (c) для кожної пари символів (b, c) переданої до зворотного виклику sort () .

Оскільки реалізація sort () у SpiderMonkey стабільна, всі символи s [] , які не належать до алфавіту, просто переміщуються в кінці в порядку появи і залишаються незмінними, коли їх порівнюють один з одним.


JavaScript (ES6), 61 байт

Вводить в синтаксис currying (a)(s), де і a, і s - це масиви символів. Повертає рядок.

a=>s=>a.map(C=>s=s.filter(c=>c!=C||!(o+=c)),o='')&&o+s.join``

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


3

R , 69 62 58 байт

function(a,s)c(rep(a,rowSums(outer(a,s,"=="))),s[!s%in%a])

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

Введення та вихід - це вектори окремих символів.

Пояснення:

function(a,s)c(                              ,           ) #combine:
                   a,                                      #[each char in a
               rep(                                        #each repeated
                     rowSums(               )              #the number of
                             outer(a,s,"==")               #occurrence in s]
                                              s            #with s
                                               [ s%in%a]   #all chars in a
                                                !          #omitted

3

Brain-Flak (BrainHack) , 118 байт

{({}(<>))<>}{}<>{<>([[]()]<{<>(({})<({}<>[({}<>)]){(<()>)}{}{}>)<>}<>({}<{({}<>)<>}<>>)>[]){({}()<(({}))>)}{}{}<>{}}<>

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

Введення - це перший рядок, за ним - нуль, за ним - другий рядок. Версія, яка використовує новий рядок як роздільник, замість цього додає 24 байти:

Мозок-Флак , 142 байти

(()){{}(({}(<>))[(()()()()()){}]<>)}{}<>{<>([[]()]<{<>(({})<({}<>[({}<>)]){(<()>)}{}{}>)<>}<>({}<{({}<>)<>}<>>)>[]){({}()<(({}))>)}{}{}<>{}}<>

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

Пояснення

# Move A to other stack reversed
# Zeroes are pushed under each character for later.
# (This is the only part that needs to change in order to use newline as separator.)
{({}(<>))<>}{}<>

# For each character in A, starting at the end:
{

  # Track current length of S.
  <>([[]()]<

    # For each character in S:
    {

      # While keeping character from A
      <>(({})<

        # Move character from S to second stack and push difference
        ({}<>[({}<>)])

        # Delete character if equal
        {(<()>)}{}{}

      >)

    <>}

    # Move S back to first stack while maintaining character from A
    <>({}<{({}<>)<>}<>>)

  # Push difference between old and new lengths of S
  >[])

  # Insert character from A at beginning of S that many times
  {({}()<(({}))>)}{}{}

<>{}}<>

2

C (gcc) , 97 байт

f(D,d,S,s,i,o)char*D,*S;{
  while(d--){
    for(i=o=s;i--;)S[i]-D[d]?S[--o]=S[i]:0;
    while(o--)S[o]=D[d];
  }
}

Усі пробіли (пробіли та нові рядки) у наведеному вище коді призначені лише для читання та їх слід видалити.

Словник передається Dі має довжину d, рядок передається Sі має довжинуs . iі oслід опустити.

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



2

Java 8, 98 байт

a->s->{for(int i=a.length;i-->0;s=s.replaceAll("[^"+a[i]+"]","")+s.replaceAll(a[i],""));return s;}

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

Пояснення:

a->s->{       // Method with String-array and String parameters, and String return-type
  for(int i=a.length;i-->0;
              //  Loop backwards over the alphabet
    s=        //   Replace the current `s` with:
      s.replaceAll("[^"+a[i]+"]","") 
              //    All the current characters of `a` in `s`
      +s.replaceAll(a[i],""));
              //    Concatted with everything else
  return s;}  //  Return the modified `s`

Не вдалося опуститися навіть із новим String.repeat(int)методом Java 11 . Приємно! :)
Олів'є Грегоар

@ OlivierGrégoire О, не знав, ранній доступ до Java 11 вже доступний. Але це .repeat(n)виглядає багатообіцяюче. : D
Кевін Круїссен

2

Perl 5 с -pF, 43 байти

$_=<>;print$F[0]x s/@{[shift@F]}//g while@F

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


Чи немає прапора, який дарує вам $_=<>;безкоштовно?
Павло

@Pavel Так, вибачте, що я використовую його для заповнення @F, але я не додав його до заголовка! Я зараз це зроблю! Дякую!
Дом Гастінгс

Ви можете вирізати 10 байт і все одно використовувати ту ж логіку: Спробуйте це в Інтернеті!
Xcali





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