จดหมายย้าย!


35

รับสายคุณต้องย้ายตัวอักษรแต่ละตัว (เริ่มต้นจากตัวอักษรตัวแรก) ตามตำแหน่งในตัวอักษร หากคุณถึงจุดสิ้นสุดของสตริงคุณต้องล้อมรอบ ไม่จำเป็นต้องย้ายตัวอักษรที่ไม่ใช่

ตัวอย่าง:

Dog

Dเป็นตัวอักษรตัวที่สี่ในตัวอักษรดังนั้นเราจึงย้ายสี่จุดไปทางขวา oDgหลังจากตัดรอบที่มีการเปลี่ยนแปลงสตริง oคือตัวอักษรที่ 15 (15 mod 3) = 0 ดังนั้นมันจะไม่เคลื่อนที่ gคืออักษรที่ 7 - (7 สมัย 3) = 1 goDดังนั้นสตริงจะกลายเป็น

hi*bye

  • hคือตัวอักษรที่ 8 เลื่อน 8 จุด - hi*bye=>i*hbye
  • iคือตัวอักษรที่ 9 ย้าย 9 จุด - i*hbye=>*hbiye
  • bคือตัวอักษรตัวที่ 2 ให้ย้าย 2 สปอต - *hbiye=>*hiybe
  • yคือตัวอักษรที่ 25 เลื่อน 25 จุด - *hiybe=>*hibye
  • eคือตัวอักษรตัวที่ 5 ย้าย 5 สปอต - *hibye=>*hibey

ไม่จำเป็นต้องย้ายตัวอักษรที่ไม่ใช่ตัวอักษร แต่พวกเขายังคงใช้พื้นที่

  • cat => tca
  • F.U.N => .F.NU
  • mississippi => msiisppssii

เราต้องทำโปรแกรมแบบสแตนด์อโลนหรือฟังก์ชั่นเพียงพอหรือไม่? นอกจากนี้เราต้องพิมพ์สตริงหรือไม่
Katenkyo

อักขระใดที่สามารถปรากฏในอินพุตได้ ASCII ที่พิมพ์ได้? linefeeds? ASCII ใด ๆ Unicode ใด ๆ
Martin Ender

3
นอกจากนี้กรณีทดสอบที่มีตัวอักษรซ้ำ ๆ จะดีเช่นกัน
Martin Ender

@Martin ASCII ใด ๆ
geokavel

อนุญาตให้ใช้ฟังก์ชัน @Katenkyo หากคุณกำลังใช้ฟังก์ชั่นแล้วเอาท์พุทเป็นค่าตอบแทน
geokavel

คำตอบ:


6

CJam, 44 42 40 ไบต์

