3 điểm bởi GN⁺ 8 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • International Obfuscated C Code Contest (Cuộc thi Mã C Làm Rối Quốc tế) là cuộc thi lập trình máy tính nhằm tranh tài bằng những đoạn mã C “obfuscated” (làm rối) sáng tạo, giàu tính nghệ thuật nhưng cực khó đọc nhất
  • Sau quãng gián đoạn 2020~2024, đây là kỳ thi thứ hai được tổ chức liên tiếp; số lượng bài dự thi tương đương năm trước nhưng quy mô và chất lượng tác phẩm dự thi vẫn duy trì ở mức đỉnh cao lịch sử
  • Yusuke Endoh, Nick Craig-Wood, Don Yang mỗi người có 3 tác phẩm đoạt giải, lập nên hat-trick, đồng thời xuất hiện thêm tác giả đoạt giải mới đến từ Taiwan
  • Nhiều tác phẩm đoạt giải đa dạng đã được chọn, như máy tính Subleq, trình giả lập GameBoy, patch/diff quine, và mỗi tác phẩm còn có thêm Fun challenge
  • Việc công bố tác phẩm đoạt giải được thực hiện qua live show trên kênh YouTube Our Favorite Universe; kỳ IOCCC30 tiếp theo dự kiến diễn ra vào cuối năm 2026

Điểm bắt đầu

  • Có thể xem link các bài dự thi IOCCC đoạt giải năm 2025 trong danh sách tác phẩm đoạt giải ở cuối trang
  • index.html của mỗi bài đoạt giải cung cấp phần lớn thông tin cần thiết để biên dịch và chạy chương trình đoạt giải đó
  • Bạn có thể đọc mã nguồn đoạt giải để tìm hiểu cách nó hoạt động, và xem phần giải thích của tác giả để biết thêm chi tiết
  • Tất cả tác phẩm đoạt giải của cuộc thi năm nay có thể được tải về dưới dạng compressed tarball

