Skip to content

Instantly share code, notes, and snippets.

@mnem
Last active August 29, 2015 14:21
Show Gist options
  • Save mnem/a977e3d430b23e4380bd to your computer and use it in GitHub Desktop.
Save mnem/a977e3d430b23e4380bd to your computer and use it in GitHub Desktop.

Revisions

  1. mnem revised this gist May 19, 2015. 1 changed file with 82 additions and 47 deletions.
    129 changes: 82 additions & 47 deletions foo.cpp
    Original file line number Diff line number Diff line change
    @@ -7,7 +7,8 @@
    //

    #include <iostream>
    #include <tuple>
    #include <set>
    #include <vector>
    #include <stdio.h>

    union Board {
    @@ -25,21 +26,23 @@ union Board {
    uint64_t all;
    };

    typedef uint64_t (*AddNeighbour)(Board, uint64_t);
    typedef Board (*SwapNeighbour)(Board, uint64_t);
    typedef int Position;
    typedef char Cell;
    typedef Cell (*AddNeighbour)(Board, Position);
    typedef Board (*SwapNeighbour)(Board, Position);

    inline uint64_t cell(Board b, uint64_t o) {
    inline Cell cell(Board b, Position o) {
    return (b.all >> (o * 4)) & 0xf;
    }

    inline Board set_cell(Board b, uint64_t o, uint64_t v) {
    const int shift = (o * 4);
    const uint64_t mask = 0xf << shift;
    b.all = (b.all & ~mask) | ((v << shift) & mask);
    inline Board set_cell(Board b, Position o, Cell v) {
    const auto shift = (o * 4);
    const auto mask = 0xfull << shift;
    b.all = (b.all & ~mask) | (((typeof(mask))v << shift) & mask);
    return b;
    }

    inline bool prime(uint64_t n) {
    inline bool prime(Cell n) {
    return 2 == n ||
    3 == n ||
    5 == n ||
    @@ -50,15 +53,15 @@ inline bool prime(uint64_t n) {
    }

    template <int offset>
    uint64_t add(Board b, uint64_t o) {
    Cell add(Board b, Position o) {
    return cell(b, o) + cell(b, o + offset);
    }

    template <int offset>
    Board swap(Board b, uint64_t o) {
    const uint64_t tmp = cell(b, o);
    set_cell(b, o, cell(b, 0 + offset));
    set_cell(b, o + offset, tmp);
    Board swap(Board b, Position o) {
    const auto tmp = cell(b, o);
    b = set_cell(b, o, cell(b, o + offset));
    b = set_cell(b, o + offset, tmp);
    return b;
    }

    @@ -72,7 +75,7 @@ static const Mutator down = {add<3>, swap<3>};

    struct Operation {
    const Mutator mutator;
    const uint64_t origin;
    const Position origin;
    };

    static const Operation kValidOperations[] = {
    @@ -89,42 +92,74 @@ static const Operation kValidOperations[] = {
    {down, 4},
    {down, 5},
    };
    static const auto kNumValidOperations = (sizeof(kValidOperations) / sizeof(Operation));

    int main(int argc, const char * argv[]) {
    // insert code here...
    const Board target = {
    1,2,3,
    4,5,6,
    7,8,9};
    const Board test1 = {
    7,3,2,
    4,1,5,
    6,8,9};
    const Board test2 = {
    9,8,5,
    2,4,1,
    3,7,6};
    const Board Target = {
    1,2,3,
    4,5,6,
    7,8,9};
    const Board Test1 = {
    7,3,2,
    4,1,5,
    6,8,9};
    const Board Test2 = {
    9,8,5,
    2,4,1,
    3,7,6};

    int solve(Board b) {
    auto step = 0;
    auto visited = std::set<uint64_t>();

    visited.insert(b.all);

    if (visited.count(Target.all) != 0) {
    return step;
    }

    // printf("0x%llx\n", cell(target, 0));
    // printf("0x%llx\n", cell(target, 1));
    // printf("0x%llx\n", cell(target, 8));

    printf("0x%llx\n", set_cell(target, 0, 10).all);
    printf("0x%llx\n", set_cell(target, 1, 10).all);
    printf("0x%llx\n", set_cell(target, 2, 10).all);
    printf("0x%llx\n", set_cell(target, 3, 10).all);
    printf("0x%llx\n", set_cell(target, 4, 10).all);
    printf("0x%llx\n", set_cell(target, 5, 10).all);
    printf("0x%llx\n", set_cell(target, 6, 10).all);
    printf("0x%llx\n", set_cell(target, 7, 10).all);
    printf("0x%llx\n", set_cell(target, 8, 10).all);
    auto unvisited_permutations = [&visited](Board b) -> std::vector<Board> {
    auto p = std::vector<Board>();
    for (size_t i = 0; i < kNumValidOperations; i++) {
    auto op = kValidOperations[i];
    if (prime(op.mutator.add(b, op.origin))) {
    auto bb = op.mutator.swap(b, op.origin);
    if (visited.count(bb.all) == 0) {
    p.push_back(bb);
    }
    }
    }
    return p;
    };

    Board foo = set_cell(target, 8, 10);
    auto mark_visited = [&visited](std::vector<Board> barr) {
    for (auto b : barr) {
    visited.insert(b.all);
    }
    };

    // printf("0x%llx\n", target.all);
    // printf("0x%llx\n", test1.all);
    // printf("0x%llx\n", test2.all);
    auto boards = unvisited_permutations(b);
    while (boards.size() > 0) {
    step++;
    mark_visited(boards);
    if (visited.count(Target.all)) {
    return step;
    }

    auto next = std::vector<Board>();
    for (auto b : boards) {
    auto unvisited = unvisited_permutations(b);
    next.insert(next.end(), unvisited.begin(), unvisited.end());
    }
    boards = next;
    }

    // std::cout << sizeof(Board);
    return -1;
    }

    int main(int argc, const char * argv[]) {
    std::cout << solve(Target) << std::endl;
    std::cout << solve(Test1) << std::endl;
    std::cout << solve(Test2) << std::endl;

    return 0;
    }
  2. mnem created this gist May 18, 2015.
    130 changes: 130 additions & 0 deletions foo.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,130 @@
    //
    // main.cpp
    // jpm-code-dojo-2015-05-cpp
    //
    // Created by David Wagner on 18/05/2015.
    // Copyright (c) 2015 David Wagner. All rights reserved.
    //

    #include <iostream>
    #include <tuple>
    #include <stdio.h>

    union Board {
    struct {
    uint8_t _0:4;
    uint8_t _1:4;
    uint8_t _2:4;
    uint8_t _3:4;
    uint8_t _4:4;
    uint8_t _5:4;
    uint8_t _6:4;
    uint8_t _7:4;
    uint8_t _8:4;
    } cells;
    uint64_t all;
    };

    typedef uint64_t (*AddNeighbour)(Board, uint64_t);
    typedef Board (*SwapNeighbour)(Board, uint64_t);

    inline uint64_t cell(Board b, uint64_t o) {
    return (b.all >> (o * 4)) & 0xf;
    }

    inline Board set_cell(Board b, uint64_t o, uint64_t v) {
    const int shift = (o * 4);
    const uint64_t mask = 0xf << shift;
    b.all = (b.all & ~mask) | ((v << shift) & mask);
    return b;
    }

    inline bool prime(uint64_t n) {
    return 2 == n ||
    3 == n ||
    5 == n ||
    7 == n ||
    11 == n ||
    13 == n ||
    17 == n;
    }

    template <int offset>
    uint64_t add(Board b, uint64_t o) {
    return cell(b, o) + cell(b, o + offset);
    }

    template <int offset>
    Board swap(Board b, uint64_t o) {
    const uint64_t tmp = cell(b, o);
    set_cell(b, o, cell(b, 0 + offset));
    set_cell(b, o + offset, tmp);
    return b;
    }

    struct Mutator {
    const AddNeighbour add;
    const SwapNeighbour swap;
    };

    static const Mutator right = {add<1>, swap<1>};
    static const Mutator down = {add<3>, swap<3>};

    struct Operation {
    const Mutator mutator;
    const uint64_t origin;
    };

    static const Operation kValidOperations[] = {
    {right, 0},
    {right, 1},
    {right, 3},
    {right, 4},
    {right, 6},
    {right, 7},
    {down, 0},
    {down, 1},
    {down, 2},
    {down, 3},
    {down, 4},
    {down, 5},
    };

    int main(int argc, const char * argv[]) {
    // insert code here...
    const Board target = {
    1,2,3,
    4,5,6,
    7,8,9};
    const Board test1 = {
    7,3,2,
    4,1,5,
    6,8,9};
    const Board test2 = {
    9,8,5,
    2,4,1,
    3,7,6};

    // printf("0x%llx\n", cell(target, 0));
    // printf("0x%llx\n", cell(target, 1));
    // printf("0x%llx\n", cell(target, 8));

    printf("0x%llx\n", set_cell(target, 0, 10).all);
    printf("0x%llx\n", set_cell(target, 1, 10).all);
    printf("0x%llx\n", set_cell(target, 2, 10).all);
    printf("0x%llx\n", set_cell(target, 3, 10).all);
    printf("0x%llx\n", set_cell(target, 4, 10).all);
    printf("0x%llx\n", set_cell(target, 5, 10).all);
    printf("0x%llx\n", set_cell(target, 6, 10).all);
    printf("0x%llx\n", set_cell(target, 7, 10).all);
    printf("0x%llx\n", set_cell(target, 8, 10).all);

    Board foo = set_cell(target, 8, 10);

    // printf("0x%llx\n", target.all);
    // printf("0x%llx\n", test1.all);
    // printf("0x%llx\n", test2.all);

    // std::cout << sizeof(Board);
    return 0;
    }