079 Passcode derivation.sf 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  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. # General recursive solution.
  8. # Runtime: 5.275s
  9. func find_candidates(callback, a, b, re_a = Regex(a.join('.*?')), re_b = Regex(b.join('.*?')), a_i=0, b_i=0, solution=[]) {
  10. if ((solution.join =~ re_a) && (solution.join =~ re_b)) {
  11. callback(solution)
  12. return solution
  13. }
  14. if ((a_i <= a.end) && (b_i <= b.end) && (a[a_i] == b[b_i])) {
  15. __FUNC__(callback, a, b, re_a, re_b, a_i+1, b_i+1, [solution..., a[a_i]])
  16. }
  17. __FUNC__(callback, a, b, re_a, re_b, a_i+1, b_i, [solution..., a[a_i]]) if (a_i <= a.end);
  18. __FUNC__(callback, a, b, re_a, re_b, a_i, b_i+1, [solution..., b[b_i]]) if (b_i <= b.end);
  19. }
  20. var passcodes = %n[319 680 180 690 129 620 762 689 318 368 710 720 629 168 160 716 731 736 729 316 769 290 719 389 162 289 718 790 890 362 760 380 728].sort
  21. var candidates = [passcodes.shift.digits.flip]
  22. while (passcodes) {
  23. var b = passcodes.shift.digits.flip
  24. var new_candidates = []
  25. for a in (candidates) {
  26. find_candidates({|solution|
  27. new_candidates << solution
  28. }, a, b)
  29. }
  30. new_candidates.uniq!
  31. var best = new_candidates.min_by { .len }
  32. candidates = new_candidates.grep { .len == best.len }
  33. say "Found: #{candidates.len} candidates (best: #{best.join})"
  34. }
  35. say "Final candidates: #{candidates.map{.join}}"