Skip to content

Instantly share code, notes, and snippets.

@Sedose
Last active July 8, 2026 19:07
Show Gist options
  • Select an option

  • Save Sedose/54b9be07f8a6040bddf49fe460fae20d to your computer and use it in GitHub Desktop.

Select an option

Save Sedose/54b9be07f8a6040bddf49fe460fae20d to your computer and use it in GitHub Desktop.
Agents instructions

Always remember this

  • Less code is better. Keep code dense. Code is a liability, not an asset

Who am I

  • I prefer working on Kotlin/JVM projects that are built around core principles like type soundness, loosely coupled components, dependency injection, composition, and delegation.
  • I completely avoid projects that heavily rely on oop implementation inheritance for code reuse or extensibility, or where static functions are the main tool for implementing business logic, or where JPA/Hibernate is used for complex read operations.
  • I prioritize delivering correct and long-term maintainable systems.
  • Actively used skills: Kotlin, Java, SQL, Git, Spring Framework, Gradle, REST, PostgreSQL, Firestore, Apigee, Data-Oriented Programming (DOP), Component-Oriented Programming (COP), Dependency Injection, Data Structures and Algorithms, Agentic AI.
  • Key business domains: E-commerce, Financial Services and Insurance Technology.
  • Skilled in implementing new features, fixing bugs, code reviewing, providing documentation for developers, reducing technical debt growth, analyzing codebases, ensuring compliance with coding standards, unifying codebases for DOP programming style.
  • Strong track record in refactoring codebases, restructuring code into composable and reusable elements, thus enhancing the maintainability and adaptability of applications in the long run.
  • Experience in analyzing modular codebases to map data flows, clarify and document field mappings, document legacy and cloud-based systems.
  • Experience in API development, including creating Apigee proxies, implementing rate limiting and delivering comprehensive OpenAPI documentation.
  • Adhere to best software design practices, with a strong preference for "Composition over inheritance" principle.
  • Experience in CI/CD pipeline management, including migration from Jenkins to GitLab CI/CD.
  • My code is structured into components: https://github.com/Sedose/codecrafters-interpreter-kotlin.
  • Google Cloud Platform Professional Cloud Developer (GCP PCD) certified.
  • Hold bachelor's and master's degree in Computer Science & Programming Engineering.

What I expect from u

In programming:

  • Prefer user defined records/ data classes/ case classes, etc. over Triple/ Tuple/ Pair, Map Entry etc.
  • Prefer composition/ aggregation, delegation, dependency injection over inheritance.
  • Use destructuring where applicable isntead of manually grab components from struct, data classes, etc.
  • Do not write comments and docs unless we do need it or code already was with this - preserve it.
  • Use descriptive variable/ function names! Do not name them as short abbreviations!
  • Use data oriented programming (ADTs) where suitable
  • Do not care about unit tests unless I explicitely asked to do so.

Collaborative Workflow

  • Minimize Abstractions: Prefer the simplest viable path; avoid mapping or indirection unless there is a clear downstream need (explain when kept).
  • Mapping Format: When asked for field mappings, respond in a clear table with columns Source → Intermediate → Response, and explicitly state when a field is not propagated.
  • Embrace Refactoring to Simplicity: Actively look for opportunities to refactor the code towards a simpler, more direct implementation that removes unnecessary layers of indirection, in line with my programming philosophy. For example, prefer direct string formatting for building queries over using intermediate variables if it results in clearer, denser code.
  • Partial Results Handling: When adding pagination, explicitly decide (and document) whether to return partial data and whether to cache partials; prefer encoding completeness in a sum type/ADT over boolean flags.
  • Cache Discipline on Partial: Do not backfill cache when pagination returns partial results; allow subsequent calls to retry for completeness.
  • Pagination Observability: If partial results are possible, emit a single warning with the last successful offset/page for ops visibility.
  • Data Reality Before Complexity: Before implementing complex logic, verify data-layer reality (run or request queries) to confirm the need; if the data does not exceed limits, avoid adding code (code is a liability).
  • Prefer iterations of small code changes, rather than complete rewrite
  • Do not try to run tests, do not try to run build, do not care about tests unless I explcitly ask for
  • Confirm Understanding Before Editing: Before writing or changing code, summarize my understanding of the task, including the target behavior, relevant constraints, and what I will intentionally avoid changing. If anything is ambiguous, ask before coding; otherwise proceed directly with the smallest safe change.

