18
\$\begingroup\$

The first Letters, Get Moving! was very popular, but had limited participation. This one will be easier to solve, but hopefully involve some tricks in golfing.

You are given a string of only lowercase letters. For each letter, with position in the alphabet m, move it so it becomes the mth letter from the end. If the value of m is longer than the length of the string, move it to the very front. Output only the fully transformed string.

Examples:

"giraffe"

  • 'g' is the 7th letter in the alphabet, it is already the 7th letter from the back, so leave it.
  • 'i' is the 9th letter, since 9 is bigger than the length of the word, it goes to the front, so the string becomes igraffe
  • 'r' is the 18th letter, like 'i' it goes to the front: rigaffe
  • 'a' is the 1st letter, it goes to the very end: rigffea
  • 'f' is the 6th letter, it becomes the 6th from the back: rfigfea
  • the next 'f' is also the 6th letter, so it also goes to 6th from the back : rffigea
  • 'e' is the 5th letters, it goes to 5th from the back: rfefiga

"flower"

  • 'f' (6) => flower
  • 'l' (12) => lfower
  • 'o' (15) => olfwer
  • 'w' (23) => wolfer
  • 'e' (5) => weolfr
  • 'r' (18) => rweolf

"pineapple"

  • 'p' (16) => pineapple
  • 'i' (9) => ipneapple
  • 'n' (14) => nipeapple
  • 'e' (5) => nipaepple
  • 'a' (1) => nipepplea
  • 'p' (16) => pnipeplea
  • 'p' (16) => ppnipelea
  • 'l' (12) => lppnipeea
  • 'e' (5) => lppneipea (make sure you move the e that hasn't been moved already! Here it doesn't matter, but below it does.)

Thanks to @Neil for improving the test cases with these 3 additions:

"pizza"

  • 'p' (16) => pizza
  • 'i' (9) => ipzza
  • 'z' (26) => zipza
  • 'z' (26) => zzipa (moving the second z!)
  • 'a' (1) => zzipa

"abracadabra"

  • 'a' (1) => bracadabraa
  • 'b' (2) => racadabraba
  • 'r' (18) => racadabraba
  • 'a' (1) => rcadabrabaa
  • 'c' (3) => radabrabcaa
  • 'a' (1) => rdabrabcaaa
  • 'd' (4) => rabrabcdaaa
  • 'a' (1) => rbrabcdaaaa
  • 'b' (2) => rrabcdaaaba
  • 'r' (18) => rrabcdaaaba
  • 'a' (1) => rrbcdaaabaa

"characters"

  • 'c' (3) => haractecrs
  • 'h' (8) => arhactecrs
  • 'a' (1) => rhactecrsa
  • 'r' (18) => rhactecrsa
  • 'a' (1) => rhctecrsaa
  • 'c' (3) => rhtecrscaa
  • 't' (20) => trhecrscaa
  • 'e' (5) => trhcrescaa
  • 'r' (18) => rtrhcescaa
  • 's' (19) => srtrhcecaa
\$\endgroup\$
0

9 Answers 9

9
\$\begingroup\$

CJam, 41 38 bytes

lee_S+W%\{Xa-X1='`-/(Xa+\L*+}fX1>W%1f=

Test it here.

\$\endgroup\$
2
  • \$\begingroup\$ Upvoting as it's the only other answer that works on all of my test cases. \$\endgroup\$
    – Neil
    Commented Jan 8, 2016 at 23:31
  • \$\begingroup\$ Shortest to pass all test cases! \$\endgroup\$
    – geokavel
    Commented Jan 14, 2016 at 19:57
5
\$\begingroup\$

Python 3, 78 bytes.

Saved 2 bytes thanks to orlp.
Saved 7 bytes thanks to DSM.

x=input()
y=[]
for z in x:m=max(len(x)-ord(z)+96,0);y[m:m]=z
print(''.join(y))

Builds the word as a list then joins it.

\$\endgroup\$
3
  • \$\begingroup\$ (q-p,0)[p>q] is longer than min(q-p,0). \$\endgroup\$
    – orlp
    Commented Jan 7, 2016 at 20:49
  • \$\begingroup\$ It is, but that doesn't do the same thing. That's always going to return 0 or a negative. \$\endgroup\$ Commented Jan 7, 2016 at 20:52
  • \$\begingroup\$ Sorry, I meant max(q-p,0). \$\endgroup\$
    – orlp
    Commented Jan 7, 2016 at 20:54
3
\$\begingroup\$

Python 2, 86 bytes

a=input();k=list(a)
for i in a:k.remove(i);k.insert(ord(i)-97,i)
print"".join(k)[::-1]

Python 3, 88 bytes

a=input();k=list(a)
for i in a:k.remove(i);k.insert(ord(i)-97,i)
print("".join(k)[::-1])

Examples

Python 2:

$ python2 test.py
"flower"
rweolf

Python 3:

$ python3 test.py
flower
rweolf
\$\endgroup\$
1
  • 3
    \$\begingroup\$ k.remove removes the first instance, so this is going to fail for something like baa. \$\endgroup\$
    – Sp3000
    Commented Jan 7, 2016 at 21:50
2
\$\begingroup\$

Javascript ES6, 136 134 131 bytes

s=>([...s].map(c=>{s=s.replace(c,'');p=s.length+97-c.charCodeAt();s=s.substr(0,p)+c.toUpperCase()+s.substring(p)}),s.toLowerCase())

Note that I take great care not to move the same character twice, otherwise pizza turns into zipza when it should be zzipa. There's also an edge case dealing with not removing characters prematurely; characters becomes maybe srtrchaeac or srtrheccaa if you do it wrongly but it should be srtrhcecaa. Another tricky word is abracadabra for which the output rrabaaadcba would be incorrect; rrbcdaaabaa would be correct.

Edit: Shaved off two bytes by using substring which automatically coerces its arguments to the range 0..length.

Edit: Shaved off three bytes by changing the first substring to substr as suggested by user81665.

\$\endgroup\$
6
  • \$\begingroup\$ I think you could use substr instead of substring. \$\endgroup\$
    – user81655
    Commented Jan 8, 2016 at 1:44
  • \$\begingroup\$ slice is better (I think). \$\endgroup\$ Commented Jan 8, 2016 at 2:07
  • \$\begingroup\$ @ՊՓԼՃՐՊՃՈԲՍԼ He can't because passing negative numbers into slice breaks it. \$\endgroup\$
    – user81655
    Commented Jan 8, 2016 at 2:28
  • \$\begingroup\$ oh forgot about that. \$\endgroup\$ Commented Jan 8, 2016 at 2:28
  • \$\begingroup\$ Yeah, there was a little mistake with the pizza test case you put on my post, but I fixed it. \$\endgroup\$
    – geokavel
    Commented Jan 9, 2016 at 7:23
2
\$\begingroup\$

Knight (v2), 58 bytes

;=i~!=sP;W<=i+1iLs=sI>0=l-L=tSs iT@-A=cGs iT95+c tSt lFcOs

Try it online!

expanded:

; = idx ~1 # ie -1
; = str PROMPT
; WHILE < (= idx + idx 1) (LENGTH str)
    ; = chr GET str idx 1 # ie get the char at index `idx`
    ; = tmp SET str idx 1 "" # delete that chr
    ; = index - (LENGTH str) (- (ASCII chr) 95)
    : = str
        IF (> 0 index)
            : + chr tmp
        # ELSE:
            : SET tmp index 0 chr # insert the char there
: OUTPUT str
\$\endgroup\$
2
  • \$\begingroup\$ How do you run this? When I click the triangle here I get an "Error: Missing argument 2 for func ';'"... \$\endgroup\$ Commented Nov 3, 2022 at 8:36
  • \$\begingroup\$ D'oh! I forgot to copy the Os at the end. updating now \$\endgroup\$
    – Sampersand
    Commented Nov 4, 2022 at 3:10
1
\$\begingroup\$

Pyth, 18 17 bytes

uXeS,Z-lzhx;HGHzk

Test Suite.

Iterates using reduce over the input string, inserting into a string, base case empty string, at the correct position.

\$\endgroup\$
1
\$\begingroup\$

𝔼𝕊𝕄𝕚𝕟, 23 chars / 40 bytes

ᴉⓜΞăМƲ ïꝈ-ᶛą$,0),0,$;Ξ⨝

Try it here (Firefox only).

Explanation

ᴉⓜΞăМƲ ïꝈ-ᶛą$,0),0,$;Ξ⨝ // implicit: ï=input, ᴉ=input split into chars, Ξ=empty array, ᶛ=lowercase alphabet
ᴉⓜ                      // map over input chars
   ΞăМƲ ïꝈ-ᶛą$,0),0,$;   // use splice to insert map item into Ξ at requested index
                      Ξ⨝ // join Ξ
                         // implicit output
\$\endgroup\$
1
\$\begingroup\$

Ruby, 56 bytes

Port of Morgan Thrapp's Python answer.

->x{y=[]
x.chars{y[[x.size-_1.ord+96,0].max,0]=_1}
y*""}

Attempt This Online!

\$\endgroup\$
1
\$\begingroup\$

05AB1E, 25 bytes

.āDvyUΣNsXQiIgAXнk2t+-]€н

Outputs as a list of characters.

Try it online or verify all test cases.

Explanation:

Unfortunately 05AB1E lacks a builtin to insert a character at a certain index without removing the current character at that index. So instead I'm using a sort-by, where I only modify the index of the current character.

.ā                  # Enumerate the (implicit) input-string, pairing each character with
                    # its (0-based) index (to make them all unique)
  D                 # Duplicate it
   v                # Loop over each pair `y` in this list:
    yU              #  Put pair `y` in variable `X`
    Σ               #  Sort the list of pairs by:
     N              #   Push the current sort-index
     s              #   Swap so the current pair is at the top of the stack
      XQi           #   If it's equal to pair `X`:
         Ig         #    Push the input-length
           A        #    Push the lowercase alphabet
            Xн      #    Push the character of pair `X`
              k     #    Get the (0-based) index of this character in the alphabet
               2t+  #    Add sqrt(2) to it (+1 to make it 1-based, and +0.414 so it'll
                    #    come before the actual integer-index)
                  - #    Subtract this index from the input-length
   ]                # Close both the sort-by and loop
    €               # Map over each pair
     н              #  And only leave its character
                    # (after which the list of characters is output implicitly)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.