Знайдіть оптимальну схему


33

Дано рядок s, що складається з малих літер, таких як

aabaaababbbbaaba

і позитивне ціле число п , такі , як 4, виводити довжина- п рядок т таким чином, що , коли т повторюється до довжини з , вони мають як багато символів в часто , як це можливо. Для даного прикладу оптимальним буде результат aaba, оскільки він має тринадцять символів спільного з цільовим рядком:

s: aabaaababbbbaaba
t: aabaaabaaabaaaba (aaba)
   ^^^^^^^^  ^ ^^^^

і жоден можливий t не має більше. Однак для aaaaaabцього є два можливих виходи: aaaaі aaba, кожен з яких має 6 символів спільного з цільовим рядком:

s: aaaaaab
t: aaaaaaaa (aaaa)
   ^^^^^^ 

s: aaaaaab
t: aabaaaba (aaba)
   ^^ ^^^^

Або aaaaчи aabaможуть бути виведені, або обидва , якщо ви хочете. Зауважте, що s ніколи не повторюється; трелінг aв обох повторених значеннях t просто ігнорується.

Тестові справи

Inputs -> Valid outputs
1 a -> a
1 aa -> a
2 aa -> aa
1 ab -> a b
2 ab -> ab
1 abb -> b
2 abb -> ab bb
2 ababa -> ab
2 abcba -> ab
2 aabbbbb -> bb  (ab is not a valid output here)
3 aababba -> aab abb
3 aababbaa -> aab
3 asdasfadf -> asf
3 asdasfadfsdf -> asf adf
2 abcdefghijklmnopqrstuvwxyzyx -> yx
2 supercalifragilisticexpialidocious -> ic ii
3 supercalifragilisticexpialidocious -> iri ili ioi
4 supercalifragilisticexpialidocious -> scii
5 supercalifragilisticexpialidocious -> iapic
2 eeeebaadbaecaebbbbbebbbbeecacebdccaecadbbbaceebedbbbddadebeddedbcedeaadcabdeccceccaeaadbbaecbbcbcbea -> bb be
10 bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd -> ebbbdbeece ebdbdbeece
20 aabbbaaabaaabaaaabbbbabbbbabbbabbbbbabbaaaababbbaababbbaababaaaabbaaabbaabbbabaaabbabbaaabbaaaaaaaba -> aabbbbaaabbabbbaabba

Правила

  • Ви можете припустити, що вхід буде колись лише порожнім рядком з малих літер і додатним цілим числом, не більшим за довжину рядка.
  • Ви можете приймати дані в будь-якому стандартному форматі та в будь-якому порядку.
  • Ви можете вивести один рядок або декілька у вигляді масиву, розділених новими рядками або пробілами тощо.
  • Ваш код повинен закінчувати кожен тестовий випадок менше ніж за 1 хвилину на будь-якому досить сучасному комп'ютері.
  • Це , тому зробіть свій код якомога коротшим.

2
Ця проблема - якість Zgarb. Хороша робота!
Мартін Ендер

Я припускаю, що ігноруються лише знаки, що відкладаються? Таким чином, ви не можете ігнорувати провідних персонажів на зразок цього: 2 abb -> baтам, де він створений як (b)[ab]a: ведучий (b)ігнорується, [ab]відповідають.
Кевін Кройсейсен

@KevinCruijssen Правильно, шаблон повинен почати повторюватися на початку.
ETHproductions

Відповіді:


11

Желе , 11 байт

sZµṢŒrUṀṪµ€

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

Не сподівався перемогти Денніса на цьому, тому спробував FGITW (після спроби декількох можливостей; існує більше ніж один спосіб зробити 11). Я прийшов коротше, на мій подив.

Приймає рядок, а потім підрахунок як аргументи командного рядка. Виходи на stdout.

Пояснення

sZµṢŒrUṀṪµ€
s            Split {the first input} into {the second input}-sized groups
 Z           Transpose
  µ      µ€  On each of the transposed groups:
   Ṣ           Sort it;
    Œr         Run-length encode it;
      U        Rearrange it to the form {count, letter};
       Ṁ       Take the largest element (i.e. largest count)
        Ṫ      Take the second element of the pair (i.e. just the letter)

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

Желе , 10 байт на основі рішення @Dennis

⁸ċ$ÞṪ
sZÇ€

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

Це поєднання рішення @Dennis і мого власного; в цьому рішенні був п’ятибайтовий режим, який я вкрав для цього рішення. (У мене вже були рішення на основі ⁸ċ, але я не міг потрапити нижче шести байтів; я не думав використовувати Þ.)

Пояснення

µ…µ€і Ç€попереднім рядком) мають три байти довгими (останній потребує нового рядка) та еквівалент. Зазвичай я використовую перший, але останній є більш гнучким, оскільки він дозволяє використовувати згадування аргументу.

