인공지능 수학 (최대최소)

(( 인공지능 수학과 경사하강법 ))  진화전략 기반 최대최소 탐구 및 코딩

 

고등학교에 도입되는 인공지능 수학 교과목의 핵심 내용인 부등식 영역에서의 최대최소 문제를 진화전략 기반 경사하강법으로 탐구합니다. 아래 게시판에 제시된 코드와 설명을 통해 탐구하려는 함수 f(x,y) 의 그래프를 3차원에서 시각화하고, 또한 바로 아래의 링크를 통해 Colab 파이썬 코딩환경에서 경사하강법으로 최대최소를 찾는 로봇개미들의 활동을 2차원 애니메이션으로 코딩실험을 하면서 수학탐구를 진행합니다.   

 

( 진화전략 경사하강법 파이썬 코딩 ) 다음을 클릭하세요 !!

   (클릭) 파이썬 탐구자료 및 코딩환경 바로가기

   (클릭) 진화전략고등수학.pdf 내용을 보세요 !!

 

 

(( 참고 ))  한시적인 사용이 가능한 링크 http://naver.me/G149JG2z 

개인용 PC 노트북에서 파이썬을 실행시켜려는 경우에는 위의 주소에서 WinPython 들어있는 zip을 다운받아 사용하세요 

 

====================================

 

부등식 영역의 최대최소 문제에서 시작하는 인공지능  최대최소 문제

2변수 함수 f(x,y) 도입과 f(x,y) 의 3차원 그래프

 

주사위 2개를 던져서 나오는 값을 각각 변수 x와 y로 표시하고, 주사위 눈의 합을 z ( = x+y ) 라고 할 때, z 는 주사위 값을 나타내는 변수 x와 y의 함수가 됩니다. z = f(x,y) = x+y 와 같이 함수로 표현할 수 있으며, z=x+y 의 그래프는 결국 좌표 (x,y,z) 에 블럭을 만드는 것으로, 각각의 주사위 값 x와 y에 대한 합 z로 함수의 그래프가 만들어집니다.

아래 [beginxyz] 단추를 누르면, beginxyz 아래의 코드가 실행되어 두 개의 주사위를 던진 경우에 해당하는 (x,y,z) 좌표에 블럭이 만들어집니다. 아래에서  return z 명령의 뜻은 각 층의 숫자 z 값에 해당하는 블럭으로 만들라는 것입니다. 블럭 1은 풀밭 땅의 블럭, 2는 나무, 3은 잎, 4는 死 빨간색, 5은 ocean 파란색, 6은 하얀 육면체 큐브 등등입니다.

if( x>=1 && x<=6 && y>=1 && y<=6 &&  z == x+y ) return  z

명령은 다음과 같은 다섯가지 조건을 모두 만족시키는 좌표 (x,y,z) 를 구하고, 그 좌표에 z 값에 해당하는 블럭을 놓으라는 것입니다. 여기서 x와 y는 주사위 눈의 값이기에 1,2,3,4,5,6 에서 값을 가지며, 주사위 두개의 눈을 더한 값을 z 라고 합니다. 즉 z는 주사위 눈 x 와 y 를 더한 값으로 z=x+y 입니다. 코딩에서는 z와 x+y 가 같다는 말을 z==x+y 로 표시합니다.

\(x \ge 1\)  이고 \(x \le 6\) 이고 \(y \ge 1 \) 이고 \(y \le 6 \) 이고 \(z = x+y\)  이다.

beginxyz ; if( x>=1 && x<=6 && y>=1 && y<=6 && z == x+y ) return z // x와 y는 각각 1 부터 6까지의 주사위 값이고, // z가 주사위 합 x+y 와 같은 (x,y,z) 에 블럭!

(( 참고 ))  위의 코드에서, 제일 먼저 나오는 beginxyz 명령은 터틀크래프트에 있는 약 210만개의 좌표를 beginxyz 아래에 쓰인 조건제시법 명령에 하나하나 대입하여 답이 되는지 (해집합의 원소가 되는지?) 확인을 하게 됩니다.  따라서 beginxyz 아래에 명령이 많으면 실행 시간이 많이 걸립니다. 이 때, 속도를 개선시키는 방법이 무엇일까요? 코딩교육의 목표인 컴퓨팅 사고력 역량 키우기에서, 틀린 코드를 찾아내는 디버깅 (debugging) 역량과 알고리즘을 구조화하여 속도를 개선시키는 역량이 중요합니다. 코드는 위에서 아래로 순차구조로 실행이 되기에, 해집합에 속하지 않는 좌표들을 빨리 포기하려면, beginxyz 명령 가까운 곳에 그 좌표는 아니다라고 말할 수 있어야합니다. 이 때, 해집합이 그려지는 영역을 살펴서 판단하면 좋습니다. 영역에는 어떤 반지름 원 안에 그려졌는지? 아니면 어떤 정사각형 안에 그려지는지? 또는 어떤 높이 밖에는 그려지지 않는다! 등의 조건입니다. 예를 들어, 조건제시법으로 위의 코드에서 만들어지는 피라미드는 지하의 세계와 12층보다 높은 층에는 그려지지 않기에 beginxyz 바로 다음에 이렇게 명령을 첨가하면 속도가 개선됩니다.

