-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbatch.sh
216 lines (182 loc) · 7.1 KB
/
batch.sh
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
209
210
211
212
213
214
215
216
#!/bin/bash -e
# https://stackoverflow.com/a/246128
export SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
MODE_WEBPBN="webpbn"
MODE_NONOGRAMS="nonograms.org"
MODE_STAT="stat"
for i in "$@"; do
if [[ ${i} == "--help" ]] || [[ ${i} == "-h" ]]; then
EXAMPLE_LOG_FILE="benches/batch.log"
echo "Batch mode for nonogram solver"
echo "Examples: "
echo " Run all http://webpbn.com puzzles till id=35000"
echo " $ nohup bash -e $0 $MODE_WEBPBN {1..35000} 2>&1 > $EXAMPLE_LOG_FILE &"
echo " NOTE: you can find maximum available puzzle ID with the command"
echo " $ curl -s https://webpbn.com/find.cgi --data 'order=1&perpage=5&search=1' | grep -oP 'play.cgi\?id=\K\d+' | sort -unr"
echo
echo " Run all http://nonograms.org puzzles till id=31000"
echo " $ nohup bash -e $0 $MODE_NONOGRAMS {1..31000} 2>&1 > $EXAMPLE_LOG_FILE &"
echo " NOTE: you can find maximum available puzzle ID with the command"
echo " $ curl -s 'https://www.nonograms.org/search/p/10000?sort=6' | grep -oP 'nonogramprint/i/\K\d+' | sort -unr"
echo
echo " Run statistic on collected log file"
echo " $ bash $0 $MODE_STAT $EXAMPLE_LOG_FILE 0.1 --details"
exit
fi
done
function run_single_webpbn() {
local puzzle_id=$1
local fmt=olsak
local path=${SCRIPT_DIR}/puzzles/${puzzle_id}.${fmt}
if [[ ! -f ${path} ]]; then
echo "File not found locally. Download into $path"
wget --timeout=10 -qO- "https://webpbn.com/export.cgi" --post-data "id=$puzzle_id&fmt=$fmt&go=1" > ${path}
if [[ $? -ne 0 ]]; then
echo "Failed to download puzzle #$puzzle_id: timeout" >&2
fi
fi
if cat ${path} | grep -q ': rows'; then
echo "Solving WEBPBN's puzzle #$puzzle_id (http://webpbn.com/$puzzle_id) ..."
/usr/bin/time -f 'Total: %U' target/release/nonogrid ${path} --timeout=3600 --max-solutions=2 2>&1 1>${SCRIPT_DIR}/solutions/${puzzle_id}
else
echo "No valid file for puzzle #$puzzle_id" >&2
local lines=$(cat ${path} | wc -l)
if [[ ${lines} -lt 2 ]]; then
echo "Removing empty file $path"
rm -f ${path}
fi
fi
}
function find_nonogram_url() {
local number=$1
local code_org_black=$(wget --spider -S http://www.nonograms.org/nonograms/i/${number} 2>&1 | grep "HTTP/" | awk '{print $2}')
local code_org_color=$(wget --spider -S http://www.nonograms.org/nonograms2/i/${number} 2>&1 | grep "HTTP/" | awk '{print $2}')
local code_ru_black=$(wget --spider -S http://www.nonograms.ru/nonograms/i/${number} 2>&1 | grep "HTTP/" | awk '{print $2}')
local code_ru_color=$(wget --spider -S http://www.nonograms.ru/nonograms2/i/${number} 2>&1 | grep "HTTP/" | awk '{print $2}')
if [[ ${code_org_black} -eq "200" ]]; then
echo http://www.nonograms.org/nonograms/i/${number}
elif [[ ${code_org_color} -eq "200" ]]; then
echo http://www.nonograms.org/nonograms2/i/${number}
elif [[ ${code_ru_black} -eq "200" ]]; then
echo http://www.nonograms.ru/nonograms/i/${number}
elif [[ ${code_ru_color} -eq "200" ]]; then
echo http://www.nonograms.ru/nonograms2/i/${number}
fi
}
function run_single_nonogram() {
local puzzle_id=$1
local path=${SCRIPT_DIR}/puzzles-norg/${puzzle_id}.js
if [[ ! -f ${path} ]]; then
echo "File not found locally. Download into $path"
local url=$(find_nonogram_url ${puzzle_id})
if [[ ! ${url} ]]; then
echo "Not found URL for puzzle #$puzzle_id" >&2
return
fi
wget --timeout=10 -qO- ${url} > ${path}
if [[ $? -ne 0 ]]; then
echo "Failed to download puzzle #$puzzle_id: timeout" >&2
fi
fi
local lines=$(cat ${path} | wc -l)
if [[ ${lines} -lt 1 ]]; then
echo "Removing empty file $path"
rm -f ${path}
else
sed -n '/^var d=.\+;/p' -i ${path}
echo "Solving NORG puzzle #$puzzle_id ${url}..."
/usr/bin/time -f 'Total: %U' target/release/nonogrid ${path} --timeout=3600 --max-solutions=2 2>&1 1>${SCRIPT_DIR}/solutions-norg/${puzzle_id}
#local instructions=$(valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes --callgrind-out-file=callgrind.norg target/release/nonogrid ${path} 2>&1 | tail -1 | awk '{print $4}' | sed 's/,//g')
#echo "Result: $instructions $puzzle_id"
fi
}
function prepare() {
echo "Start at $(date)"
export RUST_LOG=nonogrid=warn
export RUST_BACKTRACE=1
export RUSTFLAGS="-C target-cpu=native -g"
cargo build --release --no-default-features --features="args std_time logger sat"
}
function run_webpbn() {
mkdir -p ${SCRIPT_DIR}/solutions
mkdir -p ${SCRIPT_DIR}/puzzles
prepare
# https://unix.stackexchange.com/a/158569
export -f run_single_webpbn
for i in "$@"; do
# echo ${i}
## change the `xargs -P` argument to parallelize solving
#done | xargs -n1 -P10 bash -c 'run_single_webpbn "$@"' _
run_single_webpbn ${i}
echo
done
}
function run_nonograms() {
mkdir -p ${SCRIPT_DIR}/solutions-norg
mkdir -p ${SCRIPT_DIR}/puzzles-norg
prepare
export -f run_single_nonogram
export -f find_nonogram_url
for i in "$@"; do
# echo ${i}
## change the `xargs -P` argument to parallelize solving
#done | xargs -n1 -P10 bash -c 'run_single_nonogram "$@"' _
run_single_nonogram ${i}
echo
done
}
function long_solvers() {
# use this function to get the longest solved puzzles
# you have to specify log file with LOG=warn and the threshold in seconds
#
# $ long_solvers batch.log 3 # to show every puzzle that solved more than 3 seconds
#
# You can use the total time results from this function
# to quickly find information about the solution (depth, rate, etc):
# just issue the following command by providing grep with the total time for given puzzle:
# $ cat batch.log | grep -m1 -F '3599.93' -B4 -A3
#
# Also, you can use ripgrep instead: `rg -o 'Total: (.+)' -r'$1'`.
local log_file=$1
local threshold=${2:-10}
local details=
for i in "$@"; do
if [[ ${i} == "--details" ]]; then
local details=1
fi
done
while read t; do
if [[ ${details} ]]; then
exec 5>&1
else
exec 5>/dev/null
fi
# https://stackoverflow.com/a/12451419
local id=$(cat ${log_file} | grep -m1 -F "Total: ${t}" -B5 -A3 | tee >(cat - >&5) | grep -oP '#\K(\d+)' | awk '{print $1-1}' | sort -u)
echo "$id: $t"
if [[ ${details} ]]; then
echo -e '-----------------\n'
fi
done < <(cat ${log_file} | grep -oP 'Total: \K(.+)' | awk '$1 > t' t=${threshold})
}
mode=$1
case ${mode} in
${MODE_WEBPBN})
shift
run_webpbn $@
echo "End at $(date)"
;;
${MODE_NONOGRAMS})
shift
run_nonograms $@
echo "End at $(date)"
;;
${MODE_STAT})
shift
long_solvers $@
;;
*) # unknown option
echo "error: Unknown mode $mode" >&2
exit 1
;;
esac