Bỏ qua để đến nội dung

Vì sao bài Scratch chạy đúng mà máy chấm Tin học trẻ báo sai?

Một số thầy cô thắc mắc rằng khi làm bài Scratch, chạy thử với số liệu của đề thì thấy ra đúng, nhưng nộp lên máy chấm lại bị sai kết quả, lỗi chạy hoặc quá thời gian. Bài viết này giải thích máy chấm chạy bài Scratch như thế nào, rồi đi qua 8 lỗi hay gặp nhất. Mỗi lỗi đều đã được chúng tôi chạy thử bằng chính bộ chạy Scratch mà hệ thống thi sử dụng.

Vòng thi toàn quốc (và các vòng thi thử) diễn ra trên hệ thống tinhoctre.vn, xây dựng trên nền VNOJ của cộng đồng Olympic Tin học Việt Nam (VNOI). Bài Scratch được chạy bằng scratch-run, một công cụ mã nguồn mở của VNOI. Khác với lúc làm bài trên máy, scratch-run không có sân khấu, không có màn hình:

Khối lệnhTrên máy của thí sinh (bấm cờ xanh)Trên máy chấm
hỏi [] và đợiHiện ô để thí sinh gõĐọc một dòng trong file dữ liệu
hỏi [read_token] và đợiHiện ô để thí sinh gõĐọc một số (một từ), dù nhiều số nằm chung một dòng
nói []Hiện bong bóng, bong bóng sau đè bong bóng trướcIn ra một dòng kết quả
nghĩ []Hiện bong bóng suy nghĩIn ra nhưng không xuống dòng

Kết quả in ra được so với đáp án của từng test. Chỉ cần thừa một chữ, thiếu một dấu cách hay dính hai dòng vào nhau là test đó bị chấm sai.

Hai điều quan trọng rút ra từ bảng trên:

  • Máy chấm không gõ từng số như thí sinh. Dữ liệu nằm sẵn trong file, đúng như mô tả ở mục “Dữ liệu nhập vào” của đề, kể cả khi nhiều số nằm trên cùng một dòng.
  • Máy chấm không “nhìn” sân khấu. Bong bóng, hình vẽ, âm thanh đều không được tính. Chỉ có những gì nói [] và nghĩ [] in ra.

Lỗi 1. Đề cho nhiều số trên một dòng, nhưng thí sinh đọc từng dòng

Phần tiêu đề “Lỗi 1. Đề cho nhiều số trên một dòng, nhưng thí sinh đọc từng dòng”

Đề ghi: “Một dòng chứa hai số a và b, cách nhau một dấu cách”. Thí sinh viết:

khi bấm vào @greenFlag
hỏi [] và đợi
đặt [a v] thành (trả lời)
hỏi [] và đợi
đặt [b v] thành (trả lời)
nói ((a) + (b))

Trên máy, thí sinh gõ 3, Enter, rồi 5, Enter và thấy kết quả 8. Nhưng file test là 3 5 trên một dòng: khối hỏi [] và đợi đầu tiên lấy cả dòng 3 5, khối thứ hai không còn gì để đọc. Máy chấm báo lỗi chạy (hết dữ liệu vào).

Cách sửa: đặt câu hỏi là read_token (viết đúng như vậy, chữ thường, có dấu gạch dưới). Khi đó mỗi lần hỏi đọc đúng một số, dù dữ liệu nằm trên một dòng hay nhiều dòng:

khi bấm vào @greenFlag
hỏi [read_token] và đợi
đặt [a v] thành (trả lời)
hỏi [read_token] và đợi
đặt [b v] thành (trả lời)
nói ((a) + (b))

Chúng tôi đã chạy thử: với cả hai cách cho dữ liệu (3 5 hoặc 3 và 5 trên hai dòng), chương trình này đều in 8.

Thí sinh thêm liên tục ở cuối, hoặc chương trình còn một kịch bản liên tục chạy song song (ví dụ cho nhân vật nhảy múa):

khi bấm vào @greenFlag
hỏi [read_token] và đợi
đặt [a v] thành (trả lời)
hỏi [read_token] và đợi
đặt [b v] thành (trả lời)
nói ((a) + (b))
liên tục
end

Trên máy, thí sinh thấy kết quả rồi tự bấm nút dừng. Máy chấm thì đợi chương trình kết thúc, đến hết giờ thì báo quá thời gian. Tệ hơn, kết quả đã nói cũng bị mất: scratch-run gom kết quả lại và chỉ in ra khi chương trình kết thúc (hoặc khi gặp khối hỏi tiếp theo). Khi chạy thử, chương trình trên không in ra gì cả.

Cách sửa: bỏ hết các khối liên tục và các kịch bản không liên quan đến bài. Nếu muốn chắc chắn, đặt dừng lại [tất cả v] ở cuối chương trình (chúng tôi đã thử: kết quả vẫn được in đầy đủ).

nói (kết hợp [Tổng là ] ((a) + (b)))

Trên máy trông rất “lịch sự”, nhưng máy chấm nhận được Tổng là 8 trong khi đáp án là 8, nên test bị sai. Câu hỏi trong khối hỏi thì không sao: hỏi [Nhập a:] và đợi vẫn đọc đúng dữ liệu và câu “Nhập a:” không bị in ra kết quả.

Cách sửa: chỉ nói [] đúng những gì mục “Kết quả ghi ra màn hình” của đề yêu cầu.

đợi (1) giây

Khối đợi (1) giây trên máy chấm chờ thật 1 giây. Phần lớn bài có giới hạn 1 giây, nên chỉ một khối đợi là đủ quá thời gian. Các khối có thời gian khác như lướt trong (1) giây tới điểm x: (0) y: (0) cũng nên tránh.

Riêng nói [] trong (2) giây thì máy chấm không chờ (đã chạy thử), nhưng để an toàn và dễ đọc, nên dùng nói [] bình thường.

Lỗi 5. Hỏi nhiều hơn số dữ liệu đề cho

Phần tiêu đề “Lỗi 5. Hỏi nhiều hơn số dữ liệu đề cho”

Thí sinh thêm một khối hỏi “cho chắc”, hoặc vòng lặp đọc dữ liệu chạy thừa một lần. Trên máy, thí sinh vẫn gõ được thêm. Trên máy chấm, file dữ liệu đã hết nên bài bị lỗi chạy ở khối hỏi thừa đó.

Cách sửa: đếm lại đề cho bao nhiêu số, vòng lặp đọc dữ liệu chạy đúng bấy nhiêu lần.

Đề yêu cầu in các số cách nhau một dấu cách, thí sinh dùng khối danh sách:

nói (kết quả :: list)

Scratch có một quy tắc lạ: nếu mọi phần tử chỉ có một kí tự, các phần tử được ghép liền nhau; còn nếu có phần tử dài hơn thì mới có dấu cách. Chạy thử: danh sách 1, 2, 3 in ra 123, còn danh sách 10, 2, 3 in ra 10 2 3. Bài có thể đúng với ví dụ của đề mà sai ở test khác.

Cách sửa: tự ghép chuỗi kết quả bằng vòng lặp, thêm dấu cách giữa các số; hoặc nói từng phần tử nếu đề yêu cầu mỗi số một dòng. Trong chương trình dưới đây, ô trống của khối kết hợp thứ hai chứa một dấu cách.

đặt [chuỗi kết quả v] thành (phần tử thứ (1) của [kết quả v])
đặt [i v] thành (2)
lặp lại ((kích thước của [kết quả v]) - (1))
đặt [chuỗi kết quả v] thành (kết hợp (chuỗi kết quả) (kết hợp [ ] (phần tử thứ (i) của [kết quả v])))
thay đổi [i v] một lượng (1)
end
nói (chuỗi kết quả)

Máy tính lưu số thập phân không chính xác tuyệt đối, và Scratch in số rất lớn theo kiểu khoa học. Chạy thử:

Phép tínhScratch in ra
((0.1) + (0.2))0.30000000000000004
((10) / (4))2.5
((100000000000) * (100000000000))1e+22

Cách sửa:

  • Khi đề yêu cầu làm tròn, làm tròn đúng như đề nói (ví dụ làm tròn đến 2 chữ số thập phân: ((làm tròn ((x) * (100))) / (100))).
  • Khi chia lấy phần nguyên, dùng ([làm tròn xuống v] của ((a) / (b))), đừng để kết quả có phần thập phân.
  • Scratch chỉ tính đúng số nguyên đến khoảng 15–16 chữ số. Đề cho số lớn hơn thì phải xử lý như một chuỗi chữ số, không cộng nhân trực tiếp.

Lỗi 8. Phép so sánh không phân biệt chữ hoa, chữ thường

Phần tiêu đề “Lỗi 8. Phép so sánh không phân biệt chữ hoa, chữ thường”
nếu <(trả lời) = [abc]> thì
nói [CÓ]
end

Chạy thử: gõ ABC chương trình vẫn nói CÓ. Trong Scratch, A và a được coi là bằng nhau khi so sánh, và khối <[] chứa ký tự []?> cũng vậy. Phần lớn đề Bảng A không cần phân biệt hoa thường, nhưng nếu đề có câu như “chữ hoa và chữ thường là khác nhau” thì thí sinh cần đặc biệt cẩn thận: đếm chữ hoa, đổi chữ hoa sang chữ thường… sẽ cho kết quả sai nếu dựa vào phép so sánh.

  1. Đọc lại mục “Dữ liệu nhập vào”: các số nằm trên một dòng hay mỗi số một dòng? Đọc số thì dùng read_token, đọc cả câu thì dùng khối hỏi bình thường.
  2. Số khối hỏi (kể cả trong vòng lặp) đúng bằng số dữ liệu đề cho.
  3. Chỉ nói [] đúng kết quả, không kèm chữ. Đề cần nhiều dòng thì nói nhiều lần.
  4. Không còn khối liên tục, đợi (1) giây hay kịch bản thừa.
  5. Kết quả là số nguyên thì không để lọt phần thập phân. Đề yêu cầu làm tròn thì làm tròn đúng cách.
  6. Thử với test lớn nhất đề cho (ví dụ N = 10⁶) để xem có chạy kịp không. Lưu ý trình soạn Scratch trên máy chạy chậm hơn máy chấm rất nhiều, nên hãy giữ phím Shift khi bấm cờ xanh để bật chế độ chạy nhanh (Turbo).
  7. Lưu đúng tên file đề yêu cầu (ví dụ TONGHAI.sb3), và chọn đúng ngôn ngữ Scratch trước khi tải file lên. Theo hướng dẫn của Ban Tổ chức, bài Scratch chỉ được nộp bằng file, và quên chọn ngôn ngữ là lý do hay gặp nhất khiến nộp bài bị lỗi.

Vì sao trên máy chỉ thấy dòng kết quả cuối cùng?

Phần tiêu đề “Vì sao trên máy chỉ thấy dòng kết quả cuối cùng?”

Đây là thắc mắc liên quan mà thầy cô hay gặp khi chấm thử bằng trình soạn Scratch. Trên sân khấu, nhân vật chỉ có một bong bóng: mỗi lần nói [] mới sẽ đè lên lần trước, và khối hỏi tiếp theo cũng xóa bong bóng. Một bài in hai dòng 0 10 và 1 sẽ chỉ còn hiện 1; bài nói kết quả rồi hỏi dữ liệu tiếp sẽ trông như “không làm gì”. Chương trình không bị đứng, chỉ là sân khấu không hiển thị được nhiều dòng. Trên máy chấm, từng lần nói đều được in đủ.

Muốn xem đủ các dòng khi luyện tập, có thể tạm thêm kết quả vào một danh sách và hiện danh sách đó lên sân khấu, nhưng nhớ xóa phần này trước khi nộp.


Các kết quả “chạy thử” trong bài được kiểm tra bằng scratch-run 0.1.7, bộ chạy Scratch của VNOI dùng trên hệ thống thi. Hướng dẫn nộp bài lấy từ Hướng dẫn tham gia hệ thống thi Hội thi Tin học trẻ toàn quốc.