beginxyz ;  

if( z<0 || z>12 ) return 0         

여기서, and 와 or 논리가 사용됩니다. 많은 코딩 언어에서는 and 와 or 를 각각 && 와 || 기호로 나타냅니다. 또한 같지 않다는 것을 != 기호로 나타냅니다. 위에서 ( z<0 || z>12 ) 는 층수를 나타내는 z가 음수 즉 지하이거나 12층 보다 높으면 그 곳은 빈 공간으로 (0 으로) 만들라는 것입니다 (return 0 라는 말은 한마디로 그 곳은 꽝이다! 그러니까 여기말고 빨리 다른 좌표를 찾아 블럭을 만들라는 것입니다). 

 

아래는 피라미드 사각뿔을 만드는 3가지의 서로 다른 코드입니다.  아래의 코드에서, 다음 함수 명령은 수학함수인 f(x,y) 를 만듭니다. 

*   함수 f(x,y) {      return abs(x)+abs(y)    }

**   \(f(x,y) = ~~| x | + |y| \)

또한  abs( z, 12-f(x-15,y-20) ) < 1  의 수학적 표현은 아래와 같습니다.

***   \(|~ z - (~12 - f(x-15, y-20)~) ~ | < 1 \)

beginxyz ; // (1) 부등식 해집합들의 공통집합으로 만들기 if( z<=12+x+y && z<=12+x-y && z<=12-x+y && z<=12-x-y && z>0 ) return z // (2) 함수 z=f(x,y) 그래프로 만들기 함수 f(x,y) { return abs(x)+abs(y) } 집합 { abs( z, 12-f(x-15,y-20) ) < 1 && z>0 ; z } // (3) 조건제시법 집합명령으로 만들기 집합 { 정( -15,20,1, 12-z ) && z>0 ; z }

위에서 마지막 (3) 집합 { 정( -15,20,1, 12-z  )  && z>0  ; z  }  명령은 

집합 { 정(중심x=-15, 중심y=20, 시작z=1, 반지름=12-z )  && z>0 ; z  }

명령과 같습니다. 즉, z층수가 1층 부터 시작해서, 각각의 z층에서 중심의 좌표는 (-15,20) 이고 가로-세로 반지름이 12-z 인 정사각형을 만들어 쌓아 올리라는 명령입니다. 결과적으로 피라미드 사각뿔이 그려집니다.

 

(( 원기둥과 원뿔은 피타고라스 정리로 만들 수 있다 ))

 

sqrt(x*x+y*y) 는 x제곱 더하기 y제곱의 루트이다 (밑변과 높이가 각각 x와 y인 경우의 빗변의 길이 : 피타고라스 정리). 먼저 아래의 함수가 만드는 그래프를 종이 위에서 탐구해보자. 이어서 코드를 실행시켜보자. 

 

f(x,y) = 15 - sqrt(x*x+y*y)     즉    \(f(x,y) = 15 - {\sqrt{ x^2 + y^2} }\)

일 때, 집합 { z <= f(x,y) } 를 만족시키는 해집합을 생각해보자. 

beginxyz ; // (1) f(x,y)= 15- sqrt(x,y) 함수식으로 만들기 if( z <= 15- sqrt(x,y) && z>0 ) return z // (2) 조건제시법 집합명령으로 만들기 집합 { 원( 0, 30,1, 15-z ) ; z }

위에서, 처음 (1) if( z <= 15- sqrt(x,y)  &&  z>0 )  return z 명령은 내부가 꽉 찬 원뿔을 만든다. 내부가 비어있는 원뿔을 만들려면 아래와 같이 함수 f(x,y)= 15- sqrt(x,y) 의 그래프로 만들면 된다.

