Skip to content

Commit

Permalink
Clarified the meaning of the "naive" and moved some solutions to the …
Browse files Browse the repository at this point in the history
…main scoreboard according to the defined meaning
  • Loading branch information
frol committed May 20, 2018
1 parent 13d100c commit 7bd3f56
Show file tree
Hide file tree
Showing 17 changed files with 586 additions and 83 deletions.
183 changes: 117 additions & 66 deletions README.md

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions ada/main_fast.adb → ada/main_naive_pointers.adb
@@ -1,10 +1,10 @@
with Ada.Integer_Text_IO;
with Ada.Text_IO;

with Tree_Fast; use Tree_Fast;
with Tree_Naive_Pointers; use Tree_Naive_Pointers;

procedure Main_Fast is
t: Tree_Fast.Tree;
procedure Main_Naive_Pointers is
t: Tree_Naive_Pointers.Tree;
cur: Integer := 5;
res: Integer := 0;
mode: Integer;
Expand All @@ -22,4 +22,4 @@ begin
end if;
end loop;
PutI(res); New_Line(1);
end Main_Fast;
end Main_Naive_Pointers;
4 changes: 2 additions & 2 deletions ada/tree_fast.adb → ada/tree_naive_pointers.adb
@@ -1,6 +1,6 @@
with Ada.Unchecked_Deallocation;

package body Tree_Fast is
package body Tree_Naive_Pointers is

procedure initialize is
begin
Expand Down Expand Up @@ -96,4 +96,4 @@ begin
delete_node(equal);
end erase;

end Tree_Fast;
end Tree_Naive_Pointers;
4 changes: 2 additions & 2 deletions ada/tree_fast.ads → ada/tree_naive_pointers.ads
@@ -1,6 +1,6 @@
with Ada.Numerics.Discrete_Random;

package Tree_Fast is
package Tree_Naive_Pointers is

type Node is private;

Expand Down Expand Up @@ -43,4 +43,4 @@ type Node is record
y: Integer := Random(g);
end record;

end Tree_Fast;
end Tree_Naive_Pointers;
26 changes: 26 additions & 0 deletions c++/Makefile
@@ -0,0 +1,26 @@
TARGETS = \
main-naive-java-like \
main-naive-raw \
main-naive-shared_ptr \
main-tuned-raw \
main-tuned-raw-with-pool \
main-tuned-unique_ptr

.PHONY: all
all: $(TARGETS:%=%-clang) $(TARGETS:%=%-clang-static) $(TARGETS:%=%-gcc) $(TARGETS:%=%-gcc-static)

$(TARGETS:%=%-clang): %-clang : %.cpp
clang++ -O3 --std=c++17 -flto -s -o $@ $<

$(TARGETS:%=%-clang-static): %-clang-static : %.cpp
/usr/bin/clang++ -O3 --std=c++17 -flto -s -static -o $@ $<

$(TARGETS:%=%-gcc): %-gcc : %.cpp
g++ -O3 --std=c++17 -flto -s -o $@ $<

$(TARGETS:%=%-gcc-static): %-gcc-static : %.cpp
g++ -O3 --std=c++17 -flto -s -static -o $@ $<

.PHONY: clean
clean:
rm $(TARGETS:%=%-clang) $(TARGETS:%=%-clang-static) $(TARGETS:%=%-gcc) $(TARGETS:%=%-gcc-static)
2 changes: 1 addition & 1 deletion c++/README.md
@@ -1,6 +1,6 @@
# C++

Author: Stas Minakov (@supermina999)
Authors: Stas Minakov (@supermina999), Paul Harvey (@prharvey)

## Compile

Expand Down
99 changes: 99 additions & 0 deletions c++/main-naive-java-like.cpp
@@ -0,0 +1,99 @@
#include <iostream>
#include <memory>

struct Node {
explicit Node(int value) : value(value) {}

int value;
int priority = rand();

std::shared_ptr<Node> left;
std::shared_ptr<Node> right;
};

inline std::tuple<std::shared_ptr<Node>, std::shared_ptr<Node>> SplitBinary(
std::shared_ptr<Node>&& input, int value) {
if (!input) {
return std::make_tuple(nullptr, nullptr);
} else if (input->value < value) {
auto [less, greater] = SplitBinary(std::move(input->right), value);
input->right = std::move(less);
return std::make_tuple(std::move(input), std::move(greater));
} else {
auto [less, greater] = SplitBinary(std::move(input->left), value);
input->left = std::move(greater);
return std::make_tuple(std::move(less), std::move(input));
}
}

inline std::tuple<std::shared_ptr<Node>, std::shared_ptr<Node>,
std::shared_ptr<Node>>
Split(std::shared_ptr<Node>&& input, int value) {
auto [less, greater_or_equal] = SplitBinary(std::move(input), value);
auto [equal, greater] = SplitBinary(std::move(greater_or_equal), value + 1);
return std::make_tuple(std::move(less), std::move(equal), std::move(greater));
}

inline std::shared_ptr<Node>&& Merge(std::shared_ptr<Node>&& less,
std::shared_ptr<Node>&& greater) {
if (!less | !greater) {
return std::move(less ? less : greater);
} else if (less->priority < greater->priority) {
less->right = Merge(std::move(less->right), std::move(greater));
return std::move(less);
} else {
greater->left = Merge(std::move(less), std::move(greater->left));
return std::move(greater);
}
}