Ghi chú chung về cuộc thi lần này

  • Lượng bài nộp và chất lượng bài nộp của IOCCC29 ở mức gần chạm đỉnh cao lịch sử
  • IOCCC28 là kỳ thi diễn ra sau 4 năm gián đoạn, nên có giả thuyết rằng người tham gia đã có nhiều thời gian hơn để trau chuốt bài dự thi, từ đó tạo ra số lượng bài nộp kỷ lục cùng chất lượng cao hơn thường lệ
  • IOCCC29 là kỳ thi liên tiếp thứ hai sau quãng trống 2020~2024, nhưng số bài nộp vẫn tương đương năm trước và chất lượng tổng thể cũng tiếp tục duy trì ở mức cao
  • Từ lúc kết thúc IOCCC28 đến hạn chót nhận bài mới, nhóm tổ chức đã cẩn thận tài liệu hóa quy trình chấm, chọn tác phẩm đoạt giải, cập nhật website và sản xuất live show của Our Favorite Universe
  • Việc tài liệu hóa này đòi hỏi thêm thời gian và công sức, nhưng kết quả là đã cải thiện toàn diện cách vận hành IOCCC
  • Vài ngày sau khi công bố tác phẩm đoạt giải IOCCC29 trên kênh YouTube Our Favorite Universe, bản ghi của show chính sẽ được tách thành các segment riêng lẻ
  • Ở gần đầu index.html của mỗi bài đoạt giải sẽ có thêm mục Award presentation mới cùng link đến segment YouTube tương ứng
  • Thông tin về các thử thách vui

    • Các tác phẩm đoạt giải năm nay có thêm thử thách vui bên dưới mục “Judges’ remarks
    • Sau khi hiểu được chức năng của một tác phẩm đoạt giải cụ thể, bạn nên thử thách mình với phần đó
    • Một số thử thách dễ hơn những thử thách khác, và trong vài trường hợp sẽ yêu cầu tạo phiên bản thay thế của prog.c hoặc các tệp liên quan
    • Có thử thách yêu cầu viết lời giải thích cho một hạng mục cụ thể
    • Nếu mục “A fun challenge” của một tác phẩm đoạt giải nào đó vẫn ở trạng thái still open, bạn có thể đóng góp bằng cách gửi GitHub pull request
    • Ngay cả khi thử thách đã đóng, nếu bạn cho rằng mình có lời giải tốt hơn, bạn vẫn có thể gửi GitHub pull request
    • Nếu các IOCCC Judges đồng ý đó là lời giải tốt hơn, nó sẽ được xem xét
    • Nếu bạn có cải tiến tốt hơn cho thử thách vui của một tác phẩm đoạt giải, bạn có thể gửi GitHub pull request để IOCCC Judges xem xét
  • Quy tắc và hướng dẫn của cuộc thi lần này

    • Bộ quy tắc cuối cùng áp dụng cho kỳ thi này là 2025 rules phiên bản 29.15 2025-12-02
    • Bộ hướng dẫn cuối cùng áp dụng cho kỳ thi này là 2025 guidelines phiên bản 29.08 2025-12-02
    • Quy tắc và hướng dẫn của IOCCC29 đã được đại tu mạnh tay so với các kỳ trước
    • Nhiều tình nguyện viên đã hỗ trợ IOCCC Judges bằng các chỉnh sửa hữu ích, biên tập lại câu chữ, hợp nhất nội dung và cải thiện bố cục tổng thể
  • Hướng tới cuộc thi tiếp theo

    • IOCCC30 dự kiến khai mạc vào khoảng cuối năm 2026
    • IOCCC30 sẽ diễn ra trong khoảng thời gian tương tự và dự kiến kết thúc vào khoảng cuối quý 1 năm 2027
    • Trong lúc thực hiện các công việc cần thiết để mở màn IOCCC30, nhóm tổ chức cũng dự định tài liệu hóa các quy trình nội bộ giống như khi khép lại IOCCC29
    • Sau khi đăng tải các tác phẩm đoạt giải của IOCCC29 được khoảng 2~3 tuần và xử lý một phần các pull requests ban đầu cho cây thư mục 2025, IOCCC Judges sẽ bước vào kỳ IOCCC vacation
    • Sau khi công bố tác phẩm đoạt giải IOCCC28, cũng đã có kế hoạch IOCCC vacation, nhưng việc sửa lỗi và cải tiến trong mkiocccentry repo tốn rất nhiều thời gian, đến lúc kho ổn định thì đã tới thời điểm khai mạc IOCCC29
    • Lần này, sau khi kết thúc kỳ IOCCC vacation hậu IOCCC29, nhóm sẽ xử lý các mkiocccentry repo PRs
    Quảng cáo

Ghi chú về một số tác phẩm đoạt giải

  • Trong quá trình viết các bài giới thiệu tiềm năng cho những bài dự thi vào vòng cuối của nhóm cuối cùng ở vòng chấm cuối, một số bài đã bị loại ở giai đoạn chót của vòng cuối
  • Với nhiều bài còn lại, mức độ ấn tượng và đánh giá tiếp tục tăng thêm
  • Tác giả của các tác phẩm đoạt giải vừa đến từ những khu vực vốn đã từng có người chiến thắng trước đây, vừa có thêm jingp49 đến từ Taiwan, một khu vực mới tại IOCCC29
  • Ba tác giả mỗi người đoạt giải với ba bài dự thi, tạo nên các Hat-tricks của Hat trick)
  • Một số tác phẩm đoạt giải IOCCC29 đáng chú ý gồm có:
  • Danh sách trên chỉ là một phần trong số rất nhiều tác phẩm đoạt giải xuất sắc của IOCCC29
  • Ghi chú về một số bài dự thi không đoạt giải

    • Có nhiều bài dự thi xuất sắc đã tiến rất sát vòng chọn cuối cùng nhưng vẫn không đoạt giải
    • Công sức mỗi tác giả bỏ vào bài dự thi đều rất đáng trân trọng, nhưng không thể trao giải chỉ dựa trên nỗ lực
    • Mã nguồn đã gửi tới IOCCC29 nhưng không đoạt giải có thể được trau chuốt thêm rồi gửi lại cho IOCCC30
    • Ít nhất một tác phẩm đoạt giải của IOCCC29 là phiên bản cải tiến của mã từng không đoạt giải ở kỳ trước
  • Lời động viên dành cho những người chưa đoạt giải năm nay

    • Các bài dự thi IOCCC năm nay đã được đầu tư rất nhiều công sức, nhưng không thể trao giải cho tất cả
    • Nếu trao giải cho mọi bài dự thi, điều đó sẽ làm mất đi ý nghĩa của những bài được xem là tốt nhất và thực sự xứng đáng đoạt giải
    • Ngay cả một bài vào vòng cuối đủ tốt để trở thành tác phẩm đoạt giải vẫn có thể bị vượt qua bởi một bài tương tự nhưng nhỉnh hơn đôi chút
    • Với những bài được cho là rơi vào trường hợp này, tác giả được khuyến khích gửi phiên bản cải tiến ở kỳ IOCCC tiếp theo
    • Cũng có những bài đã đạt đến đẳng cấp đoạt giải sau nhiều lần chỉnh sửa và gửi lại
    • Ở kỳ IOCCC tiếp theo, bạn cũng có thể thử một kiểu bài dự thi hoàn toàn khác
    • Nếu bạn không định cải tiến rồi gửi lại bài không đoạt giải đó ở kỳ IOCCC tiếp theo, bạn có thể công bố nó
    Quảng cáo

