Optimal Alfabe Adımlama


30

Yalnızca harflerden oluşan bir giriş dizgisine bakıldığında, herhangi bir harften başlayarak bir sarma alfabesi üzerinde tüm harfleri ziyaret etmek için gereken minimum adım miktarıyla sonuçlanan adım boyutunu döndürün.

Örneğin, kelimeyi alın dog. Eğer 1 büyüklüğünde bir adım kullanırsak, sonunda:

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

Toplam 30 adım için.

Ancak, eğer adım adım 11 kullanıyorsanız, şunu elde ederiz:

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

Toplam 6 adım için. Bu asgari adım miktarıdır, bu nedenle dönüş sonucu dogadım büyüklüğüdür; 11.

Test durumları:

"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

kurallar

  • Giriş, boş olmayan bir dize veya yalnızca harften oluşan harflerden oluşan bir karakter dizisi aolacaktır z(büyük veya küçük harfler arasında seçim yapabilirsiniz).
  • Çıktı 0 dizinlenmiş (yani aralık 0-25) veya 1 dizinlenmiş ( 1-26) olabilir
  • Bir kravat varsa, herhangi bir adım boyutunu veya hepsini çıkarabilirsiniz
  • Bu , yani her dil için en düşük bayt miktarı kazanıyor!

Boş girişi ele almamız gerekiyor mu?
pizzapants184

1
@ pizzapants184 Hayır. Girişin boş olmayacağını belirten soruyu güncelledim
Jo King

Bir karakter dizisi olarak girdi alabilir miyiz?
Shaggy

Yapabilirsiniz @Shaggy Emin
Jo Kral

Bunun rakam yerine harf kullanmasının bir nedeni var mı?
Buğday Sihirbazı

Yanıtlar:


6

Kömür , 41 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı bir versiyonudur. 0 endeksli. Açıklama:

Eβ

26 kademenin üzerinde döngü. (Aslında, burada küçük harfli alfabeyi dolaşıp dizin değişkenini kullanıyorum.)

Eθ∧μ

İlkinden sonra girişin her karakteri üzerinde döngü yapın.

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

26 kez döngü yapın ve girişin önceki karakteriyle başlayan (0 indeksli) belirtilen adım büyüklüğünde 26 adım atarak elde edilen karakter dizisini oluşturun.

⌕...λ

Girilen karakterin o dizedeki konumunu veya bulunamazsa -1 ile bulun.

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

Bulunamayan tüm konumların toplamını alın, bu durumda -1 kullanın.

≔...θ

Toplamları sakla.

⌊Φθ⊕ι

Minimum negatif olmayan toplamı bulun.

I⌕θ...

Bu toplam ile ilk adım boyutunu bulun ve yazdırın.


5

JavaScript, 143 bayt

w=>(a=[...Array(26).keys(m=1/0)]).map(s=>~[...w].map(c=>(t+=a.find(v=>!p|(u(c,36)+~v*s-u(p,36))%26==0),p=c),p=t=0,u=parseInt)+t<m&&(m=t,n=s))|n

Çevrimiçi deneyin!

Shaggy sayesinde [...Array(26).keys()]9 byte tasarruf sağlanıyor.



4

Jöle , 28 26 23 bayt

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

Çıktı 0 dizinli. Girdi bytestring ve her durumda olabilir, ancak büyük harf çok daha hızlı.

Tek harfli giriş özel harflerle yazılmalıdır ve 2 bayt tutar. ._.

Çevrimiçi deneyin!

Bunun bir kaba kuvvet yaklaşımı olduğunu unutmayın; dört veya daha fazla harf içeren girişler TIO'da zaman aşımına uğrar. Test paketi _39 "verimlilik" için hazırlanır.

Nasıl çalışır

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

Jöle , 17 bayt

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

Giriş, STDIN'de bir bytestring, çıkış 1 indeksli.

Çevrimiçi deneyin!

Nasıl çalışır

Ɠ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 bayt

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

Çevrimiçi deneyin!

Yorumlananlar

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

Ruby , 121 114 112 108 102 89 bayt

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

Çevrimiçi deneyin!

0 endeksli. Girdiyi karakter dizisi olarak alır.

Sadece 12 byte değerindeki golf fikirleri için ASCII sayesinde.


:( close (python çözümüne dayanarak)
ASCII-yalnızca

100 , muhtemelen biraz daha golf oynayabilir
ASCII sadece


Harika bir fikir, -1 daha bayt p,=*shile ile ama sabit kodlu bir ceza puanı ile bir çözümün teorik sağlamlığı konusunda pek emin değilim ... Bu yüzden, sabitin sonsuza dek değiştirdim (değeriniz 2 bayt için izin verse de) ).
Kirill L.

Sadece 2 bayt, fena değil
sadece ASCII

3

Python 2 , 230 222 216 194 169 bayt

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

Çevrimiçi deneyin!

- tsh’dan 22 bayt

- Jo King'den 39 bayt

Açıklamalı eski versiyon:

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

Çevrimiçi deneyin!

Bu, çok sayıda harften oluşan bir dilde daha kısa olacaktır float('inf')(sonsuz döngülere ihtiyaç duymaz ). Aslında, bu başvuru hala "aaa" gibi karakter dizileri için buna ihtiyaç duyacaktır. Bu gönderim şimdi 26*len(s)sonsuz döngüleri durduran bir üst sınır olarak kullanıyor .

Bu gönderi 0 dizinlidir (0 - 25 arası değerler döndürür).

f bir (n büyük harf) dize alır ve En İyi Alfabetik Adımlamayı döndürür

tdizeyi ve bir alfabeyi adım adım alan ve dizeyi bitirmek için gereken atlama sayısını döndüren (veya 26*len(s)imkansızsa) yardımcı bir işlevdir .


2
Kullanın while a!=A(c)and S<len(s)*26:ve kaldırabilirsiniz if a==i:return float('inf'), çünkü len(s)*26herhangi bir cevabın üst sınırı olabilir .
tsh





2

Kırmızı , 197 bayt

func[s][a: collect[repeat n 26[keep #"`"+ n]]m: p: 99 a: append/dup a a m
u: find a s/1 repeat n 26[v: extract u n
d: 0 foreach c s[until[(v/(d: d + 1) = c)or(d > length? v)]]if d < m[m: d p: n]]p]

Çevrimiçi deneyin!


2

05AB1E (eski) , 33 27 26 bayt

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

Eski sürümü kullanır çünkü yeni iç içe geçmiş bir haritanın ardından sonucu değiştirmek / kullanmak istediğinizde bir hata var gibi görünmektedir.

0 indeksli çıkış.

Çevrimiçi deneyin veya tüm test durumlarını doğrulayın .

Açıklama:

Ç                        # 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

Python 3 , 191 178 162 bayt

Tüm ipuçlarınız için herkese teşekkürler! bu çok daha golf gibi görünüyor.

*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)))

Çevrimiçi deneyin!

Ve eğer ilgilenirse orijinal kodum .

Sözcüğü bir ASCII değerleri listesine dönüştürür, ardından listeyi tüketmek için kaç adım atıldığını kontrol etmek için 0 - 25 adım boyutları arasında yinelenir (sonsuz döngüleri durdurmak için bir tavan vardır).

Listeye adım sayısı eklenir a .

Döngü İÇİN BÜYÜK sonra en küçük değerin endeks bir basılır. Bu , QED döngüsünün yinelemesi için i değerine eşittir (adım boyutu).


1
Merhaba ve PPCG'ye Hoşgeldiniz! Yeni başlayanlar için, gönderilen bayt sayınız TIO'da bununla eşleşmiyor :) Şimdi, birkaç hızlı ipucu için: range(26)yeterli - başlangıç ​​noktası belirtmeniz gerekmez, çünkü 0 varsayılandır; a.append(n)olabilir a+=[n]; ilk satır harita olarak daha kısa olacaktı w=list(map(ord,input()))(aslında şu anki algoritmanızla Py2'de list(...)sarmalamayı bırakabilirsiniz ); Ekstra aralık / satır sonları önlemek mümkün olduğunca (örneğin oneliners içinde satırsonlarının gerek: if p>122:p-=26)
Kirill L.

1
Ayrıca, bu n>99şüpheli görünen, sınırsız döngüden kurtulmak için keyfi bir sabit midir? O zaman büyük olasılıkla girişin ne kadar büyük olacağını asla bilmediğiniz gibi 26 * len (w) gibi bir şey olmalıdır.
Kirill L.

1
list(...)Btw, yine de py3 ve onlardan bir tane daha if: 165 bayt kurtulabilirsiniz . Ayrıca, bu ipuçlarına bir göz atın , oradaki önerileri kullanarak yeteneklerinizi büyük ölçüde artıracağınızdan eminim!
Kirill L.

1
Ben bir python uzmanı değilim, ama while p!=c and n>len(w)*26:-8 baytlık bir ifadeyle son sözlerden kurtulabildiğini düşünüyorum .
Spitemaster

2
Her ne kadar korkunç görünse ve Python'un her şeye aykırı olsa da , bir tanesine n+=1ve p+=iayrı hatlara geçiş yapabilirsiniz n+=1;p+=i.
nedla2004
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.