ก้าวตัวอักษรที่เหมาะสมที่สุด


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

@Shaggy แน่ใจว่าคุณทำได้
Jo King

มีเหตุผลนี้ใช้ตัวอักษรแทนตัวเลขหรือไม่
ข้าวสาลีตัวช่วยสร้าง

คำตอบ:


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 อินพุตเป็น bytestring และสามารถเป็นได้ทุกกรณี แต่ตัวพิมพ์ใหญ่จะมากได้เร็วขึ้น

อินพุตแบบอักษรเดี่ยวจะต้องใส่ซองพิเศษและราคา 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ỤḢ

อินพุตเป็น bytestring บน 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

Ruby , 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-only สำหรับแนวคิดการเล่นกอล์ฟที่มีมูลค่า 12 ไบต์


:( ปิด (อิงตามโซลูชันไพ ธ อน)
ASCII เท่านั้น

100อาจจะสามารถตีกอล์ฟได้มากกว่านี้เล็กน้อย
ASCII เท่านั้น


ความคิดที่ดี -1 ไบต์เพิ่มเติมโดยใช้p,=*sเคล็ดลับ แต่ฉันไม่แน่ใจเกี่ยวกับความแข็งแกร่งทางทฤษฎีของวิธีแก้ปัญหาด้วยคะแนนการลงโทษ hardcoded ... ดังนั้นฉันเปลี่ยนค่าคงที่เป็นอนันต์ (แม้ว่าค่าของคุณจะอนุญาตให้ปิดอีก 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 ไบต์จากtsh

-39 ไบต์จากJo King

รุ่นเก่าพร้อมคำอธิบาย:

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 ตัวพิมพ์ใหญ่) และส่งคืน Optimal Alphabet Stepping

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 bytes

ขอบคุณทุกคนสำหรับเคล็ดลับของคุณ! นี่คือสิ่งที่ดูเหมือนกอล์ฟมากขึ้น

*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จะถูกพิมพ์ นี่เท่ากับค่าของi (ขนาดขั้นตอน) สำหรับการวนซ้ำของลูปนั้น QED


1
สวัสดีและยินดีต้อนรับสู่ PPCG! สำหรับ starters การนับไบต์ที่โพสต์ของคุณไม่ตรงกับ 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
BTW คุณยังสามารถกำจัดlist(...)ใน Py3 และหนึ่งพิเศษif: 165 ไบต์ ดูที่หัวข้อเคล็ดลับนี้ฉันมั่นใจว่าคุณจะพัฒนาทักษะของคุณอย่างมากโดยใช้คำแนะนำจากที่นั่น!
คิริลล์ลิตร

1
ฉันไม่ได้เป็นผู้เชี่ยวชาญของงูหลาม แต่ฉันคิดว่าคุณสามารถทำได้while p!=c and n>len(w)*26:และกำจัดสิ่งนั้นทิ้งหากคำสั่งสำหรับ -8 ไบต์
Spitemaster

2
แม้ว่ามันจะดูแย่และขัดกับทุกอย่างที่ Python ใช้อยู่คุณสามารถเปลี่ยนn+=1และp+=iแยกบรรทัดเป็นn+=1;p+=iหนึ่งได้
nedla2004
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.