Biên dịch và chạy các tác phẩm đoạt giải

  • Một số trình biên dịch C có thể không cho ra kết quả đủ tốt
  • Nếu trình biên dịch bạn đang dùng hoạt động không ổn, bạn có thể thử biên dịch bằng phiên bản mới nhất của clang hoặc gcc
  • Nếu gặp vấn đề khi biên dịch hoặc chạy tác phẩm đoạt giải, bạn có thể tham khảo các FAQ sau
  • Để biết thêm thông tin về việc gửi bản sửa, bạn có thể tham khảo các FAQ sau

Tác phẩm đoạt giải IOCCC lần thứ 29 năm 2025

1 bình luận

 
Ý kiến trên Hacker News
  • Mã của trình giả lập GameBoy thậm chí còn trông giống hình một chiếc GameBoy. Điên rồ đến mức chỉ biết vỗ tay chậm, và cá nhân tôi thích nhất tác phẩm này trong số các bài dự thi năm nay
    https://github.com/ioccc-src/winner/blob/master/2025/ncw1/pr...
    Tác giả Nick Craig-Wood là người tạo ra rclone

    • Rất vui vì bạn thấy nó thú vị :-) Nếu muốn xem nó được tạo ra như thế nào thì bản gốc ở đây
      https://github.com/ncw/ioccc-gameboy
      Ở đó cũng có đại khái một phiên bản không làm rối mã. Thực ra tôi làm việc chủ yếu ở phía đó, rồi sau đó dùng chương trình để đè bẹp toàn bộ tên biến và nén nó lại cho vừa với hình GameBoy
      Giới hạn kích thước của bài dự thi là phần khó nhất. Bài dự thi IOCCC cho phép tối đa 2503 ký tự không tính khoảng trắng, và tổng kích thước mã là 4KB, thực sự rất chật để nhét cả bộ xử lý Z80 lẫn trình giả lập phần cứng GameBoy vào
      Ban đầu tôi viết một trình giả lập GameBoy hoàn chỉnh bằng C và bắt đầu từ khoảng 6000 ký tự không tính khoảng trắng. Sau đó tôi đã dành khoảng 100 giờ chỉ để ép nó vào giới hạn 2503 ký tự, và có lúc tôi không chắc là nó sẽ nhét vừa nổi
      Tôi đặt mục tiêu là chạy được Tetris. Vì Tetris là game tương đối đơn giản nên tôi loại bỏ những tính năng không cần thiết như cờ half carry của trình giả lập Z80 hay hệ thống windowing trong phần giả lập GameBoy. Tôi cũng hành hạ mã C theo những cách khủng khiếp, và còn làm những trò với implicit int mà chắc cả đời không quên. Vì trình kiểm tra quy tắc của IOCCC được triển khai bằng chương trình C, tôi cũng đã dành thời gian reverse engineer nó để tìm lỗ hổng. Việc phát hiện ra một số toán tử chỉ bị tính là một token đặc biệt hữu ích
      Sau khi đủ nhỏ, tôi còn phải nhét cả game để chạy vào. Tôi đã làm 4 chương trình: một chương trình kiểm thử viết bằng hợp ngữ Z80, một máy tính số pi viết bằng hợp ngữ, cờ ca-rô 3D viết bằng C với gbdk-2020, và một chương trình cờ vua viết bằng C. Tôi cũng phát hiện khá nhiều game mã nguồn mở chạy được trên trình giả lập này nên đã thêm cả downloader khi có thể. Bất ngờ là không có nhiều game dùng phép toán BCD
      Đây là một dự án rất vui
    • https://github.com/ncw/ccforth
      https://github.com/ncw/ccforth/tree/master/examples/gameboy
    • Tuyệt thật! Trong khi nhìn cái này, tôi thì vẫn chỉ ngồi gõ CSS và PHP
    • Việc làm cho mã trông như một bức hình là một mô-típ khá phổ biến trong các cuộc thi lập trình làm rối mã
  • Điều tôi thích nhất là trình giả lập chương trình C 366 byte có thể chạy Linux và Doom [0]
    Máy ảo này triển khai OISC, tức là máy tính đơn lệnh [1]
    [0] https://github.com/ioccc-src/winner/blob/master/2025/cable/p...
    [1] https://github.com/ioccc-src/winner/blob/master/2025/cable/R...

    • Trong vài tuần qua tôi đã làm ngôn ngữ lập trình đơn giản của riêng mình, được biên dịch sang hợp ngữ Linux/amd64
      Tôi cũng có thể viết cả đống routine thư viện chuẩn như mở tệp, chạy lệnh shell, strstr, strcpy, và thành thật mà nói cũng đã triển khai vài thứ không thật sự cần cho quá trình học. Ví dụ, print(getenv("HOME")) hoạt động. Nhưng rồi tôi nhận ra mình cần một chương trình ví dụ để kiểm thử và khoe thành quả
      Thế nên dĩ nhiên chương trình thực sự đầu tiên tôi triển khai là một trình thông dịch brainfuck. Nhờ đó ngôn ngữ của tôi giờ đã gián tiếp đạt tính đầy đủ Turing
      Bản đầu tiên mất 9 phút để in ra đầu ra của chương trình mandelbrot nổi tiếng, nên tôi đã thực hiện nhiều tối ưu hóa, rồi còn thêm hỗ trợ câu lệnh switch/case để tăng tốc. Giờ nó có thể tạo cùng đầu ra trong 2 phút, nên vẫn còn chỗ để cải thiện nhưng cũng đã tiến bộ khá nhiều
      Tôi rất thích kiểu mánh gian lận là triển khai một ngôn ngữ khác bên trong chính ngôn ngữ của mình. Tất nhiên tất cả chỉ để vui và học hỏi, chứ không phải làm ra để bất kỳ ai, kể cả chính tôi, dùng một cách nghiêm túc
      https://github.com/skx/s-lang
    • Wow! Và họ đã triển khai một biến thể SUBLEQ đầy đủ Turing theo cách rất thú vị

      VM này triển khai OISC, tức One Instruction Set Computer. Lệnh này nhận ba toán hạng 32 bit có dấu a, b, c, và thực thi chương trình trên bộ nhớ m[] như sau:
      1 PC (program counter) bắt đầu từ 0
      2 Nạp lệnh tiếp theo, tức ba toán hạng 32 bit có dấu a, b, c
      3 Nếu bất kỳ toán hạng nào có bit thấp được đặt, thì xóa bit đó và thay toán hạng tương ứng bằng m[operand], tức giá trị giải tham chiếu tại địa chỉ đó
      4 Đặt m[b] = m[b] - m[a]
      5 Nếu m[b] nhỏ hơn hoặc bằng 0 thì đặt PC thành c, nếu không thì tăng PC thêm 3 word
      6 Quay lại bước 2

    • Tôi nghĩ mình thích ý tưởng này, nhưng Eternal Software Initiative được liên kết [1] thì hơi rối. Có nhiều phiên bản mô tả lệnh để giải mã nó và chúng mâu thuẫn với nhau
      Ở đây ghi là Set m[b] = m[b] - m[a]
      Sau đó nó dẫn tới phần triển khai tham chiếu trên GitHub [2], nơi nói rằng chỉ cần ghi chú trên khăn giấy [3]. Nó dùng cách chia mọi giá trị đọc được cho 4, và phần triển khai tham chiếu [4] cũng xác nhận điều này. Nhưng không rõ vì sao lại chọn 4 thay vì 2. Trông như đang lãng phí một bit. Tôi thắc mắc liệu bit đó có thực sự cần thiết hay được để dành cho mở rộng sau này
      Có vẻ bản triển khai ban đầu không chia cho 4 và điều đó được thêm vào sau, nhưng ngoài việc làm cho sinh mã LLVM dễ hơn một chút thì tôi không hiểu tại sao lại cần. Để xác minh liệu hệ thống được mô tả có bất khả thi nếu không chia cho 4 hay không, có lẽ phải lần theo rất nhiều ví dụ. Có lẽ vì chỉ có thể truy cập địa chỉ chẵn và PC lại tăng 3 mỗi lần, nên việc tham chiếu tới vị trí mã chắc chắn khá phiền toái
      Phần triển khai tham chiếu sẽ hoạt động một cách kỳ diệu khi truy cập vị trí 64 và ghi đè các vị trí 64~67 bằng thời gian hiện tại. Mô tả trên khăn giấy có nhắc tới nhưng mô tả ở trang chính thì không
      Cả hai mô tả đều nhắc đến địa chỉ -1 ma thuật, nên thật lạ khi họ không triển khai đồng hồ UTC phụ thuộc vào triển khai bằng địa chỉ âm thay vì phá hỏng bộ nhớ vốn có thể dùng tự do
      Cả hai mô tả cũng nhắc đến quy trình ngắt timer định kỳ, và điều này cũng đáng tiếc. Nó tái sử dụng địa chỉ 0 làm vị trí trình xử lý ngắt, còn 1 là PC đã lưu, nên ngay sau khi chương trình bắt đầu phải ghi đè vị trí 0 là điểm vào ban đầu
      [1] https://eternal-software.org/
      [2] https://github.com/adriancable/eternal
      [3] https://github.com/adriancable/eternal/blob/main/docs/napkin...
      [4] https://github.com/adriancable/eternal/blob/main/vm/vm.c
    • Tôi đã tải về và build thử, và có thể tự tin nói đây là thứ ấn tượng nhất tôi từng thấy cho đến giờ
    • Video ở đây
      https://www.youtube.com/live/MoWCwZx1Swc?si=eIOlRsKWNKRVRZeB...
  • Phòng khi có ai thắc mắc: IOCCC trong phần hướng dẫn cho phép dùng LLM một cách rõ ràng
    "IOCCC has a rich history of remarkable winning entries created by authors who skillfully employed various techniques (often their own tools) to develop their code."

    • Tôi thiên về phía không AI, nhưng trường hợp này thì khá thú vị. Đặc biệt là vì trên mạng không có nhiều mã C làm rối và LLM cũng khó suy ra ý đồ từ mã thực tế. Tôi tự hỏi đã có ai từng thấy bài dự thi nào có sự trợ giúp của LLM chưa
      Chiều ngược lại cũng thú vị. Liệu LLM có thể đoán đúng chức năng của mã bị làm rối đến mức nào?
    • Điều này chủ yếu ảnh hưởng đến ban giám khảo. Về cơ bản họ tự mở cửa cho khả năng bị dội bom bởi mã tệ, nhưng với tính chất của cuộc thi này, tôi nghĩ giám khảo sẽ phân biệt rất tốt giữa mã thú vị và mã chất lượng thấp
      Tôi thấy IOCCC chấp nhận những đoạn mã có thể đã được tạo ra với sự trợ giúp của máy móc là điều tốt. Nhờ vậy giá trị của những tác phẩm đoạt giải hoàn toàn làm thủ công lại càng nổi bật hơn
    • Vậy giờ nó thành cuộc thi thể dục LLM rồi à?
    • Nếu AI được tính là một "công cụ" thì quy tắc 7 trở nên tự mâu thuẫn
      https://www.ioccc.org/2025/rules.html
      Có vẻ điều họ nói ở đây là các trình sinh mã tùy chỉnh. Họ còn nhắc rõ đến một "lịch sử phong phú", mà nếu cách diễn đạt đó bao gồm cả thời kỳ trước khi có AI thì tôi không hiểu vì sao lại phải xem đó là đang chỉ AI
  • Bản thân website cũng bị làm rối nên việc tìm mã nguồn C hoàn toàn không dễ chút nào

    • Cứ vào thẳng https://www.ioccc.org/2025/#inventory là được
    • Rất khó để điều hướng. Không thể nắm được cuộc thi này là gì, trông như được làm ra với giả định là bạn đã biết sẵn rồi
    • Câu đầu tiên dẫn đến phần danh sách tác phẩm đoạt giải, và ở góc trên bên phải của mỗi tác phẩm có liên kết C code
  • Tôi ước gì Underhanded C Contest quay trở lại. Không phải để hạ thấp người tham gia Obfuscated C, nhưng với tôi bên đó thú vị hơn nhiều

  • Ở đây có tham chiếu đến Frieren [1]!
    https://www.ioccc.org/2025/yang2/index.html
    Một trong các nhân vật chính là Fern, và gần như chỉ dùng Zoltraak, loại ma pháp tấn công phổ biến
    [1] https://en.wikipedia.org/wiki/Frieren

  • Trời ơi, bản triển khai Game Boy Game of Life mà tôi làm lại có mặt trong một tác phẩm đoạt giải!

    • Sau khi làm trình giả lập, tôi đã lục GitHub để tìm một trò chơi có thể chạy trong giới hạn 32KB. Tôi tìm thấy bản của bạn, cảm ơn nhé :-) Tôi đã thêm vào script ./try.sh một tùy chọn để người dùng có thể tải từ GitHub về và thử nghiệm
  • Năm 2000 tôi đi phỏng vấn kỳ thực tập đầu tiên, là vị trí gia nhập một nhóm lập trình viên C. Người phỏng vấn đưa tôi xem một tác phẩm đoạt giải cũ rồi ra khỏi phòng, bảo tôi thử review đoạn mã đó. Khoảng 5 phút sau họ quay lại và hỏi
    – Thế nào rồi?
    – Xin lỗi, chắc tôi đã làm phí thời gian của mọi người. Tôi hoàn toàn không hiểu gì cả
    Thế là tất cả cùng phá lên cười và nói hãy bắt đầu quy trình tuyển dụng
    Tôi tự hỏi giờ họ còn trêu thực tập sinh kiểu này không. Nghĩ lại vẻ bối rối của mình hồi đó giờ vẫn thấy buồn cười

  • Ôôô! IOCCC quay lại rồi à!
    Gửi thật nhiều tình cảm đến ban tổ chức <3 <3 <3 Cảm ơn vì đã giữ cho IOCCC tiếp tục tồn tại, mong là nó sẽ không bao giờ biến mất nữa

  • Khoan, tôi hơi không hiểu
    Obfuscated C Code Contest thì được, còn Capture the Flag thì không được à? Vì AI sao?
    https://twit.tv/posts/tech/ai-disrupts-capture-flag-what-mea...

    • Capture the Flag có mục tiêu rõ ràng, còn Obfuscated C Contest thì không. Tôi hiểu chuyện AI tiến bộ trong các cuộc thi hướng mục tiêu, nhưng với một cuộc thi mở có yếu tố cảm quan nghệ thuật, thì tôi không rõ nên xem điều gì là tiến bộ
      Nếu câu hỏi là "chẳng phải có thể nghĩ ra một ý tưởng khéo léo rồi bảo AI triển khai nó sao cho phù hợp với các ràng buộc của IOCCC à?", thì theo tôi các công cụ AI hiện tại vẫn chưa làm được điều đó ở mức mà giám khảo con người sẽ thấy là đáng giá