집합 {  abs( z, f(x,y) ) < 1 }  명령은 다음 조건을 만족시키는 것이다. 즉, z와 f(x,y) 의 (절대값) 차이가 1 미만인 좌표 (x,y,z) 의 해집합이다.

\(집합 \{ ~(x,y,z) ~| ~~~~ | z-15+ {\sqrt{x^2 + y^2}}~| < 1 ~ \}\)

 

위에서 마지막 (2) 집합 { 원( 0, 30,1,  15-z )  ;  z  }  명령은 

집합 { 원(중심x= 0, 중심y= 30, 시작z= 1, 반지름=15-z )  ; z  }

명령과 같습니다. 즉, z층수가 1층 부터 시작해서, 각각의 z층에서 중심의 좌표는 (0,30) 이고 반지름이 15-z 인 원을 만들어 쌓아 올리라는 명령입니다. 결과적으로 원뿔이 그려집니다.

 

(( 참고 )) 피라미드와 원뿔을 만드는 터틀크래프트 집합명령

 

beginxyz ;

집합 { 정( 0, 0, 1, 12-z ) ; z }   // 피라미드 사각뿔을 만든다
집합 { 원( 0, 25,1, 15-z ) ; z }  // 원뿔을 만든다

beginxyz ; 집합 { 정( 0, 0, 1, 12-z ) ; z } // 중심 (0,0,1) 과 반지름 12-z 집합 { 원( 0,25,1, 15-z ) ; z } // 중심 (0,25,1) 과 반지름 15-z

원뿔을 늘리면 타원뿔이 되고, 직사각형을 쌓으면 직사각뿔

beginxyz ; 집합 { 직(25,20, z, 20-z, 10-z ) && z>0 ; 6 } 집합 { 직(0,50, z, 20-z, 0.6*(20-z) ) && z>0 ; 7 } 집합 { 원(-25,20, z, 20-z, 0.6*(20-z) ) && z>0 ; 8 } 집합 { 원( 0, 0, z, 20-z, 10-z ) && z>0 ; 9 }

아래는 진화전략 경사하강법 탐구상황을 좀더 real 하게 만들려고 수학으로 그려낸 산과 호수의 코드이다. 여기에 사용된 다음의 함수를 먼저 종이 위에서 탐구하고 이어서 아래 코드로 그 모양을 확인해보자.  

f(x,y)  = -3*(x**3 + y**3) * exp(-x*x-y*y) 

\(f(x,y) = -3 (x^3 + y^3) ~~e^{-x^2 - y^2}\)
 

beginxyz ; window(0.05) 함수 f(x,y) { return -3*(x**3+y**3)*exp(-x*x-y*y) } 집합 { abs(z, f(x,y) ) < 0.1 ; 2*z+8 } return 0

아래는 데카르트의 folium 함수의 그래프를 만드는 코드이다

f(x,y)  = x**3 + y**3 -3*x*y 

\(f(x,y) = x^3 + y^3 - 3xy\)

 

beginxyz ; window(0.05)

함수 f(x,y) { return x**3 + y**3 -3*x*y }

if( abs( z,f(x,y) ) <0.5 ) {
    if(z>=0.5) { return 6  
     }  else if( z<=-0.5 ) {  return 5 
     }  else return 7  
}
return 0

 

위 코드를 구조화시킨 아래의 코드를 실행시켜보자.

beginxyz ; window(0.05) 함수 f(x,y) { return x**3 + y**3 -3*x*y } 함수 색칠(z) { if(z>=0.5) { return 6 } else if( z<=-0.5 ) { return 5 } else return 7 } 집합 { abs( z,f(x,y) ) <0.5 ; 색칠(z) } return 0

 

 

아래는 로젠블록 함수

beginxyz ; window(0.05) a=1 ; b=100 ; c=0.001 함수 f(x,y) { return c*( (a-x)**2 + b*(y-x*x)**2 ) } if( abs(z, f(x,y) ) < c*100 ) { if(z<=0.1) { return 5 } else return 7 } return 0

 

다음과 같은 2021년도 수능시험 문제의 그래프를 그려보자

 

 

