Compare commits
No commits in common. "d824449ddb8bd568d643a4d77238f55bf1723aa9" and "d79703063f94b75b5d090073b108d6856995811c" have entirely different histories.
d824449ddb
...
d79703063f
|
@ -8,9 +8,6 @@ namespace BAN
|
||||||
template<typename T, typename Container, bool CONST>
|
template<typename T, typename Container, bool CONST>
|
||||||
class IteratorSimpleGeneral
|
class IteratorSimpleGeneral
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IteratorSimpleGeneral() = default;
|
IteratorSimpleGeneral() = default;
|
||||||
template<bool CONST2, typename = enable_if_t<CONST2 == CONST || CONST>>
|
template<bool CONST2, typename = enable_if_t<CONST2 == CONST || CONST>>
|
||||||
|
@ -59,8 +56,7 @@ namespace BAN
|
||||||
IteratorSimpleGeneral& operator--()
|
IteratorSimpleGeneral& operator--()
|
||||||
{
|
{
|
||||||
ASSERT(m_pointer);
|
ASSERT(m_pointer);
|
||||||
--m_pointer;
|
return --m_pointer;
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
IteratorSimpleGeneral operator--(int)
|
IteratorSimpleGeneral operator--(int)
|
||||||
{
|
{
|
||||||
|
@ -106,8 +102,6 @@ namespace BAN
|
||||||
using InnerIterator = either_or_t<CONST, typename Inner::const_iterator, typename Inner::iterator>;
|
using InnerIterator = either_or_t<CONST, typename Inner::const_iterator, typename Inner::iterator>;
|
||||||
using OuterIterator = either_or_t<CONST, typename Outer::const_iterator, typename Outer::iterator>;
|
using OuterIterator = either_or_t<CONST, typename Outer::const_iterator, typename Outer::iterator>;
|
||||||
|
|
||||||
using value_type = T;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IteratorDoubleGeneral() = default;
|
IteratorDoubleGeneral() = default;
|
||||||
template<bool CONST2, typename = enable_if_t<CONST2 == CONST || CONST>>
|
template<bool CONST2, typename = enable_if_t<CONST2 == CONST || CONST>>
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <BAN/Swap.h>
|
|
||||||
#include <BAN/Traits.h>
|
|
||||||
|
|
||||||
namespace BAN
|
|
||||||
{
|
|
||||||
|
|
||||||
template<typename It, typename Comp = less<typename It::value_type>>
|
|
||||||
void sort_exchange(It begin, It end, Comp comp = {})
|
|
||||||
{
|
|
||||||
for (It lhs = begin; lhs != end; ++lhs)
|
|
||||||
for (It rhs = lhs; ++rhs != end;)
|
|
||||||
if (!comp(*lhs, *rhs))
|
|
||||||
swap(*lhs, *rhs);
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace detail
|
|
||||||
{
|
|
||||||
|
|
||||||
template<typename It, typename Comp>
|
|
||||||
It sort_quick_partition(It begin, It end, Comp comp)
|
|
||||||
{
|
|
||||||
It pivot = end; --pivot;
|
|
||||||
|
|
||||||
It it1 = begin;
|
|
||||||
for (It it2 = begin; it2 != pivot; ++it2)
|
|
||||||
{
|
|
||||||
if (comp(*it2, *pivot))
|
|
||||||
{
|
|
||||||
swap(*it1, *it2);
|
|
||||||
++it1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
swap(*it1, *pivot);
|
|
||||||
|
|
||||||
return it1;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename It, typename Comp = less<typename It::value_type>>
|
|
||||||
void sort_quick(It begin, It end, Comp comp = {})
|
|
||||||
{
|
|
||||||
{
|
|
||||||
It it = begin;
|
|
||||||
if (it == end || ++it == end)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
It mid = detail::sort_quick_partition(begin, end, comp);
|
|
||||||
sort_quick(begin, mid, comp);
|
|
||||||
sort_quick(++mid, end, comp);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <BAN/Move.h>
|
|
||||||
|
|
||||||
namespace BAN
|
|
||||||
{
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void swap(T& lhs, T& rhs)
|
|
||||||
{
|
|
||||||
T tmp = move(lhs);
|
|
||||||
lhs = move(rhs);
|
|
||||||
rhs = move(tmp);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -28,7 +28,6 @@ set(USERSPACE_PROJECTS
|
||||||
test
|
test
|
||||||
test-globals
|
test-globals
|
||||||
test-framebuffer
|
test-framebuffer
|
||||||
test-sort
|
|
||||||
touch
|
touch
|
||||||
u8sum
|
u8sum
|
||||||
whoami
|
whoami
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include <BAN/Vector.h>
|
#include <BAN/Vector.h>
|
||||||
#include <BAN/Sort.h>
|
|
||||||
#include <BAN/String.h>
|
#include <BAN/String.h>
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -63,40 +62,44 @@ i64 hand_score(const Hand& hand, bool joker)
|
||||||
{
|
{
|
||||||
if (isdigit(c))
|
if (isdigit(c))
|
||||||
cnt[c - '0' + 0]++;
|
cnt[c - '0' + 0]++;
|
||||||
else if (joker && c == 'J')
|
else if (c == 'J')
|
||||||
joker_count++;
|
joker_count++;
|
||||||
else
|
else
|
||||||
cnt[c - 'A' + 10]++;
|
cnt[c - 'A' + 10]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i64 freq_max1 = 0;
|
if (!joker)
|
||||||
i64 freq_max2 = 0;
|
|
||||||
for (size_t i = 0; i < 36; i++)
|
|
||||||
{
|
{
|
||||||
if (cnt[i] > freq_max1)
|
cnt['J' - 'A' + 10] = joker_count;
|
||||||
{
|
joker_count = 0;
|
||||||
freq_max2 = freq_max1;
|
|
||||||
freq_max1 = cnt[i];
|
|
||||||
}
|
}
|
||||||
else if (cnt[i] > freq_max2)
|
|
||||||
{
|
|
||||||
freq_max2 = cnt[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
freq_max1 += joker_count;
|
|
||||||
|
|
||||||
if (freq_max1 == 5)
|
for (size_t i = 0; i < 36; i++)
|
||||||
|
if (cnt[i] + joker_count >= 5)
|
||||||
return 6'000'000 + hand_score_no_type(hand, joker);
|
return 6'000'000 + hand_score_no_type(hand, joker);
|
||||||
if (freq_max1 == 4)
|
|
||||||
|
for (size_t i = 0; i < 36; i++)
|
||||||
|
if (cnt[i] + joker_count >= 4)
|
||||||
return 5'000'000 + hand_score_no_type(hand, joker);
|
return 5'000'000 + hand_score_no_type(hand, joker);
|
||||||
if (freq_max1 == 3 && freq_max2 == 2)
|
|
||||||
|
for (size_t i = 0; i < 36; i++)
|
||||||
|
for (size_t j = 0; j < 36; j++)
|
||||||
|
if (i != j && cnt[i] + joker_count >= 3 && cnt[j] >= 2)
|
||||||
return 4'000'000 + hand_score_no_type(hand, joker);
|
return 4'000'000 + hand_score_no_type(hand, joker);
|
||||||
if (freq_max1 == 3)
|
|
||||||
|
for (size_t i = 0; i < 36; i++)
|
||||||
|
if (cnt[i] + joker_count >= 3)
|
||||||
return 3'000'000 + hand_score_no_type(hand, joker);
|
return 3'000'000 + hand_score_no_type(hand, joker);
|
||||||
if (freq_max1 == 2 && freq_max2 == 2)
|
|
||||||
|
for (size_t i = 0; i < 36; i++)
|
||||||
|
for (size_t j = 0; j < 36; j++)
|
||||||
|
if (i != j && cnt[i] + joker_count >= 2 && cnt[j] >= 2)
|
||||||
return 2'000'000 + hand_score_no_type(hand, joker);
|
return 2'000'000 + hand_score_no_type(hand, joker);
|
||||||
if (freq_max1 == 2)
|
|
||||||
|
for (size_t i = 0; i < 36; i++)
|
||||||
|
if (cnt[i] + joker_count >= 2)
|
||||||
return 1'000'000 + hand_score_no_type(hand, joker);
|
return 1'000'000 + hand_score_no_type(hand, joker);
|
||||||
|
|
||||||
return hand_score_no_type(hand, joker);
|
return hand_score_no_type(hand, joker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,21 +113,33 @@ i64 puzzle(FILE* fp, bool joker)
|
||||||
BAN::StringView line(buffer);
|
BAN::StringView line(buffer);
|
||||||
if (line.size() < 7)
|
if (line.size() < 7)
|
||||||
continue;
|
continue;
|
||||||
MUST(hands.emplace_back(
|
|
||||||
line.substring(0, 5),
|
Hand hand;
|
||||||
parse_i64(line.substring(6))
|
hand.hand = line.substring(0, 5);
|
||||||
));
|
hand.bid = parse_i64(line.substring(6));
|
||||||
|
MUST(hands.push_back(hand));
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::sort_quick(hands.begin(), hands.end(),
|
// Very slow sorting algorithm
|
||||||
[joker] (const Hand& lhs, const Hand& rhs) {
|
for (size_t i = 0; i < hands.size(); i++)
|
||||||
return hand_score(lhs, joker) < hand_score(rhs, joker);
|
{
|
||||||
|
i64 l_score = hand_score(hands[i], joker);
|
||||||
|
for (size_t j = i + 1; j < hands.size(); j++)
|
||||||
|
{
|
||||||
|
i64 r_score = hand_score(hands[j], joker);
|
||||||
|
if (r_score > l_score)
|
||||||
|
{
|
||||||
|
Hand tmp = BAN::move(hands[i]);
|
||||||
|
hands[i] = BAN::move(hands[j]);
|
||||||
|
hands[j] = BAN::move(tmp);
|
||||||
|
l_score = r_score;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
i64 score = 0;
|
i64 score = 0;
|
||||||
for (size_t i = 0; i < hands.size(); i++)
|
for (size_t i = 0; i < hands.size(); i++)
|
||||||
score += (i + 1) * hands[i].bid;
|
score += (hands.size() - i) * hands[i].bid;
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.26)
|
|
||||||
|
|
||||||
project(test-sort CXX)
|
|
||||||
|
|
||||||
set(SOURCES
|
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
add_executable(test-sort ${SOURCES})
|
|
||||||
target_compile_options(test-sort PUBLIC -O2 -g)
|
|
||||||
target_link_libraries(test-sort PUBLIC libc)
|
|
||||||
|
|
||||||
add_custom_target(test-sort-install
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/test-sort ${BANAN_BIN}/
|
|
||||||
DEPENDS test-sort
|
|
||||||
)
|
|
|
@ -1,41 +0,0 @@
|
||||||
#include <BAN/Vector.h>
|
|
||||||
#include <BAN/Sort.h>
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool is_sorted(BAN::Vector<T>& vec)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < vec.size() - 1; i++)
|
|
||||||
if (vec[i] > vec[i + 1])
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CURRENT_NS() ({ timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); ts.tv_sec * 1'000'000'000 + ts.tv_nsec; })
|
|
||||||
|
|
||||||
#define TEST(name, function, count) do { \
|
|
||||||
BAN::Vector<int> ivec(count, 0); \
|
|
||||||
for (int& i : ivec) \
|
|
||||||
i = rand() % 100; \
|
|
||||||
uint64_t start_ns = CURRENT_NS(); \
|
|
||||||
function(ivec.begin(), ivec.end()); \
|
|
||||||
uint64_t end_ns = CURRENT_NS(); \
|
|
||||||
uint64_t dur_us = (end_ns - start_ns) / 1000; \
|
|
||||||
printf(name " (" #count "): %s\n", is_sorted(ivec) ? "success" : "fail"); \
|
|
||||||
printf(" took %" PRIu64 ".%03" PRIu64 " ms\n", dur_us / 1000, dur_us % 1000); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
srand(time(0));
|
|
||||||
TEST("exchange sort", BAN::sort_exchange, 100);
|
|
||||||
TEST("exchange sort", BAN::sort_exchange, 1000);
|
|
||||||
TEST("exchange sort", BAN::sort_exchange, 10000);
|
|
||||||
|
|
||||||
TEST("quick sort", BAN::sort_quick, 100);
|
|
||||||
TEST("quick sort", BAN::sort_quick, 1000);
|
|
||||||
TEST("quick sort", BAN::sort_quick, 10000);
|
|
||||||
}
|
|
Loading…
Reference in New Issue