Оптимальний крок алфавіту


30

З огляду на рядок введення, що складається лише з літер, поверніть розмір кроків, що призводить до мінімальної кількості кроків, необхідних для відвідування всіх літер в порядку над загортанням алфавіту, починаючи з будь-якої літери.

Наприклад, візьмемо слово, dog. Якщо ми використовуємо ступінчастий розмір 1, ми закінчуємо:

defghijklmnopqrstuvwxyzabcdefg   Alphabet
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
defghijklmnopqrstuvwxyzabcdefg   Visited letters
d          o                 g   Needed letters

Всього 30 кроків.

Однак якщо ми будемо використовувати крок розміром 11, ми отримуємо:

defghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg
^          ^          ^          ^          ^          ^
d          o          z          k          v          g   Visited letters
d          o                                           g   Needed letters

Всього 6 кроків. Це мінімальна кількість кроків, тому результат повернення dog- розмір кроків; 11.

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

"dog"      -> 11
"age"      -> 6
"apple"    -> 19
"alphabet" -> 9
"aaaaaaa"  -> 0 for 0 indexed, 26 for 1 indexed
"abcdefga" -> 1 or 9
"aba"      -> Any odd number except for 13
"ppcg"     -> 15
"codegolf" -> 15
"testcase" -> 9
"z"        -> Any number
"joking"   -> 19

Правила

  • Введенням буде не порожній рядок або масив символів, що складається лише з літер aдо z(ви можете вибрати між великими або малими літерами)
  • Вихід може бути 0 індексованим (тобто діапазон 0-25) або 1 індексованим ( 1-26)
  • Якщо є краватка, ви можете вивести будь-який розмір кроку або всі їх
  • Це , тому виграє найменша кількість байтів для кожної мови!

Чи потрібно обробляти порожній вхід?
pizzapants184

1
@ pizzapants184 Ні. Я оновив питання, щоб вказати, що введення буде порожнім
Jo King,

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

@Shaggy Впевнений, що можна
Джо Кінг

Чи є причина, що вона використовує букви замість цифр?
Пшеничний майстер

Відповіді:


6

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

≔EEβEθ∧μ⌕⭆β§β⁺⌕β§θ⊖μ×κξλ⎇⊕⌊ιΣι⌊ιθI⌕θ⌊Φθ⊕ι

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

Eβ

Петля за 26 розмірами кроків. (Насправді я переглядаю алфавіт із малих букв тут і використовую змінну індексу.)

Eθ∧μ

Переведіть петлю над кожним символом введення після першого.

⭆β§β⁺⌕β§θ⊖μ×κξ

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

⌕...λ

Знайдіть позицію поточного символу вводу в цьому рядку або -1, якщо його не знайдено.

E...⎇⊕⌊ιΣι⌊ι

Візьміть суму всіх позицій, якщо жодної не було знайдено, і в цьому випадку використовуйте -1.

≔...θ

Збережіть суми.

⌊Φθ⊕ι

Знайдіть мінімальну негативну суму.

I⌕θ...

Знайдіть розмір першого кроку з цією сумою та виведіть його.



4

Желе , 28 26 23 байт

S;þḅ26ŒpṢƑƇIŻ€S:g/ƊÞḢg/

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

Введення з однієї літери має бути оброблено спеціальним коштом і коштує 2 байти. ._.

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

Зауважте, що це підхід грубої сили; введення з чотирма або більше літерами вимкнеться на TIO. Набір тестів передбачає _39 "ефективність".

Як це працює

S;þḅ26ŒpṢƑƇIŻ€S:g/ƊÞḢg/  Main link. Argument: b (bytestring)

S                        Take the sum (s) of the code points in b.
 ;þ                      Concatenate table; for each k in [1, ..., s] and each c in
                         b, yield [k, c], grouping by c.
   ḅ26                   Unbase 26; map [k, c] to (26k + c).
      Œp                 Take the Cartesian product.
        ṢƑƇ              Comb by fixed sort; keep only increasing lists.
           I             Increments; take the forward differences of each list.
            Ż€           Prepend a 0 to each list.
                         I returns empty lists for single-letter input, so this is
                         required to keep g/ (reduce by GCD) from crashing.
                   Þ     Sort the lists by the link to the left.
              S:g/Ɗ      Divide the sum by the GCD.
                    Ḣ    Head; extract the first, smallest element.
                     g/  Compute the GCD.

4

Желе , 17 байт

ƓI%
26×þ%iþÇo!SỤḢ