Це дає можливість сортувати ( Þ) за кількістю входів у ( ⁸ċ), а потім взяти останній елемент ( ), щоб знайти режим всього в п'яти символах.


5
Приємна робота, перевершивши Денніса своєю рідною мовою! : P
HyperNeutrino

10

Математика, 51 байт

#&@@@Commonest/@(PadRight@Partition[#2,UpTo@#])&

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

Також засновані на режимах ліній транспозиції. Я вважаю, що вони назвали вбудований режим списку Commonest виключно для того, щоб нарікати кодових гравців.


Принаймні, це байт коротший за MostCommon...
ETHproductions

7

Python 3, 99, 73 61 байт

-12, thx для @Rod

lambda s,n:''.join(max(s,key=s[i::n].count)for i in range(n))

Ця ж ідея, але переписав її для усунення заяви про імпорт.

lambda s,n:''.join(max(s,key=lambda c:s[i::n].count(c))for i in range(n))

Оригінал

from collections import*
lambda s,n:''.join(Counter(s[i::n]).most_common(1)[0][0]for i in range(n))

Пояснення:

s[i::n]                  a slice of every nth character of s, starting at position i

Counter(s[i::n])         counts the characters in the slice
  .most_common()         returns a list of (character, count) pairs, sorted by decreasing count
    [0][0]               grabs the letter from the first pair (i.e., the most common letter
      for i in range(n)  repeat for all starting positions

''.join                  combines the most common letters into a single string

ви можете переключитися на python2.7 і скинути, ''.join()щоб повернути список рядків
Rod

@Rod Dropping ''.join(...)змусить би повернути генератор, не впевнений, чи дозволений вихід.
L3viathan

@ L3viathan це потрібно python2.7, щоб працювати, додано до іншого коментаря
Rod

Ви можете написати пояснення, як це працює?
Мертвий Поссум

2
@Rod Список рядків дозволений у запитанні, якщо ви повернете всі можливі рішення. Ось що я сприйняв це.
mbomb007

5

Пітон 2, 106

Тепер це інша відповідь! Я думав про один (майже) -лінер від початку. Тепер ще коротше, на основі використання zip від @Rod.

Дякуємо @ L3viathan та @Rod за роз'яснення щодо використання лямбдасів як відповіді

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

lambda S,N:max(combinations(S,N),key=lambda s:sum(x==y for x,y in zip(S,s*len(S))))
from itertools import*

Пояснення:

combinations(S,N) створює всі комбінації довжиною N з символів S

max()мають аргумент, keyякий приймає як функцію введення для використання для порівняння елементів

lambda s:sum(x==y for x,y in zip(S,s*len(S))) передано як таку функцію

Ця лямбда підраховує кількість відповідних символів у списку кортежів zip(S,s*len(S))

s- одна з комбінацій і множиться на len(S)яку створює рядок, який гарантується довше, ніж S

zipстворює кортежі символів кожного рядка Sта s*len(S)ігнорує всі символи, які не можуть бути зіставлені (у випадку, якщо один рядок довший за інший)

Тож maxвибирається комбінація, яка дає максимальну суму


1
вам не потрібно використовувати []для розуміння списку всередині функцій, також ви використовуєте, 1 for ... if <cond>ви можете використовувати безпосередньо, <cond> for ...оскільки він буде використовуватися sum, python буде приймати Trueяк 1і Falseяк0
Rod

@Rod Дякую! Якщо я більше запитаю свою відповідь, вона перетвориться на вашу відповідь, підхід такий самий: D Тож я зараз намагаюся щось інше
Dead Possum

Так, просто кажу , так що ви можете використовувати в своїх майбутніх відповідей: 3
Rod

1
Перехід на лямбда дозволить заощадити 7 байт.
L3viathan

1
@DeadPossum Він мав на увазі це (зверніть увагу на колонтитул та заголовок), і так, функція є правильною відповіддю , якщо її лямбда вам навіть не потрібнаf= (якщо вона не є рекурсивною)
Rod

5

JavaScript (ES6), 104 101 94 байт

(n,s)=>s.replace(/./g,(_,i)=>[...s].map((c,j,a)=>j%n-i||(a[c]=-~a[c])>m&&(m++,r=c),m=r=``)&&r)

Збережено 3 байти двічі завдяки @Arnauld. 97-байтне рішення, яке працює з усіма символами, що не належать до нового рядка:

(n,s)=>s.replace(/./g,(_,i)=>[...s].map((c,j)=>j%n-i||(o[c]=-~o[c])>m&&(m++,r=c),m=r=``,o={})&&r)

Попереднє 104-байтне рішення також працює з символами нового рядка:

(n,s)=>[...Array(n)].map((_,i)=>[...s].map((c,j)=>j%n-i||(o[c]=-~o[c])>m&&(m++,r=c),m=0,o={})&&r).join``

Дуже хороша. Я допоміг рішення для довідки, додаючи тестові випадки, і зібрав 122 байти, переглядаючи кожну таблицю, зберігаючи рахунки в масиві об'єктів, потім будуючи рядок із цього масиву.
ETHproductions

Замість того, щоб ініціалізувати oновий об'єкт, чи можете ви просто використати переданий масив map, використовуючи його 3-й параметр?
Арнольд

@Arnauld Хм, я думаю, що це працює, тому що питання гарантує малі літери, тому я не буду плутати елементи масиву з підрахунками ...
Ніл

Думаю, (n,s)=>s.replace(/./g,(_,i)=>i<n?[...s].map((c,j,a)=>j%n-i||(a[c]=-~a[c])>m&&(m++,r=c),m=0)&&r:'')слід зберегти ще 3 байти. (Або 4 байти, використовуючи синтаксис каррі.)
Арнольд,

@Arnauld Непогано, але я поголив ще два байти. (А також зафіксував підрахунок байтів; останній рядок скидав їх.)
Ніл,

3

Желе , 12 11 байт

s@ZċþZMḢ$€ị

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

Як це працює

s@ZċþZMḢ$€ị  Main link. Arguments: n (integer), s (string)

s@           Split swapped; split s into chunks of length n.
  Z          Zip/transpose, grouping characters that correspond to repetitions.
   ċþ        Count table; for each slice in the previous result, and each character
             in s, count the occurrences of the character in the group.
             This groups by character.
     Z       Zip/transpose to group by slice.
        $€   Map the two-link chain to the left over the groups.
      M        Find all maximal indices.
       Ḣ       Head; pick the first.
          ị  Index into s to retrieve the corresponding characters.

Чи є у Jelly коментарі?
caird coinheringaahing

Ні, це не є.
Денніс

2

Pyth, 11 байт

meo/dNd.TcF

Приймає введення як s,nі виводить як список символів.

Пояснення

meo/dNd.TcF
         cFQ   Split s into chunks of length n.
       .T      Transpose.
m o/dNd        Sort characters in each string by frequency.
 e             Take the most common.

2

Japt , 16 15 байт

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

Ç=VëUZ)¬ñ!èZ o

