42
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

AtCoder に登録したら解くべき粟遞過去問 10 問を Whitespace で解いおみた

42
Last updated at Posted at 2018-03-24

はじめに

drken さんの 粟遞過去問 10 問 をゞョヌク蚀語の Whitespace で解いおみたしたコンテストペヌゞはこちらです

同じく難解蚀語である Piet で ABS を解いた方basemusi さんに觊発されおやっおしたいたした

远蚘

2018/3/24 14時頃提出コヌドぞのリンクを貌りたした゜ヌスが読めないず盛り䞊がっおいたすがCodeforces で Hack 察策にこれを䜿うずおそらく芏玄1に匕っかかるのでしないようにしたしょうね

察象

各皮䞻流蚀語でのコヌディングに疲れおきお気分転換をしたい方ゞョヌク蚀語で遊んでみたい方 人ずは違ったこずをしお泚目を集めおみたい方

呜什が特城的な蚀語ではそれに応じた考察をする2こずで普段ずは違った解き方が芋えおきお楜しいかもしれたせん

TL; DR

実質アセンブラ

Whitespace ずは

Edwin Brady 氏ず Chris Morris 氏によっお蚭蚈された蚀語で2003 幎の゚むプリルフヌルに発衚された蚀語です3名前の通り゜ヌスコヌドは以䞋の䞉぀の空癜文字から成りたす

  • スペヌスASCII 32
  • 氎平タブASCII 9
  • 改行文字ASCII 104

これらの文字の組み合わせによっお各皮呜什を衚珟したすよくある Brainf*ck の掟生劣化蚀語ではありたせんスタックずヒヌプを甚いおコヌディングを行いたすここでいうヒヌプはフィボナッチヒヌプのような意味でのヒヌプではなくヒヌプ領域の意味ず思われたす奜きに䜿っおよい配列のようなものず思っおおいお問題ないはずです

たた以䞋の説明においおは文字通り可読性のためにスペヌスを S氎平タブを T改行文字linefeedを L で衚すこずにしたす蚀語のアむデンティティこわれる

呜什に぀いお5

Whitespace の各呜什は IMPInstruction Modification Parameterず呌ばれる文字列で始たりたすこれにより呜什がカテゎリ分けされおいたす

IMP カテゎリ
S スタック操䜜
TS 算術挔算
TT ヒヌプ操䜜
TL 入出力
L フロヌ制埡

IMP に続く文字列によっお现かい呜什を衚珟したす呜什が匕数をずる堎合はコマンドの盎埌に敎数リテラルを曞きたす

敎数リテラル

2進数に基づく衚珟をしたすが2の補数衚珟は甚いられたせん笊号・絶察倀衚珟を甚いたすS が 0 にT が 1 に察応しおおりL で終端を衚したす任意ビット長の敎数を甚いるこずができたすたずえば +4 は STSSL-7 は TTTTL ずなりたすたた浮動小数点数や実数は芏定されおいたせん

スタック操䜜

コマンド 匕数 呜什の内容
S S 数倀 スタックに䞎えられた数倀を積む
S LS なし スタックの先頭ず同じ倀をさらにスタックに積む
S LT なし スタックの先頭芁玠ず次の芁玠を入れ替える
S LL なし スタックの先頭芁玠を取り陀く

ここでスタックの先頭は埌に入れられた芁玠先に取り陀かれる芁玠C++ でいうずころの std::stack::top() で埗られる芁玠を指したす

算術挔算

コマンド 匕数 呜什の内容
TS SS なし 加算
TS ST なし 枛算
TS SL なし 乗算
TS TS なし 陀算
TS TT なし 剰䜙算

スタックに積たれた二぀の数に぀いお挔算を行いたす先に積たれた芁玠が巊オペランド次の芁玠が右オペランドになりたす挔算結果がスタックに積たれたす

ヒヌプ操䜜

コマンド 匕数 呜什の内容
TT S なし 栌玍
TT T なし 取り出し

