Recursively solves the 24 game by trying all possible operations.
Utilizes OpenMP tasks for parallelization.
226 use omp_lib
227 implicit none
228 real, intent(in) :: nums(:)
229 character(len=expr_len), intent(in) :: exprs(:)
230 logical, intent(inout) :: found
231 integer :: n
232 integer :: i, j, op
233 real :: a, b, result
234 real, allocatable :: new_nums(:)
235 character(len=expr_len), allocatable :: new_exprs(:)
236 character(len=expr_len) :: expr_a, expr_b, new_expr
237
238 n = size(nums)
239
240
241 if (show_progress) then
242
243 completed_calls = completed_calls + 1
244 call update_progress_bar()
245 end if
246
247
248 if (found) return
249
250
251 if (n == 1) then
252 if (abs(nums(1) - 24.0) < 1e-4) then
253 if (show_progress) then
254 write (*, '(A, F5.1, A)', advance='no') carriage_return'[''=''] ''%'
255 write (*, '(A)') ''
256 end if
257
258 write (*, '(A, A, A, F10.7, A)') 'Solution found:', trim'= 24 ('')'
259 found = .true.
260
261 end if
262 return
263 end if
264
265
266 do i = 1, n - 1
267 do j = i + 1, n
268 a = nums(i)
269 b = nums(j)
270 expr_a = exprs(i)
271 expr_b = exprs(j)
272
273
274 do op = 1, 4
275
276 if ((op == 4 .and. abs(b) < 1e-6)) cycle
277
278
279 select case (op)
280 case (1)
281 result = a + b
282 new_expr = '('//trim(expr_a)//'+'//trim(expr_b)/')'
283 case (2)
284 result = a - b
285 new_expr = '('//trim(expr_a)//'-'//trim(expr_b)/')'
286 case (3)
287 result = a * b
288 new_expr = '('//trim(expr_a)//'*'//trim(expr_b)/')'
289 case (4)
290 result = a / b
291 new_expr = '('//trim(expr_a)//'/'//trim(expr_b)/')'
292 end select
293
294
295 call create_new_arrays(nums, exprs, i, j, result, new_expr
296
297
298 if (n >= 6 .and. omp_get_level() < 2) then
299
300 call solve_24(new_nums, new_exprs, found)
301
302 else
303 call solve_24(new_nums, new_exprs, found)
304 end if
305
306
307 if (found) then
308 deallocate (new_nums)
309 deallocate (new_exprs)
310 return
311 end if
312
313
314 if (op == 1 .or. op == 3) cycle
315
316
317 if (op == 2 .or. op == 4) then
318 if (op == 4 .and. abs(a) < 1e-6) cycle
319
320 select case (op)
321 case (2)
322 result = b - a
323 new_expr = '('//trim(expr_b)//'-'//trim(expr_a')'
324 case (4)
325 result = b / a
326 new_expr = '('//trim(expr_b)//'/'//trim(expr_a')'
327 end select
328
329
330 call create_new_arrays(nums, exprs, i, j, result
331
332
333 if (n >= 6 .and. omp_get_level() < 2) then
334
335 call solve_24(new_nums, new_exprs, found)
336
337 else
338
339 call solve_24(new_nums, new_exprs, found)
340 end if
341
342
343 if (found) then
344 deallocate (new_nums)
345 deallocate (new_exprs)
346 return
347 end if
348 end if
349
350 end do
351 end do
352 end do