26
\$\begingroup\$

Inspired by this question:

Make a function (or a full program) that receives a list of numbers and outputs the list rearranged, so that even-indexed numbers appear first, and odd-indexed numbers follow. The values of the numbers themselves don't affect ordering - only their indices do. All indices are zero-based.

For example:

Input: [0, 1, 2, 3, 4]

Output: [0, 2, 4, 1, 3]

Another example:

Input: [110, 22, 3330, 4444, 55555, 6]

Output: [110, 3330, 55555, 22, 4444, 6]

Use most natural representation for lists that your language has. There are no limitations on complexity (e.g. allocating a temporary list is OK - no need to do it in-place).

P.S. It should work for the empty list (empty input => empty output).

\$\endgroup\$
  • \$\begingroup\$ This is effectively the inverse of the current answers to this question \$\endgroup\$ – Peter Taylor Nov 19 '15 at 18:44
  • \$\begingroup\$ Can we assume that all list elements are positive or non-negative or something? \$\endgroup\$ – Martin Ender Nov 19 '15 at 21:43
  • \$\begingroup\$ @MartinBüttner Assume anything reasonable, maybe even that they are in the range 0...255. \$\endgroup\$ – anatolyg Nov 19 '15 at 21:47
  • \$\begingroup\$ Related \$\endgroup\$ – Alex A. Nov 20 '15 at 0:21
  • \$\begingroup\$ Can we output a comma-separated list? \$\endgroup\$ – Oliver Feb 25 at 12:11

33 Answers 33

1
\$\begingroup\$

Japt, 1 byte

ó

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Is this valid?? \$\endgroup\$ – ASCII-only Feb 24 at 5:43
  • \$\begingroup\$ I had this originally, too. Might be worth asking if the output format is acceptable. \$\endgroup\$ – Shaggy Feb 25 at 9:52
21
\$\begingroup\$

Python, 23 bytes

lambda x:x[::2]+x[1::2]

Try it online

\$\endgroup\$
  • 1
    \$\begingroup\$ Why lambda? Why not mu or nu? :P \$\endgroup\$ – Cows quack Nov 19 '15 at 18:59
  • 1
    \$\begingroup\$ @rayryeng I was only joking as you can see by the ":P" at the end of my comment :) \$\endgroup\$ – Cows quack Nov 19 '15 at 20:11
  • 5
    \$\begingroup\$ Yeah, you definitely should replace lambda by λ and reduce byte count by 5! :P \$\endgroup\$ – anatolyg Nov 19 '15 at 21:16
  • 3
    \$\begingroup\$ @anatolyg sounds like an idea for PEP submission! \$\endgroup\$ – Nick T Nov 20 '15 at 5:35
  • 2
    \$\begingroup\$ @ThomasKwa It's the right tool for the job :P \$\endgroup\$ – Mego Nov 21 '15 at 5:55
16
\$\begingroup\$

Pyth, 5

o~!ZQ

Try it online, or run a Test Suite

Explanation

o~!ZQ    ## implicit: Z = 0; Q = eval(input)
o   Q    ## sort Q using a supplied function
 ~!Z     ## Use the old value of Z, then set Z to be not Z
         ## This assigns a weight to each number in the list, for example given [0,1,2,3,4]
         ## This will give (value, weight) = [(0,0), (1,1), (2,0), (3,1), (4,0)]
         ## The values are sorted by weight and then by index
         ## This happens because Pyth is written in Python, which performs stable sorts
\$\endgroup\$
  • \$\begingroup\$ Genius! Beautiful. \$\endgroup\$ – isaacg Nov 20 '15 at 7:59
  • \$\begingroup\$ Wait, how does this work? \$\endgroup\$ – justhalf Nov 20 '15 at 9:37
  • \$\begingroup\$ @justhalf I've added some more explanation, does that clear it up? \$\endgroup\$ – FryAmTheEggman Nov 20 '15 at 13:48
11
\$\begingroup\$

CJam, 7 bytes

{2/ze_}

Pushes a block (the closest thing to an unnamed function) which transforms the top stack element as required.

Test it here.

Explanation

The explanation assumes that the top of the stack is the array [0 1 2 3 4]. The actual values don't affect the computation.

2/  e# Split the array into chunks of two: [[0 1] [2 3] [4]]
z   e# Zip/transpose, which works on ragged arrays: [[0 2 4] [1 3]]
e_  e# Flatten the result: [0 2 4 1 3]
\$\endgroup\$
9
\$\begingroup\$

Labyrinth, 28 25 24 23 22 bytes

" >
?!?:|}\{@
@\?"":)!

This was mad fun! :) That is by far the most densely compressed Labyrinth program I've written so far. I had so many versions at 20 and 21 bytes which almost worked that I'm still doubting this is optimal...

This takes input as a list of positive integers (with an arbitrary delimiter), and prints the result to STDOUT as linefeed-delimited integers.

The hunt for 20/21 bytes: I've checked all programs of the form

" XX
?!?X}\{@
@\?XX)!

where X is any reasonable character by brute force, but didn't find any valid solutions. Of course that doesn't mean that a shorter solution doesn't exist, but it's not possible to force 20-byte programs without a decent amount of assumptions on its structure.

Explanation

(The explanation is slightly outdated, but I'm still not convinced the solution is optimal, so I'll wait with updating this.)

So, normally Labyrinth programs are supposed to look like mazes. While the instruction pointer is in a corridor, it will follow that corridor. When the IP hits any kind of junction, the direction is determined based on the top value of Labyrinth's main stack (Labyrinth has two stacks, with an infinite amount of zeroes at the bottom). That normally means that any non-trivial loop will be quite expensive, because if you have non-wall cells all over the place everything is a junction, and in most cases the top of the stack won't have the right value for the IP to take the path you would like it to take. So what you do is you enlarge the loops such that they have a whole in the centre with only one well-defined entry and exit point each.

But this time I was really lucky and everything fit so well together, that I could squash it all into one big clump. :)

Control flow starts at the _ going South. The _ pushes a zero onto the main stack. That may seem like a no-op, but this increases the (non-implicit) stack depth to 1 which we'll need later.

? reads an integer from STDIN. If there are no more integers to be read, this pushes zero. In that case, the IP keeps moving South and @ terminates the program right away (because the input list is empty). Otherwise, the IP turns East.

We're now entering a very tight loop with two exit points:

 !?;
 \?
  ;

! prints the integer back to STDOUT, leaving only a zero on the stack. The IP keeps moving East, and ? reads the next integer. If that is non-zero, we take a right and move South. ? reads another one (the next even index). Again, if that is non-zero, we take a right and move West.

Then \ prints a linefeed without changing the stack, so we take another right, moving North. ! prints that next even-index integer. Since now there is at least one (positive) odd-index integer on the stack, we keep turning right and the loop repeats.

Once either of those ? hits the end of the list, they push a zero and move straight onto the corresponding ;, which discards that zero.

In the case that there was only a single element in the list, we're done (because we've printed that right away), so the IP would keep moving East all the way to the @, again terminating the program (printing a trailing linefeed on the way).

Otherwise, we need to print the odd-index integers as well. In that case the two paths (from the two exit points of the first loop) merge on the middle ", turning East in either case.

_ pushes a zero to avoid taking a left into the @, and ; discards that zero. Now we enter a new loop:

     "}
     ""

The IP enters this on the bottom-left cell, moving North, going around the loop in a clockwise sense. The } shifts the top of the main stack over to the auxiliary stack. While there is still an element on the stack, the IP keeps doing its thing. Once everything has been shifted to the auxiliary stack (and reversed in the process), the IP keeps moving East instead, entering the last loop:

       \{@
       #!

\ prints a linefeed again, { moves an item from the auxiliary stack back to main. If that was still an item of the list, it will be positive, and the IP turns South, where the item is printed with !. Then # pushes the stack depth (and now this is where the initial _ is important, because this # ensures a positive stack depth), so that the IP still turns right, through the \ and { again.

After we've printed everything, { pulls a zero from the bottom of the auxiliary stack, the IP continues East, and @ terminates the program.

\$\endgroup\$
8
\$\begingroup\$

MATLAB, 24

@(x)x([1:2:end 2:2:end])

similar to the python one.

Thanks @LuisMendo for saving 2 bytes!

\$\endgroup\$
  • 1
    \$\begingroup\$ Hey! Nice to see you in PPCG! \$\endgroup\$ – Luis Mendo Nov 19 '15 at 21:51
  • 3
    \$\begingroup\$ A little shorter: @(x)x([1:2:end 2:2:end]) \$\endgroup\$ – Luis Mendo Nov 19 '15 at 22:01
  • \$\begingroup\$ @LuisMendo Haha I am a bit scared of codegolf, but this one was so easy for MATLAB! Thanks for the tip ;) \$\endgroup\$ – Brain Guider Nov 20 '15 at 12:17
6
\$\begingroup\$

Haskell, 37 bytes

concat.foldr(\x[l,r]->[x:r,l])[[],[]]

Try it online!

The foldr recursively builds up the even list and odd list. Prepending an element to the list is updated by prepending it to the odd list and calling it the new even list, and calling the previous even list the new odd list. Then, the pair [l,r] is concaternated to l++r.

Thanks to Ørjan Johansen for saving 5 bytes using two-element lists in place of tuples.


42 bytes:

f l=[x|p<-[even,odd],(i,x)<-zip[0..]l,p i]

Adds indices to the list l and filters either the even or the odd ones.


g(a:_:l)=a:(g l)
g l=l
f l=g l++(g$drop 1 l)

Yet another format, for 44. The function g takes every even-indexed element. The odd indices are gotten by first dropping an element, then applying g. If l was guaranteed non-empty, we could safely just do tail for 41

g(a:_:l)=a:(g l)
g l=l
f l=g l++g(tail l)
\$\endgroup\$
  • 1
    \$\begingroup\$ yet another variant (39 bytes): l#(a:b:c)=a:(l++[b])#c;l#x=x++l;f=([]#) with f being the main function. \$\endgroup\$ – nimi Nov 19 '15 at 22:12
  • \$\begingroup\$ @nimi That's a nice solution, you should post it. \$\endgroup\$ – xnor Nov 20 '15 at 4:41
  • \$\begingroup\$ No, please include it in your post. It's just a combination of your #2 and #3. \$\endgroup\$ – nimi Nov 20 '15 at 10:20
  • 1
    \$\begingroup\$ You can save 5 bytes on your second version by using lists and concat instead of tuples and uncurry(++). \$\endgroup\$ – Ørjan Johansen Oct 16 '17 at 0:50
5
\$\begingroup\$

PowerShell v3+, 75 67 49 47 bytes

$l=,@()*2
$args|%{$l[($f=!$f)]+=$_}
$l[0]
$l[1]

Try it online!

Expects input via splatting, as shown on the TIO link.

Creates an matrix $l as an array of arrays, then pipes the input $args into a loop |%{}. Each time through the loop, we add an element to one of the two child arrays of $l by flip-flopping the $f variable using Boolean logic. The first time through, $f is $null, the ! of which is $true, or 1 when indexing into an array. This means the first element gets put into the second array of $l, so that's why $l[1] gets output first.

Props to TessellatingHeckler for the golfing assistance and this variation.
-2 bytes thanks to mazzy.


Caveats

Going strictly as the question is written, this is technically invalid, as PowerShell doesn't have a concept of "lists" as pseudo-immutable objects, only arrays or hash tables (aka dictionaries). So, I'm treating the question's line "Use most natural representation for lists that your language has" as asking about arrays, as that's the closest PowerShell has. Additionally, output is one element per line, since that's the default PowerShell way to write out an array. This means an input of (0,1,2,3,4) will output 0\r\n2\r\n4\r\n1\r\n3\r\n.

\$\endgroup\$
  • \$\begingroup\$ 47 bytes - $args+splatting instead $input and ,@()*2 instead @(),@() \$\endgroup\$ – mazzy Feb 24 at 10:00
4
\$\begingroup\$

F#, 79 77 56

fun x->List.foldBack(fun x (l,r)->x::r,l)x ([],[])||>(@)

Based on one of the Haskell answer

fun x->x|>List.indexed|>List.partition(fst>>(&&&)1>>(=)0)||>(@)|>List.map snd

We first index the list, then partition it with criteria : first item (the index) anded with 1 equal 0.
That gives us a pair of list of pairs ; first list will contains all indexed evens and the other the indexed odds.
From that we reassemble the two list with append operator and finally discard the index.

Edit : missed an obvious one there is no need to name the arg "xs" (habits) so can reduce to a 1-letter name


I also have a potential 76 bytes one which is basically the same one but defined as function composition. Problem is it doesn't compile as a value but will effectively work with any list argument given so unsure if it's ok or not :

List.indexed>>List.partition(fst>>(&&&)1>>(=)0)>>fun(e,o)->e@o|>List.map snd

Note: List.indexed is only available from F#4.0 despite not being documented in MSDN yet

\$\endgroup\$
  • \$\begingroup\$ Cutting-edge technology, cool! \$\endgroup\$ – anatolyg Nov 19 '15 at 19:08
  • 1
    \$\begingroup\$ @anatolyg It's fun, isn't it? \$\endgroup\$ – Conor O'Brien Nov 19 '15 at 23:13
  • \$\begingroup\$ I think this is similar to the Perl 6 code that I first tried. -> \xs { xs.pairs.classify( *.key%%2, :as( *.value ) ).map( *.value.Slip ) } Assuming |> in F# is roughly equivalent to the rightward feed operator ==> in Perl 6. I'm also only guessing as to what fst>>(&&&)1>>(=)0 does \$\endgroup\$ – Brad Gilbert b2gills Nov 19 '15 at 23:56
4
\$\begingroup\$

JavaScript (ES6), 52 bytes

It also does it in one pass

x=>x.map((v,i)=>x[(i*=2)>=(z=x.length)?i-z+--z%2:i])

F=x=>x.map((v,i)=>x[(i*=2)>=(z=x.length)?i-z+--z%2:i])

input.oninput = setValue;

function setValue() {
  var arr = input.value.match(/\d+/g) || [];
  unsorted.innerHTML = arr.join(', ');
  sorted.innerHTML = F(arr).join(', ');
}

setValue();
* {
  font-family: monospace
}

th {
  text-align: right;
  padding-right: 0.5em;
}
<input id="input" type="text" value="0 1 2 3 4 5 6"/>
<hr/>
<table>
  <tr>
    <th>Unsorted:</th>
    <td id="unsorted"></td>
  </tr>
  <tr>
    <th>Sorted:</th>
    <td id="sorted"></td>
  </tr>
</table>

\$\endgroup\$
  • \$\begingroup\$ You can omit the F= from the beginning; you can save a byte by using this: (i*=2)>=(z=x.length)?i-z+--z%2:i \$\endgroup\$ – Conor O'Brien Nov 19 '15 at 23:22
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Nice idea thanks! \$\endgroup\$ – George Reith Nov 19 '15 at 23:33
3
\$\begingroup\$

Julia, 23 bytes

i->i[[1:2:end;2:2:end]]
\$\endgroup\$
3
\$\begingroup\$

J, 8 bytes

/:0 1$~#

This is a monadic (one-argument) verb, used as follows:

  (/:0 1$~#) 110 22 3330 4444 55555 6
110 3330 55555 22 4444 6

Explanation

/:        Sort the input array according to
  0 1     the array 0 1
     $~   repeated enough times to be of length
       #  length of input
\$\endgroup\$
  • 1
    \$\begingroup\$ An alternative is /:0:`1:\ which is also 8 bytes. \$\endgroup\$ – miles Aug 2 '16 at 17:50
3
\$\begingroup\$

Jelly, 4 bytes

s2ZF

Try it online!

Based on Martin's CJam answer

s2ZF - Main link. Argument: L (a list) e.g.  [110, 22, 3330, 4444, 55555, 6]
s2   - Split into chunks of length 2         [[110, 22], [3330, 4444], [55555, 6]]
  Z  - Columns                               [[110, 3330, 55555], [22, 4444, 6]]
   F - Flatten                               [110, 3330, 55555, 22, 4444, 6]
\$\endgroup\$
2
\$\begingroup\$

Mathematica, 40 bytes

#[[;;;;2]]~Join~If[#=={},#,#[[2;;;;2]]]&

{}[[2;;;;2]] will throw an error.

\$\endgroup\$
2
\$\begingroup\$

Burlesque, 12 Bytes

J2ENj[-2EN_+

Usage as in:

blsq ) {0 1 2 3 4}J2ENj[-2EN_+
{0 2 4 1 3}
blsq ) {110 22 3330 4444 55555 6}J2ENj[-2EN_+
{110 3330 55555 22 4444 6}

Explanation:

J     -- duplicate
2EN   -- every 2nd element
j     -- swap
[-    -- tail
2EN   -- every 2nd element
_+    -- concatenate parts

Although once the new update is released you can do this with the new Unmerge built-in (which does the opposite of the merge ** built-in):

blsq ) {110 22 3330 4444 55555 6}J2ENj[-2EN**
{110 22 3330 4444 55555 6}
\$\endgroup\$
2
\$\begingroup\$

Perl, 35 33 bytes

perl -ape 'push@{$|--},$_ for@F;$_="@0 @1"'

31 bytes + 2 bytes for -ap. Reads a space-delimited string from STDIN:

$ echo 0 1 2 3 4 | perl -ape 'push@{$|--},$_ for@F;$_="@0 @1"'
0 2 4 1 3

$ echo 110 22 3330 4444 55555 6 | perl -ape 'push@{$|--},$_ for@F;$_="@0 @1"'
110 3330 55555 22 4444 6

When the input is empty, prints a single space, which I would consider equivalent to an empty list. If not, can be fixed at a cost of 4 bytes with:

perl -anE 'push@{$|--},$_ for@F;$,=$";say@0,@1'

(requires Perl 5.10+, prints a trailing newline)

or at a cost of 5 bytes with:

perl -ape 'push@{$|--},$_ for@F;$_=join$",@0,@1'

(no trailing whitespace)

How it works

This solution uses the -a flag, which splits the input on whitespace and puts the results in the @F array.

The real magic happens in the push:

push@{$|--},$_

The $| variable is normally used to force output flushing, but it has another interesting property: when decremented repeatedly, its value toggles between 0 and 1.

perl -E 'say $|-- for 0..4'
0
1
0
1
0

Taking advantage of the fact that there are no restrictions on identifiers specified via symbolic dereferencing, we alternately push array elements onto the @0 and @1 arrays, so @0 ends up with all the even-indexed elements and @1 with the odds. Then we simply concatenate the stringified arrays to get our output.

\$\endgroup\$
2
\$\begingroup\$

C, 70

Nothing special, just a index mapping function.

a=0;main(int c,int** v){for(c--;a<c;)puts(v[1+a*2%c+!(a++<c/2|c%2)]);}

Less golfed

a=0;
main(int c, int** v) {
  for(c--; a<c;)
    puts(v[1 + a*2%c + !(a++ < c/2 | c%2) ]);
}
\$\endgroup\$
1
\$\begingroup\$

Pyth, 8 bytes

+%2Q%2tQ

Relatively simple

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

Vitsy, 22 Bytes

Vitsy really wasn't made to do this...

r' 'Vl2/\[N{VO]l\[NVO]
r                       Reverse the implicit numerical input stack.
 ' 'V                   Save the "space" character as a global final variable.
     l2/\[....]         Repeat the stuff in the brackets the length of the input
                        stack divided by 2.
          N{VO          Output the top item of the stack as a number, then shift
                        the stack over once to the left, push a space, output it.
               l\[...]  For the rest of the stack, repeat that many times...
                  NVO   Output the top item of the stack as a number separated 
                        by a space.
\$\endgroup\$
1
\$\begingroup\$

Perl 6, 25 bytes

This is the shortest lambda I could come up with.

{|.[0,2...*],|.[1,3...*]} # 25 byte "Texas" version
{|.[0,2…*],|.[1,3…*]}     # 25 byte "French" version
say {|.[0,2…*],|.[1,3…*]}( ^5 ); # (0 2 4 1 3)␤

say ((0..4),('m'..'q'),(5..9)).map: {|.[0,2…*],|.[1,3…*]}
# ((0 2 4 1 3) (m o q n p) (5 7 9 6 8))␤


# bind it as a lexical sub
my &foo = {|.[0,2…*],|.[1,3…*]}

say foo [110, 22, 3330, 4444, 55555, 6]; # (110 3330 55555 22 4444 6)␤

say [~] foo 'a'..'z' # acegikmoqsuwybdfhjlnprtvxz␤
\$\endgroup\$
1
\$\begingroup\$

Minkolang 0.12, 15 bytes

$nI2:[i1+g]r$N.

Try it here.

Explanation

$n                 Read in all of input as numbers
  I2:              The length of the stack divided by 2 (n)
     [             Open for loop that repeats n times
      i1+          Loop counter + 1
         g         Gets the (i+1)th item from the stack and puts it on top
          ]        Close for loop
           r       Reverse the stack (for outputting)
            $N.    Output the whole stack as numbers and stop.
\$\endgroup\$
1
\$\begingroup\$

R, 49 bytes

q<-function(x)c(x[seq(x)%%2==1],x[seq(x)%%2==0])

Call it as q(blah). Or, if x already contains the list to be rearranged, then

c(x[seq(x)%%2==1],x[seq(x)%%2==0])

is just 35 bytes.

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

F#, 64

fun x->List.mapi(fun i l->l,i%2)x|>List.sortBy snd|>List.map fst

Inspired by Sehnsucht's answer (but not enough rep to comment).

Maps each value to a tuple where the second entry is the modulo of the list index, sorts by modulo, then maps back to the original value.

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

Prolog, 103 bytes

r([E,O|T],[E|A],[O|B]):-r(T,A,B).
r([],[],[]).
r([E],[E],[]).
p(L):-r(L,A,B),append(A,B,X),write(X).

Example

>p([1,2,3,4,5]).
[1,3,5,2,4]
\$\endgroup\$
1
\$\begingroup\$

bash and GNU coreutils, 68 bytes

We assume that the list is newline-separated and passed on standard input.

(paste - <(seq 0 5 9999)|tee x|grep 0$;grep 5$<x)|cut -f1|grep -v ^$

Unfortunately this will ignore any inputs beyond index 1999, so it doesn't quite meet the spec.

It also clobbers a hardcoded temporary file ('x'), which could be problematic if run in parallel, and it doesn't remove it afterwards. Sorry about that!

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

PHP, 78 69 bytes

PHP can chunk and slice, but not interleave arrays; that makes this a bit bulky:

function(&$a){while($i++<count($a)>>1)$a[]=array_splice($a,$i,1)[0];}

Call by reference or try it online.


first approach (programs for 78 bytes):

for(;++$i<$argc;)echo",",$argv[$i++];for($i=1;++$i<$argc;)echo",",$argv[$i++];

prints a leading comma; insert [!$i] before the first$argv to remove it.

Two other 78 byte solutions (print a leading and a trailing comma):

for($n=$argc-2|1;++$i<$argc*2;)$i&1?print",".$argv[$i]:$argv[$n+=2]=$argv[$i];
for($n=$argc-2;++$i<$argc*2;)$i&1?print",".$argv[$i]:$argv[1|$n+=2]=$argv[$i];

Run with php -nr '<code>' <arguments> or try them online

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

Japt, 3 bytes

ñÏu

Try it

ñÏu     :Implicit input of array
ñ       :Sort by
 Ï      :Passing the 0-based index of each through a function
  u     :  Modulo 2 of index

ó c

Try it

ó c     :Implicit input of array
ó       :Split into 2 arrays of every 2nd item
  c     :Flatten
        :Implicit output
\$\endgroup\$
0
\$\begingroup\$

Clojure/ClojureScript, 52 bytes

(defn f[l](flatten(map #(take-nth 2 %)[l(rest l)])))

Written in a ClojureScript REPL, should also be valid Clojure.

\$\endgroup\$
0
\$\begingroup\$

K, 10 bytes

{x@<2!!#x}

Based on the 5-byte Pyth answer.

\$\endgroup\$
0
\$\begingroup\$

Hassium, 191 Bytes

This one was pretty long :(
It reads the array from args, so run this with hassium file.has 0 1 2 3 4

func main(){a=args;e,o=[]for(c=0;c<a.length;c++)if(c%2==0)e.add(a[c])else o.add(a[c])print("["+(e+o).toString().replace("{", "").replace("}", "").replace("Array", "").replace("  ", "")+"]");}

Run and see expanded with test case here

\$\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.