inline std::shared_ptr<Node>&& Merge(std::shared_ptr<Node>&& less,
std::shared_ptr<Node>&& equal,
std::shared_ptr<Node>&& greater) {
return Merge(Merge(std::move(less), std::move(equal)), std::move(greater));
}

class Treap {
public:
bool HasValue(int value) {
auto [less, equal, greater] = Split(std::move(root_), value);
const bool has_value = equal != nullptr;
root_ = Merge(std::move(less), std::move(equal), std::move(greater));
return has_value;
}

void Insert(int value) {
auto [less, equal, greater] = Split(std::move(root_), value);
if (!equal) equal = std::make_shared<Node>(value);
root_ = Merge(std::move(less), std::move(equal), std::move(greater));
}

void Erase(int value) {
auto [less, equal, greater] = Split(std::move(root_), value);
root_ = Merge(std::move(less), std::move(greater));
}

private:
std::shared_ptr<Node> root_;
};

int main() {
srand(time(0));

Treap treap;
int current = 5;
int result = 0;
for (int i = 1; i < 1000000; ++i) {
const int mode = i % 3;
current = (current * 57 + 43) % 10007;
if (mode == 0) {
treap.Insert(current);
} else if (mode == 1) {
treap.Erase(current);
} else if (mode == 2) {
result += treap.HasValue(current);
}
}
std::cout << result;
return 0;
}
File renamed without changes.
File renamed without changes.
167 changes: 167 additions & 0 deletions c++/main-tuned-raw-with-pool.cpp
@@ -0,0 +1,167 @@
#include <iostream>
#include <memory>

#include <boost/pool/object_pool.hpp>
#include <boost/pool/poolfwd.hpp>

class Tree
{
public:
Tree() = default;
~Tree() {}

bool hasValue(int x);
void insert(int x);
void erase(int x);

private:
struct Node
{
Node(int x): x(x) {}
Node() {}

int x = 0;
int y = rand();

Node* left = nullptr;
Node* right = nullptr;
};

using NodePtr = Node*;

static void merge(NodePtr lower, NodePtr greater, NodePtr& merged);
static void merge(NodePtr lower, NodePtr equal, NodePtr greater, NodePtr& merged);
static void split(NodePtr orig, NodePtr& lower, NodePtr& greaterOrEqual, int val);
static void split(NodePtr orig, NodePtr& lower, NodePtr& equal, NodePtr& greater, int val);

void clear(NodePtr node);

NodePtr mRoot = nullptr;
boost::object_pool<Node> mNodePool = boost::object_pool<Node>();
};

void Tree::clear(NodePtr node)
{
if(!node)
return;

clear(node->left);
clear(node->right);
mNodePool.destroy(node);
}

bool Tree::hasValue(int x)
{
NodePtr lower, equal, greater;
split(mRoot, lower, equal, greater, x);
bool res = equal != nullptr;
merge(lower, equal, greater, mRoot);
return res;
}

void Tree::insert(int x)
{
NodePtr lower, equal, greater;
split(mRoot, lower, equal, greater, x);
if(!equal)
equal = mNodePool.construct(x);

merge(lower, equal, greater, mRoot);
}

void Tree::erase(int x)
{
NodePtr lower, equal, greater;
split(mRoot, lower, equal, greater, x);
merge(lower, greater, mRoot);
clear(equal);
}

void Tree::merge(NodePtr lower, NodePtr greater, NodePtr& merged)
{
if(!lower)
{
merged = greater;
return;
}

if(!greater)
{
merged = lower;
return;
}

if(lower->y < greater->y)
{
merged = lower;
merge(merged->right, greater, merged->right);
}
else
{
merged = greater;
merge(lower, merged->left, merged->left);
}
}

void Tree::merge(NodePtr lower, NodePtr equal, NodePtr greater, NodePtr& merged)
{
merge(lower, equal, merged);
merge(merged, greater, merged);
}

void Tree::split(NodePtr orig, NodePtr& lower, NodePtr& greaterOrEqual, int val)
{
if(!orig)
{
lower = greaterOrEqual = nullptr;
return;
}

if(orig->x < val)
{
lower = orig;
split(lower->right, lower->right, greaterOrEqual, val);
}
else
{
greaterOrEqual = orig;
split(greaterOrEqual->left, lower, greaterOrEqual->left, val);
}
}

void Tree::split(NodePtr orig, NodePtr& lower, NodePtr& equal, NodePtr& greater, int val)
{
NodePtr equalOrGreater;
split(orig, lower, equalOrGreater, val);
split(equalOrGreater, equal, greater, val + 1);
}

int main()
{
srand(time(0));

Tree tree;

int cur = 5;
int res = 0;

for(int i = 1; i < 1000000; i++)
{
int mode = i % 3;
cur = (cur * 57 + 43) % 10007;
if(mode == 0)
{
tree.insert(cur);
}
else if(mode == 1)
{
tree.erase(cur);
}
else if(mode == 2)
{
res += tree.hasValue(cur);
}
}
std::cout << res;
return 0;
}

0 comments on commit 7bd3f56

Please sign in to comment.