8
\$\begingroup\$

The Question

Given a set of 9 numbers, m[], which contains only numbers 1 through 9 in a random order, with no two numbers being the same, create a program in any language which rearranges the number to be in numerical order (1, 2, 3, etc. etc.) by only switching two numbers which are next to each other (ie. 1, 3, 2 → 1, 2, 3).

Rules

  • You may only modify the set by switching two numbers which are next to each other
  • The ending numbers (1 through 9 in order) should be contained in m[]
  • You can use any language you would like
  • The answer with the smallest amount of bytes wins

Edit:

Your code does not have to print the output, but the rearranged array must be in m[].

\$\endgroup\$
  • 6
    \$\begingroup\$ So basically a Bubble Sort algorithm ? \$\endgroup\$ – Optimizer May 10 '15 at 18:34
  • \$\begingroup\$ @Optimizer Correct \$\endgroup\$ – Meow Mix May 10 '15 at 18:38
  • 1
    \$\begingroup\$ Do you have to print the intermediate steps? \$\endgroup\$ – xnor May 10 '15 at 18:50
  • \$\begingroup\$ Can you show more examples? \$\endgroup\$ – Ismael Miguel May 10 '15 at 22:46
  • 7
    \$\begingroup\$ can we just return 1,2,3,4,5,6,7,8,9? \$\endgroup\$ – Ewan May 11 '15 at 9:27

12 Answers 12

10
\$\begingroup\$

CJam, 15 bytes

q~A{{a+$~}*]}*p

How it works:

q~                     e# Read the CJam styled input array (For ex. [1 3 4 2 5 6 8 7 9])
  A{        }*         e# Run the loop 10 times. This is enough times for a 10 length
                       e# input array in a bubble sort
    {    }*            e# reduce
     a+$~              e# Rearrange the pair so that they are sorted
           ]           e# After each loop, wrap the numbers back into the array
              p        e# Print the array after the loops are done

Try it online here

\$\endgroup\$
9
\$\begingroup\$

Mathematica, 38 bytes

#//.{a___,b_,c_,d___}/;b>c:>{a,c,b,d}&

This is an unnamed function taking an array, which applies a replacement rule until the pattern cannot be found any more. The pattern is a list which has two consecutive elements b and c where b > c, and the rule says to swap the b and c but otherwise leave the array untouched.

There's a lot of syntactic sugar here, but the code is actually very readable if you know a bit of Mathematica:

# //. {a___,b_,c_,d___} /; b>c :> {a,c,b,d} &
^  ^     ^   ^          ^      ^            ^
|  |     |   |          |      |            |
|  |     |   | Declares an unnamed function |
|  |     |   |          |      |
| The function's argument      |
   |     |   |          |      |
   | Replace while possible... |
         |   |          |      |
         | Zero or more list elements.
             |          |      |
             | A single list element
                        |      |
                        | A condition for the pattern
                               |
                               | What to replace the pattern with
\$\endgroup\$
9
\$\begingroup\$

Python 3, 72 bytes

from random import*
while m!=sorted(m):p=randrange(8);m[p:p]=m.pop(p+1),

The bogosort (aka stupid sort) approach: swap neighbor elements randomly until the array will be sorted. Usually runs under a second.

2 bytes thanks to @xnor.

\$\endgroup\$
4
\$\begingroup\$

Python 2, 45

for i in range(8)*8:m[i:i+2]=sorted(m[i:i+2])

Cycles around the list, sorting consecutive pairs of elements. The index i cycles through 0,1,2,3,4,5,6,7 eight times, which guarantees all elements bubble through and the list is sorted.

\$\endgroup\$
4
\$\begingroup\$

Pyth, 13 - 15 bytes

Solution which performs the requested swapping, and produces no output:

#X=Qhf>FT.:Q2

Solution which performs the requested swapping, and prints out the intermediate state of the list at every step:

#QX=Qhf>FT.:Q2

Solution which performs the requested swapping, and prints out the final state of the list:

#X=Qhf>FT.:Q2;Q

Demonstration of the middle solution above.

The method of swapping adjacent values is taken from @Jakube's answer.

The program uses #, the loop until error statement, to swap an adjacent pair of misordered elements until no such pair exists, at which point h, the head function, throws an error, ending the program.

\$\endgroup\$
  • \$\begingroup\$ Outputting additional things which were not requested by the question is considered to be a standard loophole. \$\endgroup\$ – Optimizer May 11 '15 at 9:20
  • \$\begingroup\$ @Optimizer Actually, the OP doesn't mention output at all. It merely talks about modifying a set of numbers. Therefore, the same objection could be made about most of the answers here. I'll put a note about this in my answer. \$\endgroup\$ – isaacg May 11 '15 at 10:05
  • \$\begingroup\$ You should instead ask the OP. I just asked. But I think its given and you are simply abusing the silence to make your program shorter :P \$\endgroup\$ – Optimizer May 11 '15 at 10:06
  • \$\begingroup\$ @Optimizer Updated my answer accordingly. \$\endgroup\$ – isaacg May 11 '15 at 10:09
  • 1
    \$\begingroup\$ I vote for the first version, the set is sorted and no output is required. It's useful add an output just to verify that the program works, but that it's part of a test and not to be counted. \$\endgroup\$ – edc65 May 11 '15 at 10:12
3
\$\begingroup\$

Retina, 95 93 bytes

Not particularly competitive (and probably still golfable), but here we go...

(.)1
1$1
([^1])2
2$1
([4-9])3
3$1
([5-9])4
4$1
([6-9])5
5$1
([7-9])6
6$1
(8|9)7
7$1
)`98
89
<empty>
<empty>

Where <empty> should be an empty line.

Since all numbers are single digits, this just expects a string with all 9 digits as the input and will print 123456789 after successfully sorting it. Each stage performs a single swap and the )1` indicates that all but the last stage should be repeated until the result stops changing.

The empty stage at the end is necessary, because otherwise we would get intermediate results every time the 98 stage is processed.

Here are all the intermediate results (whenever it changes) for an example run:

451629387
451269387
451263987
451263978
415263978
412563978
412536978
412536798
412536789
142536789
124536789
124356789
123456789

(I obtained this by adding the : option to each stage, and got rid of consecutive duplicates manually.)

\$\endgroup\$
3
\$\begingroup\$

Pyth, 17 bytes

uXGhaf>FT.:G2]Z)Q

Switching items in a list is really expensive in Pyth. So here's a fun solution, that stretches the rules a little bit. It's probably not valid.

Try it online: Pyth Compiler/Executor

Explanation

First of all, the time complexity of my code is O(n^3). But this is not the interesting part. The question doesn't say anything about the complexity.

The critical part is, how I switch two elements in the list. Let's say I want to switch the elements m[3] and m[4]. I don't care about the indices 3 and 4 at all. I simply create a second list, that replaces every element equal to m[3] with the number m[4] and every number equal to m[4] with the value m[3]. Since the list doesn't contain duplicates, this simulates switching these two values. If there were duplicates, like in the input [1, 3, 2, 2], the output would be [1, 2, 3, 3]. And if you give the input [1, 2, 1], it would end in an infinite loop. I don't explicitly create the second list, it's just part of Pyth's implementation of the translate-method. If you print out the current lists (see here), it give the correct values, which you would expect.

                   implicit: Q = input list
u               Q  set G = Q, update G as long with the following statements, 
                   until it stops changing: 
         .:G2         all pairs (G[i],G[i+1])
     f>FT             filter for pairs T, where T[0] > T[1]
    a        ]Z       add to this list of pairs [0] 
                      (ensures that the filtered list is always non-empty)
   h                  take the first element
 XG            )      translate G by this pair (switches the values T[0] with T[1])
                   print implicitly at the end 
\$\endgroup\$
2
\$\begingroup\$

JavaScript (ES6) 56

A recursive function that rearranges the given list in place.

F=l=>l.some((v,i)=>v>l[++i]&&[l[i-1]=l[i],l[i]=v])&&F(l)

Notes

  • In JS, for any numeric value v : v > undefined == false, v < undefined == false. So going outside the array bounds is not a problem if we use the right comparison

  • When the array at last is sorted, the function inside 'some' return false and recursion ends

  • The value returned in case of a swap is a 2 element array, and its value is always 'truthy'. That works even when one or more array elements are 0

  • In fact the function works with any numeric input, not only single and not repeated digits. Did not found a way to take advantage from this OP constraint.

Test using snippet (in Firefox) - the snippet version output the current list values at each step.

F=l=>(log('L='+l), l.some((v,i)=>v>l[++i]&&[l[i-1]=l[i],l[i]=v])&&F(l))

function log(x) {
   L.innerHTML = L.innerHTML +x+'\n' 
}

function go() {
  l = I.value.split(/\D+/g).map(x=>x|0)
  F(l)
  O.innerHTML = '' + l
}  

go()
Unsorted: <input id=I value="2 8 4 7 5 3 9 1 6"><button onclick="go()">-></button>
<br>Sorted: <span id=O></span>
<br>Operations log:<br>
<pre id=L></pre>

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

Javascript (ES6), 66 61 53 bytes

Thanks to the new rule, I can reduce even further :)

f=x=>x.map((a,i)=>a<(b=x[--i])&&f(x,x[i]=a,x[i+1]=b))


// Snippet demo: (Firefox only)
f(z=prompt().split(/\D+/).map(x=>+x))
alert(z.join(', '));

Commented

f=x=> // recursive function f
    x.map( // map function to array
        (a, i)=> // a = current value, i = current index
            a < (b = x[--i]) && // poll value of previous index, compare less than
                                // comparison always false at first index as undefined will always be less
                f(x, x[i] = a, x[i + 1] = b) // if true, swap values and call f
    )
\$\endgroup\$
0
\$\begingroup\$

C, 183

main(c,d,s){int a[10];for(c=0;c<10;c++)scanf("%d", &a[c]);for (c=0;c<10;c++){for(d=0;d<10-c-1;d++){if(a[d]>a[d+1]){s=a[d];a[d]=a[d+1];a[d+1]=s;}}}for(c=0;c<10;c++)printf("%d", a[c]);}

It's not golfed yet, other than variable names.

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

Haskell, 59 bytes

s e(h:t)=min e h:max e h:t
f l=iterate(init.foldr s[9])l!!9

The function s puts an element e in front or at the second place of a list depending on if it's less or greater than the first element of the list. Folding s into the input list lets the smallest element bubble to the front. I'm folding into a list containing a single 9 which I immediately remove afterwards with init, so that I don't have to check for empty lists in s. iterate repeats the folding process forever creating a list of intermediate results. The final result is the 9th element of this list.

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

Perl, 68 bytes

{for(0..7){if($m[$_]>$m[$_+1]){splice@m,$_,2,$m[$_+1],$m[$_];redo}}}

Ungolfed code

 {                                             # Block runs once unless redo is called

     for (0..7) {                                 # Loop index is in $_

         if ($m[$_] > $m[$_+1]) {                 # Check if swap needed

             splice @m, $_, 2, $m[$_+1], $m[$_];  # Replace a two element slice of
                                                  # the array with those 
                                                  # two elements reversed

             redo                                 # Restart the block over
         }
     }
}
\$\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.