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[].

asked May 10, 2015 at 18:31
\$\endgroup\$
7
  • 6
    \$\begingroup\$ So basically a Bubble Sort algorithm ? \$\endgroup\$ Commented May 10, 2015 at 18:34
  • \$\begingroup\$ @Optimizer Correct \$\endgroup\$ Commented May 10, 2015 at 18:38
  • 1
    \$\begingroup\$ Do you have to print the intermediate steps? \$\endgroup\$ Commented May 10, 2015 at 18:50
  • \$\begingroup\$ Can you show more examples? \$\endgroup\$ Commented May 10, 2015 at 22:46
  • 7
    \$\begingroup\$ can we just return 1,2,3,4,5,6,7,8,9? \$\endgroup\$ Commented May 11, 2015 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

answered May 10, 2015 at 18:52
\$\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
answered May 10, 2015 at 19:02
\$\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.

answered May 10, 2015 at 19:22
\$\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.

answered May 11, 2015 at 8:15
\$\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.

answered May 11, 2015 at 9:18
\$\endgroup\$
5
  • \$\begingroup\$ Outputting additional things which were not requested by the question is considered to be a standard loophole. \$\endgroup\$ Commented May 11, 2015 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\$ Commented May 11, 2015 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\$ Commented May 11, 2015 at 10:06
  • \$\begingroup\$ @Optimizer Updated my answer accordingly. \$\endgroup\$ Commented May 11, 2015 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\$ Commented May 11, 2015 at 10:12
3
\$\begingroup\$

Retina, (削除) 95 (削除ここまで) 93 bytes

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

(.)1
11ドル
([^1])2
21ドル
([4-9])3
31ドル
([5-9])4
41ドル
([6-9])5
51ドル
([7-9])6
61ドル
(8|9)7
71ドル
)`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.)

answered May 10, 2015 at 18:45
\$\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 
answered May 10, 2015 at 20:39
\$\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>

answered May 11, 2015 at 10:09
\$\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
 )
answered May 10, 2015 at 22:48
\$\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.

answered May 10, 2015 at 21:41
\$\endgroup\$
1
  • \$\begingroup\$ 127 bytes \$\endgroup\$ Commented Jul 13, 2020 at 2:21
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.

answered May 11, 2015 at 16:35
\$\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
 }
 }
}
answered May 12, 2015 at 20:24
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.