Введення є бітестрінгом STDIN, вихід 1-індексованим.

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

Як це працює

ƓI%            Helper link. Argument: m (26 when called)

Ɠ              Read a line from STDIN and eval it as Python code.
 I             Increments; take all forward differences.
  %            Take the differences modulo m.


26×þ%iþÇoSSỤḢ  Main link. No arguments.

26             Set the argument and the return value to 26.
  ×þ           Create the multiplication table of [1, ..., 26] by [1, ..., 26].
    %          Take all products modulo 26.
       Ç       Call the helper link with argument 26.
     iþ        Find the index of each integer to the right in each list to the left,
               grouping by the lists.
        o!     Replace zero indices (element not found) with 26!.
               This works for strings up to 25! = 15511210043330985984000000 chars,
               which exceeds Python's 9223372036854775807 character limit on x64.
          S    Take the sum of each column.
           Ụ   Sort the indices by their corresponding values.
            Ḣ  Head; extract the first index, which corresponds to the minimal value.

4

JavaScript (Node.js) ,  123 121 116  114 байт

s=>(i=26,F=m=>i--?F((g=x=>s[p]?s[k++>>5]?j=1+g(x+i,p+=b[p]==x%26+97):m:0)(b[p=k=0]+7)>m?m:(r=i,j)):r)(b=Buffer(s))

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

Прокоментував

i2526s[k++ >> 5]g32×LL

s => (                        // main function taking the string s
  i = 26,                     // i = current step, initialized to 26
  F = m =>                    // F = recursive function taking the current minimum m
    i-- ?                     // decrement i; if i was not equal to 0:
      F(                      //   do a recursive call to F:
        (g = x =>             //     g = recursive function taking a character ID x
          s[p] ?              //       if there's still at least one letter to match:
            s[k++ >> 5] ?     //         if we've done less than 32 * s.length iterations:
              j = 1 + g(      //           add 1 to the final result and add the result of
                x + i,        //             a recursive call to g with x = x + i
                p += b[p] ==  //             increment p if
                  x % 26 + 97 //             the current letter is matching
              )               //           end of recursive call to g
            :                 //         else (we've done too many iterations):
              m               //           stop recursion and yield the current minimum
          :                   //       else (all letters have been matched):
            0                 //         stop recursion and yield 0
        )(                    //     initial call to g with p = k = 0
          b[p = k = 0] + 7    //     and x = ID of 1st letter
        ) > m ?               //     if the result is not better than the current minimum:
          m                   //       leave m unchanged
        :                     //     else:
          (r = i, j)          //       update m to j and r to i
      )                       //   end of recursive call to F
    :                         // else (i = 0):
      r                       //   stop recursion and return the final result r
)(b = Buffer(s))              // initial call to F with m = b = list of ASCII codes of s

4

Рубі , 121 114 112 108 102 89 байт

->s{(r=0..25).min_by{|l|p,=s;s.sum{|c|t=r.find{|i|(p.ord-c.ord+i*l)%26<1}||1/0.0;p=c;t}}}

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

0-індексований. Вводить дані як масив символів.

Завдяки лише ASCII за ідеї для гольфу, вартістю 12 байт.


