結果

問題 No.677 10^Nの約数
ユーザー maimai
提出日時 2018-09-26 00:17:57
言語 Ruby
(3.3.0)
結果
AC  
実行時間 342 ms / 2,000 ms
コード長 12,155 bytes
コンパイル時間 56 ms
コンパイル使用メモリ 7,680 KB
実行使用メモリ 15,488 KB
最終ジャッジ日時 2024-04-16 11:54:49
合計ジャッジ時間 4,498 ms
ジャッジサーバーID
(参考情報)
judge1 / judge4
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 109 ms
15,360 KB
testcase_01 AC 100 ms
15,104 KB
testcase_02 AC 102 ms
15,232 KB
testcase_03 AC 107 ms
15,488 KB
testcase_04 AC 106 ms
15,488 KB
testcase_05 AC 116 ms
15,360 KB
testcase_06 AC 118 ms
15,360 KB
testcase_07 AC 129 ms
15,360 KB
testcase_08 AC 138 ms
15,360 KB
testcase_09 AC 148 ms
15,232 KB
testcase_10 AC 158 ms
15,232 KB
testcase_11 AC 177 ms
15,232 KB
testcase_12 AC 193 ms
15,232 KB
testcase_13 AC 213 ms
15,488 KB
testcase_14 AC 232 ms
15,104 KB
testcase_15 AC 266 ms
15,360 KB
testcase_16 AC 288 ms
15,232 KB
testcase_17 AC 320 ms
15,360 KB
testcase_18 AC 342 ms
15,360 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
Syntax OK

ソースコード

diff #

require 'stringio'

module WhitespaceCompiler
    
    class WhitespaceParseError < RuntimeError
        def initialize(io)
        end
    end
    
    
    def readchar(io, eof = false)
        loop do
            if io.eof?
                return :eof if eof
                raise WhitespaceParseError.new(io)
            end
            c = io.readbyte
            return :sp if c == 32 # 83
            return :tb if c == 9 # 84
            return :lf if c == 10 # 76
        end
    end
    
    
    def parse_int(io)
        sign = 0
        val = 0
        loop do
            c = readchar(io)
            if c == :lf
                raise WhitespaceParseError.new(io) if sign == 0
                return sign*val
            end
            if sign == 0
                sign = c == :tb ? -1 : 1
            else
                val = (val << 1)
                val |= 1 if c == :tb
            end
        end
    end
    
    
    def parse_instruction(io)
        c1 = readchar(io, true)
        return nil if c1 == :eof
        
        if c1 == :sp
            c2 = readchar(io)
            return [:stk_push, parse_int(io)] if c2 == :sp
            if c2 == :lf
                c3 = readchar(io)
                return [:stk_dup] if c3 == :sp
                return [:stk_swap] if c3 == :tb
                return [:stk_del] if c3 == :lf
            end
        elsif c1 == :lf
            c2 = readchar(io)
            c3 = readchar(io)
            return [:flw_label, parse_int(io)] if c2 == :sp && c3 == :sp
            return [:flw_call,  parse_int(io)] if c2 == :sp && c3 == :tb
            return [:flw_jump,  parse_int(io)] if c2 == :sp && c3 == :lf
            return [:flw_jumpz, parse_int(io)] if c2 == :tb && c3 == :sp
            return [:flw_jumpn, parse_int(io)] if c2 == :tb && c3 == :tb
            return [:flw_ret]                   if c2 == :tb && c3 == :lf
            return [:flw_exit]                  if c2 == :lf && c3 == :lf
        elsif c1 == :tb
            c2 = readchar(io)
            if c2 == :sp
                c3 = readchar(io)
                c4 = readchar(io)
                return [:art_add] if c3 == :sp && c4 == :sp
                return [:art_sub] if c3 == :sp && c4 == :tb
                return [:art_mul] if c3 == :sp && c4 == :lf
                return [:art_div] if c3 == :tb && c4 == :sp
                return [:art_mod] if c3 == :tb && c4 == :tb
            elsif c2 == :tb
                c3 = readchar(io)
                return [:hep_store] if c3 == :sp
                return [:hep_ret]   if c3 == :tb
            elsif c2 == :lf
                c3 = readchar(io)
                c4 = readchar(io)
                return [:iop_outc] if c3 == :sp && c4 == :sp
                return [:iop_outn] if c3 == :sp && c4 == :tb
                return [:iop_readc] if c3 == :tb && c4 == :sp
                return [:iop_readn] if c3 == :tb && c4 == :tb
            end
        end
        raise WhitespaceParseError.new(io)
    end
    
    
    def parse(io)
        extend WhitespaceCompiler
        io = StringIO.new(io, 'r') if io.is_a? String
        label = {}
        code = []
        
        loop do
            inst = parse_instruction(io)
            break if inst.nil?
            code += inst
            label[inst[1]] = code.size-2 if inst[0] == :flw_label
        end
        return [code, label]
    end
    module_function :parse
