079 Passcode derivation -- v2.sf 1.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. #!/usr/bin/ruby
  2. # Author: Trizen
  3. # Date: 24 March 2022
  4. # https://github.com/trizen
  5. # Passcode derivation
  6. # https://projecteuler.net/problem=79
  7. # Solution using the longest chain in a tree.
  8. # Assumes that each passcode has no repeated digits and that there is only a solution.
  9. # Runtime: 0.251s
  10. func make_tree(matrix) {
  11. var tree = Hash()
  12. for entry in (matrix) {
  13. var ref = tree
  14. for d in (entry) {
  15. ref = (ref{d} := Hash())
  16. }
  17. }
  18. return tree
  19. }
  20. func longest_chain(tree, hash = tree, seen = Set()) {
  21. var candidates = []
  22. if (seen.has(hash.refaddr)) {
  23. return ''
  24. }
  25. hash.keys.sort.each {|key|
  26. if (tree.has(key)) {
  27. candidates << key+__FUNC__(tree, tree{key}, seen+hash.refaddr)
  28. }
  29. else {
  30. candidates << key+__FUNC__(tree, hash{key}, seen+hash.refaddr)
  31. }
  32. }
  33. candidates.max_by { .len }
  34. }
  35. var passcodes = %w[
  36. 319 680 180 690 129 620 762 689 318 368 710 720 629 168 160 716
  37. 731 736 729 316 769 290 719 389 162 289 718 790 890 362 760 380 728
  38. ].map{ .chars }
  39. var tree = make_tree(passcodes)
  40. say longest_chain(tree)