AtCoder in OCaml: ABC121 B

2026-09-08

In the Rust version, cargo-compete and proconio handled most of the competitive-programming setup. The input looks like this (so nice):

input! {
    n: usize,
    m: usize,
    c: i32,
    b: [i32; m],
    rows: [[i32; m]; n],
}

I don't want to write loops and scanfs in Ocaml. I wanted a similar small and composable workflow, so I replicated it with a vibe-coded helper and a few input reader combinators.

The problem is ABC121 B — Can you solve this?: for each row, take its dot product with B, add C, and count it if the result is greater than zero.

Small readers that compose

The base reader consumes one integer:

let int () = Scanf.scanf " %d" Fun.id

Then list turns any reader into a reader for n values:

let list n r () = List.init n (fun _ -> r ())

This means list m int reads one row, while list n (list m int) reads the whole matrix. Here is the complete solution:

(* ===== helpers start ============================================== *)
open Printf

let int () = Scanf.scanf " %d" Fun.id
let str () = Scanf.scanf " %s" Fun.id
let list n r () = List.init n (fun _ -> r ())
let array n r () = Array.init n (fun _ -> r ())
let pair r s () = let a = r () in let b = s () in (a, b)
(* ===== helpers end ================================================ *)

type problem = {
  c : int;
  b : int list;
  rows : int list list;
}

let read_problem () =
  let n = int () in
  let m = int () in
  let c = int () in
  let b = list m int () in
  let rows = list n (list m int) () in
  { c; b; rows }

let can_solve c b row =
  List.fold_left2
    (fun score a_i b_i -> score + (a_i * b_i))
    c
    b
    row
  > 0

let solve problem =
  problem.rows
  |> List.filter (can_solve problem.c problem.b)
  |> List.length

let () =
  let problem = read_problem () in
  printf "%d\n" (solve problem)

Ocaml has some nice builtins like List.fold_left2. Also solve and helper functions can stay pure. The result is the style I wanted. Also, I don't need to care about memory, ownership or types for the most part.

For this problem, OCaml feels just as concise as Rust.

https://altariarite.github.io/posts/feed.xml