forked from 8090-inc/top-coder-challenge
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patheval.sh
More file actions
executable file
Β·208 lines (176 loc) Β· 7.57 KB
/
eval.sh
File metadata and controls
executable file
Β·208 lines (176 loc) Β· 7.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/bin/bash
# Black Box Challenge Evaluation Script
# This script tests your reimbursement calculation implementation against 1,000 historical cases
set -e
echo "π§Ύ Black Box Challenge - Reimbursement System Evaluation"
echo "======================================================="
echo
# Check if jq is available
if ! command -v jq &> /dev/null; then
echo "β Error: jq is required but not installed!"
echo "Please install jq to parse JSON files:"
echo " macOS: brew install jq"
echo " Ubuntu/Debian: sudo apt-get install jq"
echo " CentOS/RHEL: sudo yum install jq"
exit 1
fi
# Check if bc is available for floating point arithmetic
if ! command -v bc &> /dev/null; then
echo "β Error: bc (basic calculator) is required but not installed!"
echo "Please install bc for floating point calculations:"
echo " macOS: brew install bc"
echo " Ubuntu/Debian: sudo apt-get install bc"
echo " CentOS/RHEL: sudo yum install bc"
exit 1
fi
# Check if run.sh exists
if [ ! -f "run.sh" ]; then
echo "β Error: run.sh not found!"
echo "Please create a run.sh script that takes three parameters:"
echo " ./run.sh <trip_duration_days> <miles_traveled> <total_receipts_amount>"
echo " and outputs the reimbursement amount"
exit 1
fi
# Make run.sh executable
chmod +x run.sh
# Check if public cases exist
if [ ! -f "public_cases.json" ]; then
echo "β Error: public_cases.json not found!"
echo "Please ensure the public cases file is in the current directory."
exit 1
fi
echo "π Running evaluation against 1,000 test cases..."
echo
# Extract all test data upfront in a single jq call for better performance
echo "Extracting test data..."
test_data=$(jq -r '.[] | "\(.input.trip_duration_days):\(.input.miles_traveled):\(.input.total_receipts_amount):\(.expected_output)"' public_cases.json)
# Convert to arrays for faster access (compatible with bash 3.2+)
test_cases=()
while IFS= read -r line; do
test_cases+=("$line")
done <<< "$test_data"
num_cases=${#test_cases[@]}
# Initialize counters and arrays
successful_runs=0
exact_matches=0
close_matches=0
total_error="0"
max_error="0"
max_error_case=""
results_array=()
errors_array=()
# Process each test case
for ((i=0; i<num_cases; i++)); do
if [ $((i % 100)) -eq 0 ]; then
echo "Progress: $i/$num_cases cases processed..." >&2
fi
# Extract test case data from pre-loaded array
IFS=':' read -r trip_duration miles_traveled receipts_amount expected <<< "${test_cases[i]}"
# Run the user's implementation
if script_output=$(./run.sh "$trip_duration" "$miles_traveled" "$receipts_amount" 2>/dev/null); then
# Check if output is a valid number
output=$(echo "$script_output" | tr -d '[:space:]')
if [[ $output =~ ^-?[0-9]+\.?[0-9]*$ ]]; then
actual="$output"
# Calculate absolute error using bc
error=$(echo "scale=10; if ($actual - $expected < 0) -1 * ($actual - $expected) else ($actual - $expected)" | bc)
# Store result in memory array
results_array+=("$((i+1)):$expected:$actual:$error:$trip_duration:$miles_traveled:$receipts_amount")
successful_runs=$((successful_runs + 1))
# Check for exact match (within $0.01)
if (( $(echo "$error < 0.01" | bc -l) )); then
exact_matches=$((exact_matches + 1))
fi
# Check for close match (within $1.00)
if (( $(echo "$error < 1.0" | bc -l) )); then
close_matches=$((close_matches + 1))
fi
# Update total error
total_error=$(echo "scale=10; $total_error + $error" | bc)
# Track maximum error
if (( $(echo "$error > $max_error" | bc -l) )); then
max_error="$error"
max_error_case="Case $((i+1)): $trip_duration days, $miles_traveled miles, \$$receipts_amount receipts"
fi
else
errors_array+=("Case $((i+1)): Invalid output format: $output")
fi
else
# Capture stderr for error reporting
error_msg=$(./run.sh "$trip_duration" "$miles_traveled" "$receipts_amount" 2>&1 >/dev/null | tr -d '\n')
errors_array+=("Case $((i+1)): Script failed with error: $error_msg")
fi
done
# Calculate and display results
if [ $successful_runs -eq 0 ]; then
echo "β No successful test cases!"
echo ""
echo "Your script either:"
echo " - Failed to run properly"
echo " - Produced invalid output format"
echo " - Timed out on all cases"
echo ""
echo "Check the errors below for details."
else
# Calculate average error
avg_error=$(echo "scale=2; $total_error / $successful_runs" | bc)
# Calculate percentages
exact_pct=$(echo "scale=1; $exact_matches * 100 / $successful_runs" | bc)
close_pct=$(echo "scale=1; $close_matches * 100 / $successful_runs" | bc)
echo "β
Evaluation Complete!"
echo ""
echo "π Results Summary:"
echo " Total test cases: $num_cases"
echo " Successful runs: $successful_runs"
echo " Exact matches (Β±\$0.01): $exact_matches (${exact_pct}%)"
echo " Close matches (Β±\$1.00): $close_matches (${close_pct}%)"
echo " Average error: \$${avg_error}"
echo " Maximum error: \$${max_error}"
echo ""
# Calculate score (lower is better)
score=$(echo "scale=2; $avg_error * 100 + ($num_cases - $exact_matches) * 0.1" | bc)
echo "π― Your Score: $score (lower is better)"
echo ""
# Provide feedback based on exact matches
if [ $exact_matches -eq $num_cases ]; then
echo "π PERFECT SCORE! You have reverse-engineered the system completely!"
elif [ $exact_matches -gt 950 ]; then
echo "π₯ Excellent! You are very close to the perfect solution."
elif [ $exact_matches -gt 800 ]; then
echo "π₯ Great work! You have captured most of the system behavior."
elif [ $exact_matches -gt 500 ]; then
echo "π₯ Good progress! You understand some key patterns."
else
echo "π Keep analyzing the patterns in the interviews and test cases."
fi
echo ""
echo "π‘ Tips for improvement:"
if [ $exact_matches -lt $num_cases ]; then
echo " Check these high-error cases:"
# Sort results by error (descending) in memory and show top 5
IFS=$'\n' high_error_cases=($(printf '%s\n' "${results_array[@]}" | sort -t: -k4 -nr | head -5))
for result in "${high_error_cases[@]}"; do
IFS=: read -r case_num expected actual error trip_duration miles_traveled receipts_amount <<< "$result"
printf " Case %s: %s days, %s miles, \$%s receipts\n" "$case_num" "$trip_duration" "$miles_traveled" "$receipts_amount"
printf " Expected: \$%.2f, Got: \$%.2f, Error: \$%.2f\n" "$expected" "$actual" "$error"
done
fi
fi
# Show errors if any
if [ ${#errors_array[@]} -gt 0 ]; then
echo
echo "β οΈ Errors encountered:"
for ((j=0; j<${#errors_array[@]} && j<10; j++)); do
echo " ${errors_array[j]}"
done
if [ ${#errors_array[@]} -gt 10 ]; then
echo " ... and $((${#errors_array[@]} - 10)) more errors"
fi
fi
echo
echo "π Next steps:"
echo " 1. Fix any script errors shown above"
echo " 2. Ensure your run.sh outputs only a number"
echo " 3. Analyze the patterns in the interviews and public cases"
echo " 4. Test edge cases around trip length and receipt amounts"
echo " 5. Submit your solution via the Google Form when ready!"