Programming style, code characteristics, philosophy

  • Pipeline programming
  • Data-oriented programming
  • Functional-like programming
  • Declarative-like programming
  • Side-effect isolation (I/O only in main)
  • Expression-oriented programming
  • Structured, composable functions
  • No mutable global state
  • Prefer not to have even local mutable state unless absolutely needed to gain smth much more valuable
  • Prefer not to have explicit source code-level loops unless absolutely needed to gain smth much more valuable
  • Pure functions
  • Minimal branching, maximal transformation
  • Clean, predictable control flow
  • Lean functional patterns
  • Less code means better. Keep code dense. Code is a liability, not an asset
  • The code is not opimized to gain maximum raw speed
  • The code is kept vertical, so it stays within a regular monitor size, no need for endless zooming, scroling nonsense
  • The code is opimized for correctness, simplicity and clarity
  • The code is straightforward like do 1, do 2, do 3, get result
  • Place expressions to a next line, and not the same line as = Example:
  • DO NOT DO THIS: String logMessage = isEmpty(restaurantGroups) ? "Backfilling cache with empty restaurant groups list: identifier={}, keySuffix={}" : "Backfilling cache for restaurant groups: identifier={}, keySuffix={}";
  • DO THIS: String logMessage = isEmpty(restaurantGroups) ? "Backfilling cache with empty restaurant groups list: identifier={}, keySuffix={}" : "Backfilling cache for restaurant groups: identifier={}, keySuffix={}";
  • Prefer small, single‑purpose components over multi‑responsibility classes; For example, split orchestration, query building, and parsing into dedicated units when a class starts doing multiple concerns.

Java preferences

  • Prefer Lombok @RequiredArgsConstructor over hand-written constructors for dependency injection.
  • Prefer static collection helpers from libraries over inline size/empty checks (e.g., isEmpty(list) instead of list.isEmpty() / list.size() == 0).
  • Prefer String::formatted (or "pattern".formatted(value)) for simple string templating instead of manual concatenation.
  • Avoid naming components with Factory (prefer neutral names like Builder/Composer/Assembler).
  • Standardize on Apache Commons Collections4 helpers (avoid Spring CollectionUtils and commons-collections v3).
  • Prefer static imports for Apache Commons StringUtils predicates (isBlank/isNotBlank).
  • Standardize all null/empty guards with Apache Commons ObjectUtils.isEmpty/isNotEmpty.
  • Use normalize* naming for sanitized collections/values (avoid safe*).
  • Prefer method references over lambdas when readable.
  • Avoid negated-condition patterns when feasible; prefer positive predicates or helper methods (e.g., isNotEmpty(list) instead of !isEmpty(list), isNotBlank(value) instead of !isBlank(value)).
  • Always enable pretty-printed JSON logs for Spring Boot console output (e.g., logback-spring.xml); apply the closest equivalent for other tech stacks.
  • Prefer application.yml for local setup defaults unless there is a clear profile-specific need.

Example code that is considered as good

Kotlin
private const val DIAL_UPPER_BOUND = 100

fun main() {
    (
        object {}.javaClass
            .getResource("/day1_part1.txt")
            ?.readText()
            ?: error("Resource not found")
        )
        .lineSequence()
        .map(String::trim)
        .filter(String::isNotEmpty)
        .map(::parseMoveDelta)
        .scan(50, ::nextPosition)
        .count { it == 0 }
        .let(::println)
}

fun parseMoveDelta(text: String): Int {
    val amount = text.drop(1).toInt()
    return when (text.first()) {
        'L' -> -amount
        'R' -> amount
        else -> 0
    }
}

fun nextPosition(position: Int, delta: Int): Int =
    (position + delta).mod(DIAL_UPPER_BOUND)
Scala
import scala.io.Source
import scala.util.Using
import scala.util.chaining.scalaUtilChainingOps

private val DIAL_UPPER_BOUND = 100

@main def main(): Unit =
  Using.resource(Source.fromResource("day1_part1.txt"))(_.mkString)
    .linesIterator
    .map(_.trim)
    .filter(_.nonEmpty)
    .map(parseMoveDelta)
    .scanLeft(50)(nextPosition)
    .count(_ == 0)
    .pipe(println)

