13 Sun

TIL

์˜คํ† ๋งˆํƒ€์™€ ์ปดํŒŒ์ผ๋Ÿฌ

River Crossing : ์ตœ์ข… ์ฝ”๋“œ

#
#   data : 2020.12.02
#   author : sangmandu at Dankook Univ.
#   program : river crossing
#   language : python
#

#
#   H : Human,  W : Wolf,   S : Sheep,  C : Cabbage
#   1 ... W eat S when there are only W and S
#   2 ... S eat C when there are only S and C
#   3 ... boat can be accommodate in up to 2 elements and Human essential
#   4 ... objective is that all element moves left to right
#

#
#   two lists that left and right
#   prior : keep from generating duplicate
#   dir : direction left to right or vice versa
#   record : the procedure to success(or failure)
#
#   failure     1) left check issue : collision with rule 1 or 2
#               2) left check issue : collision with rule 1 or 2
#               3) duplicate case : prevent that infinite loop
#   

# initialization
_left = ['H', 'W', 'S', 'C']
_prior = ''
_right = []
_dir = '>'
_record = []

# check rule 1 and 2
# when breaking rule then True else False
def checkIssue(rand):
    if len(rand) == 2 and 'S' in rand:
        if 'W' in rand or 'C' in rand:
            return True
    return False

stack = [(_left, _prior, _right, _dir, _record)]
while stack:
    left, prior, right, dir, record = stack.pop(0)
    print()
    print("selected element : ", left, prior, right, dir)
    print("and remained stack : ", stack)
    if not left:
        _record.append(record)
        continue

    if dir == ">":
        for ele in left:
            if ele == 'H':
                continue
            print(f"ele is {ele}")
            l, p, r, rec = left[:], prior[:], right[:], record[:]
            if ele == prior:
                print("ele == prior")
                continue
            l.remove(ele)
            l.remove('H')
            if checkIssue(l):
                print("left check issue")
                continue
            r.append(ele)
            r.append('H')
            if checkIssue(r):
                print("right check issue")
                continue
            memo = f"{ele} and human move from left : {left} to right : {right}"
            if memo in rec:
                print("duplicate issue")
                continue
            rec.append(memo)
            stack.append((l, ele, r, '<', rec))
            print(f"stack append {(l, ele, r, '<', rec)}")
    else:   # dir == "<"
        for ele in right:
            if ele == 'H':
                continue
            print(f"ele is {ele}")
            l, p, r, rec = left[:], prior[:], right[:], record[:]
            if ele == prior:
                print("ele == prior")
                continue
            r.remove(ele)
            r.remove('H')
            if checkIssue(r):
                print("right check issue")
                continue
            l.append(ele)
            l.append('H')
            if checkIssue(l):
                print("left check issue")
                continue
            memo = f"{ele} and human move to left : {left} from right : {right} "
            if memo in rec:
                print("duplicate issue")
                continue
            rec.append(memo)
            stack.append((l, ele, r, '>', rec))
            print(f"stack append {(l, ele, r, '>', rec)}")
        record.append(f"only human moves to left : {left} from right : {right} ")
        right.remove('H')
        left.append('H')
        if checkIssue(right):
            print("right check issue when human only on board")
            continue
        stack.append((left, '', right, '>', record))
        print(f"stack append that only human {(l, '', r, '>', rec)}")

print()
for idx, record in enumerate(_record, 1):
    print(f"#{idx} success case")
    for rec in record:
        print(rec)
    print()

์ค‘๊ฐ„ ์ฝ”๋“œ์™€๋Š” ๋น„์Šทํ•˜๋ฉด์„œ ์ข€ ๋‹ค๋ฅด๋‹ค. (ํ•œ๋ฒˆ ๊ฐˆ์•„ ์—Ž์–ด๊ฐ€์ง€๊ณ ...) ์žฌ๊ท€ ํ•จ์ˆ˜๋ณด๋‹ค๋Š” while / stack ๋ฐฉ์‹์ด ๋ณ€์ˆ˜ ๊ด€๋ฆฌ๊ฐ€ ํŽธํ•œ ๊ฒƒ ๊ฐ™๋‹ค. ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๋ณ€์ˆ˜๋Š” l = left[:] ์™€ ๊ฐ™์ด ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ํ•˜๋ ค๊ณ  ํ•ด๋„ ์ž˜ ์•ˆ๋œ๋‹ค. ๊ฒฐ๊ตญ copy.deepcopy๋ฅผ ์จ์•ผ ๋˜๋Š”๋ฐ, ๊ตณ์ด ์ด๋ ‡๊ฒŒ? ๋ผ๋Š” ์ƒ๊ฐ์ด ๋„ˆ๋ฌด ๋งŽ์ด ๋“ ๋‹ค. ํ•จ์ˆ˜ ๋‚ด์—์„œ๋Š” ์žฌ๊ท€ํ•จ์ˆ˜ ๋˜ํ•œ ๋™์ผํ•œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ทธ๋Ÿฐ๊ฒŒ ์•„๋‹๊นŒ ๋ผ๋Š” ์ถ”์ธก์€ ์žˆ์ง€๋งŒ ํ™•์‹คํ•œ ์ด์œ ๋Š” ๋ชจ๋ฅด๊ฒ ๋‹ค.

100์ค„ ์กฐ๊ธˆ ๋„˜๊ฒŒ ์ž‘์„ฑ๋œ ์ฝ”๋“œ. ์ข€ ๋” ํ•จ์ˆ˜ํ™”ํ•˜๊ณ  ํ•จ์ถ•ํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๊ฒ ์ง€๋งŒ ์• ์ดˆ์— ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ž‘์•„์„œ ๊ทธ๋Ÿด ํ•„์š”๊ฐ€ ์—†๋‹ค. ์ข€ ๋” ์ง๊ด€์ ์ด์–ด์„œ ์„ค๋ช…ํ•˜๊ฑฐ๋‚˜ ๋ณผ ๋•Œ๋Š” ์ข‹์„ ์ˆ˜ ์žˆ๋‹ค. ์กฐ๊ธˆ ๋” ์ˆ˜์ •ํ•˜์ž๋ฉด prior ๋ณ€์ˆ˜๋ฅผ ์—†์• ๊ณ  duplicate case์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๊ฒ ๋‹ค.

๊ฐ„๋‹จํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ธ๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ๊ณ ๋ฏผ์ด ๊ธธ์—ˆ๋‹ค. ์ฃผ๋œ ํฌ์ธํŠธ๋Š” left to right์ธ์ง€ ๋˜๋Š” ๋ฐ˜๋Œ€์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ  ์ด์— ๋Œ€ํ•ด ๊ฐ left(or right)์—์„œ ๋‹ค์‹œ ๋ฐ˜๋Œ€ํŽธ์œผ๋กœ ๊ฑด๋„ˆ๊ฐˆ ์š”์†Œ๋ฅผ ๊ณ ๋ฅธ๋‹ค. ์ด ๋•Œ prior๋Š” ์ด์ „์— ๊ฐ€์ ธ์˜จ ์š”์†Œ๋ฅผ ๊ธฐ์–ตํ•˜์—ฌ ๋‹ค์‹œ ๊ณ ๋ฅด์ง€ ์•Š๋„๋ก ํ•œ๋‹ค. checkIssue๋Š” ์ „๋‹ฌ๋œ ๋ฆฌ์ŠคํŠธ์—์„œ rule์ด ์ง€์ผœ์ง€๋Š”์ง€ ํ™•์ธํ•˜์—ฌ ์ง€์ผœ์ง€์ง€ ์•Š์•˜์„ ๊ฒฝ์šฐ True๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. (๋ฃฐ ํ™•์ธ์„ ์œ„ํ•ด if๋ฌธ ์“ธ ๋•Œ not์„ ์“ฐ๊ธฐ๊ฐ€ ์ง€์ €๋ถ„ ํ•œ๊ฒƒ ๊ฐ™์•„ True๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ–ˆ๋‹ค...)

๊ฐ case๋ฅผ BFS ๋ฐฉ์‹์œผ๋กœ ์ ‘๊ทผํ•˜๋ฉฐ ๊ฐ ์ผ€์ด์Šค๋งˆ๋‹ค ์‹คํŒจํ•  ๊ฒฝ์šฐ ์‹คํŒจ ์ด์œ ๊ฐ€ ์ถœ๋ ฅ๋œ๋‹ค. ์‹คํŒจํ–ˆ์„ ๊ฒฝ์šฐ์—๋Š” ๊ทธ ๊ณผ์ •์€ ์ผ๋ถ€๋กœ ์ถœ๋ ฅํ•˜์ง€ ์•Š๋„๋ก ํ–ˆ๋‹ค. (์•ˆ๊ถ๊ธˆํ•ด์„œ?) ๋˜ํ•œ ์„ฑ๊ณตํ•  ๊ฒฝ์šฐ๋ฅผ ๋งˆ์ง€๋ง‰์— ์ •๋ฆฌํ•ด์„œ ๋‹ค์‹œ ์ถœ๋ ฅํ•˜๋„๋ก ํ–ˆ๋‹ค. ์‹ค์ œ๋กœ๋„ 2๊ฐ€์ง€์˜ ๊ฒฝ์šฐ์˜ ์ˆ˜๊ฐ€ ์กด์žฌํ•˜๋Š”๋ฐ, ํ”„๋กœ๊ทธ๋žจ ๋˜ํ•œ ๋‘ ๊ฐ€์ง€์˜ ์„ฑ๊ณต ์ผ€์ด์Šค๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค. ๊ฒฐ๊ณผ 150์ค„ ์ •๋„ ์ถœ๋ ฅ๋œ๋‹ค.

BFS๋ฐฉ์‹์œผ๋กœ ์ถœ๋ ฅํ•˜๋Š” ๋ชจ์Šต. ๊ฐ ์‹คํŒจ ์ผ€์ด์Šค์˜ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋‹ค์Œ์€ ์„ฑ๊ณต์ ์œผ๋กœ ์ถœ๋ ฅ๋˜๋Š” ๋ชจ์Šต.

Last updated

Was this helpful?