part-01.fth 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  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. : find-max ( -- u1 )
  38. \ Put a zero on the stack as an initial value for max.
  39. 0
  40. begin puzzle-input-handle file-eof? not
  41. while
  42. sum-elf-calories max
  43. repeat ;
  44. find-max . cr
  45. puzzle-input-handle close-file