14 байт коду + 1 байт для -Pпрапора. Спробуйте в Інтернеті!

Необурені і пояснення

 Ç   =VëUZ)¬ ñ!èZ o
UoZ{Z=VëUZ)q ñ!èZ o}
                          Implicit: U = input number, V = input string
Uo                        Create the range [0...U).
  Z{               }      Map each item Z by this function:
      VëUZ                  Take every U'th char of V, starting at index Z.
    Z=    )                 Call the result Z.
           q                Split the result into chars.
             ñ!èZ           Sort each char X by the number of occurrences of X in Z.
                  o         Pop; grab the last item (the most common char).
                      -P  Join the results (array of most common chars) into a string.

Я думаю, ви можете замінити gJнаo
Олівер

@obarakon Це геніально, дякую!
ETHproductions


1

05AB1E , 17 байт

Iôð«øvy{.¡é®èÙJðÜ

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

Пояснення

Iô                 # split 2nd input in chunks of 1st input size
  ð«               # append a space to each
    ø              # zip
     vy            # for each y in the zipped list
       {           # sort the string
        .¡         # group into chunks of consecutive equal elements
          é        # sort by length
           ®è      # pop the last element (the longest)
             Ù     # remove duplicate characters from the string
              J    # join the stack into one string
               ðÜ  # remove any trailing spaces

1

PHP, 245 байт

function p($c,$s,$r=""){global$a;if(($c-strlen($r)))foreach(str_split(count_chars($s,3))as$l)p($c,$s,$r.$l);else{for($v=str_pad("",$w=strlen($s),$r);$z<$w;)$t+=$v[$z]==$s[$z++];$a[$t][]=$r;}}p($argv[1],$argv[2]);ksort($a);echo join(" ",end($a));

Інтернет-версія

Зламатися

function p($c,$s,$r=""){
    global$a;
    if(($c-strlen($r)))  # make permutation
        foreach(str_split(count_chars($s,3))as$l)
            p($c,$s,$r.$l); #recursive
    else{
        for($v=str_pad("",$w=strlen($s),$r);$z<$w;) 
        $t+=$v[$z]==$s[$z++]; #compare strings
        $a[$t][]=$r; # insert value in array
    }
}
p($argv[1],$argv[2]); #start function with the input parameter
ksort($a); # sort result array 
echo join(" ",end($a)); #Output

1

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

import Data.Lists
f n=map(argmax=<<(length.).flip(filter.(==))).transpose.chunksOf n

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

f 10 "bbbbacacbcedecdbbbdebdaedcecdabcebddbdcecebbeeaacdebdbebaebcecddadeeedbbdbbaeaaeebbedbeeaeedadeecbcd"
"ebbbdbeece"

nРозбийте рядок введення на шматки по довжині , перемістіть і знайдіть для кожного підспісу найчастіший елемент.


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