栌玍の際はたず栌玍先アドレスを次に栌玍したい倀をスタックに積みこの呜什を呌びたす取り出しの際は取り出したいアドレスをスタックに積みこの呜什を呌びたす取り出された倀はスタックに積たれたす

入出力

コマンド 匕数 呜什の内容
TL SS なし スタックの先頭芁玠を文字ずしお出力
TL ST なし スタックの先頭芁玠を敎数ずしお出力
TL TS なし スタックの先頭芁玠が指すアドレスぞ文字ずしお入力を受け取る
TL TT なし スタックの先頭芁玠が指すアドレスぞ敎数ずしお入力を受け取る

フロヌ制埡

各皮ゞャンプやラベル付け関数呌び出しなどを行うこずができたすラベルは敎数リテラルを甚いたすたたラベルの名前空間は䞀぀のみでありすべおのラベルは unique である必芁がありたす

コマンド 匕数 呜什の内容
L SS ラベル 䞎えられたラベルを呜什の眮かれた堎所に付ける
L ST ラベル 関数呌び出し
L SL ラベル ラベルが瀺す先に以䞋同様無条件ゞャンプ
L TS ラベル スタックの先頭芁玠が 0 ならゞャンプ
L TT ラベル スタックの先頭芁玠が負ならゞャンプ
L TL なし 関数を終了しお caller の元ぞ垰る
L LL なし プログラムを終了する

以䞊が Whitespace で䜿える呜什列になりたす

いざ出陣

珟状AtCoder では Whitespace を甚いるこずができたせんえヌんそのため今回は C++ でむンタプリタを実装しWhitespace の゜ヌスをそこに埋め蟌む圢で提出したした

これを曞いおいる途䞭にむンタプリタの実装ミスに気づき「Whitespace らしき䜕か」を提出しおいたこずが刀明したので正しく盎しお再提出したしたただ実装ミスがあったり仕様の勘違いがあるかもしれたせん

解法

0 問目PracticeA - はじめおのあっずこヌだヌWelcome to AtCoder

敎数 $a$$b$$c$ および文字列 $s$ が䞎えられるので $a+b+c$' '$s$'\n' を出力したす

Brainf*ck ずは違い敎数の入出力で苊しむこずはありたせんやるだけです


practice_1.ws
   
	
		   	
	
		   
			   	
				      
	
		   
				   	
 	   
	
	    	     
	
  
   
   
	
	    
			 
 	
     	 	 
 
		  	
		 



提出コヌド

1 問目ABC086A - Product

敎数 $a$$b$ が䞎えられるので $a\times b$ の偶奇を刀定したす

「$a$ が偶数なら 'Even'」「$b$ が偶数なら 'Even'」「それ以倖なら 'Odd'」ずいう方針でもよいですが面倒なので指瀺された通り掛け算をすればよいです


abc086_a.ws
   
	
		   	
	
		   
			   	
				  
   	 
	 		
	  
   	 	 
   		  	  
   		  	  
   	  				
	
  	
  	
  	
  



   
   	 	 
   		 			 
   		  	 	
   			 		 
   	   	 	
	
  	
  	
  	
  	
  


提出コヌド

2 問目ABC081A - Placing Marbles

文字 $s_1s_2s_3$ が䞎えられるのでそれらに含たれる '1' の個数をカりントしたす敎数ずしお受け取っお 9 で割ったあたりを出力しおもよいですが甘えのような気がしたので指瀺通りやりたす3 回のルヌプを回せばよいです


abc081_a.ws
   
   
		   			

   
   	
	
	    	
			   		    
	  	
	  	
   
   
			   	
	   		 
   	
   	
	    
 
		 
   
				
 	   	 	 
	
  


提出コヌド

3 問目ABC081B - Shift only

$N$ 個の敎数 $A_1$ から $A_N$ が䞎えられるのでそれらの二進数衚瀺の trailing zero の最小個数を求めたす

これを解くにあたっおは $O(1)$ の空間さえあれば十分ですすなわち「今の入力」ず「今たでの trailing zero の最小個数」です個数を数える関数ず最小倀を曎新する関数を䜜りたした最初の難関です

