Skip to content

Instantly share code, notes, and snippets.

@inconvergent
Created June 19, 2019 20:30
Show Gist options
  • Save inconvergent/8b6ccfbde4fca7844c1962082ef07a7e to your computer and use it in GitHub Desktop.
Save inconvergent/8b6ccfbde4fca7844c1962082ef07a7e to your computer and use it in GitHub Desktop.
(defun do-lines-as-floats (fn n fx &key (buffer-width 80))
(declare (optimize (safety #.*sft*) (speed #.*spd*) (debug #.*dbg*))
(function fx) (fixnum n buffer-width))
(let ((buffer (make-array buffer-width :element-type 'character
:initial-element #\space)))
(with-open-file (is fn :direction :input)
(loop with res-values of-type (simple-array double-float) =
(make-array n :adjustable nil :initial-element 0d0
:element-type 'double-float)
for (val pos newl) =
(multiple-value-list (read-line-into-sequence buffer is
:eof-error-p nil))
while val
do (when newl
(with-input-from-string (in val :start 0 :end pos)
(loop with prev of-type fixnum = 0
with curr of-type fixnum = -1
for c = (peek-char #\space in nil nil)
for i of-type fixnum from 0 below n
while c
do (setf curr (file-position in)
(aref res-values i)
(parse-float:parse-float (the string val)
:start prev :end curr :type 'double-float)
prev (1+ curr))
(read-char in)
finally (setf (aref res-values i)
(parse-float:parse-float (the string val)
:start prev :end (the fixnum pos)
:type 'double-float))))
(funcall fx res-values))))))
@lispm
Copy link

lispm commented Jun 19, 2019

use something like this to read the floats

(defun floats-string->list (string)
  (loop with new-pos and number
        for start = 0 then new-pos
        for pos = (position #\space string :start start :test-not #'eql)
        while pos
        do (multiple-value-setq (number new-pos)
               (read-from-string string nil nil :start pos))
        while number
        collect number))

CL-USER 47 > (floats-string->list "1.3 2.4 1.2")
(1.3 2.4 1.2)

(defun floats-string->list (string)
  (loop with start = 0 and number
        for pos = (position #\space string :start start :test-not #'eql)
        while pos
        do (multiple-value-setq (number start)
               (read-from-string string nil nil :start pos))
        while number
        collect number))
(defun floats-string->list (string)
  (loop with number and start = 0 
        for pos = (position #\space string :start start :test-not #'eql)
        while pos
        do (setf (values number start)
                 (read-from-string string nil nil :start pos))
        while number
        collect number))

@lispm
Copy link

lispm commented Jun 19, 2019

Versions without POSITION

(defun floats-string->list (string)
  (loop with number and start = 0 
        for pos = (loop for i from start for c across string
                        unless (eql c #\space)
                        do (return i))
        while pos
        do (setf (values number start)
                 (read-from-string string nil nil :start pos))
        while number
        collect number))


(defun floats-string->list (string)
  (flet ((skip-space (string start)
           (loop for i from start for c across string
                 unless (eql c #\space)
                 do (return i))))
    (loop with number and start = 0 
          for pos = (skip-space string start)
          while pos
          do (setf (values number start)
                   (read-from-string string nil nil :start pos))
          while number
          collect number)))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment