lisp lang solution №1

This commit is contained in:
Дмитрий Голондарев 2026-03-28 20:48:30 +03:00
parent 04eede7e76
commit 2a3ed164a3
3 changed files with 103 additions and 0 deletions

53
lisp/ros/solution1.ros Executable file
View file

@ -0,0 +1,53 @@
#!/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)
"Преобразует число в список бит"
(let ((bin '()))
(loop while (/= 0 x) do
(multiple-value-bind (quotient remainder) (truncate x 2)
(setf x quotient)
(push remainder bin)))
bin))
(defun calculate-sum (numbers mask)
"Считает сумму элементов, соответствующих единицам в маске."
(loop for num in numbers
for flag in mask
when (= flag 1)
sum num))
(defun find-sum (target numbers)
"Перебирает все комбинации (через битовые маски) для поиска целевой суммы."
(let* ((len (length numbers))
(total-combinations (1- (expt 2 len))))
(loop for index from 0 to total-combinations
for mask = (ten-to-bin index)
for current-sum = (calculate-sum numbers mask)
do (when (= current-sum target)
(format t "OK: ~A~%" mask)
(return-from find-sum mask)))
(progn
(format t "NO: not found ~%")
'())))
(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 (mapcar #'parse-integer (rest args))))
(find-sum target numbers)))))

39
lisp/solution1.lisp Normal file
View file

@ -0,0 +1,39 @@
(defun ten-to-bin (x)
"Преобразует число в список бит"
(let ((bin '()))
(loop while (/= 0 x) do
(multiple-value-bind (quotient remainder) (truncate x 2)
(setf x quotient)
(push remainder bin)))
bin))
(defun calculate-sum (numbers mask)
"Считает сумму элементов, соответствующих единицам в маске."
(loop for num in numbers
for flag in mask
when (= flag 1)
sum num))
(defun find-sum (target numbers)
"Перебирает все комбинации (через битовые маски) для поиска целевой суммы."
(let* ((len (length numbers))
(total-combinations (1- (expt 2 len))))
(loop for index from 0 to total-combinations
for mask = (ten-to-bin index)
for current-sum = (calculate-sum numbers mask)
do (when (= current-sum target)
(format t "OK: ~A~%" mask)
(return-from find-sum mask)))
(progn
(format t "NO: not found ~%")
'())))
(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 (mapcar #'parse-integer (rest args))))
(find-sum target numbers)))))

11
lisp/test.txt Normal file
View file

@ -0,0 +1,11 @@
(ten-to-bin 99)
(main '("382040" "15800" "1525" "35300" "19410" "25000" "15800" "1525" "35300" "19410" "25000" "15800" "1525" "35300" "19410" "25000" "15800" "1525" "35300" "19410" "25000"))
(main '("477550" "15800" "1525" "35300" "19410" "25000" "15800" "1525" "35300" "19410" "25000" "15800" "1525" "35300" "19410" "25000" "15800" "1525" "35300" "19410" "25000" "15800" "1525" "35300" "19410" "25000"))
(time (dotimes (i 1000000) (calculate-sum #(1 2 3 4 5 6 7 8 9 10 11 12 13) #(1 1 1 0 1 1 0 0 1 1 1 0 0 0)) ))
(time (dotimes (i 1000) (main-one '("69" "12" "1" "2" "11" "12" "1" "2" "11" "12" "1" "2" "11"))))