Last active
August 29, 2015 14:20
-
-
Save baweaver/e19c0bf03621a278dfb8 to your computer and use it in GitHub Desktop.
Problem #4 without brute force - https://blog.svpino.com/2015/05/07/five-programming-problems-every-software-engineer-should-be-able-to-solve-in-less-than-1-hour
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Though it's weak to numbers such as 909 vs 980, have to find a way to compensate. Likely prioritizing digits for sorting
[
{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
It handles larger numbers like a tank though (for ruby that is):