ICSC Qualification Round 2025 — Solutions
Student name: ____________________
Candidate no.: ____________________
Date: ____________________
Problem A — Neural Network Components
Final Answers:
- w(1)21 = weight (input #2 → hidden neuron #1)
- Σ = weighted sum node (z = Σ w_i x_i + b)
- f = activation function
- Box A = hidden layer
- Box B = output layer
- ■ = predicted output
Explanation: Inputs are multiplied by weights, summed with bias (Σ), then activation f is applied.
Box A (hidden layer) transforms input features, Box B (output layer) produces the prediction ■.
Problem B — Cake Calculator
Formula:
cakes = min(floor(flour/100), floor(sugar/50))
remaining_flour = flour - 100 * cakes
remaining_sugar = sugar - 50 * cakes
Example: flour=280, sugar=160 → cakes=2, flour left=80, sugar left=60
Python code:
def cake_calculator(flour: int, sugar: int):
if flour <= 0 or sugar <= 0:
raise ValueError("flour and sugar must be > 0")
cakes = min(flour // 100, sugar // 50)
return [cakes, flour - 100*cakes, sugar - 50*cakes]
Problem C — School Messaging App
C1: Variable-length codes assign short codes to frequent characters and long codes to rare ones.
This lowers the average bits per character vs fixed-length coding.
C2: Entropy calculation:
H = -Σ p log2 p ≈ 3.324 bits/character
Final: H ≈ 3.324 bits/char
C3: Average Fano length:
L ≈ 3.48 bits/character
Efficiency = H / L ≈ 95.5%
Final: Fano code is ~95.5% efficient, close to optimal.
Problem D — Word Search Puzzle
Algorithm:
1. Place words in random positions & 8 directions (→, ←, ↑, ↓, diagonals).
2. Allow overlap if letters match.
3. If placement invalid, retry up to many times.
4. Fill empty cells with random A–Z letters.
Python code:
import random, string
DIRS = [(0,1),(0,-1),(1,0),(-1,0),(1,1),(1,-1),(-1,1),(-1,-1)]
def create_crossword(words):
n=10
grid=[['' for _ in range(n)] for _ in range(n)]
words=[[Link]() for w in words]
[Link](key=lambda x:-len(x))
def can_place(r,c,dr,dc,w):
for k,ch in enumerate(w):
rr,cc=r+dr*k,c+dc*k
if not (0<=rr<n and 0<=cc<n): return False
if grid[rr][cc] != '' and grid[rr][cc] != ch: return False
return True
def do_place(r,c,dr,dc,w):
for k,ch in enumerate(w):
grid[r+dr*k][c+dc*k]=ch
for w in words:
placed=False;tries=0
while not placed and tries<1000:
dr,dc=[Link](DIRS)
r=[Link](n); c=[Link](n)
if can_place(r,c,dr,dc,w):
do_place(r,c,dr,dc,w); placed=True
tries+=1
if not placed: raise RuntimeError(f"Could not place {w}")
for r in range(n):
for c in range(n):
if grid[r][c]=='':
grid[r][c]=[Link](string.ascii_uppercase)
return grid
Problem E — Proof: NAND is Functionally Complete
Definition: a ↑ b = NAND(a,b) = NOT(a AND b)
1) NOT: ¬a = a ↑ a
2) AND: a AND b = (a ↑ b) ↑ (a ↑ b)
3) OR: a OR b = (a ↑ a) ↑ (b ↑ b)
Conclusion: Since we can construct NOT, AND, OR with NAND, it is functionally complete.