beginxyz 아래에 쓰인 조건제시법 명령의 경우에, 터틀크래프트에 있는 약 210만개의 좌표를 하나하나 조건식에 대입하여 답이 되는지 (해집합의 원소가 되는지?) 확인을 하게 됩니다.  따라서 실행 시간이 많이 걸립니다. 이 때, 속도를 개선시키는 방법이 무엇일까요? 코딩교육의 목표인 컴퓨팅 사고력 역량 키우기에서, 틀린 코드를 찾아내는 디버깅 (debugging) 역량과 알고리즘을 구조화하여 속도를 개선시키는 역량이 중요합니다. 코드는 위에서 아래로 순차구조로 실행이 되기에, 해집합에 속하지 않는 좌표들을 빨리 포기하려면, beginxyz 명령 가까운 곳에 그 좌표는 아니다라고 말할 수 있어야합니다. 이 때, 해집합이 그려지는 영역을 살펴서 판단하면 좋습니다. 영역에는 어떤 반지름 원 안에 그려졌는지? 아니면 어떤 정사각형 안에 그려지는지? 또는 어떤 높이 밖에는 그려지지 않는다! 등의 조건입니다. 예를 들어, 조건제시법으로 위의 코드에서 만들어지는 피라미드는 지하의 세계와 12층 이상에는 그려지지 않기에, 또한 중심 좌표에서 가로 세로 15  밖에는 그려지지 않기에 이렇게 명령을 첨가하면 속도가 개선됩니다.

beginxyz;  if( z<0 || z>12 ) return 0         

여기서, and 와 or 논리가 사용됩니다. 많은 코딩 언어에서는 and 와 or 를 각각 && 와 || 기호로 나타냅니다. 또한 같지 않다는 것을 != 기호로 나타냅니다. 위에서 ( z<0 || z>12 ) 는 층수를 나타내는 z가 음수 즉 지하이거나 12층 보다 높으면 그 곳은 빈 공간으로 (0 으로) 만들라는 것입니다 (return 0 라는 말은 한마디로 그 곳은 꽝이다! 그러니까 여기말고 빨리 다른 좌표를 찾아 블럭을 만들라는 것입니다).

 

조건제시법과 원소나열법 코딩의 융합 ( 컴퓨팅 사고력 기반 창의코딩 )   

 

마인크래프트의 3차원 환경을 닮은 터틀크래프트 (TurtleCraft) 에서는 마우스 클릭과 키보드 코딩명령으로 블럭을 만들며 LEGO 레고 블럭으로 만들기를 하는 것처럼 코딩놀이를 합니다. 블럭을 만들 때, 블럭 하나하나를 만들어 붙히는 것을 수학 용어로 집합의 원소나열법이라고 합니다. 이 때, MIT 패펄트의 LOGO 거북명령 등이 쓰입니다 (참고로 LOGO 에서 스크래치 언어가 나왔으며 LEGO 회사의 연구지원을 받았습니다). 또 다른 방법이 주어진 조건식을 만족하는 모든 원소들의 해집합으로 만드는 것인데, 수학 용어로 집합의 조건제시법이라고 부릅니다. 집합과 논리 원소나열법 조건제시법은 현재 고등학교 1학년 수학에 나오지만, 2010년도 초반까지 중학교 1학년 수학의 집합과 자연수 단원에 나왔습니다. 집합과 논리는 절대로 고등학교때 배울 내용이 아닙니다. 집합과 논리의 개념은 초등학교 저학년부터 익혀야할 내용이며,  터틀크래프트는 집합과 논리 그리고 예전 고등학교 수학 내용이던 알고리즘과 순서도에 바탕하여, 초등 및 중등 창의코딩, 코딩과 수학의 융합인 코딩수학 교육과정을 지향합니다 ! 

조건제시법은 방정식과 부등식 등으로 조건의 수식을 직접 쓰거나, 또는 정직구원체 LEGO 블럭과 같은 명령으로 쓸 수가 있습니다. 창의적인 코딩에서는 beginxyz 아래의 조건제시법 코드를 [beginxyz] 단추로 만들고, beginxyz 위에 쓰인 원소나열법 명령을  [실행] 단추로 융합시켜 만들 수 있습니다.  예를 들어, 아래와 같은 파리의 개선문과 에펠탑을 만들어 봅니다 (마인크래프트의 주인공이 스티브인 것 처럼, 터틀크래프트의 주인공을 터북이라고 부르며, 터북이는 닌자옷을 입은 거북에게 명령) . 또한 만들어진 작품으로 3D 프린터와 VR 등으로 코딩놀이를 합니다.

 

 

 

(( 개선문 만들기 ))

아래 코드에서 핵심 아이디어는 Z=(1/3)*z 과 같은 표현으로, 이 것은 모눈이 그려진 z 축을 양쪽으로 잡아 당겨서 3배로 늘어난 모눈 종이를 만들라는 것입니다. 그렇게 되면 Z=10 이라고 쓰인 모눈 종이에 본래 z=30층 있던 것이 오게 됩니다. 이렇게 고무판 좌표계를 늘리고 줄이는 스토리텔링 기반 story-coding 으로 원의 방정식으로 타원을 만들 수 있습니다. 정직구원은 x-y 축을 기반으로 만들기에, z축 방향으로 서 있는 원을 만들기 어렵습니다. 이 때, 위와 같이 z 축을 늘린 후, 원의 방정식으로 타원을 만들거나, 또는 원의 방정식 수식이 어려운 저학년 학생은 먼저 구를 늘려서 3차원 타원체를 만들고 이 것을 절단시켜 타원을 만들 수 있습니다.

beginxyz ; Z=(1/3)*z // z축 방향으로 양쪽에서 당겨서 3배 늘림 집합 { x*x+(Z+5)**2 <55 && Z>0 && abs(y)<10 ; 0 } 집합 { y*y+(Z+5)**2 <50 && Z>0 && abs(x)<10 ; 0 } // 0 번 블럭으로 Z>0 위에만 터널 구멍이 나도록 함 집합 { 정(0,0,1,8) && z<10 ; 9 }

(( 탐구문제 )) 위 코드는 대문자 Z 대신에 그냥 소문자 z를 쓰는 아래의 코드와 같습니다. 이 경웨 나중에 z=3*z 하여 원래의 z 좌표로 돌려놓는 것에 주목하세요 !! 아래 코드의 설명을 이해하세요.

beginxyz ;

z=(1/3)*z      // z축 방향으로 양쪽에서 당겨서 3배 늘림 
집합 { x*x+(z+5)*(z+5) <55 && z>0 &&  abs(y)<10  ;  0 }
집합 { y*y+(z+5)*(z+5) <50 && z>0 &&  abs(x)<10  ;  0  }
// 0 번 블럭으로 z>0 위에만 터널 구멍이 나도록 함

z=3*z        // 원래의 상태로 돌려 놓음 
집합 { 정(0,0,1,8)  &&  z<10  ; 9  }


(( 설명 ))   z=(1/3)*z 과 같은 표현으로, 이 것은 모눈이 그려진 z 축을 양쪽으로 잡아 당겨서 3배로 늘어난 모눈 종이를 만들 수 있습니다. 그렇게 되면 10 이라고 쓰인 모눈 종이에 본래 30층 있던 것이 오게 됩니다. 이렇게 고무판 좌표계를 늘리고 줄이는 스토리텔링 기반 story-coding 으로 원의 방정식으로 타원을 만들 수 있습니다. 정직구원은 x-y 축을 기반으로 만들기에, z축 방향으로 서 있는 원을 만들기 어렵습니다. 이 때, 위와 같이 z 축을 늘린 후, 원의 방정식으로 타원을 만들거나, 또는 원의 방정식 수식이 어려운 저학년 학생은 먼저 구를 늘려서 3차원 타원체를 만들고 이 것을 절단시켜 타원을 만들 수 있습니다.

 

============================================

 

(( 에펠탑 만들기 ))

아래 코드와 같은 에펠탑을 생각하면, 양쪽으로 올라가는 곡선의 모양이 타원 4조각의 한 부분과 모양이 비슷합니다.  z 축 방향으로 5배 늘리는 아래의 명령을 보세요 ( z=0.2*z 라면, 본래의 z=10 좌표가 이 관계식에 의해 z=2 좌표가 된다. 따라서 지금부터 z 층으로 2층에 해당하는 것이 본래는 10 층을 나타내었던 것이다. 그래서 5배 증가한 그림이 나온다). 

      z =  0.2 * z
      집합{  구(10,0,10,9)  &&  z<=10 &&  abs(y)<0.1 ; 8 }

여기서, 구(10,0,10,9) 를 만들면 z=0.2*z 영향으로 z 축으로 5배 늘어난 타원체가 됩니다. 이 것은 z<=10 과  abs(y)<1 조건으로 단면이 생성되고,  그 모양이 타원의 일부분이 됩니다. 아래의 그림과 명령을 비교하세요.

참고로, 아래 코드에서 8번 블럭을 0번 블럭으로 바꾸어 실행하면 8번 블럭이 없어지면서 바로 위의 그림이 나온다. 위 그림과 같은 모양을 동서남북 4개로 모으면 에펠탑 모양이 만들어진다.

