From 8a3a35064e52c373350bd878b9d041cec653da2b Mon Sep 17 00:00:00 2001 From: Tayfer Date: Sat, 28 Mar 2026 21:44:22 +0300 Subject: [PATCH] =?UTF-8?q?lisp=20lang=20solution=20=E2=84=96=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lisp/ros/solution2.ros | 67 ++++++++++++++++++++++++++++++++++++++++++ lisp/solution2.lisp | 53 +++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100755 lisp/ros/solution2.ros create mode 100644 lisp/solution2.lisp diff --git a/lisp/ros/solution2.ros b/lisp/ros/solution2.ros new file mode 100755 index 0000000..59bfaf1 --- /dev/null +++ b/lisp/ros/solution2.ros @@ -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))))) diff --git a/lisp/solution2.lisp b/lisp/solution2.lisp new file mode 100644 index 0000000..8037f31 --- /dev/null +++ b/lisp/solution2.lisp @@ -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))))) \ No newline at end of file