今回のようにルヌプ䞭でルヌプ倉数を䜿甚する必芁がないずきはルヌプ倉数の正負をあらかじめ逆転しおおくず += 1 ず jump if neg だけでルヌプさせるこずができお楜です6


abc081_b.ws
   
   	 	   
		    	
	
		   	
			  		
	  

   
   	
	
		   	
			
 	 	

 	 	  
   	
	    
 
		 
   
				
 	   	 	 
	
  



   	
   
 
	
   	 
 
    	
	      	 
	 		
	  		
   	 
	 	  
	   	
	    
	
 
 	 

   		
 


	

   	  
 
    
				  	
		 	 	
 


	

   	 	
   
 
			 
	

提出コヌド

4 問目ABC087B - Coins

敎数 $A$$B$$C$$X$ が䞎えられるので$500a+100b+50c=X$ を満たす自然数解 $(a, b, c)$ の個数を数えたす$0\in\mathbb{N}$ $a\le A$$b\le B$$c\le C$ です

䞉重ルヌプを曞きたすルヌプの最も内偎で刀定甚の関数を呌び出したすスタックに返り倀を積むなどしお caller 偎で個数を数えるのが綺麗なのかもしれたせんが呌び出した関数偎で凊理しおしたいたした


abc087_b.ws
   
   
	
		   	
	
		   	 
	
		   		
	
		   		
   		
			   		  	 
	 	 		    	  
   
					    	 	
   	
					    		 
   	 
					 
   

 	 	  
   		 
			   	
	  	 
    		 
 
			 
		 	

 
 

   	
   		 
   	 
					    	 	
			   	
	  	 
    	 	
 
			 
		 	 

 
 

   	 
   	 	
   	
					    	  
			   	
	  	 
    	  
 
			 
		 		

 
 

   		
	
 	   	 	 
	
  



   	  
   		
			   		 
				  	   	 
   	 	
				  
	  	   	 	 
   	  
				  
	  	
	  	 	

	

   	 	
   	
	   
	

提出コヌド

5 問目ABC083B - Some Sums

敎数 $N$$A$$B$ が䞎えられるので$1$ 以䞊 $N$ 以䞋の敎数のうちで 10 進法での桁和が $A$ 以䞊 $B$ 以䞋であるものの個数を数えたす

ルヌプを回しお関数を呌び出しお出力したすこの蟺りから虚無を感じ始めおきたす


abc083_b.ws
   
   
	
		   	
	
		   	 
	
		   
			
   
 
 
 	 	 

 	 	 	
   	
	  	 
 
	  	

 
 

   	
 

	
 	   	 	 
	
  



   	 
   		
   
		 
   		
 
    	 	 
	 		   		
				      		
 
			    	 	 
	 	  
 
	  	  

 
 		

   	  
 


	

   	 	
   		
			   	
				  	
		 		 
   		
			   	 
			 
		  	
		 		 
 
    		
 
			  
	   		
				    
	
   		 

	

提出コヌド

6 問目ABC088B - Card Game for Two

$N$ 個の敎数 $a_1$ から $a_N$ があり倀の倧きい方から亀互に二人で取り合うこずを考えたすこのずき䞡者の埗た敎数の合蚈の差を求めたす

゜ヌトしお笊号を入れ替え぀぀足しおいけばよいのですがWhitespace で゜ヌトを実装する気にはならなかったので考察をしたす

$N$ 個の敎数に重耇がある堎合を考えたす同じ敎数が二぀あった堎合䞡者は亀互に取り合うこずから差ずしおは無芖するこずができたすすなわち各敎数の個数の偶奇さえ持っおおけばよいこずになりたす

$a_i$ の䞊限が小さいため配列で管理するこずができたす具䜓的には各 $i$ に察しお count[a_i] を count[a_i] = 1-count[a_i] で曎新したす

入力を受け取った埌はcount[100] から降順に芋おいきcount[j] が 1 なら答えに j を足し匕きしたす笊号は別でもっおおいお亀互に倉える

これで$O(N+\max a_i)$ で解けたした


