Skip to content

Commit

Permalink
Leetcode (#24)
Browse files Browse the repository at this point in the history
* Messy solution to today's problem - subsets as a method.

* Add today's problem with two subsets variants

* Leetcode problem of the day

* Create 552.rs

* Add leetcode problem of the day

* Add leetcode problem of the day #ct

* Create 523.cpp

Add Leetcode problem of the day WIP, TLE.

Try do this without loops xD

* Fix indentation, compilation about trivial missing include, add tests.
  • Loading branch information
iglesias authored Jun 12, 2024
1 parent 74ccede commit 6b76f66
Show file tree
Hide file tree
Showing 7 changed files with 333 additions and 0 deletions.
52 changes: 52 additions & 0 deletions 140.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <string>
#include <unordered_set>
#include <vector>

#include <gtest/gtest.h>

using std::string;
using std::unordered_set;
using std::vector;

void solve(vector<string>& ans, const string& s, const unordered_set<string>& words, string& sentence, int idx = 0) {
const int n = static_cast<int>(s.size());
if (idx >= n) {
ans.push_back(sentence);
} else {
for (int i = idx; i < n; i++) {
const string t = s.substr(idx, i - idx + 1);
if (words.contains(t)) {
string new_sentence = sentence;
if (sentence.empty()) new_sentence += t;
else {
new_sentence.push_back(' ');
new_sentence += t;
}
solve(ans, s, words, new_sentence, i + 1);
}
}
}
}

vector<string> wordbreak(const string& s, const vector<string>& wordDict) {
unordered_set<string> words;
for (const string& word : wordDict) words.insert(word);
vector<string> ans;
{
string sentence;
solve(ans, s, words, sentence);
}
return ans;
}

TEST(BreakIntoWords, Example_1)
{
EXPECT_EQ(wordbreak("catsanddog", vector<string>{"cat", "cats", "and", "sand", "dog"}),
vector<string>{"cat sand dog", "cats and dog"});
}

int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
95 changes: 95 additions & 0 deletions leetcode/1255.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <algorithm>
#include <array>
#include <string>
#include <vector>

#include <gtest/gtest.h>

using std::string;
using std::vector;

std::array<int, 'z' - 'a' + 1> letters_left; // global

namespace loop {

int solve(const vector<string>& words, const vector<int>& scores, vector<string>& subset, const size_t words_i = 0, int ans = 0)
{
{
int score = 0;
for (const string& word : subset) for (const char letter : word) score += scores[letter - 'a'];
ans = std::max(ans, score);
}

for (size_t j = words_i; j < words.size(); j++) {
bool jump = false;
for (size_t i = 0; i < words[j].size() and !jump; i++)
if (letters_left[words[j][i] - 'a']) letters_left[words[j][i] - 'a']--;
else {
jump = true;
for (size_t k = 0; k < i; k++) letters_left[words[j][k] - 'a']++;
}
if (jump) continue;
subset.push_back(words[j]);
ans = std::max(ans, solve(words, scores, subset, j + 1));
subset.pop_back();
for (size_t i = 0; i < words[j].size(); i++) letters_left[words[j][i] - 'a']++;
}

return ans;
}

} // namespace loop

namespace without_or_with {

int solve(const vector<string>& words, const vector<int>& scores, vector<string>& subset, const size_t words_i = 0, int ans = 0)
{
{
int score = 0;
for (const string& word : subset) for (const char letter : word) score += scores[letter - 'a'];
ans = std::max(ans, score);
}

if (words_i == words.size()) return ans;

ans = std::max(ans, solve(words, scores, subset, words_i + 1, ans));

for (size_t i = 0; i < words[words_i].size(); i++)
if (letters_left[words[words_i][i] - 'a']) letters_left[words[words_i][i] - 'a']--;
else {
for (size_t k = 0; k < i; k++) letters_left[words[words_i][k] - 'a']++;
return ans;
}
subset.push_back(words[words_i]);
ans = std::max(ans, solve(words, scores, subset, words_i + 1, ans));
subset.pop_back();
for (size_t i = 0; i < words[words_i].size(); i++) letters_left[words[words_i][i] - 'a']++;

return ans;
}

} // namespace without_or_with

int max_score(const vector<string>& words, const vector<char>& letters, const vector<int>& scores, bool loop = true)
{
std::ranges::fill(letters_left, 0);
for (const char letter : letters) letters_left[letter - 'a']++;
vector<string> subset;
if (loop) return loop::solve(words, scores, subset);
else return without_or_with::solve(words, scores, subset);
}

TEST(MaximizeWordsScore, SixteenOfFiftytwo)
{
const vector<string> words{"baa", "bba", "ccb", "ac"};
const vector<char> letters{'a', 'b', 'b', 'b', 'b', 'c'};
const vector<int> scores{2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
EXPECT_EQ(max_score(words, letters, scores), 6);
EXPECT_EQ(max_score(words, letters, scores, /* loop = */ false), 6);
}

int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
55 changes: 55 additions & 0 deletions leetcode/131.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#include <string>
#include <vector>

#include <gtest/gtest.h>

using std::string;
using std::vector;

bool is_palindrome(const string& s, int start, int end) {
while (start <= end) if (s[start++] != s[end--]) return false;
return true;
}

void solve(const string& s, vector<vector<string>>& ans, vector<int>& v, int v_index = 0) {
if (!v.size()) {
if (is_palindrome(s, 0, s.length() - 1)) ans.push_back(vector<string>{s});
} else {
bool not_palindrome_found = false;
int start = 0;
vector<string> candidate;
for (size_t i = 0; i < v.size() && !not_palindrome_found; i++) {
not_palindrome_found |= !is_palindrome(s, start, v[i]);
candidate.push_back(s.substr(start, v[i] - start + 1));
start = v[i] + 1;
}
not_palindrome_found |= !is_palindrome(s, start, s.length() - 1);
candidate.push_back(s.substr(start));
if (!not_palindrome_found) ans.push_back(candidate);
}
for (size_t j = v_index; j < s.length() - 1; j++) {
v.push_back(j);
solve(s, ans, v, j + 1);
v.pop_back();
}
}

vector<vector<string>> partition(const string& s) {
vector<vector<string>> ans;
vector<int> v;
solve(s, ans, v);
return ans;
}

TEST(PalindromePartitioning, a) {
EXPECT_EQ(partition("aab"), (vector<vector<string>>{{"a", "a", "b"}, {"aa", "b"}}));
}

TEST(PalindromePartitioning, b) {
EXPECT_EQ(partition("a"), vector<vector<string>>{{"a"}});
}

int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
38 changes: 38 additions & 0 deletions leetcode/1404.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <string>

#include <gtest/gtest.h>

int solve(std::string s)
{
int l = 0, r = s.length() - 1;
int ans = 0;
while (l < r) {
ans++;
if (s[r] == '0') {
r--;
} else {
int i = r;
do {
s[i] = '0';
i--;
} while (i >= 0 and s[i] == '1');
if (i < 0) {
s.insert(0, "1");
r++;
} else s[i] = '1';
}
}
return s[l] == '1' ? ans : ans + 1;
}

TEST(num_steps, FiveHundredChars)
{
const std::string s{"11011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101110111011101"};
EXPECT_EQ(solve(s), 626);
}

int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
23 changes: 23 additions & 0 deletions leetcode/3110.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <numeric>
#include <string_view>

constexpr int score(std::string_view s)
{
std::array<int, 1024> v;
std::adjacent_difference(s.cbegin(), s.cend(), v.begin());
return std::accumulate(std::next(v.cbegin()),
v.cbegin() + s.length(),
0,
[](int acc, const int val) {
return acc += std::abs(val);
});
}

static_assert(score("hello") == 13);
static_assert(score("platypus") == 55);
static_assert(score("honorificabilitudinitatibus") == 181);

int main(){}
46 changes: 46 additions & 0 deletions leetcode/523.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include <vector>

#include <gtest/gtest.h>

// Check if the arary has a (continuous) subarray of at least
// two elements whose sum is a multiple of k.
bool check_subarray_sum(const std::vector<int>& nums, int k)
{
const int n = static_cast<int>(nums.size());
if (n < 2) return false;
int i = 0, j = 1;
unsigned sum = 0;
while (i < n) {
sum += nums[i];
while (j < n) {
sum += nums[j];
if (!(sum % k)) return true;
j ++;
}
j--;
sum -= nums[i];
i++;
if (i == n) break;
while (j >= i + 1) {
if (!(sum % k)) return true;
sum -= nums[j];
j--;
}
sum -= nums[i];
i++, j +=2;
}
return false;
}

TEST(CheckSubarraySumDivisibility, a)
{
const std::vector nums{23, 2, 6, 4, 7};
EXPECT_EQ(check_subarray_sum(nums, 6), true);
EXPECT_EQ(check_subarray_sum(nums, 13), false);
}

int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
24 changes: 24 additions & 0 deletions leetcode/552.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
impl Solution {
pub fn check_record(n: i32) -> i32 {
let mut record_i: [i32; 6] = [1, 1, 0, 1, 0, 0];
let modulo = 1000000000 + 7;
for i in 2..(n+1) {
let mut record_j: [i32; 6] = [0; 6];
record_j[0] = (((record_i[0] + record_i[1]) % modulo) + record_i[2]) % modulo;
record_j[1] = record_i[0];
record_j[2] = record_i[1];
record_j[3] = 0;
for i in 0..6 {
record_j[3] = (record_j[3] + record_i[i]) % modulo;
}
record_j[4] = record_i[3];
record_j[5] = record_i[4];
record_i = record_j;
}
let mut ans: i32 = 0;
for i in 0..6 {
ans = (ans + record_i[i]) % modulo;
}
ans
}
}

0 comments on commit 6b76f66

Please sign in to comment.