@@ -375,6 +375,22 @@ genPerm' = genPermHelper [[]]
375
375
editing programs. That is, given a screen (represented by a
376
376
two-dimensional array of colors), a point, and a new color, fill in
377
377
the surrounding area until the color changes from the original color.
378
+
379
+ test case: fillUpColor image (0,0) Blue
380
+
381
+ original image:
382
+ [
383
+ [Red,Red,Red],
384
+ [Red,Yellow,Red],
385
+ [Yellow,Yellow,Blue]
386
+ ]
387
+
388
+ expect image:
389
+ [
390
+ [Blue,Blue,Blue],
391
+ [Blue,Yellow,Blue],
392
+ [Yellow,Yellow,Blue]
393
+ ]
378
394
-}
379
395
380
396
data Color = Red | Yellow | Blue deriving Show
@@ -402,30 +418,27 @@ image = V.fromList
402
418
V. fromList [Yellow , Yellow , Blue ]
403
419
]
404
420
405
- image1 :: Image
406
- image1 = V. fromList
407
- [
408
- V. fromList [Red , Red ],
409
- V. fromList [Red , Yellow ]
410
- ]
421
+ fillUpColor :: Image -> (Int , Int ) -> Color -> Image
422
+ fillUpColor img (i,j) c = foldl (\ acc x -> paint acc x c ) img pList
423
+ where pList = findArea img (i,j)
411
424
412
425
-- Paint a color in one location
413
426
paint :: Image -> (Int , Int ) -> Color -> Image
414
- paint vs (i, j) c =
427
+ paint vs (i,j) c =
415
428
fstHVects V. ++ V. fromList[newPaintRow] V. ++ V. drop 1 secHVects
416
- where
429
+ where
417
430
(fstHVects, secHVects) = V. splitAt i vs
418
431
(fstHPaintRow, secHPaintRow) = V. splitAt j (vs V. ! i)
419
- newPaintRow =
432
+ newPaintRow =
420
433
fstHPaintRow V. ++ V. fromList[c] V. ++ V. drop 1 secHPaintRow
421
434
422
435
-- Find all locations which need to paint
423
436
findArea :: Image -> (Int , Int ) -> [(Int , Int )]
424
437
findArea img (i,j) = uniq (
425
438
(i,j):
426
- findAreaOnDir img (i,j) boundC Up ++
427
- findAreaOnDir img (i,j) boundC Down ++
428
- findAreaOnDir img (i,j) boundC PLeft ++
439
+ findAreaOnDir img (i,j) boundC Up ++
440
+ findAreaOnDir img (i,j) boundC Down ++
441
+ findAreaOnDir img (i,j) boundC PLeft ++
429
442
findAreaOnDir img (i,j) boundC PRight ) []
430
443
where boundC = img V. ! i V. ! j
431
444
@@ -441,31 +454,31 @@ findAreaOnDir img (i,j) c Up
441
454
(i,j- 1 ): findAreaOnDir img (i,j- 1 ) c PLeft
442
455
| isInBoundAndSameColor img (i- 1 ,j) c =
443
456
(i- 1 ,j): findAreaOnDir img (i- 1 ,j) c Up
444
- | isInBoundAndSameColor img (i,j+ 1 ) c =
457
+ | isInBoundAndSameColor img (i,j+ 1 ) c =
445
458
(i,j+ 1 ): findAreaOnDir img (i,j+ 1 ) c PRight
446
459
| otherwise = []
447
460
findAreaOnDir img (i,j) c Down
448
- | isInBoundAndSameColor img (i,j- 1 ) c =
461
+ | isInBoundAndSameColor img (i,j- 1 ) c =
449
462
(i,j- 1 ): findAreaOnDir img (i,j- 1 ) c PLeft
450
463
| isInBoundAndSameColor img (i+ 1 ,j) c =
451
464
(i+ 1 ,j): findAreaOnDir img (i+ 1 ,j) c Down
452
- | isInBoundAndSameColor img (i,j+ 1 ) c =
465
+ | isInBoundAndSameColor img (i,j+ 1 ) c =
453
466
(i,j+ 1 ): findAreaOnDir img (i,j+ 1 ) c PRight
454
467
| otherwise = []
455
468
findAreaOnDir img (i,j) c PLeft
456
- | isInBoundAndSameColor img (i- 1 ,j) c =
469
+ | isInBoundAndSameColor img (i- 1 ,j) c =
457
470
(i- 1 ,j): findAreaOnDir img (i- 1 ,j) c Up
458
- | isInBoundAndSameColor img (i,j- 1 ) c =
471
+ | isInBoundAndSameColor img (i,j- 1 ) c =
459
472
(i,j- 1 ): findAreaOnDir img (i,j- 1 ) c PLeft
460
- | isInBoundAndSameColor img (i+ 1 ,j) c =
473
+ | isInBoundAndSameColor img (i+ 1 ,j) c =
461
474
(i+ 1 ,j): findAreaOnDir img (i+ 1 ,j) c Down
462
475
| otherwise = []
463
476
findAreaOnDir img (i,j) c PRight
464
- | isInBoundAndSameColor img (i- 1 ,j) c =
477
+ | isInBoundAndSameColor img (i- 1 ,j) c =
465
478
(i- 1 ,j): findAreaOnDir img (i- 1 ,j) c Up
466
- | isInBoundAndSameColor img (i,j+ 1 ) c =
479
+ | isInBoundAndSameColor img (i,j+ 1 ) c =
467
480
(i,j+ 1 ): findAreaOnDir img (i,j+ 1 ) c PRight
468
- | isInBoundAndSameColor img (i+ 1 ,j) c =
481
+ | isInBoundAndSameColor img (i+ 1 ,j) c =
469
482
(i+ 1 ,j): findAreaOnDir img (i+ 1 ,j) c Down
470
483
| otherwise = []
471
484
@@ -474,7 +487,7 @@ isInBoundAndSameColor img (i,j) c = isInBound img (i,j) && selectC == c
474
487
where selectC = img V. ! i V. ! j
475
488
476
489
isInBound :: Image -> (Int , Int ) -> Bool
477
- isInBound img (i,j)
490
+ isInBound img (i,j)
478
491
| (0 <= i && i < xBound) && (0 <= j && j < yBound) = True
479
492
| otherwise = False
480
493
where xBound = length img
0 commit comments