diff options
author | kaiwu <kaiwu2004@gmail.com> | 2022-03-16 11:48:19 +0800 |
---|---|---|
committer | kaiwu <kaiwu2004@gmail.com> | 2022-03-16 11:48:19 +0800 |
commit | 6aa919cbe332d7e45c0c3a7954d48166f4b774c0 (patch) | |
tree | a02239ddb071c554448d9cb5f3cc19d9235cb12f | |
parent | 480dfe85d94d703e10728f6a46cf05ee99ea08f8 (diff) | |
download | advent-of-code-6aa919cbe332d7e45c0c3a7954d48166f4b774c0.tar.gz advent-of-code-6aa919cbe332d7e45c0c3a7954d48166f4b774c0.zip |
strstr
-rw-r--r-- | CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/2015/day5/aoc.cpp | 35 | ||||
-rw-r--r-- | src/2015/day5/aoc.h | 6 | ||||
-rw-r--r-- | src/common.cpp | 11 | ||||
-rw-r--r-- | src/common.h | 51 | ||||
-rw-r--r-- | test/test_common.cpp | 10 |
6 files changed, 111 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 4782b07..7f2e354 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.8) project(advent-of-code LANGUAGES CXX) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Wextra -pedantic -Wno-unused-parameter") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -Wextra -pedantic -Wno-unused-parameter -Wno-sizeof-array-argument -Wno-sizeof-pointer-div") set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_EXTENSIONS Off) diff --git a/src/2015/day5/aoc.cpp b/src/2015/day5/aoc.cpp index 1c33c66..d3f310b 100644 --- a/src/2015/day5/aoc.cpp +++ b/src/2015/day5/aoc.cpp @@ -1,5 +1,40 @@ #include "aoc.h" +#include <algorithm> namespace aoc2015 { +int count_vowels(line_view lv, const char* vowels) { + ascii_count ac{lv}; + int total = 0; + per_char(vowels, [&ac, &total](char c) { + total += ac[c]; + return true; + }); + return total; } + +bool is_nice(line_view lv, int repeated) { + const char* p = lv.line; + while (p + repeated < lv.line + lv.length) { + if (is_repeated(p, p + repeated)) { + return true; + } else { + p++; + } + } + return false; +} + +bool is_nice(line_view lv, const char* disallowed[]) { + size_t size = sizeof(disallowed) / sizeof(*disallowed); + if (std::any_of(disallowed, disallowed + size, [&lv](const char* s) -> bool { return lv.contains(s); })) { + return false; + } + return true; +} + +/* +int day5(line_view) {} +*/ + +} // namespace aoc2015 diff --git a/src/2015/day5/aoc.h b/src/2015/day5/aoc.h index a0b442c..beaa278 100644 --- a/src/2015/day5/aoc.h +++ b/src/2015/day5/aoc.h @@ -3,9 +3,9 @@ namespace aoc2015 { -int count_vowels(line_view, char*); -bool contains_repeated(line_view, int); -bool has_no_disallowed(line_view, char*[]); +int count_vowels(line_view, const char*); +bool is_nice(line_view, int); +bool is_nice(line_view, const char*[]); int day5(line_view); diff --git a/src/common.cpp b/src/common.cpp index 8442bf6..1342109 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -31,3 +31,14 @@ line_view next_line(line_view file, size_t* offset) { *offset = p2 - file.line + 1; return {p1, static_cast<size_t>(p2 - p1 + 1)}; } + +bool is_repeated(const char* p1, const char* p2) { + char c = *p1; + while (p1 != p2) { + if (*p1 != c) { + return false; + } + p1++; + } + return true; +} diff --git a/src/common.h b/src/common.h index 4b2683d..7f2dfc9 100644 --- a/src/common.h +++ b/src/common.h @@ -2,12 +2,15 @@ #include <iostream> #include <stdlib.h> +#include <string.h> #include <utility> struct line_view { const char* line; size_t length; + line_view(const char* s = nullptr) : line(s) { length = s == nullptr ? 0 : strlen(s); } + line_view(const char* s, size_t l) : line(s), length(l) {} friend std::ostream& operator<<(std::ostream& o, const line_view& lv) { for (size_t i = 0; i < lv.length; i++) { o << lv.line[i]; @@ -25,6 +28,22 @@ struct line_view { } return l[i] == '\0'; } + + bool contains(const char* s) { + size_t len = strlen(s); + const char* p = line; + while (p + len < line + length) { + if (*p == *s) { + line_view x{p, len}; + if (x == s) { + return true; + } else { + p++; + } + } + } + return false; + } }; line_view load_file(const char*); @@ -41,3 +60,35 @@ void per_line(line_view file, F&& f, Args&&... args) { } } while (offset < file.length); } + +template <typename F, typename... Args> +void per_char(line_view line, F&& f, Args&&... args) { + for (size_t i = 0; i < line.length; i++) { + if (!f(line.line[i], std::forward<Args>(args)...)) { + break; + } + } +} + +struct ascii_count { + int count[256]; + + ascii_count(line_view lv) : count{0} { + per_char(lv, [this](char c) { + count[static_cast<int>(c)] += 1; + return true; + }); + } + + int operator[](char c) const noexcept { return count[static_cast<int>(c)]; } + friend std::ostream& operator<<(std::ostream& o, const ascii_count& ac) { + for (size_t i = 0; i < 256; i++) { + if (ac.count[i] > 0) { + o << i << " -> " << ac.count[i] << "\n"; + } + } + return o; + } +}; + +bool is_repeated(const char* p1, const char* p2); diff --git a/test/test_common.cpp b/test/test_common.cpp index 851bef7..1486988 100644 --- a/test/test_common.cpp +++ b/test/test_common.cpp @@ -13,3 +13,13 @@ TEST_CASE("load file", "[]") { }, lines); } + +TEST_CASE("char count", "[]") { + line_view line{"accad1\n", 7}; + ascii_count ac{line}; + REQUIRE(ac['\n'] == 1); + REQUIRE(ac['a'] == 2); + REQUIRE(ac['c'] == 2); + REQUIRE(ac['d'] == 1); + REQUIRE(ac['1'] == 1); +} |