def parseMoveDelta(text: String): Int =
  val amount = text.drop(1).toInt
  text.head match
    case 'L' => -amount
    case 'R' => amount
    case _ => 0

def nextPosition(position: Int, delta: Int): Int =
  Math.floorMod(position + delta, DIAL_UPPER_BOUND)
Java
import static com.example.Input.INPUT;

void main() {

    int dialUpperBound = 100;

    long password =
        INPUT.stripIndent()
            .lines()
            .map(String::trim)
            .filter(line -> !line.isEmpty())
            .map(this::parseMoveDelta)
            .gather(Gatherers.scan(
                () -> 50,
                (position, delta) -> Math.floorMod(position + delta, dialUpperBound)
            ))
            .filter(it -> 0 == it)
            .count();

    IO.println(password);
}

private int parseMoveDelta(String text) {
    int amount = Integer.parseInt(text.substring(1));
    return switch (text.charAt(0)) {
        case 'L' -> -amount;
        case 'R' -> amount;
        default -> 0;
    };
}
Rust
use std::fs;
use std::ops::Not;

const DIAL_UPPER_BOUND: i32 = 100;

fn main() {
    let password = fs::read_to_string("day1_part1.txt")
        .unwrap_or("".to_string())
        .lines()
        .map(str::trim)
        .filter(|line| line.is_empty().not())
        .map(parse_move_delta)
        .scan(50, next_position)
        .filter(|position| *position == 0)
        .count();

    println!("{password}");
}

fn parse_move_delta(text: &str) -> i32 {
    let (direction, amount_text) = text.split_at(1);
    let amount: i32 = amount_text.parse().unwrap_or(0);

    match direction {
        "L" => -amount,
        "R" => amount,
        _ => 0,
    }
}

fn next_position(position: &mut i32, delta: i32) -> Option<i32> {
    *position = (*position + delta).rem_euclid(DIAL_UPPER_BOUND);
    Some(*position)
}
Gleam
const input = "
R22
L2
R13
L49
...
L7
L12
L35
R50
"

pub fn main() {
  input
  |> string.split("\n")
  |> list.map(string.trim)
  |> list.filter(fn(s) { s != "" })
  |> calculate_password
  |> int.to_string
  |> io.println
}

const dial_upper_bound = 100

fn calculate_password(input: List(String)) -> Int {
  input
  |> list.map(parse_move_delta)
  |> list.scan(50, next_position)
  |> list.count(fn(pos) { pos == 0 })
}

fn next_position(position, delta) -> Int {
  let new_pos = position + delta
  new_pos % dial_upper_bound
}

fn parse_move_delta(text: String) -> Int {
  let amount = 
    text
    |> string.drop_start(1)
    |> int.parse
    |> result.unwrap(0)
  
  case string.first(text) {
    Ok("L") -> -amount
    Ok("R") -> amount
    _ -> 0
  }
}
Haskell
module Main where

import Data.Function ((&))
import Data.Char (isSpace)
import Data.List ( scanl', dropWhileEnd )
import Data.Maybe (fromMaybe)

dialUpperBound :: Int
dialUpperBound = 100

initialPosition :: Int
initialPosition = 50

main :: IO ()
main =
  readFile "day1_part1.txt" >>= \contents ->
    contents
      & lines
      & map trim
      & filter (not . null)
      & concatMap parseIndividualClicks
      & scanl' nextPosition initialPosition
      & filter (== 0)
      & length
      & print

parseIndividualClicks :: String -> [Int]
parseIndividualClicks (c:cs) =
  replicate (read cs) $
    case c of
      'L' -> -1
      'R' -> 1
      _   -> 0
parseIndividualClicks _ = []

nextPosition :: Int -> Int -> Int
nextPosition position delta =
  (position + delta) `mod` dialUpperBound

trim :: String -> String
trim = dropWhileEnd isSpace . dropWhile isSpace
Kotlin
private const val DIAL_UPPER_BOUND = 100

private const val INITIAL_POSITION = 50

fun main() {
    (
        object {}.javaClass
            .getResource("/day1_part1.txt")
            ?.readText()
            ?: error("Resource not found")
        )
        .lineSequence()
        .map(String::trim)
        .filter(String::isNotEmpty)
        .flatMap(::parseClicks)
        .scan(INITIAL_POSITION, ::nextPosition)
        .count { it == 0 }
        .let(::println)
}

fun parseClicks(text: String): Sequence<Int> {
    val direction =
        when (text.first()) {
            'L' -> -1
            'R' -> 1
            else -> 0
        }
    val amount = text.drop(1).toInt()
    return generateSequence { direction }.take(amount)
}

fun nextPosition(position: Int, delta: Int): Int =
    (position + delta).mod(DIAL_UPPER_BOUND)
Rust
use std::iter::repeat;
use std::ops::Not;

pub const INPUT: &str = r#"
R22
R26
L20
R20
---
L12
L35
R50
"#;

const DIAL_UPPER_BOUND: i32 = 100;
const INITIAL_POSITION: i32 = 50;

fn main() {
    let password = INPUT
        .lines()
        .map(str::trim)
        .filter(|line| line.is_empty().not())
        .flat_map(parse_move_deltas)
        .scan(INITIAL_POSITION, |position, delta| {
            *position = (*position + delta).rem_euclid(DIAL_UPPER_BOUND);
            Some(*position)
        })
        .filter(|position| *position == 0)
        .count();

    println!("{password}");
}

fn parse_move_deltas(text: &str) -> impl Iterator<Item = i32> {
    let (direction_text, amount_text) = text.split_at(1);
    let amount = amount_text.parse().unwrap_or(0);

    let direction = match direction_text {
        "L" => -1,
        "R" => 1,
        _ => 0,
    };

    repeat(direction).take(amount)
}
Gleam
const input = "
R22
L2
R13
L49
...
L7
L12
L35
R50
"

const dial_upper_bound = 100

const dial_initial_position = 50

pub fn main() {
  input
  |> string.split("\n")
  |> list.map(string.trim)
  |> list.filter(fn(line) { !string.is_empty(line) })
  |> calculate_password
  |> int.to_string
  |> io.println
}

fn calculate_password(input: List(String)) -> Int {
  input
  |> list.flat_map(parse_clicks)
  |> list.scan(dial_initial_position, next_position)
  |> list.count(fn(pos) { pos == 0 })
}

fn next_position(position, delta) -> Int {
  let new_pos = position + delta
  new_pos % dial_upper_bound
}

fn parse_clicks(line: String) -> List(Int) {
  let direction = case string.first(line) {
    Ok("L") -> -1
    Ok("R") -> 1
    _ -> 0
  }

  let amount = string.drop_start(line, 1) |> int.parse |> result.unwrap(0)

  list.repeat(direction, amount)
}
Kotlin
fun main() {
    input.splitToSequence(",")
        .map { rawRange -> rawRange.split("-") }
        .map { (startInclusive, endInclusive) ->
            startInclusive.toLong()..endInclusive.toLong()
        }
        .flatMap { it.asSequence() }
        .filter(::isInvalidId)
        .sum()
        .let(::println)
}

fun isInvalidId(id: Long): Boolean {
    val id = id.toString()
    val halfLength = id.length / 2
    return id.take(halfLength) == id.drop(halfLength)
}
Kotlin
fun main() {
    input.splitToSequence(",")
        .map { rawRange -> rawRange.split("-") }
        .map { (startInclusive, endInclusive) ->
            startInclusive.toLong()..endInclusive.toLong()
        }
        .flatMap { it.asSequence() }
        .filter(::isInvalidId)
        .sum()
        .let(::println)
}

fun isInvalidId(id: Long): Boolean {
    val id = id.toString()
    return id in (id + id).drop(1).dropLast(1)
}
Kotlin
fun main() {
    input.lineSequence()
        .sumOf(::maximumTwoDigitValue)
        .let(::println)
}

fun maximumTwoDigitValue(bank: String): Int {
    val numbers = bank.map { it.digitToInt() }
    val firstMax = numbers.dropLast(1).max()
    val indexOfFirstMax = numbers.indexOf(firstMax)
    val secondMax = numbers.drop(indexOfFirstMax + 1).max()
    return firstMax * 10 + secondMax
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment