Рабочие заморочки

Jun 17, 2012 00:18

Решал на работе одну интересную задачку.
Большая её часть состояла в исследовании работы существующего механизма, а практическая - довольно простой алгоритм, состоящий с следующем:
Есть множества a и b. Требуется привести b в соответствии с а.

При этом тупо удалить b и скопировать в него a нельзя из-за технических плюх.
Нужно выяснить отличия, и соответственно, добавить недостающие элементы и удалить избыточные.

Тот механизм, который существует, увы, не работал должным образом, так как основывался на технических features. Ну это как писать программмы, используя недокументированные особенности API.

Вот так это реализовывается:



#!/usr/bin/perl -w
use strict;
use Data::Dumper;

my @a = qw(1 2 3 4 5 6);
my @b = qw(12 64 3 4 5 8);

my @todel = grep { my $bc = $_; { !grep {$_ == $bc } @a } } @b;
my @toadd = grep { my $bc = $_; { !grep {$_ == $bc } @b } } @a;

print "Список на удаление: \n";
print Dumper(\@todel);
print "Список на добавление: \n";
print Dumper(\@toadd);



Тут решение на языке scheme, который есть диалект LISP-а.
Этот язык только начал изучать по причине того, что знаменитый
SICP кишит его примерами, а эту книжку я читаю вдумчиво и с
выполнением заданий.

Можно было сделать иначе, более оптимизированно, но я ещё не волшебник,
а только учусь :)

Функции типа проверки наличия члена в массиве и фильтра по предикату написал сам
для наглядности и потому что пока не знаю библиотечных аналогов.

(define (nn) (newline))

;; Определил два массива
;; Задача - привести массив b к виду массива a путём
;; добавления в b того, что есть в a но нет в b
;; а также удаления из b того, чего нет в a
;;

(define a '(1 2 3 4 5 6))
(define b '(64 32 3 4 5))

;; функция-предикат
;; возвращает true в случае
;; присутствия члена n во множестве p
;; и false в случае отстутствия

(define (ispres n p)
(define (isem l)
(= 0 (length l)))
(if (isem p)
#f
(if (= n (car p))
#t
(ispres n (cdr p)))))

;; фильтр, принимающий на вход функцию-предикат
;; и множество. Над множеством выполняется предикат
;; и в случае true элемент будет пропущен
;; в случает false - удалён
;; На выходе множество, удовлетворяющее выполнению
;; предиката

(define (filt f p)
(if (= (length p) 0)
p
(if (f (car p))
(cons (car p)
(filt f (cdr p))
)
(filt f (cdr p))
)
)
)

;; Составляем список для удаления

(define (todel a b)
(define (isnap n)
(not (ispres n a)))
(filt isnap b))

;; Составляем список для добавления

(define (toadd a b)
(define (isnap n)
(not (ispres n b)))
(filt isnap a))

; Печатаем резкультаты

(display (todel a b))
(nn)
(display (toadd a b))
(nn)

техническое, работа

Previous post Next post
Up