paiza POH silver_bullet #SILVERBULLET #銀の弾丸 #戦場のエンジニア


## Dランク

### 燃える荒野戦(d1)

```awk:d1.awk
#!/usr/bin/awk -f
$0=30*$1
```

### 砂漠の防御戦(d2)

awkの除算は小数になるので…

```sh:d2.sh
#!/bin/bash
read n
echo $(( (n-32)*5/9 ))
```

### 秘密の地下道戦(d3)

```rb:d3.rb
#!/usr/bin/ruby
p *gets.to_i+1...gets.to_i
```

### 失われた娯楽施設戦(d4)

```sh:d4.sh
#!/bin/sh
tr -d '\n'
```

### 打ち捨てられた工場戦(d5)

入力の順番的にRubyよりもPythonが適していると思いまする

```py:d5.py
#!/usr/bin/python
print('DANGER' if input().strip() in input() else 'OK')
```

## Cランク

### 崩壊した市街地戦(c1)

なんか泥臭いなぁ

```rb:c1.rb
#!/usr/bin/ruby
gets.to_i.times{
	a,b=gets.split
	b=b.to_i
	a=a.chars.map(&:to_i)
	puts [a[0]*10+a[1]+a[2], a[0]+a[1]*10+a[2], a[0]+a[1]+a[2]].include?(b) ? :Yes : :No
}
```

### 敵拠点への潜入戦(c2)

xor操作は数値でやったほうが速いんだろうか、どっちだろう。

```rb:c2.rb
#!/usr/bin/ruby
s=gets.chomp.chars.map(&:to_i)
gets.to_i.times{
	x,y=gets.split.map{|e|e.to_i-1}
	(x..y).each{|i|s[i]^=1}
}
puts s*''
```

### 国境の防衛戦(c3)

```rb:c3.rb
#!/usr/bin/ruby
gets.to_i.times{puts gets.split('//')[0]}
```

## Bランク

### ひび割れた大地戦(b1)

```rb:b1.rb
#!/usr/bin/ruby
h,w,x=gets.split.map &:to_i
x-=1;y=x;r=0
h.times{
	a=gets.split.map &:to_i
	(x..y).each{|i|r+=a[i]}
	x-=1 if 0<x
	y+=1 if y<w-1
}
p r
```

### 黒煙の戦車戦(b2)

壁の幅が広いサンプルがほしいですね。。

```rb:b2.rb
#!/usr/bin/ruby

#壁の幅は1とは限らんのね
h,w,s=gets.split.map &:to_i
l=gets.chomp
idx=l.index(s.to_s)
idxes=[]
l.size.times{|i|idxes<<i if l[i]!='#'}
(h-2).times{
	l=gets
	if 1<idx && l[idx-1]=='.'
		idx=idxes[idxes.index(idx)-1]
	elsif idx<w-1 && l[idx+1]=='.'
		idx=idxes[idxes.index(idx)+1]
	end
}
puts gets[idx]
```

### 森林の塹壕戦(b3)

```rb:b3.rb
#!/usr/bin/ruby
n,t=gets.split.map &:to_i
a=n.times.map{gets.split.map &:to_i}
r=0
while t!=0
	r+=a[t-1][1]
	t=a[t-1][0]
end
p r
```

## Aランク

### 白銀の雪原戦(a1)

慣れてさえいればb2よりかんたんでは。。

```rb:a1.rb
#!/usr/bin/ruby
def hypot(a,b)
	Math.hypot(a[0]-b[0],a[1]-b[1])
end
def f(a)
	x,y,z = a.each_slice(2).to_a
	a=hypot(x,y)
	b=hypot(y,z)
	c=hypot(z,x)
	s=(a+b+c)/2
	s*(s-a)*(s-b)*(s-c)
end
p (1..gets.to_i).each.max_by{
	gets.split.map(&:to_i).permutation.map(&method(:f)).max
}
```

## Sランク

### 夕暮れの空中戦(s1)

- 220202: ランク外になったため322点の答案を公開します.
- `lambda_list.reduce(initial){|s,f|f.call(s)}`は、initialにlambda_list内の1引数を取るlambdaを順番に適用するという意味です。[関数合成にも使えたりします。](https://qiita.com/cielavenir/items/2a685d3080862f2c2c47#ruby)

```rb:s1.rb
#!/usr/bin/env ruby
#coding:utf-8
require 'json'

# 埋める方向を決め打ちすると317点だけど、反転・回転総当りで埋める方向を決めると322点に伸ばせるらしい

class Array
	def rotate180
		self.reverse.map(&:reverse)
	end
	def rotate90
		self.reverse.transpose
	end
	def rotate270
		self.transpose.reverse
	end
end

A=[
	[ # 反転
		lambda{|a|a},
		lambda{|a|a.map(&:reverse)},
	],[ # 回転
		lambda{|a|a},
		lambda{|a|a.rotate90},
		lambda{|a|a.rotate180},
		lambda{|a|a.rotate270},
	]
]

Arev=[
	[ # 反転
		lambda{|a|a},
		lambda{|a|a.map(&:reverse)},
	],[ # 回転
		lambda{|a|a},
		lambda{|a|a.rotate270},
		lambda{|a|a.rotate180},
		lambda{|a|a.rotate90},
	]
]

T=[
	[[0,0],[1,0],[0,1]],
	[[0,0],[1,1],[0,1]],
	[[0,0],[1,1],[1,0]],
	[[1,1],[1,0],[0,1]],
]
Blocks='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrtsuvwxyz'
Siz=gets.to_i
M=Siz.times.map{gets.chomp.chars}

def f(m)
	blockidx=0
	(Siz-1).times{|y|
		(Siz-1).times{|x|
			T.each{|t|
	 			if t.all?{|dy,dx|m[y+dy][x+dx]=='.'}
					# 隣り合わないブロックは同じアルファベットを使って良いので、盤面の大きさは20x20だし、まあ巡回させればいいよね
					t.each{|dy,dx|m[y+dy][x+dx]=Blocks[blockidx%Blocks.size]}
					blockidx+=1
				end
			}
		}
	}
	blockidx
end

g_blockidx = 0
g_m = nil
af = A[0].product(*A[1..-1])
ar = Arev[0].product(*Arev[1..-1]).map(&:reverse)

af.size.times{|ai|
	m1 = JSON.parse JSON.generate M
	m2 = af[ai].reduce(m1){|s,f|f.call(s)}
	blockidx = f(m2)
	if blockidx > g_blockidx
		g_blockidx = blockidx
		g_m = ar[ai].reduce(m2){|s,f|f.call(s)}
	end
}

if g_blockidx==0
	puts :No
else
	puts :Yes
	puts g_m.map(&:join)
end
```