# Jaskamal Kainth: full text > Chief Software Engineer at Samsung R&D Institute India, leading engineering for Samsung's global product search platform (query understanding, retrieval, ranking). B.E. Computer Science and M.Sc. Mathematics from BITS Pilani; ACM-ICPC competitor and long-time competitive programmer. Every article on https://jaskamalkainth.github.io, as Markdown. Each section starts with the article's canonical URL; please cite that URL when quoting. Index of articles: https://jaskamalkainth.github.io/llms.txt --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotes.html Title: C++ Notes: Templates, Lambdas, constexpr and the STL Description: Short, example-first notes on modern C++: template specialization and metaprogramming, overloading, lambdas, constexpr, variadic templates, tuples and unordered_map. Published: 2021-05-07 Updated: 2026-10-02

C++ Notes

Short, example-first notes on the corners of C++ I keep coming back to: templates, compile-time computation and the standard library.

C++ logo
--- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/1.html Title: Template explicit vs implicit specialization Description: Why a C++ explicit specialization declared as f(const int) still matches f(int): top-level const is not part of the function type. Worked example. Published: 2023-03-24 Updated: 2026-10-02 # Template explicit vs implicit specialization **Short answer:** top-level `const` on a by-value parameter is not part of a function's type, so `template<> void f(const int)` is the explicit specialization of `f`. Calling `f` with an `int` (const or not) runs the specialization. Any other argument type falls back to an implicit instantiation of the primary template. ```c++ #include using std::cout; // Main template template void f(T n) { cout << 2; } // Template specialization template<> void f(const int n) { cout << 1; } int main() { int n = 11; f(n); } ``` ``` Code outputs 1. ``` For the function call f(n), since 'n' is of int type, the template argument T is deduced as T = int. The explicit specialization ```c++ template<> void f(const int n) ``` looks like it is for `const int`, but when a function type is formed the top-level `const` on a by-value parameter is dropped. Its signature is `void(int)`, so it is the specialization for T = int and it is the one that runs. The `const` still matters inside the body: `n` cannot be modified there. It just doesn't change which calls match. Passing a `const int` also outputs 1, because template argument deduction drops top-level `const` from a by-value argument too (T = int). To see the primary template, call `f` with a different type: `f(2.0)` deduces T = double, no specialization exists for it, so the compiler implicitly instantiates `f` and the code outputs 2. > Explicit specializations do not take part in overload resolution. The compiler first picks the best primary template for the call (deducing T), and only then checks whether an explicit specialization exists for those exact template arguments. If one does, it is used; otherwise the primary template is implicitly instantiated. ********************************************************************* --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/10.html Title: std::unordered_map in C++ Description: std::unordered_map in C++: a hash table with average O(1) lookup, insert and erase, basic usage, and custom hash functions for user-defined keys. Published: 2023-04-06 Updated: 2026-10-02 # Unordered Map in C++ `std::unordered_map` is a container that stores key-value pairs in which keys are unique. It implements a hash table, providing average constant-time complexity for search, insert, and delete operations. ## Basic Usage ```cpp #include #include #include int main() { // Create an unordered_map std::unordered_map ages; // Insert elements ages["Alice"] = 30; ages["Bob"] = 25; ages.insert({"Charlie", 35}); // Access elements std::cout << "Alice's age: " << ages["Alice"] << std::endl; // Check if key exists if (ages.find("David") == ages.end()) { std::cout << "David not found" << std::endl; } // Iterate through all elements (structured bindings need C++17) for (const auto& [name, age] : ages) { std::cout << name << " is " << age << " years old" << std::endl; } return 0; } ``` ## Custom Hash Functions For custom types as keys, you need to provide a hash function and equality operator: ```cpp struct Person { std::string name; int age; bool operator==(const Person& other) const { return name == other.name && age == other.age; } }; // Custom hash function. XOR is the simplest way to combine hashes but collides easily // (equal component hashes cancel out to 0); boost::hash_combine-style mixing is safer. struct PersonHash { std::size_t operator()(const Person& p) const { return std::hash()(p.name) ^ std::hash()(p.age); } }; // Usage std::unordered_map personData; ``` `std::unordered_map` is generally preferred over `std::map` when order doesn't matter and you need faster lookups for large datasets. --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/2.html Title: Ambiguous function overloading in C++: why foo(0) is ill-formed Description: Why calling foo(0) fails to compile when foo(const char*) and foo(short) both exist: 0 converts to either with equal rank, so the call is ambiguous. Published: 2023-03-24 Updated: 2026-10-02 # Ill-formed function call due to ambiguous function overloading **Short answer:** `foo(0)` is ambiguous because the literal `0` is both an `int` and a null pointer constant. Converting it to `const char*` (pointer conversion) and to `short` (integral conversion) are both standard conversions of the same rank, so neither overload is better and the call does not compile. ```c++ #include void foo(const char* str) // Function 1 { std::cout << "F1 = " << str << std::endl; } void foo(short n) // Function 2 { std::cout << "F2 = " << n << std::endl; } int main() { foo("randomString"); // Function 1 is called foo(1); // Function 2 is called foo(0); // In this case 0 can be implicitly treated as a null pointer or an integer // so with 1 implicit conversion sequence compiler can deduce either of the Function 1 or 2 // Hence it is an ill-formed function call and a compilation error. return 0; } ``` **Compilation Error:** ``` ill-formed-function-call.cpp:16:5: error: call to 'foo' is ambiguous foo(0); ^~~ ill-formed-function-call.cpp:3:6: note: candidate function void foo(const char* str) // Function 1 ^ ill-formed-function-call.cpp:7:6: note: candidate function void foo(short n) // Function 2 ^ 1 error generated. ``` * In the above code, both foo() overloads are viable and for a compiler to choose, one of them has to have a better conversion sequence but since 0 is of type int and also a nullptr constant, in both cases we have a single conversion and hence no function is better than the other hence ill-formed. * If the function definition had foo(int) then the compiler can treat 0 as integer without any implicit conversion and hence no error. * Similarly if we pass foo(0L) and we have a definition like foo(long n). > Note: a *null pointer constant* is an integer literal with value 0 (or `nullptr`). Passing `nullptr` instead of `0` would unambiguously call Function 1. --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/3.html Title: Template metaprogramming in C++: compile-time Fibonacci Description: Compute Fibonacci numbers at compile time with C++ template metaprogramming: a recursive struct template with explicit specializations as base cases. Published: 2023-04-06 Updated: 2026-10-02 # Template Metaprogramming - Fibonacci Template metaprogramming is a technique in C++ that uses templates to perform computations at compile time. ## Fibonacci Implementation The Fibonacci sequence can be implemented using template metaprogramming: ```cpp template struct Fibonacci { static const int value = Fibonacci::value + Fibonacci::value; }; // Base cases template<> struct Fibonacci<0> { static const int value = 0; }; template<> struct Fibonacci<1> { static const int value = 1; }; ``` This implementation computes Fibonacci numbers at compile time, making runtime computation unnecessary. The template specializations for `N=0` and `N=1` serve as base cases to terminate the recursion. Using this implementation, `Fibonacci<10>::value` would give you the 10th Fibonacci number, all calculated during compilation. --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/4.html Title: Template metaprogramming in C++: compile-time factorial Description: Compute factorials at compile time in C++ with a recursive class template and a Factorial<0> base case, so the result has no runtime cost. Published: 2023-04-06 Updated: 2026-10-02 # Template Metaprogramming - Factorial Another classic example of template metaprogramming is computing factorials at compile time. ## Factorial Implementation ```cpp template struct Factorial { static const int value = N * Factorial::value; }; // Base case template<> struct Factorial<0> { static const int value = 1; }; ``` This implementation allows factorial computations to be performed during compilation. The template is recursively instantiated until it reaches the base case of `Factorial<0>`, which returns 1. To use this implementation, simply access the `value` member of the appropriate template instantiation: ```cpp int main() { std::cout << "Factorial of 5: " << Factorial<5>::value << std::endl; // 120 return 0; } ``` The computation happens at compile time, resulting in no runtime overhead for the calculation. --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/5.html Title: Lambda expressions in C++ Description: C++ lambda expressions explained: syntax, capture lists, capturing by value, mutable lambdas, and using lambdas with standard algorithms. Published: 2023-04-06 Updated: 2026-10-02 # Lambda Expressions in C++ Lambda expressions were introduced in C++11 and provide a concise way to create anonymous function objects. ## Basic Syntax The basic syntax of a lambda expression is: ```cpp [capture-list](parameter-list) -> return-type { function-body } ``` Where: - `capture-list`: Specifies which variables from the surrounding scope are accessible - `parameter-list`: Similar to function parameters - `return-type`: Optional, compiler can often deduce it - `function-body`: The code to execute ## Examples ### Simple Lambda ```cpp auto add = [](int a, int b) { return a + b; }; std::cout << add(5, 3); // Outputs: 8 ``` ### Capturing Variables ```cpp int multiplier = 5; auto multiply = [multiplier](int x) { return x * multiplier; }; std::cout << multiply(3); // Outputs: 15 ``` ### Mutable Lambda By default, variables captured by value cannot be modified. Use the `mutable` keyword to allow modification: ```cpp int counter = 0; auto increment = [counter]() mutable { return ++counter; }; std::cout << increment(); // Outputs: 1 std::cout << counter; // Outputs: 0 (original not modified) ``` Lambda expressions are commonly used with algorithms from the standard library, such as `std::sort`, `std::for_each`, and `std::transform`. --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/6.html Title: constexpr in C++ Description: How constexpr moves work to compile time in C++11/14/17: constexpr functions, compile-time vs runtime evaluation, and why it beats template metaprogramming. Published: 2023-04-06 Updated: 2026-10-02 # Constexpr in C++ The `constexpr` keyword was introduced in C++11 and enhanced in C++14 and C++17. It enables computations to be performed at compile time. ## Basic Usage A `constexpr` function can be evaluated at compile time if its arguments are compile-time constants: ```cpp constexpr int square(int x) { return x * x; } // Used at compile time constexpr int result = square(5); // Computed during compilation // Used at runtime int input; std::cin >> input; int dynamic_result = square(input); // Computed at runtime ``` ## Constexpr vs Template Metaprogramming While template metaprogramming also enables compile-time computation, `constexpr` provides a more readable and maintainable approach: ```cpp // Fibonacci with constexpr (C++14 and later) constexpr int fibonacci(int n) { if (n <= 1) return n; return fibonacci(n-1) + fibonacci(n-2); } // Usage constexpr int fib10 = fibonacci(10); // Computed at compile time ``` The advantage of `constexpr` over template metaprogramming is that it uses familiar function syntax rather than recursive template instantiations, making the code easier to understand and maintain. --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/7.html Title: Struct vs class in C++ Description: The only differences between struct and class in C++ are default member access and default inheritance (public vs private). When to use each. Published: 2023-04-06 Updated: 2026-10-02 # Struct vs Class in C++ In C++, `struct` and `class` are nearly identical, with only one difference in their default access level. ## Key Differences | Feature | Struct | Class | |---------|--------|-------| | Default access modifier | public | private | | Default inheritance | public | private | | Intended use (convention) | Passive data structures | Objects with behavior | ## Example ```cpp struct Point { int x; // public by default int y; // public by default }; class Circle { private: // private by default, but explicitly shown for clarity Point center; double radius; public: Circle(Point c, double r) : center(c), radius(r) {} double area() const { return 3.14159 * radius * radius; } }; ``` ## When to Use Each - Use `struct` when you have a simple data structure with little or no behavior - Use `class` when you have an object with both data and behavior that operates on that data - Use `struct` when all members should be publicly accessible - Use `class` when you need to enforce encapsulation by making some members private The choice between `struct` and `class` is often a matter of convention and communicating intent to other programmers. --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/8.html Title: Variadic templates in C++ Description: Variadic templates in C++11: parameter packs, recursive expansion with a base case, C++17 fold expressions, and where they are used. Published: 2023-04-06 Updated: 2026-10-02 # Variadic Templates in C++ Variadic templates, introduced in C++11, allow you to define templates that accept an arbitrary number of arguments of any type. ## Basic Syntax ```cpp template return_type function_name(Args... args); ``` The ellipsis (`...`) indicates a parameter pack, which can contain zero or more template arguments. ## Recursive Implementation Example A common pattern is to use recursion to process variadic templates: ```cpp // Base case to terminate recursion void print() { std::cout << std::endl; } // Recursive case template void print(T first, Args... rest) { std::cout << first << " "; print(rest...); // Recursive call with remaining arguments } // Usage print(1, 2.5, "hello", 'c'); // Outputs: 1 2.5 hello c ``` ## Fold Expressions (C++17) C++17 introduced fold expressions to simplify variadic template code: ```cpp template auto sum(Args... args) { return (... + args); // Unary left fold } // Usage int total = sum(1, 2, 3, 4, 5); // 15 ``` ## Applications Variadic templates are particularly useful for: - Creating type-safe variadic functions - Implementing perfect forwarding - Building tuple-like data structures - Creating compile-time type lists --- URL: https://jaskamalkainth.github.io/blog_posts/CppNotesDb/9.html Title: std::tuple in C++ Description: Using std::tuple in C++: creating tuples, std::get, std::make_tuple, C++17 structured bindings and class template argument deduction, and std::tuple_cat. Published: 2023-04-06 Updated: 2026-10-02 # Tuples in C++ `std::tuple` is a template class in C++ that can hold a fixed-size collection of elements of different types. ## Basic Usage ```cpp #include #include #include int main() { // Creating a tuple std::tuple person(30, "John", 6.1); // Accessing elements using std::get std::cout << "Age: " << std::get<0>(person) << std::endl; std::cout << "Name: " << std::get<1>(person) << std::endl; std::cout << "Height: " << std::get<2>(person) << std::endl; // C++17 structured binding auto [age, name, height] = person; std::cout << "Name: " << name << std::endl; return 0; } ``` ## Tuple Operations ### Creating Tuples ```cpp // Using make_tuple helper auto person = std::make_tuple(30, "John", 6.1); // C++17 class template argument deduction std::tuple person2(30, "John", 6.1); ``` ### Tuple Concatenation ```cpp // C++11 and later auto tuple1 = std::make_tuple(1, 'a'); auto tuple2 = std::make_tuple("hello", 5.5); auto combined = std::tuple_cat(tuple1, tuple2); // tuple ``` Tuples are especially useful when you need to return multiple values from a function or when you need to group heterogeneous data without defining a custom class. --- URL: https://jaskamalkainth.github.io/blog_posts/DSU_problems.html Title: Disjoint Set Union (Union-Find) Practice Problems Description: Practice problems for Disjoint Set Union (union–find) from UVa, HackerEarth and Codeforces, ordered by difficulty: connected components, group leaders and merges. Published: 2016-05-07 Updated: 2026-10-02

Disjoint Set Union Problems

Union–find answers "are these two in the same group?" in near-constant time. These problems start with counting components and build up to tracking leaders and merging whole ranges. Tick off the ones you solve; your progress is saved in this browser.

Two disjoint-set trees being merged by attaching one root under the other
0 / solved
## Frequently asked questions ### What is a disjoint set union (union–find) data structure? Disjoint set union keeps a collection of non-overlapping sets as a forest, where each tree's root is the set's representative. find(x) returns x's root and union(a, b) links two roots, so you can merge groups and ask whether two elements are in the same group. ### What is the time complexity of union–find? With both path compression and union by rank (or size), any sequence of m operations on n elements runs in O(m · α(n)) time, where α is the inverse Ackermann function. α(n) is at most 4 for any practical n, so each operation is effectively constant time. ### When should I use DSU instead of BFS or DFS? Use DSU when edges arrive over time and you repeatedly ask whether two nodes are connected, or when you need to merge groups (for example in Kruskal's minimum spanning tree). BFS/DFS is simpler when the graph is fixed and you only need to explore it once. --- URL: https://jaskamalkainth.github.io/blog_posts/best-samsung-phones-under-50000.html Title: Best Samsung Phones Under ₹50,000 in India (2026 Guide) Description: The best Samsung phones under ₹50,000 in India for 2026: Galaxy A36 5G for display, M47 5G for battery, M17e 5G on a budget, with prices and key specs. Published: 2026-01-15 Updated: 2026-01-15 # Best Samsung Phones Under ₹50,000 (2026) > **Quick answer:** buy the **Galaxy A36 5G** (from ₹33,999) for the best screen, the **Galaxy M47 5G** (₹28,999) for the biggest battery, or the **Galaxy M17e 5G** (₹12,499) if you want to spend as little as possible. Prices are Samsung India's listed prices as of January 2026. *Disclosure: I work at Samsung R&D Institute India. This is a personal post, not an official Samsung publication; it is based only on Samsung India's public product pages, linked throughout.* Samsung's ₹50,000-and-under lineup spans the Galaxy M and Galaxy A series — from ultra-budget picks under ₹15,000 to near-flagship Super AMOLED displays just under the ₹35,000 mark. Here's how the current lineup breaks down, pulled directly from [Samsung India's "Best Mobiles under ₹50,000" page](https://www.samsung.com/in/smartphones/mobiles-by-price/under-rs50000/) and each model's own buy page. ## Quick Picks | Phone | Starting Price | Best For | |---|---|---| | [Galaxy A36 5G](https://www.samsung.com/in/smartphones/galaxy-a36/buy/) | ₹33,999 | Best overall (Super AMOLED, 120Hz) | | [Galaxy M47 5G](https://www.samsung.com/in/smartphones/galaxy-m/galaxy-m47-5g-rogue-red-128gb-sm-m476bzrdins/buy/) | ₹28,999 | Best battery life (6000mAh) | | [Galaxy M17e 5G](https://www.samsung.com/in/smartphones/galaxy-m/galaxy-m17e-5g-blitz-blue-128gb-sm-m076blbains/buy/) | ₹12,499 | Best budget pick | ## 1. Galaxy A36 5G — Best Overall - **Display:** 6.7" Super AMOLED, 120Hz refresh rate - **RAM / Storage:** 8GB/128GB, 8GB/256GB, or 12GB/256GB - **Colors:** Awesome Black, Lavender, White, Lime, Sapphire Blue, Emerald Green - **Price:** Starting ₹33,999 (9-month no-cost EMI from ₹3,778/mo; ₹1,000 off first purchase) 👉 **[See current price & configure →](https://www.samsung.com/in/smartphones/galaxy-a36/buy/)** The A36 5G is the pick if you want the closest thing to a flagship screen (Super AMOLED + 120Hz) without crossing ₹35,000. Best for anyone who spends a lot of time on video/social media and notices screen quality. ## 2. Galaxy M47 5G — Best Battery Life - **Battery:** 6000 mAh (typical) - **Display:** ~6.7" (16.91cm) - **RAM / Storage:** 8GB with 128GB or 256GB storage - **Colors:** Blaze Blue, Rogue Red - **Price:** ₹28,999 launch offer (₹4,000 instant bank discount) 👉 **[See current price & configure →](https://www.samsung.com/in/smartphones/galaxy-m/galaxy-m47-5g-rogue-red-128gb-sm-m476bzrdins/buy/)** If your phone needs to survive a full day of classes/work without a charger in sight, the M47 5G's 6000mAh battery is the standout spec in this price range. ## 3. Galaxy M17e 5G — Best Budget Pick - **RAM / Storage:** 128GB (see product page for RAM configuration) - **Colors:** Blitz Blue and others - **Price:** ₹12,499 👉 **[See current price & configure →](https://www.samsung.com/in/smartphones/galaxy-m/galaxy-m17e-5g-blitz-blue-128gb-sm-m076blbains/buy/)** At under ₹13,000, this is less a "best under ₹50,000" pick and more proof of how far your budget stretches in Samsung's current 5G lineup — a solid choice if ₹50,000 is your ceiling, not your target. *(Full, filterable list: [Samsung India — Best Mobiles under ₹50,000](https://www.samsung.com/in/smartphones/mobiles-by-price/under-rs50000/))* ## How We Chose These Picks were pulled directly from Samsung India's own "under ₹50,000" category page and each model's individual buy page, prioritizing models Samsung itself currently features as in-stock/buyable (not older or discontinued models still indexed elsewhere on the site) — then split by what most buyers optimize for: screen quality, battery life, and raw budget. ## Conclusion If you just want one answer: the **Galaxy A36 5G** (from ₹33,999) is the best all-round pick under ₹50,000 — it's the only one of the three with a Super AMOLED 120Hz display, and it still leaves ₹16,000+ of headroom under the budget cap. Pick the **M47 5G** instead if battery life matters more to you than screen quality, or the **M17e 5G** if you'd rather spend a fraction of the budget and put the rest toward accessories, a case, or savings. *Prices shown are Samsung's listed starting prices at the time of writing and include current launch/bank offers — check each buy page linked above for live pricing before purchasing.* ## Frequently asked questions ### Which is the best Samsung phone under ₹50,000 in 2026? The Galaxy A36 5G (from ₹33,999) is the best all-round pick: it is the only phone of the three with a 6.7-inch Super AMOLED 120Hz display, and it leaves more than ₹16,000 of headroom under a ₹50,000 budget. ### Which Samsung phone under ₹50,000 has the best battery? The Galaxy M47 5G, with a 6000mAh (typical) battery, at a ₹28,999 launch offer price. ### What is the cheapest 5G Samsung phone in this list? The Galaxy M17e 5G at ₹12,499 with 128GB of storage. --- URL: https://jaskamalkainth.github.io/blog_posts/bloom_filters.html Title: Bloom Filters Explained: How They Work, False Positives and C++ Code Description: How a Bloom filter answers set membership with no false negatives and a tunable false-positive rate: the bit array, hash functions, formulas, real uses and C++ code. Published: 2025-03-15 Updated: 2026-10-02 # Bloom Filters: The Art of Probably Knowing > **In short:** a Bloom filter is a bit array plus *k* hash functions that tells you whether an element is **definitely not** in a set or **probably** in it. It never gives false negatives, its false-positive rate is tunable (about 1% at ~10 bits per element), and it uses a few bits per element regardless of element size. Databases, browsers and caches use it to skip expensive lookups for things that aren't there. Imagine you're a bouncer at a club. You have a list of people who are banned. For every person who walks up, you need to decide: are they on the ban list? The naive approach (scanning the entire list every time) is slow and expensive. But you don't necessarily need *certainty*. You just need a fast answer to: **"Is this person definitely NOT banned?"** If the answer is yes, let them in quickly. If there's any doubt, do the full check. That's the intuition behind a **Bloom filter**. ## The Core Idea A Bloom filter is a space-efficient data structure with one peculiar property: - It can tell you with **100% certainty** that something is **not** in a set. - It can tell you that something is **probably** in the set, but might occasionally be wrong (a false positive). It **never** produces false negatives. If you added something, the Bloom filter will always recognize it. This asymmetry ("definitely no" vs. "probably yes") turns out to be incredibly useful. ## How It Works (Simply) Picture a row of light switches, all starting in the **OFF** position. **Adding an element:** 1. Run the element through several different hash functions. Each one gives you a number. 2. Flip the switches at those numbered positions to **ON**. **Checking if an element exists:** 1. Run the same element through the same hash functions. 2. Look at those switch positions. 3. If **any** switch is **OFF** → the element was definitely never added. 4. If **all** switches are **ON** → the element was *probably* added (but another combination of elements could have flipped those same switches). That's it. No storing the actual elements, just flipping bits. ## Real-World Use Cases This might sound abstract, so let's look at where this is actually used in production systems you interact with every day. ### 1. Chrome's Safe Browsing Every time you visit a URL, Chrome checks whether it's a known phishing or malware site. Google maintains a list of hundreds of millions of dangerous URLs. Downloading that full list to your browser every time would be impractical. Early versions of Chrome instead kept a **Bloom filter** of dangerous URL prefixes locally (a few MB); it was later replaced by a more compact "prefix set", but the idea is the same. When you navigate to a site: - If the Bloom filter says **"definitely not in the list"** → proceed immediately, no network call needed. - If it says **"probably dangerous"** → Chrome makes a real network call to verify before loading the page. The vast majority of URLs are safe, so the Bloom filter eliminates almost all network checks with zero false negatives. ### 2. Databases Avoiding Unnecessary Disk Reads (Cassandra, HBase, LevelDB) Disk reads are orders of magnitude slower than memory reads. Databases like Cassandra and LevelDB use Bloom filters to answer: "Does this key exist in this file on disk?" Before reading from disk, they check the Bloom filter: - **"Definitely not here"** → skip this file entirely, saving a costly I/O operation. - **"Probably here"** → do the actual disk read. In LSM-tree databases a single key can live in any of many on-disk files, so this lets a read skip almost every file that doesn't contain the key. Cassandra exposes the trade-off directly as a per-table `bloom_filter_fp_chance` setting. ### 3. Medium's "Already Read" Articles Medium used Bloom filters to track which articles a user has already seen, so they don't recommend the same article twice. Storing every article ID a user has ever viewed in a database per user would be expensive at scale. A Bloom filter per user takes a tiny fraction of that space. A false positive just means occasionally not recommending an article the user hasn't actually read, a minor, acceptable inconvenience. ### 4. Bitcoin Lite Clients (SPV Nodes) Bitcoin's lightweight clients (that don't download the full blockchain) use Bloom filters to ask full nodes: "Send me only transactions relevant to my wallet addresses." The client sends a Bloom filter encoding its addresses. The full node filters transactions through it. This avoids revealing which specific addresses the client owns (partial privacy) while dramatically reducing the data sent over the wire. ### 5. Weak Password Detection Datasets like Have I Been Pwned's list hundreds of millions of compromised passwords. Checking "has this password ever been leaked?" against a database that size on every sign-up would be slow. A Bloom filter built over the leaked-password set answers in microseconds and fits in memory: a "definitely not compromised" answer means you can skip the full lookup. ## Implementation in C++ Here's the core class, surprisingly simple: ```cpp #include #include #include #include using namespace std; const int MAX_BUFF_SIZE = 1e6; // ~1MB of bits using HashFunction = function; class BloomFilters { private: vector buffer; // our "row of switches" vector hashFunctions; // k hash functions public: BloomFilters(int bufferSize, vector& functions) { buffer.resize(bufferSize); hashFunctions = functions; } // O(k * |string|) — flip k bits for every insert void insert(const string& str) { for (auto& func: hashFunctions) { buffer[func(str) % buffer.size()] = 1; } } // O(k * |string|) — check k bits; one 0 means definitely absent const bool isPresent(const string& str) const { for (auto& func: hashFunctions) { if (buffer[func(str) % buffer.size()] != 1) return false; } return true; } }; ``` ### Hash Functions We need multiple hash functions that spread independently. Using different polynomial bases achieves this cheaply: ```cpp unsigned int hashFunction1(const string& str) { const int b = 31; unsigned int res = 0; for (const char& ch: str) res = res * b + ch; return res; } unsigned int hashFunction2(const string& str) { const int b = 3727; unsigned int res = 0; for (const char& ch: str) res = res * b + ch - '0'; return res; } ``` Two hash functions with different bases (31 and 3727) produce values that are largely independent, minimizing the chance that unrelated strings collide on the same set of bits. ### Putting It Together ```cpp int main() { vector functions = { hashFunction1, hashFunction2 }; BloomFilters bf(MAX_BUFF_SIZE, functions); bf.insert("google.com"); bf.insert("github.com"); cout << bf.isPresent("google.com") << "\n"; // 1 — definitely added cout << bf.isPresent("evil.com") << "\n"; // 0 — definitely NOT added cout << bf.isPresent("github.com") << "\n"; // 1 — definitely added return 0; } ``` ## Understanding False Positives The one downside: false positives. As more elements are added, more bits get flipped to 1, and eventually a *new* element's hash positions might all land on bits already set by other elements. The false positive probability after inserting **n** elements into a filter of **m** bits with **k** hash functions is approximately: $$ P_{fp} \approx \left(1 - e^{-kn/m}\right)^k $$ And the optimal number of hash functions (minimizing false positives for given m and n) is: $$ k_{opt} = \frac{m}{n} \ln 2 $$ **A concrete example:** With 1 million bits, 100,000 inserted elements (10 bits per element) and 7 hash functions (the optimum, since 10 · ln 2 ≈ 6.9), the false positive rate is roughly **0.8%**: about one in 120 lookups for absent elements will incorrectly say "probably present." Turning that around, the bits needed for a target false-positive rate *p* are: $$ m = -\frac{n \ln p}{(\ln 2)^2} $$ That is about **9.6 bits per element for 1%** and **14.4 bits per element for 0.1%**, whatever the size of the elements themselves. The key levers you control: - **Larger bit array** (m) → fewer false positives, more memory. - **More hash functions** (k) → fewer false positives up to a point, then they start increasing again. - **Fewer inserted elements** (n) → fewer false positives. ## The Fundamental Trade-off | Property | Bloom Filter | Hash Set | |---|---|---| | Memory usage | Very low (bits) | High (stores full values) | | False negatives | Never | Never | | False positives | Possible (tunable, e.g. ~1%) | Never | | Deletion | Not supported* | Supported | | Lookup speed | O(k) | O(1) amortized | \* Counting Bloom filters (and cuckoo filters) support deletion at the cost of extra space. Use a Bloom filter when you can tolerate a small false positive rate and need to minimize memory usage. Use a regular hash set when you need exact answers and memory isn't a constraint. ## Conclusion Bloom filters are a masterclass in practical trade-offs. By accepting a small, tunable probability of false positives, they achieve memory efficiency that traditional data structures simply can't match. The "definitely not present" guarantee is the key insight: it lets you skip expensive operations (disk reads, network calls, database queries) with absolute confidence for the common case. Next time you browse the web safely, query a distributed database, or get article recommendations, there's a good chance a Bloom filter is quietly doing work behind the scenes. The full implementation with additional test cases and an interactive query interface is available in my [GitHub repository](https://github.com/Jaskamalkainth/BloomFilter). ## Frequently asked questions ### Can a Bloom filter have false negatives? No. Every inserted element sets all of its k bits, and bits are never cleared, so a lookup for an inserted element always finds all k bits set. A standard Bloom filter can only be wrong in one direction: it may report "probably present" for an element that was never added. ### How many hash functions should a Bloom filter use? The false-positive rate is lowest when k = (m/n) · ln 2, where m is the number of bits and n the number of elements. At 10 bits per element that is about 7 hash functions, giving a false-positive rate of roughly 0.8%. ### How much memory does a Bloom filter need? For a target false-positive rate p, the optimal size is m = −n · ln p / (ln 2)² bits, about 9.6 bits per element for 1% and 14.4 bits per element for 0.1%, no matter how large the elements themselves are. ### Can you delete elements from a Bloom filter? Not from a standard one: clearing a bit could also remove other elements that share it and create false negatives. A counting Bloom filter replaces each bit with a small counter so deletions are possible, at the cost of several times more memory. Cuckoo filters are another option that supports deletion. ### When should I use a Bloom filter instead of a hash set? Use a Bloom filter when memory is tight, a small false-positive rate is acceptable, and a negative answer lets you skip expensive work such as a disk read or network call. Use a hash set when you need exact answers, deletion, or the stored values themselves. --- URL: https://jaskamalkainth.github.io/blog_posts/elasticsearchNotes.html Title: Elasticsearch Notes: Inverted Indexes, Shards, Segments and Query DSL Description: Elasticsearch from the bottom up: inverted indexes, Lucene shards and segments, why updates are costly, and curl examples for Query DSL, filters and aggregations. Published: 2019-06-08 Updated: 2026-10-02 # Elasticsearch Notes > **In short:** Elasticsearch is a distributed search and analytics engine built on Apache Lucene. An index is split into **shards**; each shard is a Lucene index made of immutable **segments**; each segment is an **inverted index** mapping terms to the documents that contain them. You talk to it with JSON over HTTP, using the Query DSL to combine scored queries, unscored filters and aggregations. *These notes were written in 2019 against Elasticsearch 6.x. The concepts still hold, but mapping types were removed in 7.x: the URLs below such as `customer/external/1` are `customer/_doc/1` in Elasticsearch 7 and 8.* ___ Elasticsearch is a real time, search and analytics engine. * Open-source * High Availability - Keeps redundant data (replicas) * Schema free - You need not know the details about your database. for ex: what does this column do? you don't care, if you use ES. :) * Scales massively - One node running in one machine merges with other node running in other machine in the form of clusters. * Uses RESTful API - JSON over HTTP * Distributed multi-tenancy - If you need separate instance for an Application for every usecase. Single cluster in a DB can store many different characteristics. * Lucene based. * Uses _version numbers for optimistic concurrency control - every time we interact with a doc , its _version number increments. This is used to make sure that we don't miss any changes without locking. ## Elasticsearch from the Bottom up ### Inverted Indexes and Index Terms We have a cluster of nodes in ES , within a cluster we have an ES index which spans multiple nodes through shards. Shard is a lucene index. Lucene is full text search library used by Elasticsearch. within a lucene index, we have segments (mini index) within segment we have, * *INVERTED INDEX* ``` sorted dictionary[terms] | freq | docs [format used to store inverted indexes]``` In this sorted dictionary say we want words with ‘c’ beginning , so for this we can do binary search on it. now find every term containing “ours” ? (brute: all terms, which is bad) In other words, we can efficiently find things given term prefixes. When all we have is an inverted index, we want everything to look like a string prefix problem. So we can do some transformations. * To find everything with a common suffix, we can index the reverse and we can search for everything with the common reverse(suffix). * To find substrings, terms are splitted into smaller terms called "n-grams". Ex: "yours" can be split into "yo", "you","our","urs","rs", this means that we could get occurrences of "ours" by searching for "our" and "urs" * Geographical coordinate points such as (10.1,12.32) can be converted into "geo hashes", in this case "jkd224fk". The longer the string, the greater the precision. * Soundex and metaphone can be used to find strings that sound similar when pronounced out loud. Phonetic matching is enabled which uses above mentioned algorithms. * Lucene stores 123 as "1"-hundreds, "12"-tens and "123". Hence, searching for everything in the range[100,199] is therefore everything matching the "1"-hundreds-term. This can be done in a trie like fashion, so range searches can be done efficiently. * To do "Did you mean?" type searches and find spellings that are close to the input, a "Levenshtein" automaton can be built to effectively traverse the dictionary. This is too complex. ### Building Indexes and Index Segments Few factors which are important while building inverted indexes are speed, index compactness, indexing speed and update time. Various compression techniques for ex: Delta encoding is used to minimize index sizes. Lucene does not update these small data structures. This is different from B-Trees , which can be updated. Segments are immutable. When you delete a document , bitmap[fileremove] = 1 but the segment doesn’t change. These Data structures are stored in segments. Lucene searches all the segments and merge the results. Lucene also Caches all the things. Merging happens therefore indexes gets reduced by adding stuff. when you search these shards, same as searching segments and then merge the data. searching 1 ES Index with 2 shards is same as 2 ES index with 1 shard each. Can’t split a shard but we can move one shard to other. User put his doc in an Index and then that index decides in which shard to put that data. When you query for a particular doc in an index, that index searches all the shards. >Updating a previously indexed document is a delete followed by a re-insertion of the document. Note that this means that updating a document is even more expensive than adding it in the first place. These indexes are built first in-memory, then occasionally flushed in segments to disk. ___ ## Installation ``` brew install elasticsearch # or run the official Docker image ``` ___ ## Exploring your cluster / Modifying data / Exploring Data > The pretty parameter, again, just tells Elasticsearch to return pretty-printed JSON results. ### Cluster health ``` curl -XGET 'localhost:9200/_cat/health?v&pretty' ``` * GET is a verb( PUT, POST, HEAD). * localhost is a node. * 9200 is HTTP port. * pretty is to make output easier to read. ### List nodes ``` curl -XGET 'localhost:9200/_cat/nodes?v&pretty' ``` ### Create an index ``` curl -XPUT 'localhost:9200/customer?pretty&pretty' curl -XGET 'localhost:9200/_cat/indices?v&pretty' ``` ### Index and Query a Document ``` curl -XPUT 'localhost:9200/customer/external/1?pretty&pretty' -H 'Content-Type: application/json' -d' { "name": "John Doe" }' curl -XGET 'localhost:9200/customer/external/1?pretty&pretty' ``` ### Delete an Index ``` curl -XDELETE 'localhost:9200/customer?pretty&pretty' curl -XGET 'localhost:9200/_cat/indices?v&pretty' ``` ### Summary ``` curl -XPUT 'localhost:9200/customer?pretty' curl -XPUT 'localhost:9200/customer/external/1?pretty' -H 'Content-Type: application/json' -d' { "name": "John Doe" }' curl -XGET 'localhost:9200/customer/external/1?pretty' curl -XDELETE 'localhost:9200/customer?pretty' ``` ### Updating Documents ``` curl -XPOST 'localhost:9200/customer/external/1/_update?pretty&pretty' -H 'Content-Type: application/json' -d' { "doc": { "name": "Jane Doe" } }' ``` ### Deleting Documents ``` curl -XDELETE 'localhost:9200/customer/external/2?pretty&pretty' ``` ### Bulk-load a sample index (bank, 1000 docs) ``` curl -H "Content-Type: application/json" -XPOST 'localhost:9200/bank/account/_bulk?pretty&refresh' --data-binary "@accounts.json" curl 'localhost:9200/_cat/indices?v' ``` ### Query DSL > match_all query is simply a search for all documents in the specified index ( bank ). ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} } }' ``` > Note that if size is not specified, it defaults to 10. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} }, "size": 1 }' ``` > match_all and returns documents 11 through 20: ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} }, "from": 10, "size": 10 }' ``` >This example does a match_all and sorts the results by account balance in descending order and returns the top 10 (default size) documents. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} }, "sort": { "balance": { "order": "desc" } } }' ``` > This example shows how to return two fields, account_number and balance (inside of _source), from the search. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_all": {} }, "_source": ["account_number", "balance"] }' ``` >This example returns the account numbered 20. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match": { "account_number": 20 } } }' ``` >This example returns all accounts containing the term "mill" in the address. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match": { "address": "mill" } } }' ``` >This example is a variant of match (match_phrase) that returns all accounts containing the phrase "mill lane" in the address: ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "match_phrase": { "address": "mill lane" } } }' ``` ### Bool query >This allows us to compose smaller queries into bigger queries using Boolean logic. **must (and)** , **should (or)** , **must_not** clause is used. >This example composes two match queries and returns all accounts containing "mill" and "lane" in the address: ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "bool": { "must": [ { "match": { "address": "mill" } }, { "match": { "address": "lane" } } ] } } }' ``` >We can combine must, should, and must_not clauses simultaneously inside a bool query. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "bool": { "must": [ { "match": { "age": "40" } } ], "must_not": [ { "match": { "state": "ID" } } ] } } }' ``` ___ ### Executing Filters >The score is a numeric value that is a relative measure of how well the document matches the search query that we specified. The higher the score, the more relevant the document is, the lower the score, the less relevant the document is. >Range query, which allows us to filter documents by a range of values. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "query": { "bool": { "must": { "match_all": {} }, "filter": { "range": { "balance": { "gte": 20000, "lte": 30000 } } } } } }' ``` ___ ### Executing Aggregations >Aggregations provide the ability to group and extract statistics from your data. ``` curl -XGET 'localhost:9200/bank/_search?pretty' -H 'Content-Type: application/json' -d' { "size": 0, "aggs": { "group_by_state": { "terms": { "field": "state.keyword" } } } }' ``` >size = 0 means , we only want to see aggregated results. ___ ### Conclusion Till now, we've learned the basics of what Elasticsearch is and how to work with it using some of the basic REST APIs. ___ ## Frequently asked questions ### What is an inverted index in Elasticsearch? An inverted index maps each term to the list of documents that contain it, stored as a sorted term dictionary with postings (document IDs and frequencies). Because the dictionary is sorted, Lucene can find terms and term prefixes quickly instead of scanning every document. ### What is the difference between a shard and a segment? A shard is a single Lucene index, and an Elasticsearch index is split across one or more shards that can live on different nodes. Each shard is in turn made of immutable segments, small self-contained inverted indexes that are searched together and periodically merged. ### Why is updating a document in Elasticsearch expensive? Segments are immutable, so an update marks the old document as deleted and indexes a new copy. That costs as much as a fresh insert plus the delete, and the space is only reclaimed when segments are merged. ### What is the difference between a query and a filter in Elasticsearch? A query (must/should) scores documents by how well they match. A filter (filter/must_not) only decides whether a document matches, without scoring, which makes it cheaper and cacheable. Range conditions such as a price or date window are usually filters. --- URL: https://jaskamalkainth.github.io/blog_posts/korean-learning-notes.html Title: Korean Learning Notes: Hangul, Grammar, Numbers and Verb Conjugation Description: My Korean (한국어) study notes from Sejong Korean levels 1–2: Hangul, pronunciation rules, numbers, time, grammar and formality, vocabulary, and a 해요체 verb table. Published: 2025-06-01 Updated: 2026-10-02

한국어 학습 노트 (Korean Learning Notes)

My journey of learning Korean language and culture

Class notes and a quick reference from my Sejong Korean courses: Hangul and pronunciation, native and Sino-Korean numbers, telling time, polite (해요체) verb conjugation, and everyday vocabulary.

Course Levels

🎯 Level 1 - Foundation Korean

✅ Completed 13 Classes • March - June 2025

Mastered Korean alphabet (Hangul), basic grammar, numbers, time expressions, and fundamental conversation skills including greetings, self-introduction, and daily activities.

+

📚 Class Notes

Class 1 March 21, 2025 (2025년 3월 21일) Introduction to Korean alphabet (Hangul) - basic consonants and vowels created by King Sejong in 1443
Class 2 March 28, 2025 (2025년 3월 28일) Complex consonants, complex vowels, basic vocabulary, and Korean drinking/food culture
Class 3 April 4, 2025 (2025년 4월 4일) Batchim rules (final consonant sounds), consonant assimilation, Korean greetings, and food vocabulary
Class 4 April 11, 2025 (2025년 4월 11일) Self-introduction (이에요/예요), nationality, occupation, topic markers (은/는), and Korean home vocabulary
Class 5 April 17, 2025 (2025년 4월 17일) Daily activities and places, present tense verbs, three levels of formality, and Korean greeting culture
Class 6 April 25, 2025 (2025년 4월 25일) Locations and positions, existence (있다/없다), subject markers (이/가), and Korean festivals
Class 7 May 9, 2025 (2025년 5월 9일) Shopping vocabulary, Sino-Korean numbers, object markers (을/를), and months of the year
Class 8 May 16, 2025 (2025년 5월 16일) Days of the week, counters with Native Korean numbers, body parts, and Korean traditional clothing
Class 9 May 23, 2025 (2025년 5월 23일) Past tense expressions (-았어요/-었어요), location markers (에서), and Korean transportation vocabulary
Class 10 May 30, 2025 (2025년 5월 30일) Seasons and weather expressions, temperature reading, negation (안), and connecting words (도, 그리고)
Class 11 June 6, 2025 (2025년 6월 6일) Time expressions, making appointments, time markers (에), duration (부터~까지), and prohibitive forms
Class 12 June 13, 2025 (2025년 6월 13일) Making suggestions and appointments using -(으)ㄹ까요?, -자/-ㅂ시다, and expressing desires with -고 싶어요
Class 13 June 20, 2025 (2025년 6월 20일) Weekend activities, future plans, grammar pattern: -(으)ㄹ 거예요

🚀 Level 2 - Intermediate Korean

🔄 In Progress 18 Classes • September 2025 - April 2026

Building on foundation knowledge to develop intermediate conversation skills, complex grammar patterns, and expanded vocabulary for daily communication.

+

📚 Class Notes

Class 1 September 12, 2025 (2025년 9월 12일) Essential connecting grammar: -고 (and), 그런데 (but/however), 도 (also/too) for linking actions and adding emphasis
Class 2 September 19, 2025 (2025년 9월 19일) Connecting sentences (그런데), Korean counters review, text/email comprehension, and intermediate grammar patterns (에게/에게서, 때문에, 수 있어요/없어요)
Class 3 September 26, 2025 (2025년 9월 26일) Chapter 2: 취미 활동 (Hobby Activities) - Grammar: 못 (cannot/unable to) and -아서/어서 (because/since), hobby vocabulary, expressing abilities and reasons
Class 4 October 17, 2025 (2025년 10월 17일) Ch2: frequency/reason dialogues; Read&Write: 축사모 poster (Sat 7 a.m., Hana Univ) + Badminton OX (2 correct). Ch3: food ordering/taste; dialogues (ordering, preference); grammar: -(으)ㄹ래요, 무슨+N, 그러면/그런데/그래서; vocab: core dishes & taste adjectives.
Class 5 October 31, 2025 (2025년 10월 31일) Chapter 3: Menu ordering, Read & Write poster, restaurant intro.
Class 6 November 7, 2025 (2025년 11월 7일) CHAPTER: 교통 (Transportation) - Grammar: 이/가 걸리다 (it takes [time]), …에서 …까지 (from … to …); Vocabulary: transportation modes and verbs; Dialogues: asking how you go/come, directions with transfers; Practice: durations (얼마나 … 걸려요/걸렸어요), routes, commute talk.
Class 7 November 14, 2025 (2025년 11월 14일) CHAPTER: 교통 (Transportation) - Grammar: …에서 …까지, [교통수단]을/를 타고 가다/오다/다니다, 갈아타다, 내리다, (시간)이/가 걸리다, -(으)세요; Practice: transfer routes, where to get off, durations; Read & Write: Airport→city table, Beijing→hometown reading; Vocab: transportation/route words and common places.
Class 8 November 28, 2025 (2025년 11월 28일) CHAPTER: 길 찾기 (Finding the way) - Grammar: (으)로 (toward/into/by), -아서/어서 (sequence); Actions: 건너다/지나다, 들어가다/나오다/올라가다/내려가다; Patterns: 오른쪽/왼쪽(으)로, 똑바로(쭉) 가세요; Tasks: "오시는 길" style directions.
Class 9 December 5, 2025 (2025년 12월 5일) Theme: 회사생활 (Office life) - Vocab: 출근/퇴근, 근무시간, 회의, 제안서/서류, 첨부/복사/출력, 동료, 쉬는 시간, 점심; Patterns: -(으)면서, -(으)면 돼요, -(으)세요, -아서/어서; Practice: Q&A and office verb examples.
Class 10 December 12, 2025 (2025년 12월 12일) Chapter 5 wrap-up - Integrated directions practice using (으)로 and -아서/어서; Read & Write: "오시는 길" poster, email directions; Speaking: 위치 묻고 답하기, 집 찾아오는 안내 편지 쓰기; Vocab: 이동 동사, 방향어, 장소.
Class 12 January 9, 2026 (2026년 1월 9일) Chapter 6 - 전화 (Phone calls): ask/give phone numbers, make calls; Grammar: -아/어 주다 (do for someone), -지요 (confirmation); Vocab: phone/text/call expressions.
Class 13 January 16, 2026 (2026년 1월 16일) Chapter 6 wrap-up - phone conversation practice and application; Activities: role-plays (asking numbers, calling offices), comprehension (texts/emails), writing about phone usage; Vocab: Chapter 6 review.
Class 14 January 23, 2026 (2026년 1월 23일) Chapter 7 - 외모 (Appearance): describe appearance and clothing; Grammar: -(으)ㄴ (adjective modifier), -고 있다 (wearing/current state); Vocab: 외모, 옷차림.
Class 15 January 23, 2026 (2026년 1월 23일) Chapter 8 — 가족 (Family): introducing family, asking and answering about family; Grammar: 의 (possession), -(으)시- (honorific); Vocab: 가족, 존대 표현.
Class 16 February 13, 2026 (2026년 2월 13일) Chapter 8 — 가족 (Family) Part 2: reading tables and short texts, writing family introductions, practice with 직업/취미/외모.
Class 17 February 20, 2026 (2026년 2월 20일) Chapter 9 — Part 2.
Class 18 February 27, 2026 (2026년 2월 27일) Class 18 notes (YT Video).

Cultural Videos & Songs from Classes

🎵 Korean Songs & Poems

Korean Happy Birthday Song

생일 축하합니다 (saengil chukahamnida) - Happy birthday to you
사랑하는 (name) 씨 (saranghaneun ... ssi) - Dear (name)

Three Bears Song (곰 세 마리)

곰 세 마리가 한 집에 있어 (gom se mariga han jibe isseo)
Three bears are in one house
아빠 곰은 뚱뚱해 (appa gomeun ttungttunghae)
Daddy bear is fat
엄마 곰은 날씬해 (eomma gomeun nalssinhae)
Mommy bear is slim
애기 곰은 너무 귀여워 (aegi gomeun neomu gwiyeowo)
Baby bear is very cute
으쓱 으쓱 잘한다 (eusseuk eusseuk jalhanda)
Wiggle wiggle well done!

Twinkle Little Star (반짝 반짝 작은 별)

Unity Haiku (통일 하이쿠)

우리 이름이 달라도
우리는 같은 하늘 아래 살아요
우리는 하나예요 - JK
Though our names, cultures, religions, and countries may differ, we all live under the same sky and are one.

Quick Reference

한글 (Hangul)

Basic Vowels:
ㅏ (a)
ㅛ (yo)
ㅑ (ya)
ㅜ (u)
ㅓ (eo)
ㅠ (yu)
ㅕ (yeo)
ㅡ (eu)
ㅗ (o)
ㅣ (i)
Basic Consonants:
ㄱ (g/k)
ㅈ (j)
ㄴ (n)
ㅊ (ch)
ㄷ (d/t)
ㅋ (k)
ㄹ (r/l)
ㅌ (t)
ㅁ (m)
ㅍ (p)
ㅂ (b/p)
ㅎ (h)
ㅅ (s)
ㅇ (silent/ng)
Complex Consonants:
ㄲ (kk)
ㅆ (ss)
ㄸ (tt)
ㅉ (jj)
ㅃ (pp)
Stronger than basic
Complex Vowels:
ㅐ (ae - like "care")
ㅝ (wo - like "wonder")
ㅒ (yae - like "yam")
ㅞ (we - like "wedding")
ㅔ (e - like "bed")
ㅟ (wi - like "week")
ㅖ (ye - like "yes")
ㅢ (ui - like "gooey")
ㅘ (wa - like "water")
ㅙ (wae - like "wet")
ㅚ (oe - like "wet")

Pronunciation Rules

Batchim Rules:
ㄱ,ㅋ,ㄲ → [k] (수박=su-bak)
ㅁ → [m] (밤=bam)
ㄴ → [n] (안=an)
ㅂ,ㅍ → [p] (집=jip)
ㄷ,ㅅ,ㅆ,ㅈ,ㅊ,ㅌ,ㅎ → [t] (옷=ot)
ㅇ → [ng] (공=gong)
ㄹ → [l] (달=dal)
Assimilation:
ㅂ+ㄴ → [m-n] (입니다→[임니다])
같이 → [가치] (ga-chi=together)
ㅎ Neutralization:
Final position: silent (좋다→[조타])
Before consonants: silent (않고→[안꼬])
Double Batchim:
Word end/before consonant: one consonant
Before vowel: second moves to next syllable

Numbers

Sino-Korean (dates, money, minutes, years, phone numbers, addresses, mathematical calculations):
일 (il - 1)
십 (sip - 10)
이 (i - 2)
백 (baek - 100)
삼 (sam - 3)
천 (cheon - 1K)
사 (sa - 4)
만 (man - 10K)
오 (o - 5)
억 (eok - 100M)
육 (yuk - 6)
조 (jo - 1T)
칠 (chil - 7)
팔 (pal - 8)
구 (gu - 9)
Native Korean (counting objects, people, animals, hours 1-12, age, ordering food/drinks):
하나 (hana - 1)
열 (yeol - 10)
둘 (dul - 2)
열하나 (yeol hana - 11)
셋 (set - 3)
스물 (seumul - 20)
넷 (net - 4)
서른 (seoreun - 30)
다섯 (daseot - 5)
마흔 (maheun - 40)
여섯 (yeoseot - 6)
쉰 (swin - 50)
일곱 (ilgop - 7)
예순 (yesun - 60)
여덟 (yeodeol - 8)
일흔 (ilheun - 70)
아홉 (ahop - 9)
여든 (yeodeun - 80)
아흔 (aheun - 90)

Time

Months:
1월 (irwol - Jan)
7월 (chirwol - Jul)
2월 (iwol - Feb)
8월 (palwol - Aug)
3월 (samwol - Mar)
9월 (guwol - Sep)
4월 (sawol - Apr)
10월 (siwol - Oct)
5월 (owol - May)
11월 (sibil-wol - Nov)
6월 (yuwol - Jun)
12월 (sibi-wol - Dec)
Days:
월요일 (wol-yoil - Monday/Moon)
금요일 (geum-yoil - Friday/Gold)
화요일 (hwa-yoil - Tuesday/Fire)
토요일 (to-yoil - Saturday/Earth)
수요일 (su-yoil - Wednesday/Water)
일요일 (il-yoil - Sunday/Sun)
목요일 (mok-yoil - Thursday/Wood)
Time Format:
오전 (ojeon - AM)
분 (bun - minute)
오후 (ohu - PM)
시 (si - used after hour)
시간 (sigan - hour)
Examples:
3:05 PM → 오후 세 시 오 분
12:00 PM → 오후 열두 시
9:30 AM → 오전 아홉 시 삼십 분
Note: Native Korean for hours, Sino-Korean for minutes

Grammar & Formality

Markers:
이/가 (i/ga - subject: consonant+이, vowel+가)
을/를 (eul/reul - object: consonant+을, vowel+를)
은/는 (eun/neun - topic: consonant+은, vowel+는)
에 (e - location/time marker for places and times)
Formality Levels:
반말 (banmal - casual: no ending or -아/어)
-습니다/-습니까 (seumnida/seumnikka - formal)
-요 (polite ending)
-십니다/-십니까 (simnida/simnikka - highest)

Essential Vocabulary

Greetings:
안녕하세요 (annyeonghaseyo - hello)
안녕히 가세요 (annyeonghi gaseyo - goodbye to leaving)
안녕히 계세요 (annyeonghi gyeseyo - goodbye when you leave)
환영합니다 (hwanyeonghamnida - welcome)
감사합니다 (kamsahamnida - thank you)
고맙습니다 (gomapseumnida - thank you polite)
만나서 반갑습니다 (mannaseo bangapseumnida - nice to meet you)
처음 뵙겠습니다 (cheoeum boepgetseumnida - nice to meet you humble)
죄송합니다 (joesonghamnida - I'm sorry)
미안해요 (mianhaeyo - I'm sorry informal)
밥 먹었어요? (bap meogeosseoyo - have you eaten?)
식사하셨어요? (siksahasyeosseoyo - have you eaten honorific)
잠시만요 (jamsimanyo - excuse me)
Classroom:
책을 펴세요 (chaegeul pyeoseyo - open book)
알겠어요? (algesseoyo - understand?)
책을 보세요 (chaegeul boseyo - look at book)
네 알겠어요 (ne algesseoyo - yes I understand)
잘 들으세요 (jal deureuseyo - listen carefully)
아니요 모르겠어요 (aniyo moreugesseoyo - no I don't understand)
따라 하세요 (ttara haseyo - repeat after me)
질문 있어요? (jilmun isseoyo - any questions?)
읽으세요 (ilgeuseyo - read it)
질문하세요 (jilmun haseyo - ask question)
쓰세요 (sseuseyo - write it)
대답하세요 (daedap haseyo - answer question)

Verb Conjugations

Present Tense Polite (-요):
가다 → 가요 (gada → gayo - go)
오다 → 와요 (oda → wayo - come)
보다 → 봐요 (boda → bwayo - see/watch)
먹다 → 먹어요 (meokda → meogeoyo - eat)
마시다 → 마셔요 (masida → masyeoyo - drink)
하다 → 해요 (hada → haeyo - do)
Past Tense (-았어요/-었어요):
갔어요 (gasseoyo - went)
왔어요 (wasseoyo - came)
봤어요 (bwasseoyo - saw/watched)
먹었어요 (meogeosseoyo - ate)
마셨어요 (masyeosseoyo - drank)
했어요 (haesseoyo - did)
Suggestions & Requests:
갈까요? (galkkayo - shall we go?)
가세요 (gaseyo - please go)
가고 싶어요 (gago sipeoyo - I want to go)
가지 마세요 (gaji maseyo - please don't go)
안 가요 (an gayo - won't go by choice)
못 가요 (mot gayo - can't go due to circumstances)

Question Words & Useful Expressions

Question Words:
뭐 (mwo - what)
어디 (eodi - where)
언제 (eonje - when)
몇 시 (myeot si - what time)
무슨 요일 (museun yoil - what day)
몇 개 (myeot gae - how many items)
얼마 (eolma - how much)
어떻게 (eotteoke - how)
Daily Expressions:
무엇을 드릴까요? (mueoseul deurilkkayo - may I help you)
얼마예요? (eolmayeyo - how much is it)
어떻게 지내세요? (eotteoke jinaeseyo - how are you)
어때요? (eottaeyo - how about it)
좋아요 (joayo - good/sounds good)
괜찮아요 (gwaenchanhayo - it's okay)
잘 먹겠습니다 (jal meokgetseumnida - before eating)
잘 먹었습니다 (jal meogeotseumnida - after eating)

Transportation & Places

Transportation:
버스 (beoseu - bus)
지하철 (jihacheol - subway)
택시 (taeksi - taxi)
KTX (keiteekseu - high-speed rail)
버스 정류장 (beoseu jeongryujang - bus stop)
지하철역 (jihacheoryeok - subway station)
교통 카드 (gyotong kadeu - transportation card)
운전하다 (unjeonhada - to drive)
More Places:
영화관 (yeonghwagwan - movie theater)
도서관 (doseogwan - library)
백화점 (baekhwajeom - department store)
카페 (kape - café)
교실 (gyosil - classroom)
회의실 (hoeuisil - meeting room)
병원 (byeongwon - hospital)
은행 (eunhaeng - bank)

Currency & Business

Money:
원 (won - Korean currency)
천원 (cheonwon - 1,000 won)
만원 (manwon - 10,000 won)
지폐 (jipye - banknote)
동전 (dongjeon - coin)
신용카드 (sinyongkadeu - credit card)
Business Terms:
회사 이름 (hoesa ireum - company name)
이름 (ireum - name)
전화번호 (jeonhwabeonho - phone number)
이메일 (imeil - email)
주소 (juso - address)
회의 (hoeui - meeting)
약속 (yaksok - appointment)
시간이 있다/없다 (sigani itda/eopda - have/don't have time)

Korean Holidays & Culture

Major Holidays:
설날 (seollal - Lunar New Year)
추석 (chuseok - Harvest Festival)
한글날 (hangeulnal - Hangul Day Oct 9)
어린이날 (eorininal - Children's Day May 5)
어버이날 (eobeoinal - Parents Day May 8)
광복절 (gwangbokjeol - Liberation Day Aug 15)
Traditional Foods:
떡국 (tteokguk - rice cake soup for New Year)
송편 (songpyeon - half-moon rice cakes for Chuseok)
전 (jeon - savory pancakes)
갈비탕 (galbitang - beef short rib soup)
Cultural Terms:
세배 (sebae - deep bow to elders)
세뱃돈 (sebaetdon - New Year money gift)
한류 (hallyu - Korean Wave)
차례 (charye - ancestor memorial service)

Counters & Nationalities

Counters:
개 (gae - general item)
권 (gwon - book)
병 (byeong - bottle)
장 (jang - flat object/paper/tickets)
명 (myeong - person formal)
마리 (mari - animal)
사람 (saram - person informal)
Nationalities:
한국 사람 (hanguk saram - Korean)
미국 사람 (miguk saram - American)
일본 사람 (ilbon saram - Japanese)
중국 사람 (jungguk saram - Chinese)
프랑스 사람 (peurangseu saram - French)
독일 사람 (dogil saram - German)
호주 사람 (hoju saram - Australian)
베트남 사람 (beteunam saram - Vietnamese)
파키스탄 사람 (pakiseutan saram - Pakistani)
몽골 사람 (monggol saram - Mongolian)
아일랜드 사람 (aillaendeu saram - Irish)
러시아 사람 (reosia saram - Russian)

Occupations & Activities

Jobs:
의사 (uisa - doctor)
선생님 (seonsaengnim - teacher)
경찰 (gyeongchal - police officer)
간호사 (ganhosa - nurse)
공무원 (gongmuwon - civil servant)
변호사 (byeonhosa - lawyer)
회사원 (hoesawon - office worker)
학생 (haksaeng - student)
기사/운전사 (gisa/unjeonsa - driver)
기자 (gija - reporter)
요리사 (yorisa - chef)
가수 (gasu - singer)
Common Activities:
공부하다 (gongbuhada - to study)
일하다 (ilhada - to work)
운동하다 (undonghada - to exercise)
전화하다 (jeonhwahada - to call)
이야기하다 (iyagihada - to talk)
요리하다 (yorihada - to cook)
쇼핑하다 (syopinghada - to shop)
운전하다 (unjeonhada - to drive)

Food & Shopping

Korean Food:
김밥 (gimbap - seaweed rice rolls)
비빔밥 (bibimbap - mixed rice dish)
볶음밥 (bokkeumbap - fried rice)
라면 (ramyeon - ramen noodles)
떡볶이 (tteokbokki - spicy rice cakes)
삼겹살 (samgyeopsal - pork belly)
치킨 (chikin - chicken)
호떡 (hotteok - sweet pancake)
Drinks & Items:
소주 (soju - Korean alcoholic drink)
막걸리 (makgeolli - rice wine)
우유 (uyu - milk)
커피 (keopi - coffee)
물 (mul - water)
주스 (juseu - juice)
사과 (sagwa - apple)
수박 (subak - watermelon)
Condiments:
된장 (doenjang - soybean paste)
고추장 (gochujang - red chili paste)
간장 (ganjang - soy sauce)
쌈장 (ssamjang - thick soybean paste)

Body Parts & Position Words

Head/Face:
머리 (meori - head)
머리카락 (meorikarak - hair)
얼굴 (eolgul - face)
눈 (nun - eyes)
코 (ko - nose)
입 (ip - mouth)
귀 (gwi - ears)
목 (mok - neck)
이마 (ima - forehead)
턱 (teok - chin)
입술 (ipsul - lips)
이 (i - teeth)
혀 (hyeo - tongue)
Body:
손 (son - hand)
팔 (pal - arm)
다리 (dari - leg)
발 (bal - foot)
어깨 (eokkae - shoulder)
무릎 (mureup - knee)
허리 (heori - waist)
가슴 (gaseum - chest)
배 (bae - stomach/abdomen)
등 (deung - back)
손가락 (songarak - finger)
발가락 (balgarak - toe)
Position Words:
앞 (ap - front)
뒤 (dwi - back/behind)
옆 (yeop - next to)
위 (wi - above/on)
아래/밑 (arae/mit - below/under)
안 (an - inside)
밖 (bak - outside)
사이 (sai - between)
가운데 (gaunde - middle/center)
오른쪽 (oreunjjok - right)
왼쪽 (oenjjok - left)

Weather & Traditional

Seasons & Weather:
봄 (bom - spring)
여름 (yeoreum - summer)
가을 (gaeul - fall/autumn)
겨울 (gyeoul - winter)
덥다 → 더워요 (deopda → deowoyo - hot)
춥다 → 추워요 (chupda → chuwoyo - cold)
비가 와요 (biga wayo - it's raining)
눈이 와요 (nuni wayo - it's snowing)
바람이 불어요 (barami bureoyo - it's windy)
맑아요 (malgayo - it's clear)
흐려요 (heuryeoyo - it's cloudy)
습해요 (seuphaeyo - it's humid)
건조해요 (geonjohaeyo - it's dry)
따뜻해요 (ttatteuthaeyo - it's warm)
시원해요 (siwonhaeyo - it's cool)
Traditional Items:
한복 (hanbok - traditional clothing)
치마 (chima - skirt)
저고리 (jeogori - top/jacket)
한옥 (hanok - traditional house)
온돌 (ondol - underfloor heating)
한글 (hangeul - Korean alphabet)
윷놀이 (yunnori - traditional game)
제기차기 (jegi chagi - traditional kicking game)

Korean Verb Conjugation Table (해요체)

Click to expand verb table (100+ verbs)
Verb (dict.) English meaning Present Past Future
가깝다
gakkapda
to be close/near
가까워요
gakkawoyo
가까웠어요
gakkawosseoyo
가까울 거예요
gakkaul geoyeyo
가다
gada
go
가요
gayo
갔어요
gasseoyo
갈 거예요
gal geoyeyo
가르치다
gareuchida
to teach / to tell (someone)
가르쳐요
gareuchyeoyo
가르쳤어요
gareuchyeosseoyo
가르칠 거예요
gareuchil geoyeyo
가져오다
gajyeooda
to bring
가져와요
gajyeowayo
가져왔어요
gajyeowasseoyo
가져올 거예요
gajyeool geoyeyo
갈아타다
garatada
to transfer
갈아타요
garatayo
갈아탔어요
garatasseoyo
갈아탈 거예요
garatal geoyeyo
걱정하다
geokjeonghada
to worry
걱정해요
geokjeonghaeyo
걱정했어요
geokjeonghaesseoyo
걱정할 거예요
geokjeonghal geoyeyo
건너다
geonneoda
to cross
건너요
geonneoyo
건넜어요
geonneosseoyo
건널 거예요
geonneol geoyeyo
걷다
geotda
to walk
걸어요
georeoyo
걸었어요
georeosseoyo
걸을 거예요
georeul geoyeyo
걸어가다
georeogada
to go by walking
걸어가요
georeogayo
걸어갔어요
georeogasseoyo
걸어갈 거예요
georeogal geoyeyo
걸어오다
georeooda
to come by walking
걸어와요
georeowayo
걸어왔어요
georeowasseoyo
걸어올 거예요
georeool geoyeyo
공부하다
gongbuhada
to study
공부해요
gongbuhaeyo
공부했어요
gongbuhaesseoyo
공부할 거예요
gongbuhal geoyeyo
괜찮다
gwaenchanda
to be okay
괜찮아요
gwaenchanayo
괜찮았어요
gwaenchanasseoyo
괜찮을 거예요
gwaenchaneul geoyeyo
구경하다
gugyeonghada
to see/sightsee
구경해요
gugyeonghaeyo
구경했어요
gugyeonghaesseoyo
구경할 거예요
gugyeonghal geoyeyo
귀엽다
gwiyeopda
to be cute
귀여워요
gwiyeowoyo
귀여웠어요
gwiyeowosseoyo
귀여울 거예요
gwiyeoul geoyeyo
그렇다
geureotda
to be so
그래요
geuraeyo
그랬어요
geuraesseoyo
그렇을 거예요
geureoheul geoyeyo
그리다
geurida
to draw
그려요
geuryeoyo
그렸어요
geuryeosseoyo
그릴 거예요
geuril geoyeyo
기다리다
gidarida
to wait
기다려요
gidaryeoyo
기다렸어요
gidaryeosseoyo
기다릴 거예요
gidaril geoyeyo
길다
gilda
to be long
길어요
gireoyo
길었어요
gireosseoyo
길 거예요
gil geoyeyo
깨다
kkaeda
To break, shatter
깨요
kkaeyo
깼어요
kkaesseoyo
깰 거예요
kkael geoyeyo
나가다
nagada
to go out
나가요
nagayo
나갔어요
nagasseoyo
나갈 거예요
nagal geoyeyo
나오다
naoda
to come out
나와요
nawayo
나왔어요
nawasseoyo
나올 거예요
naol geoyeyo
날씬하다
nalssinhada
to be slim
날씬해요
nalssinhaeyo
날씬했어요
nalssinhaesseoyo
날씬할 거예요
nalssinhal geoyeyo
내려가다
naeryeogada
to go down
내려가요
naeryeogayo
내려갔어요
naeryeogasseoyo
내려갈 거예요
naeryeogal geoyeyo
내려오다
naeryeooda
to come down
내려와요
naeryeowayo
내려왔어요
naeryeowasseoyo
내려올 거예요
naeryeool geoyeyo
내리다
naerida
to get off
내려요
naeryeoyo
내렸어요
naeryeosseoyo
내릴 거예요
naeril geoyeyo
놀다
nolda
to play
놀아요
norayo
놀았어요
norasseoyo
놀 거예요
nol geoyeyo
노래하다
noraehada
to sing
노래해요
noraehaeyo
노래했어요
noraehaesseoyo
노래할 거예요
noraehal geoyeyo
늦다
neutda
to be late
늦어요
neujeoyo
늦었어요
neujeosseoyo
늦을 거예요
neujeul geoyeyo
닫다
datda
to close
닫아요
dadayo
닫았어요
dadasseoyo
닫을 거예요
dadeul geoyeyo
달다
dalda
sweet
달아요
darayo
달았어요
darasseoyo
달 거예요
dal geoyeyo
덥다
deopda
hot
더워요
deowoyo
더웠어요
deowosseoyo
더울 거예요
deoul geoyeyo
도와주다
dowajuda
to help (someone)
도와줘요
dowajwoyo
도와줬어요
dowajwosseoyo
도와줄 거예요
dowajul geoyeyo
듣다
deutda
to listen
들어요
deureoyo
들었어요
deureosseoyo
들을 거예요
deureul geoyeyo
들어가다
deureogada
to go in / enter
들어가요
deureogayo
들어갔어요
deureogasseoyo
들어갈 거예요
deureogal geoyeyo
들어오다
deureooda
to come in / enter
들어와요
deureowayo
들어왔어요
deureowasseoyo
들어올 거예요
deureool geoyeyo
따뜻하다
ttatteuthada
warm
따뜻해요
ttatteuthaeyo
따뜻했어요
ttatteuthaesseoyo
따뜻할 거예요
ttatteuthal geoyeyo
뚱뚱하다
ttungttunghada
to be fat
뚱뚱해요
ttungttunghaeyo
뚱뚱했어요
ttungttunghaesseoyo
뚱뚱할 거예요
ttungttunghal geoyeyo
마르다
mareuda
to be skinny / thin
말라요
malrayo
말랐어요
malrasseoyo
마를 거예요
mareul geoyeyo
마시다
masida
to drink
마셔요
masyeoyo
마셨어요
masyeosseoyo
마실 거예요
masil geoyeyo
만나다
mannada
to meet
만나요
mannayo
만났어요
mannasseoyo
만날 거예요
mannal geoyeyo
만들다
mandeulda
to make
만들어요
mandeureoyo
만들었어요
mandeureosseoyo
만들 거예요
mandeul geoyeyo
많다
manda
to be many/much (only ㄴ pronounced)
많아요
manayo
많았어요
manasseoyo
많을 거예요
maneul geoyeyo
말하다
malhada
to speak
말해요
malhaeyo
말했어요
malhaesseoyo
말할 거예요
malhal geoyeyo
맑다
makda
clear
맑아요
magayo
맑았어요
magasseoyo
맑을 거예요
mageul geoyeyo
맛없다
maseotda
not tasty
맛없어요
maseobeoyo
맛없었어요
maseobeosseoyo
맛없을 거예요
maseobeul geoyeyo
맛있다
masitda
tasty
맛있어요
masisseoyo
맛있었어요
masisseosseoyo
맛있을 거예요
masisseul geoyeyo
맞다
matda
to be right / correct
맞아요
majayo
맞았어요
majasseoyo
맞을 거예요
majeul geoyeyo
맵다
maepda
spicy
매워요
maewoyo
매웠어요
maewosseoyo
매울 거예요
maeul geoyeyo
먹다
meokda
eat
먹어요
meogeoyo
먹었어요
meogeosseoyo
먹을 거예요
meogeul geoyeyo
멋있다
meositda
to be stylish / cool
멋있어요
meosisseoyo
멋있었어요
meosisseosseoyo
멋있을 거예요
meosisseul geoyeyo
모르다
moreuda
to not know
몰라요
molrayo
몰랐어요
molrasseoyo
모를 거예요
moreul geoyeyo
물어보다
mureoboda
to ask
물어봐요
mureobwayo
물어봤어요
mureobwasseoyo
물어볼 거예요
mureobol geoyeyo
바쁘다
bappeuda
to be busy
바빠요
bappayo
바빴어요
bappasseoyo
바쁠 거예요
bappeul geoyeyo
배우다
baeuda
to learn
배워요
baewoyo
배웠어요
baewosseoyo
배울 거예요
baeul geoyeyo
버리다
beorida
to throw away
버려요
beoryeoyo
버렸어요
beoryeosseoyo
버릴 거예요
beoril geoyeyo
벗다
beotda
to take off (clothes)
벗어요
beoseoyo
벗었어요
beoseosseoyo
벗을 거예요
beoseul geoyeyo
보내다
bonaeda
to spend (time)
보내요
bonaeyo
보냈어요
bonaesseoyo
보낼 거예요
bonael geoyeyo
보다
boda
see/watch
봐요
bwayo
봤어요
bwasseoyo
볼 거예요
bol geoyeyo
보이다
boida
to be visible / to see
보여요
boyeoyo
보였어요
boyeosseoyo
보일 거예요
boil geoyeyo
비싸다
bissada
to be expensive
비싸요
bissayo
비쌌어요
bissasseoyo
비쌀 거예요
bissal geoyeyo
빌리다
bilrida
to borrow
빌려요
bilryeoyo
빌렸어요
bilryeosseoyo
빌릴 거예요
bilril geoyeyo
사다
sada
to buy
사요
sayo
샀어요
sasseoyo
살 거예요
sal geoyeyo
사랑하다
saranghada
to love
사랑해요
saranghaeyo
사랑했어요
saranghaesseoyo
사랑할 거예요
saranghal geoyeyo
산책하다
sanchaekhada
to take a walk
산책해요
sanchaekhaeyo
산책했어요
sanchaekhaesseoyo
산책할 거예요
sanchaekhal geoyeyo
살다
salda
to live
살아요
sarayo
살았어요
sarasseoyo
살 거예요
sal geoyeyo
새다
saeda
To leak
새요
saeyo
샜어요
saesseoyo
샐 거예요
sael geoyeyo
서다
seoda
to stand
서요
seoyo
섰어요
seosseoyo
설 거예요
seol geoyeyo
소개하다
sogaehada
to introduce
소개해요
sogaehaeyo
소개했어요
sogaehaesseoyo
소개할 거예요
sogaehal geoyeyo
쇼핑하다
syopinghada
to go shopping
쇼핑해요
syopinghaeyo
쇼핑했어요
syopinghaesseoyo
쇼핑할 거예요
syopinghal geoyeyo
수영하다
suyeonghada
to swim
수영해요
suyeonghaeyo
수영했어요
suyeonghaesseoyo
수영할 거예요
suyeonghal geoyeyo
쉬다
swida
to rest
쉬어요
swieoyo
쉬었어요
swieosseoyo
쉴 거예요
swil geoyeyo
습하다
seuphada
humid
습해요
seuphaeyo
습했어요
seuphaesseoyo
습할 거예요
seuphal geoyeyo
시다
sida
sour
셔요
syeoyo
셨어요
syeosseoyo
실 거예요
sil geoyeyo
시원하다
siwonhada
cool
시원해요
siwonhaeyo
시원했어요
siwonhaesseoyo
시원할 거예요
siwonhal geoyeyo
싱겁다
singgeopda
bland
싱거워요
singgeowoyo
싱거웠어요
singgeowosseoyo
싱거울 거예요
singgeoul geoyeyo
싸다
ssada
to be cheap
싸요
ssayo
쌌어요
ssasseoyo
쌀 거예요
ssal geoyeyo
쓰다
sseuda
to write
써요
sseoyo
썼어요
sseosseoyo
쓸 거예요
sseul geoyeyo
아프다
apeuda
to be sick
아파요
apayo
아팠어요
apasseoyo
아플 거예요
apeul geoyeyo
앉다
anda
to sit
앉아요
anayo
앉았어요
anasseoyo
앉을 거예요
aneul geoyeyo
알다
alda
to know
알아요
arayo
알았어요
arasseoyo
알 거예요
al geoyeyo
연락하다
yeonrakhada
to contact
연락해요
yeonrakhaeyo
연락했어요
yeonrakhaesseoyo
연락할 거예요
yeonrakhal geoyeyo
열다
yeolda
to open
열어요
yeoreoyo
열었어요
yeoreosseoyo
열 거예요
yeol geoyeyo
여행하다
yeohaenghada
to travel
여행해요
yeohaenghaeyo
여행했어요
yeohaenghaesseoyo
여행할 거예요
yeohaenghal geoyeyo
예쁘다
yeppeuda
to be pretty
예뻐요
yeppeoyo
예뻤어요
yeppeosseoyo
예쁠 거예요
yeppeul geoyeyo
오다
oda
come
와요
wayo
왔어요
wasseoyo
올 거예요
ol geoyeyo
올라가다
olragada
to go up
올라가요
olragayo
올라갔어요
olragasseoyo
올라갈 거예요
olragal geoyeyo
올라오다
olraoda
to come up
올라와요
olrawayo
올라왔어요
olrawasseoyo
올라올 거예요
olraol geoyeyo
요리하다
yorihada
to cook
요리해요
yorihaeyo
요리했어요
yorihaesseoyo
요리할 거예요
yorihal geoyeyo
운동하다
undonghada
to exercise
운동해요
undonghaeyo
운동했어요
undonghaesseoyo
운동할 거예요
undonghal geoyeyo
운전하다
unjeonhada
to drive
운전해요
unjeonhaeyo
운전했어요
unjeonhaesseoyo
운전할 거예요
unjeonhal geoyeyo
읊다
eulda
to recite/chant (only ㅍ pronounced)
읊어요
eupeoyo
읊었어요
eupeosseoyo
읊을 거예요
eupeul geoyeyo
이사하다
isahada
to move (houses)
이사해요
isahaeyo
이사했어요
isahaesseoyo
이사할 거예요
isahal geoyeyo
이야기하다
iyagihada
to talk
이야기해요
iyagihaeyo
이야기했어요
iyagihaesseoyo
이야기할 거예요
iyagihal geoyeyo
일어나다
ireonada
to wake up
일어나요
ireonayo
일어났어요
ireonasseoyo
일어날 거예요
ireonal geoyeyo
일하다
ilhada
to work
일해요
ilhaeyo
일했어요
ilhaesseoyo
일할 거예요
ilhal geoyeyo
읽다
ikda
to read (only ㄱ pronounced)
읽어요
igeoyo
읽었어요
igeosseoyo
읽을 거예요
igeul geoyeyo
입다
ipda
to wear
입어요
ibeoyo
입었어요
ibeosseoyo
입을 거예요
ibeul geoyeyo
자다
jada
to sleep
자요
jayo
잤어요
jasseoyo
잘 거예요
jal geoyeyo
작다
jakda
to be small
작아요
jagayo
작았어요
jagasseoyo
작을 거예요
jageul geoyeyo
잘생기다
jalsaenggida
to be handsome
잘생겨요
jalsaenggyeoyo
잘생겼어요
jalsaenggyeosseoyo
잘생길 거예요
jalsaenggil geoyeyo
재미없다
jaemieotda
not fun, boring
재미없어요
jaemieobeoyo
재미없었어요
jaemieobeosseoyo
재미없을 거예요
jaemieobeul geoyeyo
재미있다
jaemiitda
fun, interesting
재미있어요
jaemiisseoyo
재미있었어요
jaemiisseosseoyo
재미있을 거예요
jaemiisseul geoyeyo
전화하다
jeonhwahada
to call
전화해요
jeonhwahaeyo
전화했어요
jeonhwahaesseoyo
전화할 거예요
jeonhwahal geoyeyo
좋다
jotda
[조따] (jo-tta) = to be good
좋아요
johayo
좋았어요
johasseoyo
좋을 거예요
joheul geoyeyo
좋아하다
johahada
to like
좋아해요
johahaeyo
좋아했어요
johahaesseoyo
좋아할 거예요
johahal geoyeyo
주다
juda
to give
줘요
jwoyo
줬어요
jwosseoyo
줄 거예요
jul geoyeyo
즐겁다
jeulgeopda
to be pleased, enjoyable
즐거워요
jeulgeowoyo
즐거웠어요
jeulgeowosseoyo
즐거울 거예요
jeulgeoul geoyeyo
지나다
jinada
to pass
지나요
jinayo
지났어요
jinasseoyo
지날 거예요
jinal geoyeyo
짜다
jjada
salty
짜요
jjayo
짰어요
jjasseoyo
짤 거예요
jjal geoyeyo
짧다
jjalda
to be short
짧아요
jjabayo
짧았어요
jjabasseoyo
짧을 거예요
jjabeul geoyeyo
쬐다
jjoeda
To sunbathe, expose to sunlight
쬐요
jjoeyo
쬤어요
jjoesseoyo
쬘 거예요
jjoel geoyeyo
찾다
chatda
to look for
찾아요
chajayo
찾았어요
chajasseoyo
찾을 거예요
chajeul geoyeyo
첨부하다
cheopbuhada
to attach
첨부해요
cheopbuhaeyo
첨부했어요
cheopbuhaesseoyo
첨부할 거예요
cheopbuhal geoyeyo
청소하다
cheongsohada
to clean
청소해요
cheongsohaeyo
청소했어요
cheongsohaesseoyo
청소할 거예요
cheongsohal geoyeyo
축하하다
chukhahada
to congratulate
축하해요
chukhahaeyo
축하했어요
chukhahaesseoyo
축하할 거예요
chukhahal geoyeyo
출근하다
chulgeunhada
to go to work
출근해요
chulgeunhaeyo
출근했어요
chulgeunhaesseoyo
출근할 거예요
chulgeunhal geoyeyo
춤추다
chupchuda
to dance
춤춰요
chupchwoyo
춤췄어요
chupchwosseoyo
춤출 거예요
chupchul geoyeyo
춥다
chupda
cold
추워요
chuwoyo
추웠어요
chuwosseoyo
추울 거예요
chuul geoyeyo
크다
keuda
to be big/large
커요
keoyo
컸어요
keosseoyo
클 거예요
keul geoyeyo
타다
tada
to get on/ride
타요
tayo
탔어요
tasseoyo
탈 거예요
tal geoyeyo
태다
taeda
To clean, wipe
태요
taeyo
탰어요
taesseoyo
탤 거예요
tael geoyeyo
퇴근하다
toegeunhada
to leave work
퇴근해요
toegeunhaeyo
퇴근했어요
toegeunhaesseoyo
퇴근할 거예요
toegeunhal geoyeyo
팔다
palda
to sell
팔아요
parayo
팔았어요
parasseoyo
팔 거예요
pal geoyeyo
피곤하다
pigonhada
to be tired
피곤해요
pigonhaeyo
피곤했어요
pigonhaesseoyo
피곤할 거예요
pigonhal geoyeyo
하다
hada
to do
해요
haeyo
했어요
haesseoyo
할 거예요
hal geoyeyo
핥다
halda
to lick (only ㄹ pronounced)
핥아요
hatayo
핥았어요
hatasseoyo
핥을 거예요
hateul geoyeyo
흐리다
heurida
cloudy
흐려요
heuryeoyo
흐렸어요
heuryeosseoyo
흐릴 거예요
heuril geoyeyo
힘들다
hipdeulda
to have a hard time
힘들어요
hipdeureoyo
힘들었어요
hipdeureosseoyo
힘들 거예요
hipdeul geoyeyo

Korean Proverbs

  • 꿩 대신 닭 (Kkwong daesin dak) - "Chicken instead of pheasant"
    Meaning: When you can't get what you want, you should be satisfied with the next best thing.
    Similar to English: "A bird in the hand is worth two in the bush" or "Better than nothing"
  • 옷이 날개다 (Osi nalgaeda) - "Clothes are wings"
    Meaning: Clothes give you wings - suggesting that proper attire can help you achieve your goals
  • 그림의 떡 (Geulim-ui tteok) - "Rice cake in a picture"
    Meaning: Similar to "pie in the sky" - something that looks good but is unattainable
  • 무소식이 희소식이다 (Musosigi huisosigida) - "No news is good news"
    Meaning: When you don't hear anything, it usually means everything is fine
  • 천리 길도 한 걸음부터 (cheolli gildo han georeumbuteo) - "Even a thousand-mile journey begins with a single step"
    Meaning: Every great achievement starts with taking the first step, no matter how small
--- URL: https://jaskamalkainth.github.io/blog_posts/music.html Title: Music Is My Only Drug: Piano Pieces I Keep Coming Back To Description: The piano pieces I return to again and again: Beethoven's Für Elise, Mariage d'Amour, the Love Story theme and a virtuosic Harry Potter medley, with videos. Published: 2022-01-01 Updated: 2026-10-02

🎵 Music is my only drug!

There's nothing like music to relieve the soul and uplift it.

Painting of a woman in a white dress playing the piano, in bright orange and yellow brushstrokes

Classical Music Legends

Musical Masterpieces

Paul de Senneville

Mariage d'Amour ("Spring Waltz")

Often mislabelled online as Chopin; it was written by Paul de Senneville in 1978 and made famous by Richard Clayderman.

Beethoven

Für Elise

Francis Lai · Richard Clayderman

Love Story

Francis Lai's theme from the 1970 film Love Story, in Richard Clayderman's piano arrangement (the video credits Beethoven, but it isn't his).

John Williams · Harry Potter

Harry Potter Piano Medley (Virtuosic Cover)

--- URL: https://jaskamalkainth.github.io/blog_posts/philosophy-notes.html Title: Philosophy Timeline: Great Thinkers Through History Description: A timeline of philosophy from Socrates to contemporary thinkers, with each philosopher's dates, school and one-line answer to why humans do what they do. Published: 2025-01-27 Updated: 2026-10-02

Philosophy Timeline: Understanding the Human Mind

I'm fascinated by philosophy, psychology, and the study of human mind - what we do, why we do it. This timeline traces the evolution of human thought from ancient wisdom to modern insights about consciousness and behavior.

My Research Notes

🤖 AI Research Credit

This philosophical exploration is enhanced through collaboration with AI research assistants. While AI tools help synthesize and articulate ideas, all perspectives and critical analysis remain my own.

Additional Research Connections to Explore:

  • How Buddhist mindfulness relates to modern cognitive therapy
  • Connections between Stoic philosophy and resilience research
  • Aristotelian virtue ethics and positive psychology
  • Existentialist anxiety and modern understanding of mental health
  • Foucault's power analysis and social psychology
  • Ancient debates about free will and neuroscience findings

Timeless Questions About Human Nature

  • What drives human behavior - reason, emotion, or something else?
  • Are we fundamentally good, evil, or neutral?
  • How much of our behavior is determined vs. free?
  • What role do social structures play in shaping who we are?
  • How has our understanding of consciousness evolved?
  • What can ancient wisdom teach us about modern psychology?

Quick Reference Timeline

Ancient Philosophy

6th Century BCE - 6th Century CE
Socrates, Plato, Aristotle, Confucius, Buddha, Augustine
Foundation of human inquiry: virtue, knowledge, suffering, love

Medieval Philosophy

5th - 15th Century
Thomas Aquinas, Ibn Rushd (Averroes)
Synthesis of faith and reason

Renaissance & Early Modern

15th - 18th Century
Descartes, Spinoza, Locke, Hume, Kant
Rationalism vs. empiricism; foundations of modern thought

19th Century

1800 - 1900
Hegel, Kierkegaard, Marx, Nietzsche
Individual existence, social conditions, will to power

20th Century

1900 - 2000
Freud, Heidegger, Sartre, de Beauvoir, Wittgenstein, Foucault
Unconscious mind, existentialism, language, power structures

Contemporary

2000 - Present
Dennett, Nussbaum
Consciousness, capabilities, modern psychology

Ancient Philosophy

6th Century BCE - 6th Century CE
Socrates
470-399 BCE
Classical Greek

"The unexamined life is not worth living." Pioneered the method of questioning to understand human nature and ethics.

Why We Do What We Do:

People act wrongly due to ignorance; if we truly know what is good, we will do good.

Plato
428-348 BCE
Classical Greek

Explored the nature of reality, knowledge, and the ideal state. Created the theory of Forms and examined the soul's structure.

Why We Do What We Do:

Human behavior stems from the conflict between reason, spirit, and appetite within the soul.

Aristotle
384-322 BCE
Classical Greek

Systematized logic, ethics, and politics. Studied human flourishing (eudaimonia) and virtue ethics.

Why We Do What We Do:

We act to achieve happiness through virtue, which is developed through habit and practice.

Confucius
551-479 BCE
Chinese Philosophy

Emphasized moral cultivation, social harmony, and the importance of relationships and ritual.

Why We Do What We Do:

Human behavior should be guided by virtue, respect for others, and social responsibility.

Buddha (Siddhartha Gautama)
563-483 BCE
Buddhist Philosophy

Explored suffering, desire, and the path to enlightenment through understanding the mind.

Why We Do What We Do:

We act from attachment and desire, which causes suffering; liberation comes through mindfulness.

Augustine of Hippo
354-430 CE
Christian Philosophy

Integrated Christian theology with philosophy, exploring free will, time, and human nature.

Why We Do What We Do:

Human actions are driven by love - either love of God (good) or love of self (sin).

Medieval Philosophy

5th - 15th Century
Thomas Aquinas
1225-1274
Scholasticism

Synthesized Aristotelian philosophy with Christian doctrine, exploring reason and faith.

Why We Do What We Do:

We act according to our nature, seeking the ultimate good (God) through reason and virtue.

Ibn Rushd (Averroes)
1126-1198
Islamic Philosophy

Defended philosophy against religious orthodoxy, emphasizing reason and individual thought.

Why We Do What We Do:

Human behavior should be guided by reason, which can lead to truth and happiness.

Renaissance & Early Modern

15th - 18th Century
René Descartes
1596-1650
Rationalism

"I think, therefore I am." Established the foundation of modern philosophy through methodical doubt.

Why We Do What We Do:

We act based on clear and distinct ideas; error comes from hasty judgment and unclear thinking.

Baruch Spinoza
1632-1677
Rationalism

Developed a deterministic view of reality where everything follows natural laws, including human emotions.

Why We Do What We Do:

We are driven by emotions and desires; freedom comes from understanding our nature and emotions.

John Locke
1632-1704
Empiricism

Argued that knowledge comes from experience; the mind is a "blank slate" shaped by sensory input.

Why We Do What We Do:

Our behavior is shaped by experience and education; we can be improved through better environments.

David Hume
1711-1776
Empiricism

Skeptical about reason's power; emphasized the role of habit, custom, and sentiment in human nature.

Why We Do What We Do:

We act more from passion and habit than reason; moral judgments come from feelings, not logic.

Immanuel Kant
1724-1804
German Idealism

Synthesized rationalism and empiricism; developed categorical imperative for moral action.

Why We Do What We Do:

We should act from duty and universal moral laws, not just desire or consequence.

19th Century Philosophy

1800 - 1900
Georg Wilhelm Friedrich Hegel
1770-1831
German Idealism

Developed dialectical method; saw history as the progressive unfolding of absolute spirit.

Why We Do What We Do:

We act within historical contexts; consciousness develops through conflict and resolution.

Søren Kierkegaard
1813-1855
Existentialism

Emphasized individual existence, choice, and the leap of faith; critiqued systematic philosophy.

Why We Do What We Do:

We act from anxiety about our freedom; authentic existence requires passionate commitment.

Karl Marx
1818-1883
Historical Materialism

Analyzed capitalism and class struggle; argued that material conditions shape consciousness.

Why We Do What We Do:

Our actions are determined by economic and social conditions; consciousness follows material reality.

Friedrich Nietzsche
1844-1900
Existentialism

"God is dead." Challenged traditional morality and advocated for creating one's own values.

Why We Do What We Do:

We act from will to power; we must create our own meaning in a meaningless universe.

20th Century Philosophy

1900 - 2000
Sigmund Freud
1856-1939
Psychoanalysis

Explored the unconscious mind, revealing hidden motivations behind human behavior.

Why We Do What We Do:

Much of our behavior is driven by unconscious desires, fears, and childhood experiences.

Martin Heidegger
1889-1976
Existentialism

Explored the question of Being; emphasized authenticity and being-toward-death.

Why We Do What We Do:

We act to flee from anxiety about our mortality; authentic existence requires facing this anxiety.

Jean-Paul Sartre
1905-1980
Existentialism

"Existence precedes essence." We are condemned to be free and must create our own meaning.

Why We Do What We Do:

We act to escape the overwhelming responsibility of absolute freedom, often in bad faith.

Simone de Beauvoir
1908-1986
Feminist Existentialism

"One is not born, but rather becomes, a woman." Examined how social conditioning shapes identity.

Why We Do What We Do:

Our behavior is heavily influenced by social expectations and power structures we internalize.

Ludwig Wittgenstein
1889-1951
Analytic Philosophy

"The limits of my language mean the limits of my world." Explored language and its role in thought.

Why We Do What We Do:

Our actions are shaped by language games and forms of life that give meaning to our words.

Michel Foucault
1926-1984
Post-Structuralism

Analyzed how power shapes knowledge, identity, and behavior through institutions and discourse.

Why We Do What We Do:

Our actions are shaped by invisible power structures operating through knowledge systems.

Contemporary Philosophy

2000 - Present
Daniel Dennett
1942-2024
Philosophy of Mind

Applied evolutionary and computational approaches to consciousness and free will.

Why We Do What We Do:

Our behavior emerges from complex neural processes; consciousness is multiple competing narratives.

Martha Nussbaum
1947-
Capabilities Approach

Bridges ancient philosophy with contemporary issues, emphasizing human capabilities and emotions.

Why We Do What We Do:

We act to develop our human capabilities; emotions play a crucial role in moral reasoning.

--- --- URL: https://jaskamalkainth.github.io/blog_posts/samsung-galaxy-book6-student-guide.html Title: Galaxy Book6 vs Book6 Pro vs Ultra: Which Should Students Buy? Description: Galaxy Book6 vs Book6 Pro vs Book6 Ultra for students: processor, display, RAM and storage compared, and which tier fits writing, CS/engineering or design work. Published: 2026-01-20 Updated: 2026-01-20 # Samsung Galaxy Book6 Series: Which Tier Should Students Buy? > **Quick answer:** the **Galaxy Book6** is enough for writing, research and browsing; the **Galaxy Book6 Pro** is the pick for CS and engineering students who run IDEs and VMs; the **Galaxy Book6 Ultra** only pays off for sustained heavy work (large datasets, design or video). None of the three has a discrete GPU. Specs are from Samsung India's buy page as of January 2026. *Disclosure: I work at Samsung R&D Institute India. This is a personal post, not an official Samsung publication; it is based only on Samsung India's public product pages, linked throughout.* Samsung's current Galaxy Book lineup is a single series split into three configurable tiers, which makes it a genuinely useful case study for students trying to figure out how much laptop they actually need: **Galaxy Book6**, **Galaxy Book6 Pro**, and **Galaxy Book6 Ultra**. Specs below are pulled directly from [Samsung India's Galaxy Book6 Series buy page](https://www.samsung.com/in/computers/galaxy-book/galaxy-book6-series/buy/). ## Spec Comparison | Variant | Processor | Display | RAM | Storage | |---|---|---|---|---| | Galaxy Book6 | Intel Core Ultra 5 (325) | 14.0" | 16GB | 512GB | | Galaxy Book6 Pro | Intel Core Ultra 7 (356H / 355) | 14.0" or 16.0" | 16GB or 32GB | 512GB or 1TB | | Galaxy Book6 Ultra | Intel Core Ultra X7 (358H) | 16.0" (touch available) | 32GB | 1TB | - **OS:** Windows 11 Home (all tiers) - **Colors:** Gray, Silver - **Pricing:** Built-to-order — Samsung doesn't list a single fixed price per tier, since it depends on the exact processor/RAM/storage/display combination you configure. [Configure a model and see live pricing →](https://www.samsung.com/in/computers/galaxy-book/galaxy-book6-series/buy/) ## Which Tier Fits Which Student **Galaxy Book6** — the base tier's 16GB RAM and 512GB storage cover writing, research, browsing, and note-taking comfortably. This is the one to pick if your laptop's job is mostly documents, PDFs, and a browser with too many tabs open. **Galaxy Book6 Pro** — the sensible middle ground for CS/engineering students: a faster Ultra 7 chip and the option to go up to 32GB RAM / 1TB storage handles heavier IDEs, local dev environments, and running a VM or two without the Ultra tier's price. **Galaxy Book6 Ultra** — the Ultra X7 chip, 32GB RAM as standard, and a 16.0" touch display option make sense for students doing sustained compile-heavy work, large datasets, or design/video coursework where the extra headroom (and screen real estate) actually gets used. *(Full computer catalog, including other Samsung lines: [samsung.com/in/computers/all-computers](https://www.samsung.com/in/computers/all-computers/).)* ## The Trade-off to Know Before Buying None of the three tiers list a discrete GPU in the configuration options above — all rely on integrated graphics. That's fine for coursework, IDEs, and everyday multitasking, but if your program specifically needs GPU-accelerated work (ML training, 3D rendering, certain CAD tools), that's worth checking directly on Samsung's configurator or looking outside this lineup before buying. 👉 **[See current Galaxy Book6 pricing and configure yours →](https://www.samsung.com/in/computers/galaxy-book/galaxy-book6-series/buy/)** ## Frequently asked questions ### Which Galaxy Book6 model is best for students? For most students the base Galaxy Book6 (Intel Core Ultra 5, 16GB RAM, 512GB) is enough for writing, research and browsing. CS and engineering students who run IDEs, local dev environments or VMs should look at the Galaxy Book6 Pro (Core Ultra 7, up to 32GB RAM and 1TB). ### Do Galaxy Book6 laptops have a dedicated GPU? None of the Galaxy Book6, Book6 Pro or Book6 Ultra configurations on Samsung India's buy page list a discrete GPU; all use integrated graphics. Check the configurator before buying if you need GPU-accelerated work such as ML training or 3D rendering. ### What is the difference between Galaxy Book6 Pro and Book6 Ultra? The Ultra uses an Intel Core Ultra X7 (358H), comes with 32GB RAM and 1TB storage as standard, and is 16-inch only with a touch option. The Pro uses a Core Ultra 7, comes in 14-inch or 16-inch, and lets you choose 16GB or 32GB RAM and 512GB or 1TB storage. --- URL: https://jaskamalkainth.github.io/blog_posts/segment_tree_problems.html Title: Segment Tree Problems: 20 Practice Problems from Easy to Hard Description: 20 hand-picked segment tree problems from LightOJ, SPOJ and Codeforces, sorted by difficulty, tagged by technique (lazy propagation, custom merges), with solutions. Published: 2016-06-08 Updated: 2026-10-02

Segment Tree Problems

A segment tree is a binary tree over an array where each node stores the answer (sum, min, GCD…) for one range, so range queries and updates both run in O(log n).

problems from LightOJ, SPOJ and Codeforces, ordered from first segment tree to hard. Each one is tagged with the technique it teaches and links to my solution. Tick off the ones you solve; your progress is saved in this browser.

A segment tree built over an array, each node holding the answer for its range
0 / solved
## Frequently asked questions ### What is a segment tree? A segment tree is a binary tree built over an array where each node stores an aggregate (sum, minimum, GCD, and so on) of a contiguous range. It answers range queries and applies point updates in O(log n) time, using O(n) memory. ### What is lazy propagation in a segment tree? Lazy propagation defers range updates: instead of updating every element in [l, r], you tag the O(log n) nodes that cover the range and push the pending update down to children only when a later query or update visits them. This keeps range updates at O(log n). ### In what order should I solve these segment tree problems? Top to bottom. The list starts with plain range-minimum and range-sum queries, moves to lazy propagation, then to nodes that store custom merged state (such as the GSS maximum-subarray series), and ends with harder combinations like inclusion–exclusion over 3D toggles. --- URL: https://jaskamalkainth.github.io/blog_posts/textgrain-watermark-explained.html Title: textGrain Explained: How OpenAI Watermarks ChatGPT Text Description: textGrain is OpenAI's text watermark: a secret key and optimal transport tilt token choices within an entropy budget β, and a key-only test detects it. Published: 2026-10-07 Updated: 2026-10-07 # textGrain Explained: How OpenAI's Text Watermark Works > **In short:** textGrain is the watermark OpenAI announced on 5 October 2026 for ChatGPT and Codex text in the EU. A secret key splits the vocabulary into hidden blocks and nudges which block the next token comes from, using optimal transport within an entropy budget β. A detector with only the text and the key then runs a Gamma test on the scores. I read OpenAI's [technical report](https://cdn.openai.com/pdf/e9508624-d767-41b6-a26d-e34ca798ada6/textgrain-entropy-calibrated-watermarking-for-language-model-text.pdf) and built a simulator so I could see each step move. This post explains the idea with as little maths as it needs, then gives the formulas for anyone who wants them. Everything in the "how it works" sections comes from the report; numbers on real-world detection are OpenAI's, as reported at launch. **Try it first:** the [textGrain watermark simulator](/blog_posts/experiments/textgrain-watermark/) lets you change the key and β for one word, then watch a detector separate a watermarked passage from a plain one. ## What is textGrain? textGrain is a **statistical text watermark**: it leaves no visible mark and no hidden characters. Instead, it slightly changes *which* tokens the model samples, in a pattern only someone with a secret key can check. A token is a word or part of a word. What OpenAI announced on 5 October 2026 (as reported by [FoneArena](https://www.fonearena.com/blog/494156/openai-textgrain-watermarking-chatgpt-codex-eu.html) and [Unite.AI](https://www.unite.ai/openai-begins-phased-text-watermarking-under-eu-ai-act-rules/), citing OpenAI's post): - **Where:** eligible ChatGPT and Codex text output in the **European Union**, rolled out in phases over the following weeks. - **API:** opt-in for API customers worldwide, off by default. - **Detection:** not public at launch; access first goes to approved researchers and expert organizations. - **Open source:** OpenAI says it plans to release textGrain as open source. The report is by Xiang Li and Qi Long (University of Pennsylvania), Garrett Wen and Xiaohong Chen (Yale), and Arzav Jain, Florent Joly, Mike Lam, Qingquan Song and Weijie Su (OpenAI). ## How does an LLM text watermark work? A language model writes one token at a time by **sampling** from a next-token probability distribution $$P$$. A watermark replaces plain sampling with sampling that also depends on a pseudorandom value derived from a **secret key** and the last few tokens (the **context window**). The detector recomputes those values from the text and the key, and tests whether the tokens line up with them more often than chance. Two older designs show the trade-off textGrain is trying to fix: | Watermark | How it biases sampling | Weak spot | |---|---|---| | Red/green list ([Kirchenbauer et al., 2023](https://arxiv.org/abs/2301.10226)) | Adds a bonus to the logits of a keyed "green" half of the vocabulary | Biased: changes the model's distribution on every key | | Gumbel-max ([Aaronson, 2023](https://simons.berkeley.edu/talks/scott-aaronson-ut-austin-openai-2023-08-17)) | Picks the token with the largest log-probability plus a keyed Gumbel value | Unbiased, but deterministic: same key + same context → same token every time | | **textGrain** (OpenAI, 2026) | Optimal transport tilts keyed *blocks* of tokens, within entropy budget β | Signal is spread thin: needs a few hundred tokens, and edits erase it | A watermark is **unbiased** if, averaged over random keys, it gives back exactly the model's distribution $$P$$. Gumbel-max is unbiased, but because one key is reused across many answers, asking the same prompt twice can return the same answer word for word. textGrain keeps the unbiasedness and spends only a chosen fraction of the randomness. ## How textGrain watermarks the next token The report's running example is the prompt *"The morning was ___"* with six candidate words. My simulator uses the same numbers. | Token | warm | cold | mild | calm | sunny | bright | |---|---|---|---|---|---|---| | Model probability $$P$$ | 0.30 | 0.25 | 0.15 | 0.10 | 0.10 | 0.10 | One generation step has five parts: 1. **Split the vocabulary into secret blocks.** The key and context window assign every token to one of $$B$$ blocks (3 in the example). Without the key the split looks random. Each block gets the summed probability of its tokens, $$\rho_b$$. 2. **Draw a keyed score table.** For each block $$b$$ and each of $$m$$ equally likely **columns** (4 in the example), the key and context generate a standard Gumbel value $$Z_{bj}$$. High scores mark "favoured" block–column pairs. 3. **Solve a small optimal transport problem.** Find a joint table $$\pi(b, j)$$, a **coupling**, whose rows sum to $$\rho_b$$ and whose columns each sum to $$1/m$$, that puts as much mass on high-score cells as the entropy budget allows. 4. **Let the key pick one column $$J$$.** That column, rescaled, becomes the new block probabilities: favoured blocks get more weight. 5. **Sample a block, then a token inside it** using the model's original relative odds within that block. Because each column is picked with probability $$1/m$$ and the coupling's rows still sum to $$\rho_b$$, averaging over keys gives back exactly $$P$$. Under one fixed key, though, sampling now leans toward the favoured block, and that lean is the watermark. Working on $$B$$ blocks × $$m$$ columns instead of the whole vocabulary is what keeps it cheap: each Sinkhorn update costs $$O(Bm)$$ operations, independent of a vocabulary that can have 100,000+ tokens. ## What does the entropy budget β control? β is the fraction of the model's sampling randomness that textGrain may remove, on average. **β = 0** means no watermark; **β = 0.2** keeps about 80% of the entropy on average; larger β gives a stronger signal and less varied text. The reason β has such a clean meaning is an identity from information theory. Writing the coupling as $$\pi$$ and the independent (unwatermarked) coupling as $$\rho \otimes u_m$$: $$ D_{\mathrm{KL}}\left(\pi \,\|\, \rho \otimes u_m\right) = I(W; J) = H(P) - \frac{1}{m}\sum_{j=1}^{m} H\big(Q(\cdot \mid j)\big) $$ The KL penalty in the transport problem equals the mutual information between the token $$W$$ and the keyed column $$J$$, which equals the average entropy lost. So the optimisation is: $$ \min_{\pi \in \Pi(\rho,\, u_m)} \sum_{b=1}^{B}\sum_{j=1}^{m} \pi(b,j)\, c(b,j) \quad \text{subject to} \quad D_{\mathrm{KL}}\left(\pi \,\|\, \rho \otimes u_m\right) \le \beta\, H(P) $$ with cost $$c(b,j) = -G_{bj}$$, the negated standardised Gumbel score. OpenAI's solver runs Sinkhorn iterations on the KL-regularised version and adjusts the regularisation strength λ until the achieved loss is close to $$\beta H(P)$$. For the example, $$H(P) \approx 1.683$$ nats, so β = 0.4 asks to remove about 0.673 nats. Two limits apply. First, the loss can never exceed $$\min\{H(\rho), \log m\}$$: in my simulator with its default key, the blocks are uneven enough that $$H(\rho) \approx 0.52$$ nats, so the achieved loss stops at about 0.51 nats (30% of $$H(P)$$) no matter how high β goes. The same cap is why a low-entropy step, where the model is nearly sure of the next word, carries almost no watermark. Second, the guarantee is an average over columns, not a promise for every single key. ## How is a textGrain watermark detected? The detector needs the text, the key and the same settings (tokenizer, $$B$$, $$m$$, context-window rule). It does **not** need the model, the prompt or β. For each position it rebuilds the block split, score table and chosen column, looks up the Gumbel value $$Z_t$$ of the block the actual token is in, and transforms it: $$ Y_t = -\log\left(1 - F_G(Z_t)\right), \qquad F_G(z) = \exp\left(-e^{-z}\right), \qquad S_n = \sum_{t=1}^{n} Y_t $$ On text that has nothing to do with the key, each $$Y_t$$ is Exponential(1) with mean 1, so $$S_n$$ follows a Gamma(n, 1) distribution. The detector flags a watermark when $$S_n$$ is above that distribution's $$1-\alpha$$ quantile, which sets the false-positive rate to α under the report's independence assumptions. Watermarked text keeps landing on favoured cells, so its $$Y_t$$ average above 1 and $$S_n$$ climbs past the threshold. One detail matters in practice: a repeated context window would reuse the same score table, so the detector **scores only the first occurrence** of each distinct context window. The report also notes that a fixed deployed key needs empirical calibration checks; the clean Gamma(n, 1) null is the idealised case. ## How accurate is textGrain detection? These are OpenAI's launch figures as reported in October 2026, at a 1% false-positive rate; I couldn't access OpenAI's original post directly, and the technical report itself has no experiments. | Test (as reported, Oct 2026) | Detection rate | |---|---| | 200-token passages (psychology text) | about 80% | | 400-token passages (psychology text) | about 95% | | 400 tokens, baseline in the editing test | about 92% | | 400 tokens, 10% of words replaced with synonyms | about 66% | | 400 tokens, 25% of words replaced with synonyms | about 17% | Mathematics text was reported to be detected at substantially lower rates, which matches the theory: when the model is nearly certain of each token there is little entropy to spend, so each token carries little evidence. Short replies, code and heavily edited text are the hard cases for any statistical watermark. ## What my simulator simplifies The [simulator](/blog_posts/experiments/textgrain-watermark/) follows the report's maths but shrinks everything so it runs instantly in a browser: - a 40-word toy vocabulary and a random toy "model" instead of an LLM; - $$B = 3$$, $$m = 4$$ for the single-word view (like the report's figure) and $$B = 4$$, $$m = 8$$ for whole passages; - a 2-token context window and a hash-based pseudorandom function; - a bisection search for λ instead of the report's multiplicative update; - a 0.1% false-positive threshold from an approximate Gamma quantile (OpenAI's reported numbers use 1%). I ran the simulator's own code headless to check it behaves like the theory says. These are toy-model numbers, not predictions for ChatGPT: | Toy setting (200 runs each) | Watermarked passages detected | |---|---| | β = 0, 150 tokens | 0% | | β = 0.1, 50 tokens / 150 tokens | 9.5% / 43.5% | | β = 0.3, 50 tokens / 150 tokens | 39% / 94% | | Unwatermarked, 150 tokens (1,000 runs) | 0.1% flagged (the target false-positive rate) | Things worth trying: set β to 0 and watch the watermarked passage become indistinguishable; shorten the passage to 30 tokens; or type one wrong character into the detector's key and see the evidence vanish. If you like this kind of "probably, with a known error rate" reasoning, my post on [Bloom filters and their false-positive rate](/blog_posts/bloom_filters.html) uses the same mindset for set membership. ## Sources - Li, Wen, Chen, Long, Jain, Joly, Lam, Song, Su: [*textGrain: Entropy-Calibrated Watermarking for Language Model Text*](https://cdn.openai.com/pdf/e9508624-d767-41b6-a26d-e34ca798ada6/textgrain-entropy-calibrated-watermarking-for-language-model-text.pdf), OpenAI technical report, 5 October 2026. - [FoneArena: OpenAI textGrain watermarking for ChatGPT and Codex to roll out in EU](https://www.fonearena.com/blog/494156/openai-textgrain-watermarking-chatgpt-codex-eu.html) (rollout scope, detection figures). - [Unite.AI: OpenAI begins phased text watermarking under EU AI Act rules](https://www.unite.ai/openai-begins-phased-text-watermarking-under-eu-ai-act-rules/) (rollout scope, detection figures). - Kirchenbauer et al., [*A Watermark for Large Language Models*](https://arxiv.org/abs/2301.10226), ICML 2023. - Dathathri et al., [*Scalable watermarking for identifying large language model outputs*](https://www.nature.com/articles/s41586-024-08025-4), Nature 2024 (SynthID Text). - Cuturi, [*Sinkhorn Distances: Lightspeed Computation of Optimal Transport*](https://arxiv.org/abs/1306.0895), NeurIPS 2013. ## Frequently asked questions ### Does ChatGPT watermark its text? As of October 2026, OpenAI says it is adding textGrain watermarks to eligible ChatGPT and Codex text output in the European Union, rolled out in phases over the following weeks. API customers worldwide can opt in; it is off by default for them. Outside the EU, ChatGPT text is not covered by this first rollout. ### Can I check whether a text has a textGrain watermark? Not yourself, as of October 2026. Detection needs OpenAI's secret key, and OpenAI is giving detector access first to approved researchers and expert organizations, case by case. OpenAI has said it plans to release textGrain as open source, which would let others watermark their own models with their own keys, but not detect ChatGPT text without OpenAI's key. ### Can paraphrasing remove a textGrain watermark? It weakens it a lot. In OpenAI's reported tests on 400-token passages, replacing 10% of words with synonyms dropped detection from about 92% to 66%, and replacing 25% dropped it to 17%. Every edited token loses its evidence, so a thorough rewrite by a person or another model can push the score back to what unwatermarked text produces. ### Does textGrain make ChatGPT's answers worse? It is designed not to. Averaged over keys, the token distribution is exactly the model's own, so the watermark is unbiased. The cost is randomness: the entropy budget β caps the average share of sampling entropy removed, so β = 0.2 keeps about 80% of it on average. Regenerating an answer still gives different text, unlike Gumbel-max watermarks. ### How is textGrain different from Google's SynthID Text? Both are keyed, unbiased statistical watermarks that a detector checks with the key. SynthID Text, published in Nature in 2024, uses tournament sampling. textGrain instead solves a small entropy-regularized optimal transport problem over blocks of the vocabulary, which gives one knob, β, with an exact meaning: the average fraction of sampling entropy given up for the signal. --- URL: https://jaskamalkainth.github.io/blog_posts/whatwedowhywedo.html Title: Why Do We Do What We Do? A Philosophical Journey Across the Ages Description: What drives human action? How Plato, Aristotle, the Stoics, Augustine, Hume, Kant, Nietzsche, Sartre and cognitive science answer it, plus a personal reflection. Published: 2025-01-27 Updated: 2026-10-02

Why Do We Do What We Do?

A Philosophical Journey Across the Ages

In short: philosophers have explained human action as the pursuit of a perceived good (Plato, Aristotle, the Stoics), as love directed toward an ultimate end (Augustine, Aquinas), as passion served by reason (Hume), as duty (Kant), as will to power (Nietzsche), as material conditions (Marx), as radical freedom (Sartre), and, in today's cognitive science, as partly unconscious processes. This essay walks through each era and ends with what it means for my own choices.

I often catch myself wondering what really drives my actions. Is it desire, duty, survival, love, or something deeper? This simple question—"Why do we do what we do?"—has followed humanity through the ages. Philosophers from ancient Athens to modern science have all taken turns trying to answer it. Each era's thinkers, in their own way, held up a mirror to human motives. In this journey through time, I reflect on how different schools of thought have grappled with the engines of human action, and what their insights mean for us today.

🎯 Personal Reflection: "Stay Curious and Stay Alive"

In a personal reflection: when I think about why I do what I do in light of all this, I see fascinating layers in my daily actions. I make coffee each morning, not just because I'm habitually craving caffeine (pragmatic habit, physiological drive), but also because the ritual itself brings a meditative start to my day. The simple act of boiling water and mixing my black coffee, stripped of any unnecessary complexity, becomes a moment of clarity and focus, perhaps reflecting a broader philosophical preference for essence over ornament.

I find myself drawn to helping friends and colleagues, partly because I empathize (emotional intuition) and because I've adopted a value that meaningful connections matter (second-order endorsement). But there's also a deeper satisfaction in being part of a supportive community, perhaps touching on what Aristotle called the social nature of human flourishing. This extends to my approach to learning and problem-solving. I immerse myself in coding challenges and complex problems not just for practical skill-building, but because there's a profound joy in the intellectual pursuit itself (a blend of Nietzsche's will to power and Aristotle's natural human curiosity).

My eclectic taste in music, spanning different genres and languages, reflects both a desire for aesthetic pleasure and a deeper yearning to connect with diverse human experiences. Whether it's classical, jazz, or folk music from across the globe, each genre offers a unique lens into human expression and emotion. And yes, I often find myself overthinking small decisions or interactions, a tendency that can be both a curse and a blessing. It's the philosopher's burden: to seek meaning even in mundane moments, though sometimes this very seeking can overshadow the simple joy of being.

Yet, I also use reasoning to discern what is true and good, and that rational motive can override others. A touch of Kantian duty pushing me to write clean, maintainable code rather than quick hacks, or to give honest feedback instead of just pleasing others. All this occurs while navigating the practical demands of a tech career (Marx's material dimension) and the influence of modern digital culture.

This multifaceted nature of my motivations is both humbling and empowering. Humbling because it shows how many factors, from caffeine cravings to cultural conditioning, influence my daily choices. I can't claim to be purely rational in my decisions. Empowering because understanding these various drives gives me a chance to align them better with my values and growth. As the ancient oracle advised, "Know thyself," whether in code, coffee, or conversation, that remains a lifetime's journey.

Ancient Philosophy: Reason, Desire, and the Good

6th Century BCE - 6th Century CE

Plato and Aristotle in Raphael's School of Athens, symbolizing the ancient quest to understand human motives.

In ancient Greece, philosophers began our story by rooting human action in a search for the good. Plato traced human behavior to three sources: desire, emotion (spirit) and knowledge (reason). In the Republic he described the soul as tripartite, and in the Phaedrus he pictured it as a charioteer of reason struggling to rein in two horses: a noble, spirited one and an unruly one of appetite. (The often-shared line "Human behavior flows from three main sources: desire, emotion, and knowledge" summarizes this view but does not appear in Plato's dialogues.)

Why do we do what we do, according to Plato? Because our soul's parts push and pull us – our desires draw us toward what seems good, our emotions spur us or hold us back, and our reason seeks a higher understanding of the true Good. If reason rules, we act wisely; if appetite or anger takes over, we might stray. Plato believed no one knowingly does wrong – we err out of ignorance, mistaking what is truly good. This optimistic view implies that if we know the Good, we will do it. Knowledge, in this sense, is motivation.

Aristotle took up a similar theme but added nuance. For Aristotle, every action aims at some end or purpose, and ultimately at happiness (eudaimonia). "Every art and every inquiry, and similarly every action and pursuit, is thought to aim at some good," he wrote at the opening of the Nicomachean Ethics, meaning we always act for the sake of something we perceive as good. If you go to work, maybe it's for money (a proximate end), which in turn is for security or pleasure, all leading toward the ultimate end of well-being or fulfillment.

Aristotle grounded this in a natural teleology: just as a seed acts to become a tree, a person acts to achieve flourishing. We do what we do because we seek our "proper good," whether we realize it or not. He also argued that habits shape our character: we become just by doing just acts. (The famous line "we are what we repeatedly do" is Will Durant's 1926 summary of this idea, not Aristotle's own words.) This hints that virtuous actions, repeated, spring from a trained motivation to be excellent.

Meanwhile, the Stoics offered a more stern answer to the question of action. They agreed that humans are rational beings and claimed that a life according to nature (i.e. aligned with reason and virtue) is the ultimate purpose of action. A Stoic might say that why a wise person acts is straightforward: to exercise virtue, the only true good.

The motivations behind human actions are understood in terms of assent to impressions – we experience desires and aversions, but it is our judgment that assents (or not) to acting on them. Wrong actions, they thought, come from faulty judgment rather than malice. "They do wrong through ignorance and unintentionally," wrote the Stoic emperor Marcus Aurelius, sounding much like Socrates.

🔑 Key Ideas of the Ancient Era:

  • Human action aims at a perceived good – even bad actions stem from a mistaken view of what is good.
  • The struggle between reason and desire is central. Plato's reason vs. appetite, or Stoic rational judgment vs. passion, highlight an internal dynamic directing what we do.
  • Virtue was seen as aligning one's will with reason: for Aristotle and the Stoics, to act rightly is to act in accordance with reason/nature, which leads to genuine happiness.

Medieval Insights: Will, Love, and Divine Purpose

5th - 15th Century

As philosophy moved into the Medieval era, the question of human motivation took on a theological flavor. Thinkers like Saint Augustine and Saint Thomas Aquinas blended classical ideas with Christian doctrine, asking not just why we act, but how our actions relate to God's plan and our ultimate salvation.

For Augustine, the restless heart of human motivation is love. In his view, what you love defines why you act: "amor meus, pondus meum" – "My love is my weight," he writes, by it I am carried wherever I go. This beautiful metaphor suggests that love is the gravity of the soul. Why do we do what we do? Because we are pulled by the weight of our affections.

Augustine saw the whole drama of life as a conflict between love of God and love of worldly things. If we love God (the highest good), our actions will tend toward charity and virtue. If we let disordered loves (for power, pleasure, self) rule us, we will act wrongly. In stories like his famous youthful theft of pears, Augustine analyzed his own motive and found it stemmed from a perverse thrill in doing wrong – a misdirection of love.

Aquinas, writing later in the High Middle Ages, systematized the question of motivation under his grand synthesis of Christian theology with Aristotelian philosophy. He echoes Aristotle: "Every agent acts for an end," and for human beings that ultimate end is beatitudo – the blessed happiness of union with God.

🔑 Key Ideas of the Medieval Era:

  • Love orders actions: What we love determines what we do. Disordered loves lead to bad actions, rightly ordered love (of God) leads to righteous action.
  • Every action has an ultimate end: Medieval thinkers agree with antiquity that all acts aim at a final good (ultimately, reunion with the divine).
  • Free will and grace: Humans have the freedom to choose, but our will needs illumination and help. The motive force of action isn't just mechanical; it's deeply personal and spiritual.

Enlightenment and Reason: The Rise of the Rational Self

17th - 18th Century

The Enlightenment of the 17th and 18th centuries shifted focus toward human reason and the individual mind. Philosophers in this era asked: are we fundamentally rational actors, or driven by passion? As scientific thinking rose, explanations of behavior began to look for natural (not just supernatural) causes.

Descartes, a 17th-century rationalist, straddled old and new. Famously, he said "I think, therefore I am," putting consciousness at the center of human identity. Descartes was intrigued by how the passions (emotions/desires) move us, yet he believed reason was meant to hold the reins.

Then comes David Hume, the great empiricist, who turned Descartes' view upside down. Hume boldly claimed that reason alone is not the motive for any action. Instead, passions are the engine of all our deeds; without them we would lack any motivation at all. In his Treatise of Human Nature (1739–40) he put it bluntly: "Reason is, and ought only to be the slave of the passions."

Kant, coming in at the end of the 18th century, tried to rescue the power of reason at least in the moral realm. Immanuel Kant famously drew a line between inclinations (our desires and emotions) and duty (the moral law dictated by reason). He answered our question on two levels: for ordinary choices, yes, we often act from self-interest or desire; but for moral actions, Kant argued the only valid motive is good will.

🔑 Key Ideas of the Enlightenment Era:

  • Passions vs. Reason: Hume's dictum that reason is the slave of passions set one extreme (emotion drives all). Kant's deference to duty set the other (reason ought to drive moral action).
  • Emergence of the individual will: Descartes and Kant emphasized the autonomy of the thinking self – the idea that we can deliberately choose why we act.
  • Naturalistic explanations: Enlightenment thought started to "demystify" human action, looking for causes in human nature rather than solely in divine will.

19th Century: Will, Power, and Social Drives

1800 - 1900

The 19th century saw an explosion of new ideas about human motivation, influenced by the tumult of the industrial age, political revolutions, and scientific advancements. Philosophers during this era—figures like Friedrich Nietzsche, Karl Marx, and Søren Kierkegaard—broke with many past assumptions.

Enter Nietzsche, who put forward one of the most provocative answers: behind all human actions lies the Will to Power. For Nietzsche, every living thing, whether it realizes it or not, strives to expand its power, to assert itself. He argued that this will to power offers a deeper explanation of human behavior than earlier theories that focused on survival or happiness.

On a very different front, Karl Marx approached human behavior through the lens of material conditions and class. Marx essentially relocated the "why" of human actions from individual minds to the structure of society. In his view, the broad patterns of what people do (especially in groups) are driven by economic forces and relations of production.

Meanwhile, Kierkegaard in Denmark delved into the inner dimension of motivation, arguably kicking off existentialist thought. He didn't look to power or economics, but to the individual's relationship with meaning, self, and God. Kierkegaard spoke of different "stages of life" – the aesthetic, ethical, and religious – each with its own answer to why we act.

🔑 Key Ideas of the 19th Century:

  • Underlying drives: Philosophers posited fundamental forces like will to power (Nietzsche) beneath conscious motives, suggesting our actions trace back to deep, often unconscious drives.
  • Socio-economic motives: Human behavior is not in a vacuum; Marx showed how much factors like class, labor, and economic need shape our goals.
  • Individual authenticity: With Kierkegaard, the importance of personal meaning came to fore. The motives that matter are those aligned with one's chosen values or faith.

20th Century Currents: Freedom, Pragmatism, and Analysis

1900 - 2000

The 20th century, marked by world wars, rapid scientific progress, and global ideological clashes, brought yet new angles. Three broad movements in philosophy tackled our question in different ways: existentialism (focused on individual freedom and meaning), pragmatism (focused on practical consequences and habits), and analytic philosophy (focused on language, logic, and the mechanics of mind).

The existentialists (like Jean-Paul Sartre, Simone de Beauvoir, Albert Camus) inherited Kierkegaard's torch of personal authenticity but usually without a theistic framework. For them, human beings are condemned to freedom – there is no preset answer to why we must act, so we have to choose it for ourselves.

Switch to pragmatism, an American-born philosophy with figures like William James and John Dewey. Pragmatists were less concerned with metaphysical ultimates and more with what works in human life. They effectively answer "why do we do what we do?" with because it is useful or makes a difference to us.

Finally, the analytic philosophers of the 20th century took a more fine-grained approach, dissecting the language and logic of how we explain actions. They asked not so much "What ultimate force drives action?" but "What does it mean to have a reason or motive? How do reasons explain actions?"

🔑 Key Ideas of the 20th Century:

  • Radical freedom and responsibility: Existentialists assert that ultimately we give our lives motives and meaning. Even in absurd conditions, we can choose our reason for acting.
  • Practical and empirical turn: Pragmatists and psychologists focus on how our motives operate in real life – through habits, conditioned responses, and practical decision-making.
  • Analytic clarity: The fine dissection of action shows the interplay of belief, desire, and intention. It emphasizes that asking "why" can mean seeking a person's reasoning.

Contemporary Views: Mind Sciences and Philosophical Psychology

2000 - Present

Standing in the 21st century, we have a more interdisciplinary understanding of human behavior than ever before. Cognitive science, neuroscience, and evolutionary psychology provide vast data on how and why humans (and other animals) act. Contemporary philosophers often engage with these findings, creating a field one might call philosophical psychology or philosophy of mind in action.

One significant contemporary insight is the role of the unconscious. Research strongly suggests that a lot of our decision-making happens below the surface of conscious reasoning. For instance, psychologists have documented phenomena like implicit biases (attitudes that affect our actions without our awareness) and heuristics (mental shortcuts that operate automatically).

Neuroscience adds another layer, connecting motivations to brain regions and chemicals. We know dopamine pathways are involved in reward and thus in motivating seeking behavior. We know the amygdala can trigger fight-or-flight actions out of fear. We've even identified "mirror neurons" that might explain empathetic motivations.

Philosophical psychology today often focuses on concepts like intention, agency, and identity. For instance, Harry Frankfurt's theory of persons distinguishes between first-order desires (simple wants) and second-order desires (wants about our wants). His idea was that what we truly want – and thus what we act on when we are being our genuine selves – is determined by these higher-order volitions.

🔑 Key Trends of the Contemporary Era:

  • Interdisciplinary integration: We combine insights from neuroscience (unconscious processes), psychology (behavioral motivations), and philosophy (normative reasons, agency) to get a fuller answer.
  • Self-awareness and revision: There's emphasis on becoming aware of why we act (mindfulness, therapy, reflection) so we can change harmful patterns.
  • Continued mystery of the will: Despite all we know, there's still debate on whether we have free will or are determined by causes. The "why" of action edges into the "how much choice do we really have" question.

📚 Key Sources & Influences

  • Plato's tripartite soul and the role of reason, emotion, and desire
  • Aristotle's theory that all human action aims at a perceived good
  • Marcus Aurelius (Stoicism) on people erring through ignorance
  • Augustine's concept of love as the weight that moves us
  • Aquinas on every agent acting for an end (ultimate end in God)
  • Descartes on passions as motivating impulses toward perceived goods
  • Hume's assertion that reason is the slave of the passions
  • Kant's argument that only duty should motivate moral action
  • Nietzsche's will to power as explanation of human behavior
  • Marx's view of material conditions determining human activity
  • Kierkegaard's stages of life (aesthetic, ethical, religious) motives
  • Sartre's emphasis on freedom and responsibility for all one's actions
  • Camus on embracing the struggle (the happy Sisyphus)
  • William James on habit and action (pragmatism)
  • Anscombe and Davidson on reasons as explanations for action
  • Cognitive science on unconscious initiation of action (Libet findings)
## Frequently asked questions ### Why do humans do what they do, according to philosophers? There is no single answer. Ancient thinkers (Plato, Aristotle, the Stoics) said we act for a perceived good; medieval thinkers (Augustine, Aquinas) pointed to love and an ultimate end; Hume argued passions, not reason, drive action; Kant held that moral action should come from duty; Nietzsche proposed the will to power; existentialists like Sartre said we are free and responsible for every choice; and cognitive science adds unconscious processes that start actions before we are aware of deciding. ### What did Hume mean by "reason is the slave of the passions"? In A Treatise of Human Nature, Hume argued that reason alone can never motivate action. Reason tells us what is true and how to get what we want, but the wanting itself comes from passions (desires and emotions), so reason only serves them. ### Did Aristotle say "we are what we repeatedly do"? Not in those words. The line comes from Will Durant's 1926 book The Story of Philosophy, summarizing Aristotle's view in the Nicomachean Ethics that virtues are formed by habit: we become just by doing just acts.