最適なアルファベットのステッピング


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

ルール

  • 入力は文字のみからなる文字の非空の文字列または配列になりますaz(あなたが大文字または小文字のどちらかを選択することができます)
  • 出力は0インデックス(つまり範囲0-25)または1インデックス(1-26)にできます
  • 同点の場合、任意のステップサイズまたはすべてを出力できます
  • これはなので、各言語の最小バイト数が勝ちです!

空の入力を処理する必要がありますか?
pizzapants184

1
@ pizzapants184号には、私は非空になります入力を指定するために質問を更新しました
ジョー・キングを

入力を文字の配列として受け取ることはできますか?
シャギー

@Shaggy Sure you can
ジョーキング

これが数字の代わりに文字を使用する理由はありますか?
小麦ウィザード

回答:


6

、41バイト

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

オンラインでお試しください!リンクは、コードの詳細バージョンです。0インデックス。説明:

Eβ

26のステップサイズでループします。(実際、ここで小文字のアルファベットをループし、インデックス変数を使用します。)

Eθ∧μ

入力の最初の文字の後の各文字をループします。

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

26回ループし、入力の前の文字から始まる(0から始まる)指定されたステップサイズで26ステップを実行することにより、文字列を生成します。

⌕...λ

その文字列内の入力の現在の文字の位置を見つけるか、見つからない場合は-1を見つけます。

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

見つからない場合を除き、すべての位置の合計を取ります。その場合、-1を使用します。

≔...θ

合計を保存します。

⌊Φθ⊕ι

最小の非負の合計を見つけます。

I⌕θ...

その合計で最初のステップサイズを見つけて出力します。



4

ゼリー28 26 23バイト

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

出力は0から始まります。入力はバイト文字列であり、どのような場合でも可能ですが、大文字の方がはるかに高速です。

1文字の入力は特殊なケースである必要があり、2バイトかかります。._。

オンラインでお試しください!

これは総当たり的なアプローチであることに注意してください。4文字以上の入力は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))

オンラインでお試しください!

コメント済み

2526s[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

Ruby121 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インデックス。入力を文字の配列として受け取ります。

12バイトに値するゴルフのアイデアをASCIIのみに感謝します。


:(閉じる(Pythonソリューションに基づく)
ASCIIのみ

100、おそらくかなり多くgolfedすることができます
ASCIIのみの


素晴らしいアイデアです、p,=*sトリックによって-1バイト多くなりますが、ハードコードされたペナルティスコアを使用したソリューションの理論的な堅牢性については確信がありません...だから、定数を無限に変更しました(ただし、値はさらに2バイトを許可しますが)。
キリルL.

2バイトのみ、悪くない
ASCIIのみ

3

パイソン2230の 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))

オンラインでお試しください!

tshから-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

Python 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

big forループの後、aの最小値のインデックスが出力されます。これは、ループのその反復QED のiの値(ステップサイズ)に等しくなります。


1
こんにちは、PPCGへようこそ!まず第一に、投稿されたバイト数はTIOのバイト数と一致しません:)さて、いくつかの簡単なヒント:range(26)十分です-0がデフォルトであるため、開始を指定する必要はありません。a.append(n)可能性がありa+=[n]ます。最初の行はmapとして短くなりw=list(map(ord,input()))ます(実際、現在のアルゴリズムでは、Py2ではlist(...)ラッピングもドロップできます)。余分なスペース/改行を可能な限り避けてください(たとえば、onelinersで改行が不要:if p>122:p-=26
Kirill L.

1
また、n>99疑わしいように見えますが、それは無限ループから抜け出すための任意の定数ですか?それから、おそらく26 * len(w)のようなものになるはずです。
キリルL.

1
ところで、あなたはまだlist(...)Py3 でそれを取り除くことができます、そしてもう1つ余分なif165バイト。また、このヒントトピックをご覧ください。そこからのアドバイスを使用して、スキルを大幅に向上させることができます。
キリルL.

1
私はpythonの専門家ではありませんが、while p!=c and n>len(w)*26:-8バイトの最後のifステートメントを削除できると思います。
Spitemaster

2
それはひどい見え、Pythonがあるすべてのものに反していますが、変更することができますn+=1p+=iに別々のライン上のn+=1;p+=i1に。
nedla2004
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.