abc088_b.ws
   		  	  

   
 
    
		    	
	  	 
 
	  	

 
 

   	
 

   
   
	
		   
				  	
   	 
   
	
		   
			 
 			   	
 
		  			    	
	    
 
		 	 
 

   
   
		    		  	 	
   	
		    		  	  

   		
 
 			
	  	  
 
    		  	 	
				  
   
				      
 
			    		  	 	
   		  	 	
			  		
	  
		 
   	  
   	
	  	 
 
	  	 	

 
 		

   	 	
 

   
				
 	   	 	 
	
  


提出コヌド

7 問目ABC085B - Kagami Mochi

$N$ 個の敎数 $d_1$ から $d_N$ のうちで unique なものの個数を数えたす7

実質的に 6 問目ず同じで個数を数えおいきたす今回は偶奇ではなく OR で曎新したすすなわちcount[a_i] = 1 ず曎新しおcount[j] が 1 なら答えに 1 足したすずいうか盎接 count[j] を足しおもいいです簡単ですね


abc085_b.ws
   		  	  

   
 
    
		    	
	  	 
 
	  	

 
 

   	
 

   
   
	
		   
				  	
   	 
   
	
		   
			   	
		    	
	    
 
		 	 
 

   
   
		    		  	  

   		
 
 			   
				      
 
			    	
	  	 
 
	  	  

 
 		

   	  
 

   
				
 	   	 	 
	
  


提出コヌド

8 問目ABC085C - Otoshidama

敎数 $N$ ず $Y$ が䞎えられるので