qN+ee_{Xa/~\+XW=eu__el=!\'@-*m<Xa+}fXWf=

เอาท์พุทมี linefeed ต่อท้าย

ทดสอบที่นี่

คำอธิบาย

แทนที่จะย้ายตัวอักษรผ่านสายอักขระฉันลบตัวอักษรซ้ำ ๆ หมุนสายอักขระตามลำดับจากนั้นแทรกตัวอักษรอีกครั้ง มีสิ่งหนึ่งที่ต้องทำเช่นนี้: เราจำเป็นต้องแยกแยะจุดเริ่มต้นของสตริงจากจุดสิ้นสุดของสตริง (ซึ่งเราไม่สามารถทำได้หลังจากการหมุนแบบธรรมดา) นั่นเป็นเหตุผลที่เราแทรก linefeed ที่ท้ายเป็นการ์ด (ตัวอักษรก่อน linefeed คือจุดสิ้นสุดของสตริงตัวอักษรหลังจากที่มันเป็นจุดเริ่มต้น) โบนัสคือสิ่งนี้จะส่งคืนสตริงสุดท้ายโดยอัตโนมัติไปยังการหมุนที่ถูกต้องโดยที่ linefeed จริง ๆ แล้วจะอยู่ที่ส่วนท้ายของสตริง

lN+     e# Read input and append a linefeed.
ee      e# Enumerate the array, so input "bob" would become [[0 'b] [1 'o] [2 'b] [3 N]]
        e# This is so that we can distinguish repeated occurrences of one letter.
_{      e# Duplicate. Then for each element X in the copy...
  Xa/   e# Split the enumerated string around X.
  ~     e# Dump the two halves onto the stack.
  \+    e# Concatenate them in reverse order. This is equivalent to rotating the current
        e# character to the front and then removing it.
  XW=   e# Get the character from X.
  eu    e# Convert to upper case.
  _     e# Duplicate.
  _el=! e# Check that convert to lower case changes the character (to ensure we have a
        e# letter).
  \'@-  e# Swap with the other upper-case copy and subtract '@, turning letters into 1 to
        e# 26 (and everything else into junk).
  *     e# Multiply with whether it's a letter or not to turn said junk into 0 (that means
        e# everything which is not a letter will be moved by 0 places).
  m<    e# Rotate the string to the left that many times.
  Xa+   e# Append X to the rotated string.
}fX
Wf=     e# Extract the character from each pair in the enumerated array.

เมื่อต้องการดูสาเหตุที่สิ่งนี้สิ้นสุดลงในตำแหน่งที่ถูกต้องให้พิจารณาการวนซ้ำล่าสุดของhi*byeตัวอย่าง หลังจากที่เราประมวลผลeแล้วสตริงที่แจกแจงจะอยู่ในตำแหน่งนี้:

[[4 'y] [6 N] [2 '*] [0 'h] [1 'i] [3 'b] [5 'e]]

อันดับแรกเราแบ่งแถว linefeed และต่อส่วนเข้าด้วยกัน:

[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y]]

linefeed ตอนนี้จะเป็นที่จุดเริ่มต้นหรือจุดสิ้นสุดของสตริงนี้ แต่เนื่องจากตัวป้อนบรรทัดเป็นเพียงตัวป้องกันที่ทำเครื่องหมายจุดสิ้นสุดของสายอักขระซึ่งหมายความว่าอักขระนั้นอยู่ในลำดับที่ถูกต้อง ตอนนี้ linefeed ไม่ใช่ตัวอักษรดังนั้นอาร์เรย์จะไม่หมุนเลย ดังนั้นเมื่อเราต่อท้าย linefeed มันจะไปที่ไหนและทุกอย่างอยู่ในลำดับที่เรากำลังมองหา:

[[2 '*] [0 'h] [1 'i] [3 'b] [5 'e] [4 'y] [6 N]]

ผลลัพธ์เพิ่มเติมบางอย่างถ้ามีคนต้องการเปรียบเทียบกรณีทดสอบที่ยาวกว่า:

Hello, World!
,W oeHlo!lrld

Programming Puzzles & Code Golf
ago fgliPomomnrr elP& uC dezzsG

The quick brown fox jumps over the lazy dog
t eg chbi ko qfTounyzrj omw epx ueoahs rlvd

abcdefghijklmnopqrstuvwxyz
aqbrcdsetfguhivjwklxmnyozp

zyxwvutsrqponmlkjihgfedcba
abcdefghijklmnopqrstuvwxyz

ฉันชอบอันสุดท้าย :)


Pyth ต้องการรายชื่อสับในรายการ
isaacg

@isaacg Nah ฉันแน่ใจว่ามันไม่ได้ ;)
Martin Ender

คุณสามารถสร้างมันเพื่อรองรับสตริงหลายบรรทัดได้หรือไม่?
geokavel

@geokavel โอ้ถูกต้องแก้ไขแล้ว
Martin Ender

sith ยินดี Darth Büttner
geokavel

4

ทับทิม 125 130 132 139ไบต์

->q{a=q.chars.map{|c|[c,c=~/[a-z]/i&&c.ord%32]}
while i=a.index{|c,s|s}
c,s=a.delete_at i
a.insert (i+s)%q.size,[c]
end
a*''}

การสาธิตออนไลน์พร้อมการทดสอบ: http://ideone.com/GYJm2u

เวอร์ชันเริ่มต้น (เวอร์ชันที่ไม่ได้แต่งแต้ม): http://ideone.com/gTNvWY

แก้ไข:ขอบคุณมากสำหรับการจัดการข้อเสนอแนะของเขา!

แก้ไข 2 : จำนวนตัวอักษรคงที่ (เริ่มแรกฉันนับจำนวนจุดสิ้นสุดของบรรทัด CRLF)


เพิ่งผ่านการทดสอบแทบ: →c.upcase.ord-64 c.ord%32
จัดการ

@ การทำงานที่ได้ผลดีขอบคุณ!
Cristian Lupascu

มองอีกครั้ง ... รอ! a.join??? คุณเป็นใครและคุณทำอะไรกับ w0lf a*''แน่นอนเขาจะเขียนว่ามันเป็น
จัดการ

@ การจัดทำ :) ฉันเสียใจมากเกี่ยวกับการมีwhile ... endในรหัสของฉันที่ฉันลืมที่จะทำ ขอบคุณที่สังเกต!
Cristian Lupascu

คุณไม่สามารถเปิดที่while ... endเข้ามา(...)while ...?
Martin Ender

3

Python 3, 278 275 273 270 260 258 249 248 243 238 ไบต์

ฉันควรตีกอล์ฟให้ดีกว่านี้จริงๆ แต่นี่เป็นวิธีแก้ปัญหาของฉันด้วยkatenkyoสำหรับความช่วยเหลือของเขาเกี่ยวกับตรรกะและCyoceและMegoสำหรับความช่วยเหลือในการเล่นกอล์ฟ

แก้ไข:ในที่สุดฉันได้รับมันไปหนึ่งคำสั่งเปรียบเทียบ แอ่ว! (และใช่ฉันสามารถย้ายที่z=-zเข้ามาa,m=m,aเล็กน้อย แต่ที่ไม่ได้บันทึกไบต์และมันงงรหัสมากกว่าที่ผมคิดว่าเป็นสิ่งที่จำเป็น)

แก้ไข:จำนวนไบต์ถูกปิด

def m(s):
 l=len(s);r=range(l);p=[[i,s[i]]for i in r]
 for i in r:
  if s[i].isalpha():
   a=p[i][0];p[i][0]=m=(a+ord(s[i])%32)%l;z=1
   if a>m:a,m=m,a;z=-z
   for j in r:p[j][0]-=z*(j!=i)*(a<=p[j][0]<=m) 
 return''.join(dict(p).values())

Ungolfed:

def move(string):
 length = len(string)
 places = [[i,string[i]]for i in range(length)]
 for index in range(length):
  char = string[index]
  if char.isalpha():
   a = places[index][0]
   mov = (a + ord(char)%32) % length
   places[index][0] = mov
   for j in range(length):
    k = places[j][0]
    if a <= k <= mov and j!=index:
     places[j][0]-=1
    elif mov <= k <= a and j != index:
     places[j][0]+=1
 return''.join(dict(places).values())

ฉัน * เชื่อ * ที่p[j][0]สามารถลดได้โดยการตั้งค่าJ=p[j];ที่จุดเริ่มต้นจากนั้นแทนที่อินสแตนซ์ของp[j][0]ด้วยP[0]
Cyoce

@Cyoce ฉันคิดว่าปัญหาคือฉันต้องแก้ไขpโดยตรงและไม่ใช่ตัวแปรที่p[j]กำหนดให้ นอกจากนี้ถ้าคุณดูประวัติการแก้ไขของฉันฉันก็มีตัวแปรk = p[j][0]สำหรับa<=k<=mการเปรียบเทียบ แต่มันกลับกลายเป็นว่าลดลงkก็ยังดีเพราะฉันบันทึกไบต์เพิ่มเติมเกี่ยวกับเยื้องจากเส้นพิเศษชุดกว่าที่ฉันบันทึกไว้โดยใช้k k
Sherlock9
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.