Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 1; 2; 3; 4; 5 // 1 кусок
- 6; 5; 4; 3 // 2 кусок
- // 3 кусок пустой
- -3; -3; -3 // 4 кусок
- 1; 2; 3; 4; 5; 5.5; 6; 5; 4; 3; 0; -3; -3; -3
- // 1-ая часть (5 + 6)/2 2-ая часть (3 + -3)/2 4-я часть
- IEnumerable<double> FlattenWithInsertedValues(IEnumerable<IEnumerable<double>> seqs)
- {
- double? firstAddend = null;
- foreach (var seq in seqs)
- {
- double? lastInThisSeq = null;
- foreach (var v in seq)
- {
- if (firstAddend != null)
- {
- yield return (firstAddend.Value + v) / 2;
- firstAddend = null;
- }
- yield return v;
- lastInThisSeq = v;
- }
- if (lastInThisSeq != null)
- firstAddend = lastInThisSeq;
- }
- }
- void Test1()
- {
- var result = FlattenWithInsertedValues(TestGenerator1());
- foreach (var v in result)
- Console.Write(v + " ");
- }
- void Test2()
- {
- var result = FlattenWithInsertedValues(TestGenerator2());
- Console.Write(result.Count());
- }
- IEnumerable<IEnumerable<double>> TestGenerator1()
- {
- Console.Write("Generating outer seq 1 ");
- yield return Generator(1, 5, 1);
- yield return Generator(1, 0, 2);
- yield return Generator(1, 3, 3);
- }
- IEnumerable<IEnumerable<double>> TestGenerator2()
- {
- Console.Write("Generating outer seq 2 ");
- yield return Generator(1, 5, 1);
- yield return Generator(1, 10000000000000, 2);
- }
- IEnumerable<double> Generator(double from, double to, int seqNum)
- {
- Console.Write($"Generating seq #{seqNum} ");
- for (double curr = from; curr < to; curr += 1)
- yield return curr;
- }
- #include <math.h>
- #include <unistd.h>
- #include <sysexits.h>
- #define DBLRead(fd, d) (read(fd, d, sizeof(double)) == sizeof(double))
- #define DBLWrite(fd, d) (write(fd, d, sizeof(double)) == sizeof(double))
- int
- flatten (int n, int in[], int out)
- {
- int i, j, rc = 0;
- double d0 = NAN, d;
- for (i = 0; !rc && i < n; close(in[i++]))
- for (j = 0; !rc && DBLRead(in[i], &d); j++) {
- if (!isnan(d0) && j == 0) {
- double m = (d0 + d) / 2;
- if (!DBLWrite(out, &m)) {
- rc = EX_IOERR;
- break;
- }
- }
- if (!DBLWrite(out, &d))
- rc = EX_IOERR;
- d0 = d;
- }
- close(out);
- return rc;
- }
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <err.h>
- #include <sysexits.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- int
- generate (int p[2], double from, int step, int n)
- {
- if (fork()) {
- close(p[1]);
- return p[0];
- }
- int i, rc = 0;
- for (i = 0; i < n; i++, from += step)
- if (!DBLWrite(p[1], &from)) {
- rc = EX_IOERR;
- break;
- }
- exit(rc);
- }
- #define A_SIZE(a) (sizeof(a) / sizeof(a[0]))
- int
- main (int ac, char *av[])
- {
- int p1[2], p2[2], p3[2], p4[2], res[2];
- if (pipe(p1) || pipe(p2) || pipe(p3) || pipe(p4) || pipe(res))
- err(EX_OSERR, "pipes");
- int gen_input[4] = {
- generate(p1, 1.0, 1, 5),
- generate(p2, 6.0, -1, 4),
- generate(p3, 1.0, 1, 0),
- generate(p4, -3.0, 0, 3)
- };
- if (!fork())
- exit(flatten(A_SIZE(gen_input), gen_input, res[1]));
- close(res[1]);
- double r = 0;
- while(DBLRead(res[0], &r) || (puts(""), 0))
- printf("%g ", r);
- pid_t pid;
- int s;
- while ((pid = wait(&s)) > 0)
- if (!WIFEXITED(s) || WEXITSTATUS(s))
- printf("pid: %d rc = %dn", (int)pid, WEXITSTATUS(s));
- return puts("End") == EOF;
- }
- function *f(g) {
- for (var x of g) {
- for (var y of x) {
- if (l === +l) {
- yield (l+y)/2;
- l = '';
- }
- yield y;
- }
- var l = y;
- }
- }
- for (var x of f([[1,2,3,4,5], [6,5,4,3], [], [-3,-3,-3]])) {
- console.log(x);
- }
- flatten :: [[Float]] -> [Float]
- flatten [] = []
- flatten [y] = y
- flatten ([]:xs) = flatten xs
- flatten (y:[]:xs) = flatten $ y:xs
- flatten ([y]:(yy:ys):xs) = y : (y + yy)/2 : flatten ((yy:ys):xs)
- flatten ((y:ys):zs:xs) = y : flatten (ys:zs:xs)
- main = do
- let ls = [[1, 2, 3, 4, 5], [6, 5, 4, 3], [-3, -3, -3]]
- print ls
- let fs = flatten ls
- print fs
- def inter_means(sequences)
- Enumerator.new do |y|
- last_inserted = nil
- sequences.lazy.each do |seq|
- first = true
- seq.lazy.each do |element|
- if first && last_inserted
- y << (element + last_inserted) / 2.0
- last_inserted = nil
- end
- first = false
- y << element
- last_inserted = element
- end
- end
- end
- end
- # ---------------- ----------------
- # Далее код для тестов
- # Поток чисел из stdin (изначально не ленивый!)
- stdin_number_stream = Enumerator.new do |y|
- number = ""
- STDIN.each_char.lazy.each do |c|
- if c =~ /d/
- number += c
- else
- y << number.to_i if number != ""
- number = ""
- end
- end
- # Когда поток закрыли, могло накопиться число
- y << number.to_i if number != ""
- end
- inputs = [ # v-вот теперь ленивый
- [[], stdin_stream.lazy, [1]],
- [[*1..5], [*3..6].reverse, [], [-3, -3, -3]],
- [],
- [[], [], []],
- [[], [1, 2, 3], [], [-3, -2, -1], [], []]
- ]
- inputs.each do |input|
- puts " #{input.inspect}n=> #{inter_means(input).to_a.inspect}"
- end
- [[1, 2, 3, 4, 5], [6, 5, 4, 3], [], [-3, -3, -3]]
- => [1, 2, 3, 4, 5, 5.5, 6, 5, 4, 3, 0.0, -3, -3, -3]
- []
- => []
- [[], [], []]
- => []
- [[], [1, 2, 3], [], [-3, -2, -1], [], []]
- => [1, 2, 3, 0.0, -3, -2, -1]
- from itertools import chain
- def flatten(*lists):
- prev_i = -1
- prev_elt = None
- for i, elt in chain(*map(enumerate, lists)):
- if prev_i != i - 1:
- yield (prev_elt + elt) / 2
- yield elt
- prev_i = i
- prev_elt = elt
- lst = [[1, 2, 3, 4, 5], [6, 5, 4, 3], [-3, -3, -3]]
- print(list(flatten(*lst)))
- [1, 2, 3, 4, 5, 5.5, 6, 5, 4, 3, 0.0, -3, -3, -3]
- FLOAT next(){
- static FLOAT prev = NAN;
- static bool isFirst = false;
- static Seq<float> local = GLOBAL.next();
- if (!local)
- return null; //end result seq
- if (isFirst) //it's first elem in seq so we read it before
- isFirst = false;
- return prev;
- }
- FLOAT temp = local.next();
- if (!temp){ //if we read current seq
- local = GLOBAL.next();
- if (!local) //we read all seq
- return null; //end result seq
- FLOAT tmp = prev;
- prev = local.next();
- if (!prev){ //if empty seq
- prev = NAN;
- local = GLOBAL.next(); //go next seq
- return NAN;
- }
- isFirst = true; // we read first elem need save it
- return (prev + tmp)/2;
- }
- return prev = temp;
- }
- let flatten seqs =
- // нумеруем каждый элемент внутренней пос-ти его индексом
- let numbering = Seq.zip (Seq.initInfinite id) in
- // сливаем внутренние посл-ти
- let pairs = (Seq.map numbering >> Seq.concat) seqs in
- let folder (prev_i, prev_elem, _) (cur_i, cur_elem) =
- // если индексы текущего и предыдущего элементов не последовательны
- // значит, это граница, добавляем средний
- let is_bound = cur_i - prev_i <> 1 in
- let with_mean =
- if is_bound then [| (cur_elem + prev_elem) / 2.; cur_elem |]
- else [| cur_elem |] in
- (cur_i, cur_elem, Seq.ofArray with_mean) in
- let take_3rd = function | _, _, x -> x in
- (Seq.scan folder (-1, 0., Seq.empty)
- >> Seq.skip 1
- >> Seq.map take_3rd
- >> Seq.concat) pairs
- [[1; 2; 3; 4; 5]; [6; 5; 4; 3]; []; [-3; -3; -3]]
- |> List.map (List.map float) |> List.map Seq.ofList |> Seq.ofList
- |> flatten
- |> List.ofSeq
- |> printfn "%A"
- seq {
- printfn "Generating outer seq";
- yield seq { printfn "Generating inner seq 1"; yield 1.0; };
- yield seq { printfn "Generating inner seq 2"; yield 2.0; };
- yield seq { printfn "Generating inner seq 3"; yield 3.0; }
- }
- |> flatten
- |> List.ofSeq
- |> printfn "%A"
- [1.0; 2.0; 3.0; 4.0; 5.0; 5.5; 6.0; 5.0; 4.0; 3.0; 0.0; -3.0; -3.0; -3.0]
- Generating outer seq
- Generating inner seq 1
- Generating inner seq 2
- Generating inner seq 3
- [1.0; 1.5; 2.0; 2.5; 3.0]
- def flatten(*lists):
- prev = elt = None
- for lst in lists:
- for elt in lst:
- if prev is not None:
- yield (prev + elt) / 2
- prev = None
- yield elt
- prev = elt
- lst = [[1, 2, 3, 4, 5], [6, 5, 4, 3], [-3, -3, -3]]
- print(list(flatten(*lst)))
- f = foldr c []
- where c [] y = y
- c (x:[]) (y:b) = x : (x+y)/2 : b
- c (x:a) y = x : c a y
- c x [] = x
- flatten [] = []
- flatten [y] = y
- flatten lists = concat . append_end . map adder . zip xxs $ xs
- where
- xxs@(_:xs) = concat . map (zip [1..]) $ lists
- adder ((n, a), (m, b))
- | n + 1 == m = [(a, b)]
- | otherwise = [(a, undefined), ((a + b) /2, b)]
- append_end [] = []
- append_end [x] = [map fst x, [snd $ last x]]
- append_end (x:xs) = map fst x : append_end xs
- (ns inter-means.match
- (:require [clojure.core.match :refer [match]]))
- (defn inter-means
- "Функция, возвращающая ленивую конкатенацию переданной последовательности
- последовательностей через средниые арифметические крайних элементов"
- ([input-seqs]
- (inter-means input-seqs nil false))
- ([input-seqs last-inserted junction?]
- (match input-seqs
- ([] :seq)
- ()
- ([([] :seq) & remainder] :seq)
- (recur remainder last-inserted (-> last-inserted nil? not))
- ([([head & tail] :seq) & remainder] :seq)
- (let [continuation
- (cons head (lazy-seq (inter-means
- (cons tail remainder)
- head
- false)))]
- (if junction?
- (cons (/ (+ head last-inserted) 2) continuation)
- continuation)))))
- flatten = fst . foldl adder ([], undefined)
- where
- adder x [] = x
- adder ([], _) xs = llist xs
- adder (ys, prev) [x] = (ys ++ [(prev + x)/2, x], x)
- adder (ys, prev) (x:xs) = let (lxs, lx) = llist xs
- in (ys ++ [(prev + x)/2, x] ++ lxs, lx)
- llist [x] = ([x], x)
- llist (x:xs) = let (ys, y) = llist xs in (x:ys, y)
Add Comment
Please, Sign In to add comment