From 48400da29ab495f35b22720bd8ad402aecef5617 Mon Sep 17 00:00:00 2001 From: Tayfer Date: Sat, 28 Mar 2026 23:33:59 +0300 Subject: [PATCH] =?UTF-8?q?lisp=20lang=20solution=20=E2=84=963=20GOOD!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lisp/ros/solution3.ros | 80 ++++++++++++++++++++++++++++++++++++++++++ lisp/solution3.lisp | 61 ++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100755 lisp/ros/solution3.ros create mode 100644 lisp/solution3.lisp diff --git a/lisp/ros/solution3.ros b/lisp/ros/solution3.ros new file mode 100755 index 0000000..4706c79 --- /dev/null +++ b/lisp/ros/solution3.ros @@ -0,0 +1,80 @@ +#!/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) + +(declaim (optimize (speed 3) ; Максимальная скорость + (safety 0) ; Отключить проверку типов и границ массивов + (debug 0) ; Не сохранять данные для отладчика + (space 0))) ; Не заботиться о размере бинарника + +(defun ten-to-bin (x len) + "Создает вектор бит фиксированной длины (аналог маски)." + (let ((mask (make-array len :element-type 'bit :initial-element 0))) + (loop for i from (1- len) downto 0 + while (> x 0) + do (multiple-value-bind (quotient remainder) (truncate x 2) + (setf (aref mask i) remainder) + (setf x quotient))) + mask)) + +(defun calculate-sum (numbers-vec mask-vec) + "Считает сумму элементов вектора по маске. Использует across для векторов." + (loop for num across numbers-vec + for flag across mask-vec + when (= flag 1) + sum num)) + +(defun find-sum (target numbers-vec) + (declare (optimize (speed 3) (safety 0) (debug 0)) + (type (simple-array fixnum (*)) numbers-vec) + (type fixnum target)) + (let* ((len (length numbers-vec)) + (total (1- (ash 1 len))) + (current-sum 0) + ;; Массив для отслеживания текущего состояния (биты) + (bits (make-array len :element-type 'bit :initial-element 0))) + (declare (type fixnum current-sum)) + + ;; Итерация по Коду Грея + (loop for i fixnum from 1 to total do + (let* ((gray-diff (logand i (- i))) ; Находим индекс изменяемого бита + (bit-idx (1- (integer-length gray-diff))) + (num (aref numbers-vec bit-idx))) + (declare (type fixnum bit-idx num)) + + ;; Если бит был 0, прибавляем число, если 1 — вычитаем + (if (zerop (aref bits bit-idx)) + (progn + (incf current-sum num) + (setf (aref bits bit-idx) 1)) + (progn + (decf current-sum num) + (setf (aref bits bit-idx) 0))) + + ;; Проверка цели + (when (= current-sum target) + (format t "OK:~A~%" bits) + (return-from find-sum bits)))) + (format t "NO:~%"))) + +(defun main (&rest args) + (let ((len (length args))) + (if (or (< len 5) (> len 30)) + (progn + (format t "ER: input parameters~%") + (uiop:quit 1)) + (let* ((target (parse-integer (first args))) + (numbers-vec (coerce (mapcar #'parse-integer (rest args)) 'vector))) + (find-sum target numbers-vec))))) + + \ No newline at end of file diff --git a/lisp/solution3.lisp b/lisp/solution3.lisp new file mode 100644 index 0000000..a14ded0 --- /dev/null +++ b/lisp/solution3.lisp @@ -0,0 +1,61 @@ +(defun ten-to-bin (x len) + "Создает вектор бит фиксированной длины (аналог маски)." + (let ((mask (make-array len :element-type 'bit :initial-element 0))) + (loop for i from (1- len) downto 0 + while (> x 0) + do (multiple-value-bind (quotient remainder) (truncate x 2) + (setf (aref mask i) remainder) + (setf x quotient))) + mask)) + +(defun calculate-sum (numbers-vec mask-vec) + "Считает сумму элементов вектора по маске. Использует across для векторов." + (loop for num across numbers-vec + for flag across mask-vec + when (= flag 1) + sum num)) + +(defun find-sum (target numbers-vec) + (declare (optimize (speed 3) (safety 0) (debug 0)) + (type (simple-array fixnum (*)) numbers-vec) + (type fixnum target)) + (let* ((len (length numbers-vec)) + (total (1- (ash 1 len))) + (current-sum 0) + ;; Массив для отслеживания текущего состояния (биты) + (bits (make-array len :element-type 'bit :initial-element 0))) + (declare (type fixnum current-sum)) + + (format t "Combinations: ~D~%" total) + + ;; Итерация по Коду Грея + (loop for i fixnum from 1 to total do + (let* ((gray-diff (logand i (- i))) ; Находим индекс изменяемого бита + (bit-idx (1- (integer-length gray-diff))) + (num (aref numbers-vec bit-idx))) + (declare (type fixnum bit-idx num)) + + ;; Если бит был 0, прибавляем число, если 1 — вычитаем + (if (zerop (aref bits bit-idx)) + (progn + (incf current-sum num) + (setf (aref bits bit-idx) 1)) + (progn + (decf current-sum num) + (setf (aref bits bit-idx) 0))) + + ;; Проверка цели + (when (= current-sum target) + (format t "Found: ~A~%" bits) + (return-from find-sum bits)))) + nil)) + +(defun main (args) + (let ((len (length args))) + (if (or (< len 5) (> len 30)) + (progn + (format t "ER: input parameters~%") + (uiop:quit 1)) + (let* ((target (parse-integer (first args))) + (numbers-vec (coerce (mapcar #'parse-integer (rest args)) 'vector))) + (find-sum target numbers-vec)))))