17
\$\begingroup\$

Given a string as an input (which can be any acceptable/convenient format in your language), implement pendulum encoding. The test cases are split into individual items (which aren't quoted) for a visually appealing explanation.

How do I do that?

The current iteration index starts at 0.

  • If the iteration index is even, append the current item onto the output string.
  • If the iteration index is odd, prepend the current item onto the output string.

An example

The input is [a b c d e f g].
Note that the letters a-g are individual one-character strings, to prevent confusion from the iteration index.
N: the iteration index

N:0 Out:      [a]
N:1 Out:    [b a]
N:2 Out:    [b a c]
N:3 Out:  [d b a c]
N:4 Out:  [d b a c e]
N:5 Out:[f d b a c e]
N:6 Out:[f d b a c e g]

The output should be [f d b a c e g].

Another example

The input is [u d l n u e m p].

N:0 Out:        [u]
N:1 Out:      [d u]
N:2 Out:      [d u l]
N:3 Out:    [n d u l]
N:4 Out:    [n d u l u]
N:5 Out:  [e n d u l u]
N:6 Out:  [e n d u l u m]
N:7 Out:[p e n d u l u m]

Test cases

Here's a sample program doing this encoding.

Take note that the characters in the string aren't always unique.

Your output *has* to be flattened.

[a,b,c,d,e,f,g]   -> [f,d,b,a,c,e,g]
[]                -> []
[a]               -> [a]
[a,b,c,d]         -> [d,b,a,c]
[a,b]             -> [b,a]
[a,b,d]           -> [b,a,d]
[a,b,a,c,b,c]     -> [c,c,b,a,a,b]
[a,a,b,b,c,c]     -> [c,b,a,a,b,c]
[u,d,l,n,u,e,m,p] -> [p,e,n,d,u,l,u,m]
\$\endgroup\$
  • \$\begingroup\$ Can I/O be a string? If not, may we output a 2D-array? \$\endgroup\$ – Shaggy Mar 23 at 8:52
  • \$\begingroup\$ yes I/O can be a string? \$\endgroup\$ – Shaggy Mar 23 at 9:14
  • \$\begingroup\$ @Shaggy Yes, I/O can be a string. Everyone else seems to be doing that. \$\endgroup\$ – Member for 3 months Mar 23 at 9:15

20 Answers 20

5
\$\begingroup\$

05AB1E, 4 bytes

ι`Rì

I/O as a list of characters.

Try it online or verify all test cases.

Explanation:

ι     # Uninterleave the (implicit) input-list (into 2 parts by default for lists)
      #  i.e. ["u","d","l","n","u","e","m","p"] → [["u","l","u","m"],["d","n","e","p"]]
 `    # Push both parts separated to the stack
  R   # Reverse the second part
      #  → ["p","e","n","d"]
   ì  # And prepend it in front of the first
      #  → ["p","e","n","d","u","l","u","m"]
      # (after which the result is output implicitly)
| improve this answer | |
\$\endgroup\$
18
\$\begingroup\$

Python 3, 29 bytes

lambda l:l[1::2][::-1]+l[::2]

Try it online!

Input: A sequence
Output: The pendulum encoding of that sequence

How
Consider the sequence [0,1,2,3,4,5], whose pendulum encoding is [5,3,1,0,2,4]. We can see that all even indices ended up in order on the right, and all odd indices are in reversed order on the left.

  • l[1::2][::-1] takes all odd indices and reverses them, e.g [5,3,1]
  • l[::2] takes all even indices, e.g [0,2,4]
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Too bad that you can’t simply write l[-2::-2] or similar instead of the longer and more complex l[1::2][::-1]. \$\endgroup\$ – David Foerster Mar 25 at 12:55
14
\$\begingroup\$

brainfuck, 24 21 18 bytes

,[[<],[>],<]>>[.>]

Try it online!

Thanks to Jo King for -3 bytes

,[          while input
  [<],      add new character to start of memory
  [>],      add new character to end of memory
  <         go one back, so the loop will run another time, moving the pointer to the start of memory
]
>>[.>]      print memory
| improve this answer | |
\$\endgroup\$
7
\$\begingroup\$

APL (Dyalog Unicode), 11 bytes

I promised you'll see at least one interesting answer :)

{⍵[⍋-\⍳≢⍵]}

Try it online!

Uses my own tip about -\⍳, specifically the variation, to generate the permutation needed for this challenge.

How it works

⍋-\⍳≢⍵ generates the target permutation for both even- and odd-length arrays:

⍋-\⍳≢⍵  ⍝ Length-7 vector  | Length-8 vector
    ≢   ⍝ Length
        ⍝ 7                | 8
   ⍳    ⍝ Range (1..n)
        ⍝ 1 2 3 4 5 6 7    | 1 2 3 4 5 6 7 8
 -\     ⍝ Cumulative alternating difference
        ⍝ 1 -1 2 -2 3 -3 4 | 1 -1 2 -2 3 -3 4 -4
⍋       ⍝ Grade up; permutation that will sort the input array
        ⍝ 6 4 2 1 3 5 7    | 8 6 4 2 1 3 5 7

Then ⍵[...] arranges the original elements in that particular order.

| improve this answer | |
\$\endgroup\$
7
\$\begingroup\$

JavaScript, 36 bytes

Feels like forever since I posted a JS solution here!

Input as an array, output as a string. Handling the empty array cost 3 bytes.

a=>a.reduce((x,y,z)=>z%2?y+x:x+y,"")

Try it online!

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ ... Did you outgolf Arnauld? \$\endgroup\$ – Member for 3 months Mar 23 at 10:16
  • 2
    \$\begingroup\$ @a'_' Not only that, but he managed used reduce instead of map! \$\endgroup\$ – Neil Mar 23 at 11:25
6
\$\begingroup\$

Haskell, 53 37 bytes

([]#)
p#(a:b:s)=(b:p++[a])#s
p#l=p++l

Try it online!

Golfed 16 bytes thanks to @xnor

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ 37 bytes by merging the bases cases. Note that the f= doesn't have to be counted. \$\endgroup\$ – xnor Mar 23 at 7:47
  • \$\begingroup\$ What does the first line do? \$\endgroup\$ – corvus_192 Mar 23 at 18:19
  • \$\begingroup\$ @corvus_192 It is easier to see if you click the "try it online" button. ([]#) defines the actual function that I am submitting, where # is an auxiliar function that takes two arguments; the left argument (that starts as []) is the string I'm building and the right argument is the string to be "parsed" \$\endgroup\$ – RGS Mar 23 at 18:33
  • \$\begingroup\$ @corvus_192 Also see this HaskellWiki entry. \$\endgroup\$ – Jonathan Frech Mar 24 at 3:55
4
\$\begingroup\$

JavaScript (ES6), 42 bytes

A recursive function taking and returning a string.

f=([c,...a],k,o='')=>c?f(a,!k,k?c+o:o+c):o

Try it online!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Red, 52 bytes

func[a][append reverse extract next a 2 extract a 2]

Try it online!

| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

J, 13 bytes

{~[:/:[:-/\#\

Try it online!

A J port of Bubbler's APL solution - don't forget to upvote his answer!

           #\  length of successive prefixes
        -/\    cumulative alternating difference
      [:       function composition (caps the previous two verbs as a fork)
    /:         grade up 
  [:           caps the fork
{~             use the list to index into the input (arguments reversed)
| improve this answer | |
\$\endgroup\$
3
\$\begingroup\$

Perl 5 +p, 30 bytes

$\=--$|%2?$\.$_:$_.$\for/./g}{

Try it online!

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Keg, -lp, -ir, -hd, 15 bytes

⑫&(&⑶+&)⒁2%[⒂|&

Try it online!

Purely a literal interpretation of the question plus a bit to ensure even length strings don't break.

Explained

⑫&

First, we start by storing an empty string (pushed by ) in the register. This will be used as the final output, meaning that it needs to be initalised.

(&⑶+&)

Then, we enter the main for loop, which has the implicit condition ! (take length of stack), as no explicit condition is provided. Now, there isn't anything on the stack at this point, so doing such a thing may seem pointless. But, by using the -lp flag (--lengthpops), we can have the ! command take input if the stack is empty and push the length of the input. Also, the -ir (--inputraw) command ensures that the input word is taken as a series of letters, rather than a single string.

Inside the for loop, we push the contents of the register, reverse it ( reverses the top item of the stack) and then add whatever is next to the register. By doing so, we achieve the process behind the main algorithm, as consecutive letters are appended in the desired order.

⒁2%

At this point, the encoding has been fully completed. However, if the string is of an even length, the result will be reversed in the register. This requires us to push the length of the register () and check to see if it is even.

[⒂|&

If the register is of odd length, then we reverse the register and push it onto the stack (). Otherwise, we simply push the register. -hd will then ensure that only the top item on the stack is printed.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Japt -P, 7 6 5 bytes

I/O as a string.

ó ÔvÔ

Try it

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Zsh, 26 bytes

for x y;a=($y $a $x)
<<<$a

Try it online!

Input is a list of characters.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Retina, 20 bytes

*>^`.(.)?
$1
1,2,`.

Try it online! Link includes test suite. Explanation:

*>`

Execute this stage and immediately output the result without actually changing the working string.

^`

Before making the replacements, reverse their order.

.(.)?
$1

Keep only alternate characters.

1,2,`.

Delete alternate characters.

29 bytes as a reusable function:

,V,2,`
O^$`.((?=(..)*$))?
$#1

Try it online! Link includes test cases. Explanation:

,V,2,`

Reverse all the characters except alternate characters.

O^$`.((?=(..)*$))?
$#1

Sort all characters by the parity of their position from the end, and then reverse the result. This means that alternate characters end up reversed and sorted to the start, leaving the remaining characters at the end, although technically having been reversed twice.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Charcoal, 13 bytes

F²«P✂θιLθ²←↷⁴

Try it online! Link is to verbose version of code. Explanation:

F²«

Loop over the even and alternate characters.

P✂θιLθ²

Print the current set of characters.

←↷⁴

Prepare to print the alternate characters backwards.

| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Java (JDK), 60 bytes

a->{var r="";for(var c:a)r=r.length()%2<1?r+c:c+r;return r;}

Try it online!

Alternative with Streams (62 bytes)

s->{int[]x={0};return s.reduce("",(a,b)->x[0]++%2<1?a+b:b+a);}

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Ruby, 42 bytes

f=->s,*w{s ?f[s[2..-1],s[1],*w,s[0]]:w*''}

Try it online!

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

PHP, 49 48 bytes

for(;$a=$argv[++$i];)$s=$i%2?$s.$a:$a.$s;echo$s;

Try it online!

Again, not a really great score for PHP..

EDIT: Thanks for @OlivierGrégoire for saving 1 byte

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

Icon, 62 bytes

procedure f(s)
t:=""
t[k:=|(0|1)\*s:k]:=pop(s)&\z
return t
end

Try it online!

Takes the input as a list of chars.

Icon, 66 bytes

procedure f(s)
t:=""
i:=1to*s&t[1-i%2:1-i%2]:=s[i]&\z
return t
end

Try it online!

Takes the input as a string.

procedure, return and end add a lot to the byte count :)

Icon's slice operator : can be used to insert substrings into strings, if the the two indices are equal. This s[1:1]:="a" prepends s with "a"; s[0:0]:="b" appends "b" to s. I start with an empty string t, scan the input string s and use the odd/even index i with the slice operator to prepend/append to t.

| improve this answer | |
\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 93 bytes

public static string P(this string a){int z=0;return a.Aggregate("",(x,y)=>z++%2>0?y+x:x+y);}

Try it online!

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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