beginxyz ; if( z<0 || nemo(x,y) > 20 || z>50 ) return 0 집합 { 구( 0,0,48, 2 ) ; 6 } z=0.2*z 집합{ 구(10,0,10,9) && z<=10 && abs(y)<1 ; 8 } 집합{ 구(10,0,10,10) && z<=10 && abs(y)<1 ; 9 } z=5*z 집합 { abs(x)+abs(y)<=4 && (z==15 || z==16) ; 8 } 집합 { abs(x)+abs(y)<=7 && z<=9 && z>=7 ; 9 }

위의 코드에서 beginxyz 바로 아래에 쓰여진  if(z<0 || z>50) return 0  명령은 0층 아래의 지하 세계와 55층 위는 0 블럭 즉 빈 공간으로 두라는 것이다. 이와 같은 명령으로 블럭을 만들지 않는 빈 공간의 위치를 빨리 거북에게 알려주어 실행 속도를 높이려고 쓴 것이다. beginxyz 조건제시법은 약 210만개의 좌표에 블럭을 지정하여 만들기에 빨리 실행시키는 코딩 방법이 중요하다. 

 

(( 만리장성 성벽 만들기 ))

아래 코드에서, 만리장성 성벽을 만드는 창의코딩의 doitsxyz 명령 대신에 코딩수학 과정에서는 다른 방법으로 성벽을 만들 수 있다는 것에 주목하세요. 또한 아래 코드에서는 z 층의 변수를 통해 반지름이 다른 다양한 원들을 쌓아서 이런 탑을 만들었다는 것입니다. 3차원 구도 실제로는 2차원 원을 쌓은 것입니다. 마지막에 쓰인 직사각형 만드는 직 명령으로는 탑 위의 십자가 모양을 만들었습니다. 이런 십자가는 beginxyz 위에서 원소 나열법으로 쉽게 만들 수도 있습니다. 원소나열법에는 doit 거북명령 외에도, 행렬 배열을 사용하는 do 벡터 dovt 명령과, 주어진 좌표 (a,b,c) 에 블럭을 만드는 cube(a,b,c) 명령 등을 통해 만들 수 있습니다.

beginxyz; if( z<6 ) { 집합 { nemo(x,y)<15 && nemo(x,y)>12 && z>3 ; 0 } 집합 { nemo(x,y)<16 && nemo(x,y)>11 && z < 6 - abs(x+y)%2 ; 16 } } 집합{원(0,0,1,7) && z<15} ; 집합 { 원(0,0,14,6) && z<20; 5} 집합{원(0,0,20,5) && z<24; z-19} ; 집합{ 원(0,0,24,29-z) ;16} 집합 {원(0,0,30,35-z) ; 6 } ; 집합 { 구(0,0,30,5) && z<30 ; 6 } 집합 {직(0,0,35,0,0) && z<41; 15 } 집합 {직(0,0,38,1,0) && z<39; 15 }

hanaone.com 주소에서 위 코드를 실행시키고, 3D 프린터용 파일을 obj 파일로 다운 받은 후, obj 파일을 3차원 VR로 놀아보자. 또한 beginxyz 바로 아래에 다음과 같은 명령을 추가하면 동그란 성벽으로 둘러쌓인 건축물을 만들 수 있다.

beginxyz ;    // 조건제시법 명령 시작
if(z<0) return 0;  // 속도개선 (지하층 NO)
if(z<6) {
  집합 { sqrt(x,y)< 19 && sqrt(x,y) > 16 &&
             z> 3 ; 0 } 
  집합 { sqrt(x,y)< 20 && sqrt(x,y) > 15 &&
             z < 6-  abs(x+y)%2  ; 46 }
}

코딩언어에서 a%b 란 a를 b로 나눈 나머지를 뜻한다. 따라서 각각의 좌표 (x,y) 에 대해 abs(x+y)%2 의 값은 엑스좌표와 와이좌표를 더한값의 절대값이 짝수이면 0 이고 홀수이면 1이 된다 (참고: 자바스크립트에서는 -3%2 = -1 이지만, 파이썬에서는 -3%2 = 1 이 된다. 그래서 자바스크립트에서는 abs(a)%b 로 계산). 이것을 이용하여 각 위치에서  z < 6-  abs(x+y))%2  에 의해 성벽을 쌓으면 짝수 위치는 6-0 으로 홀수 위치에서는 6-1 로 높이가 달라져 요철이 만들어지며 성벽 모양이 만들어진다.

위의 명령을 이해하자. sqrt(x,y) 함수와 a%b 연산을 이해하자.