fork download
  1. # @file pendulum.002.rb
  2. # Question-8 from some problem set.
  3. # @date 03/28/2026
  4.  
  5. # Rearrange the word so the character with the smallest ASCII value
  6. # is placed at the center, the second smallest to its right and the
  7. # third to its left and so on.
  8. #
  9. # Example-1: In : COMPUTER
  10. # Out: TPMCEORU
  11. #
  12. # Example-2: In : SCIENCE
  13. # Out: SIECCEN
  14. #
  15. # The problem specifies characters should be rearranged by invoking
  16. # the function 'int minimumCharIndex(String str)'.
  17.  
  18. def minimum_char_index(s)
  19. s.index(s.each_byte.min.chr) # faster than each_char.min
  20. end
  21.  
  22. def pendulum_0(s)
  23. s = s.dup
  24. n = s.size
  25. m = (n-1) / 2
  26. r = []
  27. n.times do |i|
  28. k = minimum_char_index(s)
  29. m = i.even? ? m-i : m+i
  30. r[m] = s.slice!(k)
  31. end
  32. r.join
  33. end
  34.  
  35. # Breaking the rules a bit.
  36.  
  37. def minimum_index(a, first, last)
  38. subarray = a[first...last]
  39. subarray.index(subarray.min) + first
  40. end
  41.  
  42. def pendulum_0_1(s)
  43. s = s.bytes
  44. n = s.size
  45. m = (n-1) / 2
  46. r = []
  47. n.times do |i|
  48. k = minimum_index(s, i, n)
  49. m = i.even? ? m-i : m+i
  50. r[m] = s[k]
  51. s[k] = s[i]
  52. end
  53. r.map(&:chr).join
  54. end
  55.  
  56. def swap!(a, i, j)
  57. a[i], a[j] = a[j], a[i] if i != j
  58. a
  59. end
  60.  
  61. def selectsort!(a)
  62. (a.size-1).times do |i|
  63. swap!(a, i, minimum_index(a, i, a.size))
  64. end
  65. a
  66. end
  67.  
  68. def pendulum_0_2(s)
  69. n = s.size
  70. m = (n-1) / 2
  71. r = []
  72. selectsort!(s.bytes).each_with_index do |x, i|
  73. r[m = i.even? ? m-i : m+i] = x
  74. end
  75. r.map(&:chr).join
  76. end
  77.  
  78. # Breaking the rules a bit more.
  79.  
  80. def pendulum_1(s)
  81. n = s.size
  82. m = (n-1) / 2
  83. r = []
  84. s.chars.sort!.each_with_index do |x, i|
  85. r[m = i.even? ? m-i : m+i] = x
  86. end
  87. r.join
  88. end
  89.  
  90. def pendulum_2(s)
  91. r = []
  92. s.chars.sort!.each_with_index do |x, i|
  93. r.public_send(i.even? ? :unshift : :push, x)
  94. end
  95. r.join
  96. end
  97.  
  98. def pendulum_3(s)
  99. t = s.chars.sort!
  100. l, r = t.drop(1).partition.each_with_index{|_, i| i.odd?}
  101. (l.reverse + t.take(1) + r).join
  102. end
  103.  
  104. def pendulum_4(s)
  105. l, r = (1...s.size).partition{|i| i.even?}
  106. s.chars.sort!.values_at(*l.reverse, 0, *r).join
  107. end
  108.  
  109. # Main.
  110.  
  111. def test(f)
  112. ss = ["", "a", "ba", "bca", "computer", "science"]
  113. rs = ["", "a", "ab", "cab", "tpmceoru", "sieccen"]
  114.  
  115. ss.zip(rs) do |s, r|
  116. s = f.call(s)
  117. if s != r
  118. puts ".Failed: expected `#{r}' got `#{s}'"
  119. return
  120. end
  121. end
  122. puts ".Passed"
  123. end
  124.  
  125. def time(f)
  126. def choices(pool, n)
  127. n.times.map{pool.sample}
  128. end
  129.  
  130. symbols = ('a'..'z').to_a
  131. elapsed = 0
  132.  
  133. 12.times do |i|
  134. s = choices(symbols, 2**i).join
  135. t = Time.now
  136. f.call(s)
  137. elapsed += Time.now - t
  138. end
  139. printf(".Elapsed: %.6fs\n", elapsed)
  140. end
  141.  
  142. fs = [
  143. :pendulum_0,
  144. :pendulum_0_1,
  145. :pendulum_0_2,
  146. :pendulum_1,
  147. :pendulum_2,
  148. :pendulum_3,
  149. :pendulum_4
  150. ]
  151.  
  152. fs.map(&method(:method)).each do |f|
  153. puts f.name
  154. test(f)
  155. time(f)
  156. end
Success #stdin #stdout 0.2s 37456KB
stdin
Standard input is empty
stdout
pendulum_0
.Passed
.Elapsed: 0.097306s
pendulum_0_1
.Passed
.Elapsed: 0.044082s
pendulum_0_2
.Passed
.Elapsed: 0.036619s
pendulum_1
.Passed
.Elapsed: 0.002647s
pendulum_2
.Passed
.Elapsed: 0.001967s
pendulum_3
.Passed
.Elapsed: 0.002730s
pendulum_4
.Passed
.Elapsed: 0.002822s