part-02-improved.fth 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. : input-filename s" input" ;
  2. 256 Constant max-bytes-line
  3. Create line-buffer max-bytes-line 2 + allot
  4. input-filename r/o open-file throw Value puzzle-input-handle
  5. : not 0= ;
  6. \ Sum all calories an elf carries.
  7. : sum-elf-calories ( c-addr length -- ??? )
  8. \ Put 0 on the stack, as the initial accumulator value.
  9. 0
  10. begin
  11. \ Read the next line from the puzzle input.
  12. line-buffer max-bytes-line puzzle-input-handle read-line throw \ stack: acc length eof-flag
  13. swap \ stack: acc eof-flag length
  14. \ Check if more than 0 characters were read as a number.
  15. dup 0 > \ stack: acc eof-flag length more-than-0-chars-flag
  16. rot \ stack: acc length more-than-0-chars-flag eof-flag
  17. \ Check that both true.
  18. and \ stack: acc length flag
  19. while
  20. \ stack: acc length
  21. \ Put a float at the bottom for >number which requires a
  22. \ double to be at specific position.
  23. 0. \ stack: acc length 0. 0
  24. rot \ stack: acc 0. 0 length
  25. line-buffer swap \ stack: acc 0. 0 c-addr length
  26. >number \ stack: acc the-number 0 c-addr length
  27. 2swap \ stack: acc c-addr' length' the-number 0
  28. \ convert double to one integer number (?)
  29. d>s \ stack: acc c-addr' length' the-number
  30. \ Use the numbers here. For now only dropping them.
  31. -rot \ stack: acc the-number c-addr' length'
  32. 2drop \ stack: acc the-number
  33. \ Add up the calories.
  34. + \ stack: acc
  35. repeat
  36. drop ;
  37. : rotate-4 ( u1 u2 u3 u4 -- u2 u3 u4 u1 )
  38. { a b c d }
  39. b c d a ;
  40. : min-of-4 ( u u u u -- u )
  41. min min min ;
  42. : drop-min-of-4
  43. .s cr ; \ todo
  44. : find-max ( -- u1 )
  45. \ Put a zero on the stack as an initial value for max.
  46. 0
  47. begin puzzle-input-handle file-eof? not
  48. while
  49. sum-elf-calories
  50. \ If there are more than 3 calories sums, discard the
  51. \ lowest one.
  52. depth 3 > if drop-min-of-4 then
  53. .s cr
  54. repeat
  55. + + ;
  56. find-max . cr
  57. puzzle-input-handle close-file