:( close (заснований на розчині python)
лише для ASCII,

100 , напевно, можна пограти в гольф зовсім трохи більше
лише ASCII


Чудова ідея, ще 1 байт за p,=*sтрюк, але я не настільки впевнений у теоретичній надійності рішення з твердим балом штрафних санкцій ... Отже, я змінив константу на нескінченність (хоча ваше значення дозволило б вимкнути ще 2 байти ).
Кирило Л.

Всього 2 байти, непогано
лише для ASCII

3

Python 2 , 230 222 216 194 169 байт

def t(s,l,S=0):
 a=ord(s[0])
 for c in s[1:]:
	while a-ord(c)and S<len(s)*26:S+=1;a=(a-65+l)%26+65
 return S
def f(s):T=[t(s,l)for l in range(26)];return T.index(min(T))

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

-22 байти з тш

-39 байт від Джо Кінга

Старіша версія з поясненням:

A=map(chr,range(65,91)).index
def t(s,l,S=0):
 a=A(s[0]) 
 for c in s[1:]:
	while a!=A(c)and S<len(s)*26:
	 S+=1;a+=l;a%=26
 return S
def f(s):T=[t(s,l)for l in range(26)];return T.index(min(T))

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

Це було б коротше мовою з основним числом букв (не знадобиться float('inf')обробка нескінченних циклів). Насправді, це подання все одно знадобиться для обробки рядків типу "aaa". Це подання тепер використовується 26*len(s)як верхня межа, яка зупиняє нескінченні петлі.

Це подання 0-індексовано (повертає значення від 0 до 25 включно).

f приймає рядок (n верхнього регістру) і повертає крок оптимального алфавіту

t- це допоміжна функція, яка приймає ступінь струни та алфавіту і повертає кількість переходів, необхідних для завершення рядка (або, 26*len(s)якщо це неможливо).


2
Використовуйте while a!=A(c)and S<len(s)*26:і ви можете видалити if a==i:return float('inf'), оскільки len(s)*26це верхня межа будь-якої відповіді.
tsh






2

05AB1E (спадщина) , 33 27 26 байт

Ç¥ε₂%U₂L<©ε®*₂%Xk'-žm:]øOWk

Використовується застаріла версія, оскільки, здається, виникла помилка, коли ви хочете змінити / використовувати результат після вкладеної карти в новій версії 05AB1E ..

0-індексований вихід.

Спробуйте в Інтернеті або перевірте всі тестові випадки .

Пояснення:

Ç                        # ASCII values of the (implicit) input
 ¥                       # Deltas (differences between each pair)
  ε                      # Map each delta to:
   ₂%                    #  Take modulo-26 of the delta
     U                   #  Pop and store it in variable `X`
      L<                #  Push a list in the range [0,25]
         ©               #  Store it in the register (without popping)
          ε              #  Map each `y` to:
           ®*            #   Multiply each `y` by the list [0,25] of the register
             ₂%          #   And take modulo-26
                         #   (We now have a list of size 26 in steps of `y` modulo-26)
               Xk        #   Get the index of `X` in this inner list (-1 if not found)
                 '-₄:   '#   Replace the minus sign with "1000"
                         #   (so -1 becomes 10001; others remain unchanged) 
]                        # Close both maps
 ø                       # Zip; swapping rows/columns
  O                      # Sum each
   W                     # Get the smallest one (without popping the list)
    k                    # Get the index of this smallest value in the list
                         # (and output the result implicitly)

2

Пітон 3 , 191 178 162 байт

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

*w,=map(ord,input())
a=[]
for i in range(26):
 n=1;p=w[0]
 for c in w:
  while n<len(w)*26and p!=c:
   n+=1;p+=i;
   if p>122:p-=26
 a+=[n]
print(a.index(min(a)))

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

І мій оригінальний код, якщо когось цікавить.

Перетворює слово у список значень ASCII, потім повторює кроки розмірами від 0 до 25, перевіряючи, скільки кроків потрібно, щоб вичерпати список (є стеля для зупинки нескінченних циклів).

Кількість кроків додається до списку a .

Після великого циклу друкується індекс найменшого значення в a . Це дорівнює значенню i (розмір кроку) для цієї ітерації циклу, QED.


1
Привіт і Ласкаво просимо до PPCG! Для початку ваш розміщений байт не відповідає такому в TIO :) Тепер для декількох швидких підказок: range(26)достатньо - вам не потрібно вказувати початок, оскільки 0 за замовчуванням; a.append(n)міг бути a+=[n]; перший рядок був би коротшим, як карта w=list(map(ord,input()))(насправді, за вашим поточним алгоритмом, у Py2 ви також можете скинути list(...)обгортання); уникнути додаткових перерв розносу / ліній якомога більше (наприклад, немає необхідності в oneliners перекладів рядків: if p>122:p-=26)
Кирило Львович

1
Крім того, це n>99виглядає підозріло, чи це довільна константа, що вирветься з нескінченного циклу? Тоді, мабуть, має бути щось на зразок 26 * len (w), як ніколи не знаєте, наскільки великим буде вхід.
Кирило Л.

1
До речі, ви все одно можете позбутися цього list(...)в Py3, а також одного зайвого if: 165 байт . Також погляньте на це тему порад , я впевнений, що ви значно покращите свої навички, використовуючи поради звідти!
Кирило Л.

1
Я не експерт з пітонів, але я думаю, що ви можете зробити while p!=c and n>len(w)*26:та позбутися цього останнього, якщо заява на -8 байт.
Шпітемастер

2
Хоча це виглядає жахливо і суперечить усьому, що є Python, ви можете змінити n+=1і p+=iокремими лініями n+=1;p+=iна одну.
nedla2004
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.