Skip to content

Instantly share code, notes, and snippets.

@baweaver
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save baweaver/e19c0bf03621a278dfb8 to your computer and use it in GitHub Desktop.
Save baweaver/e19c0bf03621a278dfb8 to your computer and use it in GitHub Desktop.
def permutation_sorting_n4(my_array)
my_array
.map(&:to_s)
.permutation
.flat_map { |a|
a.join.to_i
}.max
end
def string_sorting_n4(my_array)
# We make a scoring algorithm for comparing the numbers
score = -> v {
# We use the first digit and multiply it by the average of the other digits, such that:
# 9 -> 81
# 90 -> 40.5
# 981 -> 54.0
# 909 -> 54.0
#
# The above failure is compensated for below in the sort.
v[0].to_i * (v.chars.map(&:to_i).reduce(:+) / v.length.to_f)
}
# Now to the solver
my_array
# First we want to have all the numbers as strings
.map(&:to_s)
# Then we lexigraphically sort it backwards
.sort { |a,b| b <=> a }
# and make groups based on the first digit (ie 9 and 90 end up in the same pool)
# as the first digit being greater will always give priority
.slice_when { |b, a| b[0] != a[0] }
# Then we compact the results of the sort
.flat_map { |xs|
xs.sort { |a,b|
# We use our scoring algorithm above
sa, sb = score[a], score[b]
# and use it with the comparator
compare = sb <=> sa
# If it's 0, we have a potential 981 vs 909 problem, so we compare numerically
# to compensate
compare.zero? ? (b.to_i <=> a.to_i) : compare
}
}
.join
.to_i # and there we have our number
end
my_array = (1..100).to_a.sample(10)
permutation_way = -> _ { permutation_sorting_n4(my_array) }
string_way = -> _ { string_sorting_n4(my_array) }
puts "Array used: #{my_array}"
puts
puts "Permutation sort result: #{per = permutation_sorting_n4(my_array)}"
puts "String sort result: #{str = string_sorting_n4(my_array)}"
puts
puts "The results are #{per == str ? :equal : :not_equal}"
puts
string_method_benchmark = Benchmark.measure { 5.times(&string_way) }.real
permutation_method_benchmark = Benchmark.measure { 5.times(&permutation_way) }.real
puts "It took string sort #{string_method_benchmark} seconds to run 5 times"
puts "It took permutation sort #{permutation_method_benchmark} seconds to run 5 times"
puts
puts "Using permutations is #{permutation_method_benchmark / string_method_benchmark} times slower than using a sorting algorithm"
puts "or #{(string_method_benchmark / permutation_method_benchmark)*100} percenth of the time"
# Array used: [18, 30, 69, 10, 80, 38, 97, 43, 37, 76]
#
# Permutation sort result: 97807669433837301810
# String sort result: 97807669433837301810
#
# The results are equal
#
# It took string sort 0.00245954398997128 seconds to run 5 times
# It took permutation sort 35.3980373670347 seconds to run 5 times
# Using permutations is 14392.113949321169 times slower than using a sorting algorithm
# or 0.006948249600588849 percenth of the time
# Did not fail on the defaults, though I'd love to hear a counter in the comments.
def test_run(run_times: 100_000, max_int: 100, sample_size: 5)
run_times.times.map { |n|
my_a = (1..100).to_a.sample(5)
per = permutation_sorting_n4(my_a)
str = string_sorting_n4(my_a)
{array: my_a, permutation: per, string: str} if per != str
}.select(&:itself)
end
@baweaver
Copy link
Author

baweaver commented May 9, 2015

It handles larger numbers like a tank though (for ruby that is):

[65] pry(main)> Benchmark.measure { string_sorting_n4((1..100_000).to_a.sample(50)) }.real
=> 0.009160167013760656
[66] pry(main)> Benchmark.measure { string_sorting_n4((1..100_000).to_a.sample(500)) }.real
=> 0.03558827703818679
[67] pry(main)> Benchmark.measure { string_sorting_n4((1..1_000_000).to_a.sample(1000)) }.real
=> 0.097451273992192
[68] pry(main)> Benchmark.measure { string_sorting_n4((1..1_000_000).to_a.sample(100_000)) }.real
=> 8.706967013014946
[69] pry(main)> Benchmark.measure { string_sorting_n4((1..1_000_000).to_a.sample(10_000)) }.real                                                                                                              
=> 0.62532677303534
[70] pry(main)> Benchmark.measure { string_sorting_n4((1..1_000_000).to_a.sample(20_000)) }.real
=> 1.3599909140029922
[71] pry(main)> Benchmark.measure { string_sorting_n4((1..1_000_000).to_a.sample(15_000)) }.real
=> 0.9819273960310966

@baweaver
Copy link
Author

baweaver commented May 9, 2015

Though it's weak to numbers such as 909 vs 980, have to find a way to compensate. Likely prioritizing digits for sorting

@baweaver
Copy link
Author

baweaver commented May 9, 2015

