lisp lang solution № 2
This commit is contained in:
parent
5983863625
commit
8a3a35064e
2 changed files with 120 additions and 0 deletions
67
lisp/ros/solution2.ros
Executable file
67
lisp/ros/solution2.ros
Executable file
|
|
@ -0,0 +1,67 @@
|
||||||
|
#!/bin/sh
|
||||||
|
#|-*- mode:lisp -*-|#
|
||||||
|
#|
|
||||||
|
exec ros -Q -- "$0" "$@"
|
||||||
|
|#
|
||||||
|
(progn ;;init forms
|
||||||
|
(ros:ensure-asdf)
|
||||||
|
#+quicklisp(ql:quickload '() :silent t)
|
||||||
|
)
|
||||||
|
|
||||||
|
(defpackage :ros.script.subset-sum.3983202585
|
||||||
|
(:use :cl))
|
||||||
|
(in-package :ros.script.subset-sum.3983202585)
|
||||||
|
|
||||||
|
(defun ten-to-bin (x len mask)
|
||||||
|
"Преобразует число в список бит (оптимизировано через сдвиги)"
|
||||||
|
(declare (optimize (speed 3) (safety 0))
|
||||||
|
(type fixnum x len)
|
||||||
|
(type (simple-array fixnum (*)) mask))
|
||||||
|
|
||||||
|
(let ((i 0))
|
||||||
|
(declare (type fixnum i))
|
||||||
|
;; Пока число не 0 и мы в пределах len
|
||||||
|
(loop while (and (> x 0) (< i len)) do
|
||||||
|
(setf (aref mask i) (logand x 1)) ; (x & 1)
|
||||||
|
(setf x (ash x -1)) ; (x >>= 1)
|
||||||
|
(incf i))
|
||||||
|
i))
|
||||||
|
|
||||||
|
(defun calculate-sum (len numbers mask)
|
||||||
|
(declare (type fixnum len)
|
||||||
|
(type (simple-array fixnum (*)) numbers mask))
|
||||||
|
|
||||||
|
(let ((sum 0))
|
||||||
|
(declare (type fixnum sum))
|
||||||
|
(dotimes (i len sum)
|
||||||
|
(setf sum (the fixnum (+ sum (the fixnum (* (aref numbers i) (aref mask i)))))))))
|
||||||
|
|
||||||
|
(defun find-sum (target len numbers mask)
|
||||||
|
"Перебирает все комбинации (через битовые маски) для поиска целевой суммы."
|
||||||
|
(declare (optimize (speed 3) (safety 0))
|
||||||
|
(type (simple-array fixnum(*)) numbers)
|
||||||
|
(type (simple-array fixnum(*)) mask)
|
||||||
|
(type fixnum target)
|
||||||
|
(type (integer 0 62) len))
|
||||||
|
|
||||||
|
(let* ((total-combinations
|
||||||
|
(1- (ash 1 (the (integer 0 61) (- len 1))))))
|
||||||
|
(declare (type fixnum total-combinations))
|
||||||
|
(format t "~D~%" total-combinations)
|
||||||
|
(loop for i from 0 to total-combinations do
|
||||||
|
(let* ((current-sum (calculate-sum (ten-to-bin i len mask) numbers mask)))
|
||||||
|
(declare (type fixnum current-sum))
|
||||||
|
(when (= current-sum target)
|
||||||
|
(return mask))))))
|
||||||
|
|
||||||
|
(defun main (&rest args)
|
||||||
|
(if (or (< (length args) 5) (> (length args) 30))
|
||||||
|
(progn
|
||||||
|
(format t "ER: input parameters~%")
|
||||||
|
(uiop:quit 1))
|
||||||
|
(progn
|
||||||
|
(let* ((len (length args))
|
||||||
|
(target (parse-integer (first args)))
|
||||||
|
(mask (make-array len :element-type 'fixnum :initial-element 0))
|
||||||
|
(numbers (coerce (mapcar #'parse-integer (rest args)) '(simple-array fixnum (*)))))
|
||||||
|
(find-sum target len numbers mask)))))
|
||||||
53
lisp/solution2.lisp
Normal file
53
lisp/solution2.lisp
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
(defun ten-to-bin (x len mask)
|
||||||
|
"Преобразует число в список бит (оптимизировано через сдвиги)"
|
||||||
|
(declare (optimize (speed 3) (safety 0))
|
||||||
|
(type fixnum x len)
|
||||||
|
(type (simple-array fixnum (*)) mask))
|
||||||
|
|
||||||
|
(let ((i 0))
|
||||||
|
(declare (type fixnum i))
|
||||||
|
;; Пока число не 0 и мы в пределах len
|
||||||
|
(loop while (and (> x 0) (< i len)) do
|
||||||
|
(setf (aref mask i) (logand x 1)) ; (x & 1)
|
||||||
|
(setf x (ash x -1)) ; (x >>= 1)
|
||||||
|
(incf i))
|
||||||
|
i))
|
||||||
|
|
||||||
|
(defun calculate-sum (len numbers mask)
|
||||||
|
(declare (type fixnum len)
|
||||||
|
(type (simple-array fixnum (*)) numbers mask))
|
||||||
|
|
||||||
|
(let ((sum 0))
|
||||||
|
(declare (type fixnum sum))
|
||||||
|
(dotimes (i len sum)
|
||||||
|
(setf sum (the fixnum (+ sum (the fixnum (* (aref numbers i) (aref mask i)))))))))
|
||||||
|
|
||||||
|
(defun find-sum (target len numbers mask)
|
||||||
|
"Перебирает все комбинации (через битовые маски) для поиска целевой суммы."
|
||||||
|
(declare (optimize (speed 3) (safety 0))
|
||||||
|
(type (simple-array fixnum(*)) numbers)
|
||||||
|
(type (simple-array fixnum(*)) mask)
|
||||||
|
(type fixnum target)
|
||||||
|
(type (integer 0 62) len))
|
||||||
|
|
||||||
|
(let* ((total-combinations
|
||||||
|
(1- (ash 1 (the (integer 0 61) (- len 1))))))
|
||||||
|
(declare (type fixnum total-combinations))
|
||||||
|
(format t "~D~%" total-combinations)
|
||||||
|
(loop for i from 0 to total-combinations do
|
||||||
|
(let* ((current-sum (calculate-sum (ten-to-bin i len mask) numbers mask)))
|
||||||
|
(declare (type fixnum current-sum))
|
||||||
|
(when (= current-sum target)
|
||||||
|
(return mask))))))
|
||||||
|
|
||||||
|
(defun main (args)
|
||||||
|
(if (or (< (length args) 5) (> (length args) 30))
|
||||||
|
(progn
|
||||||
|
(format t "ER: input parameters~%")
|
||||||
|
(uiop:quit 1))
|
||||||
|
(progn
|
||||||
|
(let* ((len (length args))
|
||||||
|
(target (parse-integer (first args)))
|
||||||
|
(mask (make-array len :element-type 'fixnum :initial-element 0))
|
||||||
|
(numbers (coerce (mapcar #'parse-integer (rest args)) '(simple-array fixnum (*)))))
|
||||||
|
(find-sum target len numbers mask)))))
|
||||||
Loading…
Add table
Add a link
Reference in a new issue