<commit_before>import FS from "fs";
import Path from "path";
import _ from "lodash-fp";
import { split } from "../helpers";

export const title = "Day 5: Doesn't He Have Intern-Elves For This?";

const getMatches = _.curry((list, string) => _.filter((x) => _.includes(x, string), list));

export function isNiceString(string) {
    // Contains at least 3 vowels.
    const vowels = ["a", "e", "i", "o", "u"];
    const threeVowels = _.compose(_.gte(3), _.get("length"), _.filter((x) => _.includes(x, vowels)), split(""));
    
    // Contains at least one letter that appears twice.
    const pattern = /([a-z])\1+/;
    const duplicateLetters = (str) => pattern.test(str);
    
    // Doesn't contain 'ab', 'cd', 'pq', or 'xy'.
    const blacklist = ["ab", "cd", "pq", "xy"];
    const blacklistWords = _.compose(_.gte(1), _.get("length"), getMatches(blacklist));

    return threeVowels(string) && duplicateLetters(string) && !blacklistWords(string);
}

export function run() {
    const inputPath = Path.join(__dirname, "input.txt");
    const input = FS.readFileSync(inputPath, "utf-8").trim().split("\n");
    
    console.log("How many strings are nice?");
}<commit_msg>Completed part 1. Spoiler alert: the answer is 236.<commit_after>import FS from "fs";
import Path from "path";
import _ from "lodash-fp";
import { split } from "../helpers";

export const title = "Day 5: Doesn't He Have Intern-Elves For This?";

const getMatches = _.curry((list, string) => _.filter((x) => _.includes(x, string), list));

export function isNiceString(string) {
    // Contains at least 3 vowels.
    const vowels = ["a", "e", "i", "o", "u"];
    const threeVowels = _.compose(_.gte(3), _.get("length"), _.filter((x) => _.includes(x, vowels)), split(""));
    
    // Contains at least one letter that appears twice.
    const pattern = /([a-z])\1+/;
    const duplicateLetters = (str) => pattern.test(str);
    
    // Doesn't contain 'ab', 'cd', 'pq', or 'xy'.
    const blacklist = ["ab", "cd", "pq", "xy"];
    const blacklistWords = _.compose(_.gte(1), _.get("length"), getMatches(blacklist));

    return threeVowels(string) && duplicateLetters(string) && !blacklistWords(string);
}

export function run() {
    const inputPath = Path.join(__dirname, "input.txt");
    const input = FS.readFileSync(inputPath, "utf-8").trim().split("\n");
    const niceStrings = _.compose(_.get("length"), _.filter(isNiceString));
    
    console.log("How many strings are nice?", niceStrings(input));
}
{'fraction_non_alphanumeric': 0.1906677393403057, 'fraction_numerical': 0.006436041834271922, 'mean_word_length': 3.8385214007782102, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1259714', 'n_tokens_mistral': 851, 'n_tokens_neox': 807, 'n_words': 233}