def score(a)
return a.map.with_index{|x,i| (x-i).abs}.inject(&:+)
end
def qsort(a, cmp)
return a if a.size <= 1
pivot, lt, gt = a[0], [], []
a[1..-1].each{|x| (cmp[x,pivot] ? lt : gt) << x}
return qsort(lt, cmp) + [pivot] + qsort(gt, cmp)
end
def msort(a, cmp)
return a if a.size <= 1
a1 = msort(a[0...a.size/2], cmp)
a2 = msort(a[a.size/2..-1], cmp)
aa = []
aa << (cmp[a1[0],a2[0]] ? a1 : a2).shift while a1.size>0 && a2.size>0
return aa + a1 + a2
end
def bsort1(a, cmp)
a = a.dup
for s in 0...a.size
for i in 0...a.size-s-1
a[i], a[i+1] = a[i+1], a[i] unless cmp[a[i], a[i+1]]
end
end
return a
end
def bsort2(a, cmp)
a = a.dup
for s in 0...a.size
for i in 0...a.size-1
a[i], a[i+1] = a[i+1], a[i] unless cmp[a[i], a[i+1]]
end
end
return a
end
def ssort(a, cmp)
a = a.dup
h = 1
h = 3*h+1 while (3*h+1)*2 < a.size
while h>0
for i in h...a.size
k = i-h
while k>=0
a[k], a[k+h] = a[k+h], a[k] unless cmp[a[k], a[k+h]]
k -= h
end
end
h = (h-1)/3
end
return a
end
N = 100
qs = 0.0
ms = 0.0
bs1 = 0.0
bs2 = 0.0
ss = 0.0
cmp = lambda{|x,y| rand(10)==0 ? rand(2)==0 : x<y}
N.times do
a = [*0...52].shuffle
qs += score(qsort(a, cmp))
ms += score(msort(a, cmp))
bs1 += score(bsort1(a, cmp))
bs2 += score(bsort2(a, cmp))
ss += score(ssort(a, cmp))
end
puts "q #{qs/N}"
puts "m #{ms/N}"
puts "b1 #{bs1/N}"
puts "b2 #{bs2/N}"
puts "s #{ss/N}"
# your code goes here
ZGVmIHNjb3JlKGEpCglyZXR1cm4gYS5tYXAud2l0aF9pbmRleHt8eCxpfCAoeC1pKS5hYnN9LmluamVjdCgmOispCmVuZAoKZGVmIHFzb3J0KGEsIGNtcCkKCXJldHVybiBhIGlmIGEuc2l6ZSA8PSAxCgoJcGl2b3QsIGx0LCBndCA9IGFbMF0sIFtdLCBbXQoJYVsxLi4tMV0uZWFjaHt8eHwgKGNtcFt4LHBpdm90XSA/IGx0IDogZ3QpIDw8IHh9CglyZXR1cm4gcXNvcnQobHQsIGNtcCkgKyBbcGl2b3RdICsgcXNvcnQoZ3QsIGNtcCkKZW5kCgpkZWYgbXNvcnQoYSwgY21wKQoJcmV0dXJuIGEgaWYgYS5zaXplIDw9IDEKCglhMSA9IG1zb3J0KGFbMC4uLmEuc2l6ZS8yXSwgY21wKQoJYTIgPSBtc29ydChhW2Euc2l6ZS8yLi4tMV0sIGNtcCkKCWFhID0gW10KCWFhIDw8IChjbXBbYTFbMF0sYTJbMF1dID8gYTEgOiBhMikuc2hpZnQgd2hpbGUgYTEuc2l6ZT4wICYmIGEyLnNpemU+MAoJcmV0dXJuIGFhICsgYTEgKyBhMgplbmQKCmRlZiBic29ydDEoYSwgY21wKQoJYSA9IGEuZHVwCglmb3IgcyBpbiAwLi4uYS5zaXplCgkJZm9yIGkgaW4gMC4uLmEuc2l6ZS1zLTEKCQkJYVtpXSwgYVtpKzFdID0gYVtpKzFdLCBhW2ldIHVubGVzcyBjbXBbYVtpXSwgYVtpKzFdXQoJCWVuZAoJZW5kCglyZXR1cm4gYQplbmQKCmRlZiBic29ydDIoYSwgY21wKQoJYSA9IGEuZHVwCglmb3IgcyBpbiAwLi4uYS5zaXplCgkJZm9yIGkgaW4gMC4uLmEuc2l6ZS0xCgkJCWFbaV0sIGFbaSsxXSA9IGFbaSsxXSwgYVtpXSB1bmxlc3MgY21wW2FbaV0sIGFbaSsxXV0KCQllbmQKCWVuZAoJcmV0dXJuIGEKZW5kCgpkZWYgc3NvcnQoYSwgY21wKQoJYSA9IGEuZHVwCgloID0gMQoJaCA9IDMqaCsxIHdoaWxlICgzKmgrMSkqMiA8IGEuc2l6ZQoKCXdoaWxlIGg+MAoJCWZvciBpIGluIGguLi5hLnNpemUKCQkJayA9IGktaAoJCQl3aGlsZSBrPj0wCgkJCQlhW2tdLCBhW2sraF0gPSBhW2sraF0sIGFba10gdW5sZXNzIGNtcFthW2tdLCBhW2sraF1dCgkJCQlrIC09IGgKCQkJZW5kCgkJZW5kCgkJaCA9IChoLTEpLzMKCWVuZAoJcmV0dXJuIGEKZW5kCgpOICAgPSAxMDAKcXMgID0gMC4wCm1zICA9IDAuMApiczEgPSAwLjAKYnMyID0gMC4wCnNzICA9IDAuMApjbXAgPSBsYW1iZGF7fHgseXwgcmFuZCgxMCk9PTAgPyByYW5kKDIpPT0wIDogeDx5fQpOLnRpbWVzIGRvCglhID0gWyowLi4uNTJdLnNodWZmbGUKCXFzICs9IHNjb3JlKHFzb3J0KGEsIGNtcCkpCgltcyArPSBzY29yZShtc29ydChhLCBjbXApKQoJYnMxICs9IHNjb3JlKGJzb3J0MShhLCBjbXApKQoJYnMyICs9IHNjb3JlKGJzb3J0MihhLCBjbXApKQoJc3MgKz0gc2NvcmUoc3NvcnQoYSwgY21wKSkKZW5kCnB1dHMgInEgI3txcy9OfSIKcHV0cyAibSAje21zL059IgpwdXRzICJiMSAje2JzMS9OfSIKcHV0cyAiYjIgI3ticzIvTn0iCnB1dHMgInMgI3tzcy9OfSIKIyB5b3VyIGNvZGUgZ29lcyBoZXJl