Compare commits

..

No commits in common. "d824449ddb8bd568d643a4d77238f55bf1723aa9" and "d79703063f94b75b5d090073b108d6856995811c" have entirely different histories.

7 changed files with 53 additions and 175 deletions

View File

@ -8,9 +8,6 @@ namespace BAN
template<typename T, typename Container, bool CONST>
class IteratorSimpleGeneral
{
public:
using value_type = T;
public:
IteratorSimpleGeneral() = default;
template<bool CONST2, typename = enable_if_t<CONST2 == CONST || CONST>>
@ -59,8 +56,7 @@ namespace BAN
IteratorSimpleGeneral& operator--()
{
ASSERT(m_pointer);
--m_pointer;
return *this;
return --m_pointer;
}
IteratorSimpleGeneral operator--(int)
{
@ -106,8 +102,6 @@ namespace BAN
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 value_type = T;
public:
IteratorDoubleGeneral() = default;
template<bool CONST2, typename = enable_if_t<CONST2 == CONST || CONST>>

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -28,7 +28,6 @@ set(USERSPACE_PROJECTS
test
test-globals
test-framebuffer
test-sort
touch
u8sum
whoami

View File

@ -1,5 +1,4 @@
#include <BAN/Vector.h>
#include <BAN/Sort.h>
#include <BAN/String.h>
#include <ctype.h>
@ -63,40 +62,44 @@ i64 hand_score(const Hand& hand, bool joker)
{
if (isdigit(c))
cnt[c - '0' + 0]++;
else if (joker && c == 'J')
else if (c == 'J')
joker_count++;
else
cnt[c - 'A' + 10]++;
}
i64 freq_max1 = 0;
i64 freq_max2 = 0;
for (size_t i = 0; i < 36; i++)
if (!joker)
{
if (cnt[i] > freq_max1)
{
freq_max2 = freq_max1;
freq_max1 = cnt[i];
cnt['J' - 'A' + 10] = joker_count;
joker_count = 0;
}
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);
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);
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);
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);
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);
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 hand_score_no_type(hand, joker);
}
@ -110,21 +113,33 @@ i64 puzzle(FILE* fp, bool joker)
BAN::StringView line(buffer);
if (line.size() < 7)
continue;
MUST(hands.emplace_back(
line.substring(0, 5),
parse_i64(line.substring(6))
));
Hand hand;
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(),
[joker] (const Hand& lhs, const Hand& rhs) {
return hand_score(lhs, joker) < hand_score(rhs, joker);
// Very slow sorting algorithm
for (size_t i = 0; i < hands.size(); i++)
{
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;
for (size_t i = 0; i < hands.size(); i++)
score += (i + 1) * hands[i].bid;
score += (hands.size() - i) * hands[i].bid;
return score;
}

View File

@ -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
)

View File

@ -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);
}