\left\{\begin{array}{l}
x + y + z = N \\
10000x + 5000y + 1000z = Y
\end{array}\right.

の自然数解$0\in\mathbb{N}$をひず぀出力したす存圚しなければ '-1 -1 -1' を出力したす

$Y$ が 1000 の倍数であるこずになっおいるのでY = Y/1000 - N ずしおおきx ず y に぀いお二重ルヌプを回しお Y-9*x-4*y を 0 たらしめる x ず y が芋぀かればそれらず N-x-y をそうでなければ -1 たちを出力したす

倚重ルヌプを回し぀぀ルヌプ倉数を䜿おうずするずたぶんスタックだけでは事足りなくなるので倧倉ですね


abc085_c.ws
   
	
		   	
   	
	
		   	
			   					 	   
	 	    
				  			    	 
   
					    		
   
		 
   

 	 		
   		
			   	
	  	 
    		
 
			 
		 	

 
 

   	
   	 
			   	
	  	 
    	 
 
			 
		 	 
   		
   
			   	 
				  			 
 
 

   	 
  		
	
 	   	     
	
    		
	
 	   	     
	
    		
	
 	   	 	 
	
  



   		
   	
			   	  	
   	 
				  
   	  
   		
				  
	   	  	
	  	  

	

   	  
   	 
				
 	   	     
	
     		
				
 	   	     
	
     
			   	 
			   		
				   	  		
 	   	 	 
	
  


提出コヌド

9 問目ABC049C - 癜昌倢 / Daydream

正芏衚珟で殎りたすできたらなあ


arc065_a.ws
   	

   
 
 	
	  
 			   	 	 
	  	
	  	
   	
	   
 
 

   	
   	
	  	
   	 

 	 	 	
 
 
	  	  

 
 	 

   		
   	 	 
   	  				
   	  			 
	
  	
  	
  



   	  
   	 	 
   	 	  		
   	   	 	
   	 		  	
	
  	
  	
  	
  



   	 	
 
    			  	 

 	 	 	 

	  		 
   	
	  	 
    		  	 	

 	 	 	 

	  		
   	
	  	 
    		 		 	

 	 	 	 

		 			
 
    			  		

 	 	 	 

	  		

 
 	  	

   		 
 
    		 		 	

 	 	 	 

	  	   

   			
   	
	  	 
    		    	

 	 	 	 

	  		
   	
	  	 
    		  	 	

 	 	 	 

	  		
   	
	  	 
    			  	 

 	 	 	 

	  		
   	
	  	 
    		  	  

 	 	 	 

	  		
   	
	  	
	

   	   
 
    		  	 	

 	 	 	 

	  		
   	
	  	 
    			  		

 	 	 	 

	  		

   	  	
   	
	  	 
    		    	

 	 	 	 

	  		
   	
	  	 
    			  	 

 	 	 	 

	  		
   	
	  	 
    		  	 	

 	 	 	 

	  		
   	
	  	
	

   	 	 
 
					  	
	  	 		
   

	

   	 		
  		

	

提出コヌド

10 問目ABC086C - Traveling

たぶん 9 問目の方が぀らいですこれも $O(1)$ の空間があれば十分ですね

txy および前の倀ずの差分の絶察倀 dtdxdy を持っおおきたすdt < dx + dy たたは (dt+dx+dy)%2 > 0 になるこずがあれば 'No'最埌たで耐え切れば 'Yes' です倧文字小文字に気を取られお改行を出力し忘れお WAなんおこずがないようにしたしょうね

ずころでどうやら dx などを考慮しなくおも AC できる嘘解法があるようですあず$i=1$ の郚分しか刀定しないず思われるバグを提出したずころ WA のケヌスが䞀぀だけだったので怖かったです


arc089_a.ws
   
   
   
	
		   
				  	   
   
		    	
   
		    	 
   
		    		
   
		    	  
   
		    	 	
   
		 
   
   		
	
		   		
			 
    
				  	   		
 
			    
 
			    	  
	
		   	  
			 
    	
				  	
 	 	 
   	  
 
			    	
 
			    	 	
	
		   	 	
			 
    	 
				  	
 	 	 
   	 	
 
			    	 
 
			    	  
			   	 	
				    
    		
			 
		  	
		 	
   		
				      	
	      	 
	 		
	  	
   	
	    
 
		 
   	 	 
   			  		
   		  	 	
   	 		  	
	
  	
  	
  	
  



   	
   	 	 
   		 				
   	  			 
	
  	
  	
  



   	 
 
 
		 		

	

   		
  		
	  

	

提出コヌド

あずがき

Whitespace を曞いおいたはずなのにコヌディングフェむズではほずんど印字可胜文字ばかり入力しおいたしたアセンブラ颚の代替蚀語を曞いおそれを Whitespace に倉換するスクリプトBashにおたかせしたした

そのスクリプトにバグがあったり代替蚀語でミスを埋め蟌んだり散々でした眰が圓たったわけですね

あず Whitespace の゜ヌスを貌る際に通垞の ``` で囲む方法ではタブがスペヌスに展開されたり印字可胜文字のない行の空癜が省かれたりしお぀らかったです結局 HTML を盎接曞きたしたいい方法があったら教えおほしいですね

  1. Can-do's and Can't-do's の 4. ↩

  2. n57577 ↩

  3. https://esolangs.org/wiki/Whitespace やそのリンク先が参考になりたす ↩

  4. 実際には氎平タブや改行文字を入力しおいるのにここでの衚瀺では同じになっおしたっおいお぀らいいい方法があれば教えおほしいです...ず思ったけどプレビュヌずは衚瀺が違っおいお困惑 ↩

  5. https://hackage.haskell.org/package/whitespace-0.4/src/docs/tutorial.html や http://web.archive.org/web/20150618184706/http://compsoc.dur.ac.uk/whitespace/tutorial.php など ↩

  6. Human Resource Machine ずいうゲヌムで埗た知芋です垞識なのかもしれたせん ↩

  7. n575 ↩

  8. Atcoder ではなくお AtCoder です間違えないようにしたしょうねWhiteSpace ではなくお Whitespace だず思うのですが既存のタグに合わせおしたいたしたよわい
    文字列を埌ろから読んでいっお 'maerd''remaerd''esare''resare' のいずれにもマッチしない郚分があれば 'NO'先頭たでマッチさせ続けられれば 'YES' を出力したすcase-insensitive な人間8にならないように泚意したしょう ↩

42
11
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
42
11

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?