rishatss
@rishatss
Simple Developer ^)

Как перевернуть древовидный список рекурсивно?

Доброе день господа :)

Вообщем пытаюсь сейчас вникнуть в абстракцию данных.. Голова кругом ходит, теоретически улавливаю, а на практики в ступор сразу :(
Как вы вникли в абстракцию данных? Решали ли вы мелкие задачки? Или на практике приходилось понимать это?

Вот например:
['(((4, 5), 6), 5, (2, 3), 1)', l(1, l(3, 2), 5, l(6, l(5, 4)))]


Есть древовидный список, как я могу перевернуть его? Не используя готовых функций.

В моем случае написаны тесты для этого.

<?php

namespace App\Solution;

require 'Pair.php';

use function App\Pair\car;
use function App\Pair\isPair;
use function App\Pair\cdr;
use function App\Pair\cons;
use function App\Pair\listToString;

function reverse($list)
{
    // BEGIN (write your solution here)

    // END
}


<?php

namespace App;

require_once 'Solution.php';

use function App\Pair\l;
use function App\Pair\listToString;

class TestSolution extends \PHPUnit_Framework_TestCase
{
    /**
     * @dataProvider additionProvider
     */
    public function testReverse($expected, $source)
    {
        $this->assertEquals($expected, listToString(Solution\reverse($source)));
    }

    public function additionProvider()
    {
        return [
            ['(((4, 5), 6), 5, (2, 3), 1)', l(1, l(3, 2), 5, l(6, l(5, 4)))],
            ['(((7), 6, 5, (100, 4), 3))', l(l(3, l(4, 100), 5, 6, l(7)))]
        ];
    }
}


Есть функции

<?php

namespace App\Pair;

function cons($x, $y)
{
    return function ($method) use ($x, $y) {
        switch ($method) {
            case "car":
                return $x;
            case "cdr":
                return $y;
        }
    };
}

function car(callable $pair)
{
    return $pair("car");
}

function cdr(callable $pair)
{
    return $pair("cdr");
}

function listToString($list)
{
    if (!isPair($list)) {
        return $list;
    }

    $arr = [];
    $iter = function ($items) use (&$arr, &$iter) {
        if ($items != null) {
            $arr[] = listToString(car($items));
            $iter(cdr($items));
        }

    };
    $iter($list);

    return "(" . implode(", ", $arr) . ")";
}

function l()
{
    return array_reduce(array_reverse(func_get_args()), function ($acc, $item) {
        return cons($item, $acc);
    });
}

function accumulate($list, $func, $acc)
{
    $iter = function ($list, $acc) use (&$iter, $func) {
        if ($list === null) {
            return $acc;
        }

        return $iter(cdr($list), $func(car($list), $acc));
    };
    return $iter($list, $acc);
}

function isPair($item)
{
    return is_callable($item);
}
  • Вопрос задан
  • 287 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы