#!/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)))))