end




class WhitespaceInterpreter
    
    class WhitespaceRuntimeError < RuntimeError
        def initialize(wip = '')
            if wip.is_a? WhitespaceInterpreter
                @wip = wip
                msg = "[pc=%d, stack.size=%d, callstack.size=%d]"%[wip.pc, wip.stack.size, wip.callstack.size]
                super msg
            else
                super
            end
        end
    end
    
    def initialize(code, label, stdinio)
        @code = code
        @label = label
        self.stdin = stdinio
        reset()
    end
    
    attr_reader :stdin, :stdout, :pc, :halt, :stack, :heap, :callstack
    def stdin=(s)
        s = StringIO.new(s, 'r') if s.is_a? String
        @stdin = s
    end
    
    def reset
        @pc = 0
        @halt = false
        @stack = []
        @heap = []
        @callstack = []
        @stdout = ''
        self
    end
    
    def step
        return false if @halt
        unless 0 <= @pc && @pc < @code.size
            raise WhitespaceRuntimeError.new(self)
        end
        #p [@code[@pc], @code[@pc+1], @stack, @callstack]
        #abort if @callstack.size >= 4
        self.send(@code[@pc], @code[@pc+1])
        @pc += 1
        true
    end
    
    def run
        while step
        end
        self
    end
    
    
    def getchar
        @stdin.eof? ? -1 : @stdin.readbyte
    end
    
    def getint
        a = @stdin.gets
        a ? a.to_i : 0
    end
    
    
    def stk_push(val)
        @stack.push(val)
        @pc += 1
    end
    def stk_dup(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        @stack.push(@stack[-1])
    end
    def stk_swap(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 2
        @stack[-1], @stack[-2] = @stack[-2], @stack[-1]
    end
    def stk_del(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        @stack.pop()
    end
    
    def flw_label(label)
        # ignore
        @pc += 1
    end
    def flw_call(label)
        pc = @label[label]
        raise WhitespaceRuntimeError.new(self) if pc.nil?
        @callstack.push(@pc+1)
        @pc = pc+1
    end
    def flw_jump(label)
        pc = @label[label]
        raise WhitespaceRuntimeError.new(self) if pc.nil?
        @pc = pc+1
    end
    def flw_jumpz(label)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        @pc += 1
        flw_jump(label) if @stack.pop() == 0
    end
    def flw_jumpn(label)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        @pc += 1
        flw_jump(label) if @stack.pop() < 0
    end
    def flw_ret(_)
        raise WhitespaceRuntimeError.new(self) if @callstack.size < 1
        @pc = @callstack.pop
    end
    def flw_exit(_)
        @halt = true
    end
    
    def art_add(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 2
        a, b = @stack.pop(2)
        @stack.push(a + b)
    end
    def art_sub(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 2
        a, b = @stack.pop(2)
        @stack.push(a - b)
    end
    def art_mul(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 2
        a, b = @stack.pop(2)
        @stack.push(a * b)
    end
    def art_div(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 2
        a, b = @stack.pop(2)
        @stack.push(a / b)
    end
    def art_mod(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 2
        a, b = @stack.pop(2)
        @stack.push(a % b)
    end
    
    def hep_store(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 2
        adr, val = @stack.pop(2)
        @heap[adr] = val
    end
    def hep_ret(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        adr = @stack.pop
        raise WhitespaceRuntimeError.new(self) if @heap[adr].nil?
        @stack.push(@heap[adr])
    end
    
    def iop_outc(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        @stdout << ("%c"%(@stack.pop))
    end
    def iop_outn(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        @stdout << @stack.pop.to_s
    end
    def iop_readc(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        adr = @stack.pop
        @heap[adr] = getchar()
    end
    def iop_readn(_)
        raise WhitespaceRuntimeError.new(self) if @stack.size < 1
        adr = @stack.pop
        @heap[adr] = getint()
    end
    
end


code, label = WhitespaceCompiler.parse("   	 
   	   
		    		
   	   
		 
 
 

   	 

	  		
 
	
   		
 


	

   	  

		 	 	
 
	
   	 	
 


	

   		 

	  			
 
 
	  			
 

   	

	

   			
 

   

	

   	   

	  	  	
 

   	

	

   	  	

	  	 	 
   	

	

   	 	 
   

	

   

 
 	   	

   	    
   	 
			   		
			 
    	 
 
			    		
	      		
 
			    	  
 
			    	 	
   	
   	 
				   		    	 	
			 
			    	 	
			  		
	    
			    	  
			   	 
   	 
				    
    
   	 
				   								 			 

   
   	 
				   			 
    	
   	 
				   								 			 

   	
   	 
				   			 
    	 
   	 
				   					 			 

   	 
			   		
 
			    	 
 
			    

	

   	   	

 
 	  		

   	  	 
   	 
			   		
			 
    	 
 
			    	 	
	      		
 
			    	  
 
			    	 	
   	
   	 
				   		    	 	
			 
			    	 	
			  		
	    
			    	  
			
   	 	  
   	
   	 
				   			   
   	 
				   				  	   	
 
		  	
		 	 	 	
   	 
			   		
 
			    	 
 
			    

	

   	 	 	

   	 		 
   	
   
   	
   	 
				   			   
   	 
				   				  	   	 
	  	
 	 	 

	  	 			
   	
   	 
				    
  
 			   	
	  			 			 


   		   
   	
   
   
   	 
				   						   	
   	 
				   						 
		  	
 	 	  

	  		  	
   
   	 
				   			   	
   	 
				   			
 	 	    
 


   		  	
   	 
			   		
 
			    	 
 
			    

	

   	 			
   	 
   	 
				    
    
	      
   	 
				   					    	
	      
   	 
				   			   	
	   		    
   	 
				   			   
   	 
				   			   	
   	 
				   				      	 
	 	 
 	 	    
 


   		 	 
   	
   
   		
   	 
				   			   	
   	 
				   				  	
 	 	  

	  		 		

   			  
   	 
   	 
				   						   		
   	 
				   							  	
		 			 	
   	  
   	 
				    
    	 
   	 
				   			   	
	   					 			 

   	 
   	 
				   			   	
	    
    		
   	 
				   								 			 

   		
   	 
				   			 
    	  
   	 
				   					 			 

   	  
   	 
				    
    	 
   	 
				   								 			 

   	 
   	 
				   			 
    	 
   	 
				    
  
 			   	
	   		 								 			 

   	 
   	 
				   			 
    	  
   	 
				   					 			 


   			 	
   		
   	 
				    
  
 			   	
	   		 			 


 
 		 	 

   		 		
   
   	 
				   			   	 
   	 
				   			
 	 	  	 
 

   	 
   	 
				   			   	
	      	
   	 
				   			
 	 	  	 
 

   	 
			   		
 
			    	 
 
			    

	

   	  		

 
 					

   				 
   	 
			   		
			 
    	 
 
			    		
	      		
 
			    	  
 
			    	 	
   	
   	 
				   		    	 	
			 
			    	 	
			  		
	    
			    	  
			   	 
   	 
				      
	      	
		 
   	     
   
   	
   	
   	
   	 
				   			 
		  	
 	 	  

	  	    	
   	 
   	 
				    
  
 			   
   	 
				   				  
		 			 

   	
   	 
				    
  
 			   	
	  			 			 


 
 	     

   	    	
   	 
   	 
				   			 
	   	 
			   		
 
			    	 
 
			 
	
   	 
			   		
 
			    	 
 
			    

	

   					

 
 	   		

   	   	 
   	 
			   		
			 
    	 
 
			    		  	  		
	      		
 
			    		  	    
   	 
				      
	      
		    
   	 
				    
    	  
	
		   	  
					 			 

   		  	   	
   	 
				    
    
	      
		    	
	      
		 
   	  	  
   
   	
   		  	   	
   	 
				   			   
   	 
				   			 
		  	
 	 	  

	  	  	 	
   		  	  	 
   	 
				    
    
		 			 


   	  		 
   
   	
   		  	  	 
   	 
				   			   
   	 
				   			 
		  	
 	 	  

	  	  			
   	
   	 
				      		  	    
   	 
				   				    
    	 
   		  	   	
   	 
				   			
 	 				 
   	 	
   		  	  	 
   	 
				   			
 	 				 
	  
		 			 

   		  	    
   	 
				    
  
 			   	
	   		 			 

   		  	  	 
   	 
				    
  
 			   	
	   		 			 


 
 	  		 

   	  			
   		  	   	
   	 
				    
  
 			   	
	   		 			 


 
 	  	  

   	  	 	
   	
   	 
				      		  	    
   	 
				   				    
    
		 			 

   	
   	 
				      	
   	 
				      		  	    
   	 
				   				   
 	 	  	 
 

   		  	   	
   	 
				    
    
		 			 

   		  	    
   	 
				    
  
 			   	
	  			 			 


   	 	   
   
   	
   		  	   	
   	 
				   			   		  	    
   	 
				   			 
		  	
 	 	  

	  	 	  	
   	
   	 
				      		  	   	
   	 
				   				   			 
 	
 	 

   	 	 
 
 	
   

   		  	   	
   	 
				    
  
 			   	
	   		 			 


 
 	 	   

   	 	  	
   	 
			   		
 
			    	 
 
			    

	

   	   		

 	 	   	 



")

ip = WhitespaceInterpreter.new(code, label, STDIN.read)
ip.run
print ip.stdout


0