[
  {array: [494, 902, 66, 658, 443], permutation: 90266658494443, string: 90265866494443},
  {array: [423, 183, 648, 7, 794],  permutation: 7947648423183,  string: 7794648423183},
  {array: [606, 84, 448, 890, 311], permutation: 89084606448311, string: 84890606448311},
  {array: [760, 467, 565, 47, 848], permutation: 84876056547467, string: 84876056546747},
  {array: [581, 92, 932, 483, 66],  permutation: 9329266581483,  string: 9293266581483},
  {array: [541, 92, 951, 883, 984], permutation: 98495192883541, string: 98492951883541},
  {array: [220, 88, 944, 136, 15],  permutation: 9448822015136,  string: 9448822013615},
  {array: [577, 8, 513, 383, 896],  permutation: 8968577513383,  string: 8896577513383},
  {array: [583, 274, 787, 918, 92], permutation: 92918787583274, string: 91892787583274},
  {array: [427, 519, 928, 442, 54], permutation: 92854519442427, string: 92851954442427},
  {array: [629, 404, 829, 560, 84], permutation: 84829629560404, string: 82984629560404},
  {array: [614, 931, 890, 983, 8],  permutation: 9839318908614,  string: 9839318890614},
  {array: [890, 757, 749, 85, 581], permutation: 89085757749581, string: 85890757749581},
  {array: [856, 108, 311, 46, 482], permutation: 85648246311108, string: 85646482311108},
  {array: [579, 26, 235, 528, 255], permutation: 57952826255235, string: 57952825526235},
  {array: [585, 57, 327, 994, 581], permutation: 99458558157327, string: 99458557581327},
  {array: [200, 524, 84, 423, 863], permutation: 86384524423200, string: 84863524423200},
  {array: [2, 214, 38, 523, 503],   permutation: 523503382214,   string: 523503382142},
  {array: [76, 667, 61, 170, 773],  permutation: 7737666761170,  string: 7677366761170},
  {array: [129, 67, 682, 424, 549], permutation: 68267549424129, string: 67682549424129},
  {array: [772, 633, 328, 34, 588], permutation: 77263358834328, string: 77263358832834},
  {array: [780, 94, 938, 503, 116], permutation: 94938780503116, string: 93894780503116},
  {array: [80, 805, 30, 339, 327],  permutation: 8080533932730,  string: 8058033932730},
  {array: [950, 196, 295, 92, 724], permutation: 95092724295196, string: 92950724295196},
  {array: [634, 292, 4, 437, 814],  permutation: 8146344437292,  string: 8146344374292},
  {array: [658, 769, 134, 72, 742], permutation: 76974272658134, string: 76972742658134},
  {array: [363, 399, 51, 94, 953],  permutation: 9539451399363,  string: 9495351399363},
  {array: [500, 25, 248, 54, 226],  permutation: 5450025248226,  string: 5450024825226},
  {array: [317, 538, 85, 881, 634], permutation: 88185634538317, string: 85881634538317},
  {array: [77, 785, 96, 685, 449],  permutation: 9678577685449,  string: 9677785685449},
  {array: [297, 48, 494, 843, 655], permutation: 84365549448297, string: 84365548494297},
  {array: [41, 783, 956, 836, 83],  permutation: 9568383678341,  string: 9568368378341},
  {array: [678, 613, 242, 825, 68], permutation: 82568678613242, string: 82567868613242},
  {array: [421, 665, 41, 784, 64],  permutation: 7846656442141,  string: 7846656441421},
  {array: [851, 568, 82, 811, 426], permutation: 85182811568426, string: 82851811568426},
  {array: [652, 46, 447, 663, 673], permutation: 67366365246447, string: 67366365244746},
  {array: [979, 105, 159, 255, 26], permutation: 97926255159105, string: 97925526159105},
  {array: [273, 45, 310, 448, 491], permutation: 49145448310273, string: 49144845310273},
  {array: [879, 892, 379, 315, 33], permutation: 89287937933315, string: 89287937931533},
  {array: [536, 584, 54, 767, 626], permutation: 76762658454536, string: 76762658453654},
  {array: [240, 53, 703, 479, 517], permutation: 70353517479240, string: 70351753479240},
  {array: [520, 536, 853, 345, 50], permutation: 85353652050345, string: 85353650520345},
  {array: [592, 622, 58, 848, 881], permutation: 88184862259258, string: 88184862258592},
  {array: [917, 561, 750, 707, 5],  permutation: 9177507075615,  string: 9177507075561},
  {array: [1, 16, 128, 655, 565],   permutation: 655565161281,   string: 655565128161},
  {array: [308, 33, 764, 297, 8],   permutation: 876433308297,   string: 876430833297},
  {array: [607, 573, 680, 62, 928], permutation: 92868062607573, string: 92868060762573},
  {array: [905, 64, 591, 639, 535], permutation: 90564639591535, string: 90563964591535},
  {array: [6, 658, 844, 201, 273],  permutation: 8446658273201,  string: 8446586273201},
  {array: [946, 316, 33, 376, 868], permutation: 94686837633316, string: 94686837631633},
  {array: [753, 74, 160, 581, 648], permutation: 75374648581160, string: 74753648581160},
  {array: [25, 762, 903, 46, 229],  permutation: 9037624625229,  string: 9037624622925},
  {array: [587, 668, 11, 104, 809], permutation: 80966858711104, string: 80966858710411}
]

Small sample of failed cases. Working on reconciling, definitely an issue of digit priority.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment