Skip to content
Snippets Groups Projects
Commit 3a6eb579 authored by Lee Sihoon's avatar Lee Sihoon
Browse files

init

parents
No related branches found
No related tags found
No related merge requests found
1 2 3 4 5 6 7 8 9
\ No newline at end of file
1 1 1 1 1 1 1 1 1
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
# 마방진 과제
##### 사이버보안학과 201720692 이시훈
# magic_3x3.py
n의 크기가 작기 때문에 `permutations`를 이용했다.
```
if ns[0]+ns[1]+ns[2] == ns[3]+ns[4]+ns[5] == ns[6]+ns[7]+ns[8] == \
ns[0]+ns[3]+ns[6] == ns[1]+ns[4]+ns[7] == ns[2]+ns[5]+ns[8] == \
ns[0]+ns[4]+ns[8] == ns[2]+ns[4]+ns[6]:
```
마방진을 체크하는 로직은 위와 같은데 for문이 아닌 하드코딩을 하였다. 크기가 작아 for을 사용할 경우 파이썬 인터프리터에서 분기문을 실행하며 처리하는 오버헤드가 있을 수 있다. 하드코딩으로 인덱싱하여 리스트에 접근하고 합을 확인하였다. 테스트 결과는 다음과 같다.
## Test
```
> cat 3x3.txt
1 2 3 4 5 6 7 8 9
> cat 3x3.txt|python3 magic_3x3.py
8 1 6 3 5 7 4 9 2
6 7 2 1 5 9 8 3 4
2 7 6 9 5 1 4 3 8
6 1 8 7 5 3 2 9 4
8 3 4 1 5 9 6 7 2
4 3 8 9 5 1 2 7 6
4 9 2 3 5 7 8 1 6
2 9 4 7 5 3 6 1 8
총 8 개의 답이 있습니다. 계산시간은 총 0.13 초 입니다.
```
1~9까지의 숫자를 입력할 경우 위와 같이 8개의 답을 출력한다. 중복된 답이 있을 경우 아래와 같이 중복을 제거하고 해결하였다. `set`을 이용하여 중복된 리스트를 제거할 수 있다.
```
> cat 3x3_dup.txt
1 1 1 1 1 1 1 1 1
> cat 3x3_dup.txt|python3 magic_3x3.py
1 1 1 1 1 1 1 1 1
총 1 개의 답이 있습니다. 계산시간은 총 0.60 초 입니다.
```
# magic_4x4.py
4x4는 충분히 큰 숫자이기 전에 순열로 해결할 수 없다. `permutations`를 사용하기 전에 최적화를 진행했다. `combinations`를 통해 각 행에 올수 있는 모든 숫자를 구했다. 이후 행별로 `permutations`로 순열을 구하여 가로, 세로., 사분면, 대각선의 합을 확인하여 마방진을 구했다.
## Test
```
> python3 magic_4x4.py > 4x4_1.txt
1 2 3 4 5 6 7 8 9 10 10 11 13 14 14 15
총 4608 개의 답이 있습니다. 계산시간은 총 156.78 초 입니다.
```
```
> python3 magic_4x4.py > 4x4_2.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
총 3456 개의 답이 있습니다. 계산시간은 총 203.81 초 입니다.
```
조합을 사용하여 최적화를 더 진행하였지만 여러번 시도 끝에 포기했다.
# test_nxn.py
stdin으로 받은 마방진 결과를 테스트하는 코드이다. 숫자를 입력받을 때 `EOFError`를 핸들링하여 예외를 처리하였다. 3x3에서는 마방진 검증을 하드코딩 했지만 nxn이기 때문에 for문을 이용하여 검증하였다. 결과 관리가 쉽도록 `results` 변수를 따로 두어 `입력값``검증 결과`, `중복 여부`를 저장하였다. 가장 먼저 수의 개수가 제곱수인지 nxn 여부를 체크한다. 이후 가로, 세로의 합을 확인하고 대각선의 합을 확인한다. 확인이 모두 끝나면 중복된 값이 있는지 검사한다. 이후 결과를 출력한다.
## Test
```
> cat test.txt|python3 test_nxn.py
8 1 6 3 5 7 4 9 2 - True
8 1 6 2 6 7 4 9 2 - False
1 2 3 4 5 6 7 8 - False
7 1 7 3 5 7 5 9 1 - False
7 1 7 7 5 3 1 9 5 - False
1 14 14 4 11 7 6 9 8 10 10 5 13 2 3 15 - True
1 2 3 4 5 6 7 8 9 10 10 11 13 14 14 15 - False
1 1 1 1 1 1 1 1 1 - True (Duplicated)
1 1 1 1 1 1 1 1 1 - True (Duplicated)
```
위와 같이 마방진 검증 결과가 실행되며 중복된 값은 Duplicated라는 결과가 출력된다.
아래는 4x4 마방진에 대한 테스트 결과이다.
```
> cat 4x4_2.txt|python3 test_nxn.py|tail -5
10 11 6 7 8 5 12 9 15 14 3 2 1 4 13 16 - True
11 10 7 6 5 8 9 12 2 3 14 15 16 13 4 1 - True
11 10 7 6 5 8 9 12 14 15 2 3 4 1 16 13 - True
11 10 7 6 8 5 12 9 2 3 14 15 13 16 1 4 - True
11 10 7 6 8 5 12 9 14 15 2 3 1 4 13 16 - True
```
\ No newline at end of file
from itertools import permutations
import time
import sys
#inputs = '1 1 1 1 1 1 1 1 1'
#inputs = '1 2 3 4 5 6 7 8 9'
try:
inputs = input()
except EOFError:
pass
if len(inputs.split()) != 9:
print('Error', file=sys.stderr)
exit()
start_time = time.time()
inputs = list(map(int, inputs.split()))
magic_squares = []
for ns in permutations(inputs):
if ns[0]+ns[1]+ns[2] == ns[3]+ns[4]+ns[5] == ns[6]+ns[7]+ns[8] == \
ns[0]+ns[3]+ns[6] == ns[1]+ns[4]+ns[7] == ns[2]+ns[5]+ns[8] == \
ns[0]+ns[4]+ns[8] == ns[2]+ns[4]+ns[6]:
magic_squares.append(ns)
magic_squares = set(magic_squares)
for magic_square in magic_squares:
print(' '.join(map(str, magic_square)), file=sys.stdout)
elapsed_time = time.time() - start_time
print(f'{len(magic_squares)} 개의 답이 있습니다. 계산시간은 총 {elapsed_time:.2f} 초 입니다. ', file=sys.stderr)
\ No newline at end of file
from itertools import combinations, permutations, chain
import sys, time
try:
inputs = input()
except EOFError:
pass
#inputs = '1 2 3 4 5 6 7 8 9 10 10 11 13 14 14 15'
if len(inputs.split()) != 16:
print('Error', file=sys.stderr)
exit()
start_time = time.time()
inputs = list(map(int, inputs.split()))
ns = inputs
def get_removed_list(l, removings):
removed = l.copy()
list(map(lambda x: removed.remove(x), removings))
return removed
magic_row_squares = []
for partition1 in combinations(ns, 4):
magic_sum = sum(partition1)
remain_partition1 = get_removed_list(ns, partition1)
for partition2 in combinations(remain_partition1, 4):
if sum(partition2) != magic_sum: continue
remain_partition2 = get_removed_list(remain_partition1, partition2)
for partition3 in combinations(remain_partition2, 4):
if sum(partition3) != magic_sum: continue
remain_partition3 = get_removed_list(remain_partition2, partition3)
for partition4 in combinations(remain_partition3, 4):
if sum(partition4) != magic_sum: continue
magic_row_squares.append([partition1, partition2, partition3, partition4])
c = 0
magic_squares = []
for magic_row_square in magic_row_squares:
for row1 in permutations(magic_row_square[0]):
magic_sum = sum(row1)
for row2 in permutations(magic_row_square[1]):
if not sum(row1[:2] + row2[:2]) == sum(row1[2:] + row2[2:]) == magic_sum: continue
for row3 in permutations(magic_row_square[2]):
for row4 in permutations(magic_row_square[3]):
if not sum(row3[:2] + row4[:2]) == sum(row3[2:] + row4[2:]) == magic_sum: continue
if not (row1[0] + row2[1] + row3[2] + row4[3] == magic_sum and \
row1[3] + row2[2] + row3[1] + row4[0] == magic_sum): continue
end = 0
for i in range(len(magic_row_square)):
if row1[i] + row2[i] + row3[i] + row4[i] != magic_sum:
end = 1
break
if end:
continue
magic_squares.append(row1 + row2 + row3 + row4)
c+=1
for magic_square in magic_squares:
print(' '.join(map(str, magic_square)), file=sys.stdout)
elapsed_time = time.time() - start_time
print(f'{len(magic_squares)} 개의 답이 있습니다. 계산시간은 총 {elapsed_time:.2f} 초 입니다. ', file=sys.stderr)
\ No newline at end of file
from itertools import combinations, permutations, chain
#ns = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 13, 14, 14, 15]
ns = list(range(1,17))
def get_removed_list(l, removings):
removed = l.copy()
list(map(lambda x: removed.remove(x), removings))
return removed
def get_magic_quad_square(row1, row2):
magic_sum = sum(row1)
for quad_row1 in combinations(row1, 2):
for quad_row2 in combinations(row2, 2):
if sum(quad_row1 + quad_row2) != magic_sum: continue
remain_row1 = get_removed_list(list(row1), quad_row1)
remain_row2 = get_removed_list(list(row2), quad_row2)
if sum(remain_row1 + remain_row2) == magic_sum:
return [list(quad_row1), list(quad_row2)], [remain_row1, remain_row2]
#return list(quad_row1) + remain_row1, list(quad_row2) + remain_row2
return None
magic_row_squares = []
for partition1 in combinations(ns, 4):
magic_sum = sum(partition1)
remain_partition1 = get_removed_list(ns, partition1)
for partition2 in combinations(remain_partition1, 4):
if sum(partition2) != magic_sum: continue
remain_partition2 = get_removed_list(remain_partition1, partition2)
for partition3 in combinations(remain_partition2, 4):
if sum(partition3) != magic_sum: continue
remain_partition3 = get_removed_list(remain_partition2, partition3)
for partition4 in combinations(remain_partition3, 4):
if sum(partition4) != magic_sum: continue
magic_row_squares.append([partition1, partition2, partition3, partition4])
magic_quad_squares = []
for i, rows in enumerate(magic_row_squares):
quad_square1 = get_magic_quad_square(rows[0], rows[1])
quad_square2 = get_magic_quad_square(rows[2], rows[3])
if quad_square1 is None or quad_square2 is None: continue
magic_quad_squares.append([quad_square1 + quad_square2])
c = 0
magic_col_squares = []
for magic_quad_square in magic_quad_squares:
magic_sum = sum(chain(*magic_quad_square[0][0]))
for magic_quad in magic_quad_square:
for quad1_row1_idxs in permutations(range(2)):
for quad1_row2_idxs in permutations(range(2)):
for quad2_row1_idxs in permutations(range(2)):
for quad2_row2_idxs in permutations(range(2)):
left_quads = [magic_quad[0], magic_quad[2]]
right_quads = [magic_quad[1], magic_quad[3]]
square = [[left_quads[0][0][quad1_row1_idxs[0]], left_quads[0][0][quad1_row1_idxs[1]],
right_quads[0][0][quad1_row1_idxs[0]], right_quads[0][0][quad1_row1_idxs[1]]],
[left_quads[0][1][quad1_row2_idxs[0]], left_quads[0][1][quad1_row2_idxs[1]],
right_quads[0][1][quad1_row2_idxs[0]], right_quads[0][1][quad1_row2_idxs[1]]],
[left_quads[1][0][quad2_row1_idxs[0]], left_quads[1][0][quad2_row1_idxs[1]],
right_quads[1][0][quad2_row1_idxs[0]], right_quads[1][0][quad2_row1_idxs[1]]],
[left_quads[1][1][quad2_row2_idxs[0]], left_quads[1][1][quad2_row2_idxs[1]],
right_quads[1][1][quad2_row2_idxs[0]], right_quads[1][1][quad2_row2_idxs[1]]]]
if square[0][0] + square[1][0] + square[2][0] + square[3][0] == \
square[0][1] + square[1][1] + square[2][1] + square[3][1] == \
square[0][2] + square[1][2] + square[2][2] + square[3][2] == \
square[0][3] + square[1][3] + square[2][3] + square[3][3] == \
square[0][0] + square[1][1] + square[2][2] + square[3][3] == \
square[3][0] + square[2][1] + square[1][2] + square[0][3] == \
magic_sum:
print(square)
c+=1
print(c)
#print((magic_col_squares))
#print(magic_quad_squares[0])
#1 4 5 8, 14 14 10 10, 3 2 7 6
#[([[1, 14], [4, 14]], [[3, 15], [2, 13]], [[5, 10], [8, 10]], [[7, 11], [6, 9]])]
# 1 14 3 15
# 4 14 2 13
# 5 10 7 11
# 8 10 6 9
\ No newline at end of file
from itertools import combinations, permutations, chain
ns = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 13, 14, 14, 15]
#ns = list(range(1,17))
def get_removed_list(l, removings):
removed = l.copy()
list(map(lambda x: removed.remove(x), removings))
return removed
def get_magic_quad_square(row1, row2):
magic_sum = sum(row1)
for quad_row1 in combinations(row1, 2):
for quad_row2 in combinations(row2, 2):
if sum(quad_row1 + quad_row2) != magic_sum: continue
remain_row1 = get_removed_list(list(row1), quad_row1)
remain_row2 = get_removed_list(list(row2), quad_row2)
if sum(remain_row1 + remain_row2) == magic_sum:
return [list(quad_row1), list(quad_row2)], [remain_row1, remain_row2]
#return list(quad_row1) + remain_row1, list(quad_row2) + remain_row2
return None
magic_row_squares = []
for partition1 in combinations(ns, 4):
magic_sum = sum(partition1)
remain_partition1 = get_removed_list(ns, partition1)
for partition2 in combinations(remain_partition1, 4):
if sum(partition2) != magic_sum: continue
remain_partition2 = get_removed_list(remain_partition1, partition2)
for partition3 in combinations(remain_partition2, 4):
if sum(partition3) != magic_sum: continue
remain_partition3 = get_removed_list(remain_partition2, partition3)
for partition4 in combinations(remain_partition3, 4):
if sum(partition4) != magic_sum: continue
magic_row_squares.append([partition1, partition2, partition3, partition4])
magic_quad_squares = []
for i, rows in enumerate(magic_row_squares):
quad_square1 = get_magic_quad_square(rows[0], rows[1])
quad_square2 = get_magic_quad_square(rows[2], rows[3])
if quad_square1 is None or quad_square2 is None: continue
magic_quad_squares.append([quad_square1 + quad_square2])
magic_col_squares = []
for magic_quad_square in magic_quad_squares:#[:1]:
magic_sum = sum(chain(*magic_quad_square[0][0]))
for magic_quad in magic_quad_square:
magic_cols = [[None]*16,[None]*16]
for i in range(2):
cols1 = []
cols2 = []
perm_col_quads = []
for quad_rows in magic_quad[i::2]:
perm_quads = []
for rows1 in permutations(quad_rows[0]):
for rows2 in permutations(quad_rows[1]):
perm_quads.append([rows1, rows2])
perm_col_quads.append(perm_quads)
for quad1 in perm_col_quads[0]:
for quad2 in perm_col_quads[1]:
cols1.append([quad1[0][0], quad1[1][0], quad2[0][0], quad2[1][0]])
cols2.append([quad1[0][1], quad1[1][1], quad2[0][1], quad2[1][1]])
for j, col1 in enumerate(cols1):
col2 = cols2[j]
if sum(col1) == magic_sum and sum(col2) == magic_sum:
magic_cols[i][j] = [col1, col2]
magic_col_square = []
magic_cols1, magic_cols2 = magic_cols
for i, magic_col1 in enumerate(magic_cols1):
if magic_col1 is None or magic_cols2[i] is None: continue
magic_col_square.append([magic_col1[0], magic_col1[1], magic_cols2[i][0], magic_cols2[i][1]])
if magic_col_square:
magic_col_squares.append(magic_col_square)
print(len(magic_col_squares))
#print((magic_col_squares))
#print(magic_quad_squares[0])
#1 4 5 8, 14 14 10 10, 3 2 7 6
#[([[1, 14], [4, 14]], [[3, 15], [2, 13]], [[5, 10], [8, 10]], [[7, 11], [6, 9]])]
# 1 14 3 15
# 4 14 2 13
# 5 10 7 11
# 8 10 6 9
\ No newline at end of file
8 1 6 3 5 7 4 9 2
8 1 6 2 6 7 4 9 2
1 2 3 4 5 6 7 8
7 1 7 3 5 7 5 9 1
7 1 7 7 5 3 1 9 5
1 14 14 4 11 7 6 9 8 10 10 5 13 2 3 15
1 2 3 4 5 6 7 8 9 10 10 11 13 14 14 15
1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
\ No newline at end of file
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment