異世界ニートエンジニア英雄になる。

能力値ですがたくさん稼ぎたいので、装備を整えてから訓練に入るべきと思います。[^1]
賢者の衣/賢者のPC/賢者の本を装備できれば、最大で2380*5 = 11900のボーナスとなるようです。

解答は、今回問題が多いので ~~確認できたものから順次掲載します。~~ 102本ノック完遂しました。

なお、BashでいけるものはBashでいきます。[^2]

当時のランキング画像です

![GARitJTasAAvcY3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/29692/6d06e7c6-67b8-590a-2519-930e5b45a7a3.jpeg)

## Practice

### S-Algo (1-7)

#### 1: スーパー鳩時計

```rb
def greet(i)
if i%15==0
puts :FIZZBUZZ
elsif i%3==0
puts :FIZZ
elsif i%5==0
puts :BUZZ
else
puts
end
end
24.times{|i|60.times{|j|greet(i+j)}}
```

#### 2: 格子点

```rb
n=100
m=100000
r=0
(0...n).each{|x|(0...n-x).each{|y|
if x**3+y**3<m
r=[r,x*y].max
end
}}
p r
```

#### 3: お金の支払い

互いが割り切れないと貪欲法は適用できないので注意.全探索で良いと思う.

```rb
X,Y,Z=gets.split.map &:to_i
r=Z
x=0
while x*X<=Z
  y=0
  while x*X+y*Y<=Z
    r=[r,x+y+Z-(x*X+y*Y)].min
    y+=1
  end
  x+=1
end
p r
```

#### 4: 二重ループ：活用編 三角形の探索

```rb
n=gets.to_i
1.upto(n-2){|i|
i.upto(n-1-i){|j|
k=n-i-j
k<i+j && k*k==i*i+j*j && (puts :YES;exit)
}}
puts :NO
```

#### 5: 条件を満たす最小の自然数

これがSってどういうことやねん…

```rb
p (10000..1/0.0).find{|i|i%13==0}
```

#### 6: シミュレーションの練習

```rb
n,a,b=`dd`.split.map &:to_i
x=y=1
r=0
while y<=n
y+=x*a
x+=y%b
r+=1
end
p r
```

#### 7: 辞書

```rb
x,y,z=gets.split.map &:to_i
h={};g={}
x.times{a,b=gets.split.map &:to_i;h[a]=b}
y.times{a,b=gets.split.map &:to_i;g[a]=b}
(1..x).each{|i|puts [i,g[h[i]]]*' '}
```

### S-SQL (8-14)

#### 8: 上から 50 件を取得しよう

```sql
SELECT * FROM ordered_menu LIMIT 50;
```

#### 9: 上から 25 件を取得しよう

```sql
SELECT ordered_id, num, sum FROM ordered_menu LIMIT 25;
```

#### 10: 昇順に並べ替え

```sql
SELECT * FROM ordered ORDER BY bill LIMIT 10;
```

#### 11: 降順に並べ替え

```sql
SELECT ordered_id, num, sum FROM ordered_menu ORDER BY sum DESC LIMIT 100;
```

#### 12: 複数の条件で並べ替え

```sql
SELECT * FROM menu ORDER BY price, name LIMIT 5;
```

#### 13: 複数の条件で並べ替え2

```sql
SELECT name, name_yomi, join_date FROM customer ORDER BY join_date DESC, name_yomi LIMIT 30;
```

#### 14: 価格の高い順に 10 件取得しよう

```sql
SELECT * FROM menu ORDER BY price DESC LIMIT 10;
```

### A-Algo (15-23)

#### 15: 卵の最大の生産量

```rb
n,k,*a=`dd`.split.map &:to_i
b=[0]
a.each{|e|b<<b[-1]+e}
p (0..n-k).map{|i|b[i+k]-b[i]}.max
```

#### 16: FizzBuzz

```rb
(1..100).each{|i|
if i%15==0
puts :FizzBuzz
elsif i%3==0
puts :Fizz
elsif i%5==0
puts :Buzz
else
p i
end
}
```

#### 17: 行列の転置

```rb
H,W=gets.split.map &:to_i
M=H.times.map{gets.split}
puts M.transpose.map{|e|e*' '}
```

#### 18: かけ算表

```rb
n,*a=`dd`.split.map &:to_i
a.each{|e|puts a.map{|f|e*f}*' '}
```

#### 19: 素数の個数

```rb
require'prime'
p (2..gets.to_i).count(&:prime?)
```

#### 20: log2

商を足し続けるやつですね。5でやれば10進法での末尾の0の個数(有名問題)。

非自明なわけですから…この問題セットだったらSとちゃいます?

```rb
n=gets.to_i
r=0
while n>0
n/=2
r+=n
end
p r
```

#### 21: ソートと検索 (query)

```rb
n,k,x=gets.split.map &:to_i
a=([x]+n.times.map{gets.to_i}).sort
r=a.index(x)+1
k.times{
s=gets.chomp
if s=='sorting'
p r
elsif s.split[1].to_i<x
r+=1
end
}
```

#### 22: 累積和

```rb
n,k=gets.split.map &:to_i
a=n.times.map{gets.to_i}
b=[0]
a.each{|e|b<<b[-1]+e}
k.times{p b[gets.to_i]}
```

#### 23: 区間和

```rb
n,k=gets.split.map &:to_i
a=n.times.map{gets.to_i}
b=[0]
a.each{|e|b<<b[-1]+e}
k.times{
l,r=gets.split.map &:to_i
p b[r]-b[l-1]
}
```

### A-SQL (24-32)

#### 24: カテゴリ名の昇順に並べ替えよう

```sql
SELECT category_id, name FROM category ORDER BY name;
```

#### 25: フリガナの昇順に並べ替えよう

```sql
SELECT * FROM customer ORDER BY name_yomi;
```

#### 26: メニュー名の昇順に並べ替えよう

```sql
SELECT name, price FROM menu ORDER BY name;
```

#### 27: 漢字名の昇順に並べ替えよう

```sql
SELECT name, name_yomi FROM customer ORDER BY name;
```

#### 28: 入会した順に並べ替えよう

```sql
SELECT * FROM customer ORDER BY join_date;
```

#### 29: 注文番号、注文数を条件で並べ替え

```sql
SELECT * FROM ordered_menu ORDER BY ordered_id, num DESC;
```

#### 30: 価格、メニュー名を条件で並べ替え

```sql
SELECT * FROM menu ORDER BY price DESC, name;
```

#### 31: 注文数、小計にを条件で並べ替え

```sql
SELECT ordered_id, num, sum FROM ordered_menu ORDER BY num DESC, sum DESC;
```

#### 32: 入会日、名前を条件で並べ替え

```sql
SELECT join_date, name, name_yomi FROM customer ORDER BY join_date, name_yomi;
```

### B-Algo (33-42)

#### 33: 気温2

```rb
n,*a=`dd`.split.map &:to_i
x,y=a.minmax
p y-x
```

#### 34: ゾロ目

```rb
p gets.to_i/11*11
```

#### 35: 寒暖差

```rb
puts `dd`.split.map(&:to_i).each_cons(2).any?{|a,b|(a-b).abs>=3}?:Yes: :No
```

#### 36: 2 の累乗を表示

```rb
p *(1..gets.to_i).map{|i|1<<i}
```

#### 37: 重複の削除

```rb
puts gets.chomp.chars.uniq.join
```

#### 38: 数列の最大値

```rb
gets
p gets.split.map(&:to_i).max
```

#### 39: 数式の計算（ 1 桁）

これがBランクなわけはない、何かの間違いや…

```rb
p eval gets
```

#### 40: 何個ある?

```rb
n,m,*a=`dd`.split.map(&:to_i)
p a.count(n)
```

#### 41: 配列の書き換え

```rb
a,b,n,*x=`dd`.split.map &:to_i
puts x.map{|e|e==a ? b : e}
```

#### 42: 九九の表示 2

```rb
n=gets.to_i
puts (1..9).map{|i|n*i}*' '
```

### B-SQL (43-52)

#### 43: 通し番号の昇順に並べ替えよう

```sql
SELECT customer_id, name, residence FROM customer ORDER BY customer_id;
```

#### 44: メニューを安い順に並べ替えよう

```sql
SELECT * FROM menu ORDER BY price;
```

#### 45: 注文数の降順に並べ替えよう

```sql
SELECT * FROM ordered_menu ORDER BY num DESC;
```

#### 46: カテゴリ番号の降順に並べ替えよう

```sql
SELECT * FROM category ORDER BY category_id DESC;
```

#### 47: 価格の降順に並べ替えよう

```sql
SELECT * FROM menu ORDER BY price DESC;
```

#### 48: 小計の降順に並べ替えよう

```sql
SELECT ordered_id, sum FROM ordered_menu ORDER BY sum DESC;
```

#### 49: 注文番号の降順に並べ替えよう

```sql
SELECT ordered_id, datetime FROM ordered ORDER BY ordered_id DESC;
```

#### 50: 通し番号の降順に並べ替えよう

```sql
SELECT customer_id, name, name_yomi FROM customer ORDER BY customer_id DESC;
```

#### 51: 合計金額の高い順に並べ替えよう

```sql
SELECT * FROM ordered ORDER BY bill DESC;
```

#### 52: 日時の昇順に並べ替えよう

```sql
SELECT * FROM ordered ORDER BY datetime;
```

### C-Algo (53-67)

#### 53: 最大値と最小値

```rb
*a=gets.split.map &:to_i
puts [a.min,a.max]*' '
```

#### 54: テレワーク可能か

```rb
a,b=gets.split
puts a.to_i>=30||b=='rainy' ? :Yes : :No
```

#### 55: 気温

```awk
$0=$1>=35?"extremely hot day":$1>=30?"hot summer day":$1>=25?"summer day":$1<0?"ice day":"normal day"
```


#### 56: 改行区切りでの N 個の整数

```sh
read
dd
```

#### 57: 2 行目で与えられる N 個の整数

```sh
read
tr ' ' $'\n'
```

#### 58: 改行区切りでの N 個の文字列

```sh
read
dd
```

#### 59: 2 行目で与えられる N 個の文字列

```sh
read
tr ' ' $'\n'
```

#### 60: 整数の組からの選択

```rb
8.times{gets}
puts gets
```

#### 61: 文字列と整数の組からの選択

```rb
8.times{gets}
puts gets
```

#### 62: 占い

```awk
$0=$1-7?"No":"Yes"
```

#### 63: 集合の探索

```rb
n,b,*a=`dd`.split.map &:to_i
puts a.include?(b)?:Yes: :No
```

#### 64: 重複の削除

```rb
gets
puts gets.split.uniq*' '
```

#### 65: 重複の判定 1

```rb
n,*a=`dd`.split.map &:to_i
h={a[0]=>1}
(1...n).each{|i|
puts h[a[i]]?:Yes: :No
h[a[i]]=1
}
```

#### 66: 集合の結合

```rb
gets
puts (gets.split|gets.split).map(&:to_i).sort*' '
```

#### 67: 数値の出現率

```rb
h=Hash.new(0)
gets
gets.split.each{|e|h[e.to_i]+=1}
puts 10.times.map{|i|h[i]}*' '
```

### C-SQL (68-77)

#### 68: 注文数、小計を取得しよう

```sql
SELECT num, sum FROM ordered_menu;
```

#### 69: メニュー名、価格を取得しよう

```sql
SELECT name, price FROM menu;
```

#### 70: 漢字名、ふりがなを取得しよう

```sql
SELECT name, name_yomi FROM customer;
```

#### 71: 注文番号、メニュー番号、注文数を取得

```sql
SELECT ordered_id, menu_id, num FROM ordered_menu;
```

#### 72: 漢字名、フリガナ、入会日、居住地を取得しよう

```sql
SELECT name, name_yomi, join_date, residence FROM customer;
```

#### 73: 合計金額の昇順に並べ替えよう

```sql
SELECT * FROM ordered ORDER BY bill;
```

#### 74: 注文数の昇順に並べ替えよう

```sql
SELECT * FROM ordered_menu ORDER BY num;
```

#### 75: カテゴリ番号の昇順に並べ替えよう

```sql
SELECT * FROM category ORDER BY category_id;
```

#### 76: 小計の昇順に並べ替えよう

```sql
SELECT ordered_id, sum FROM ordered_menu ORDER BY sum;
```

#### 77: カテゴリ番号の昇順に並べ替えよう

```sql
SELECT category_id, name FROM menu ORDER BY category_id;
```

### D-Algo (78-92)

#### 78: 1 行の出力

```sh
echo 813
```

#### 79: 3 行の入力

```sh
dd
```

#### 80: 3 つの数値を出力

```sh
echo '8 1 3'
```

#### 81: 半角スペース区切りでの分割

```sh
echo -e "Hello\npaiza"
```

#### 82: 1 つの文字列を出力

```sh
echo paiza
```

#### 83: 1 行の入力

```sh
dd
```

#### 84: 入力された 2 つの文字列を出力

```sh
dd
```

#### 85: 2 行の入力

```sh
dd
```

#### 86: 数行の出力


```sh
seq `dd`
```

```rb
p *1..gets.to_i
```

#### 87: 小文字にする

```sh
tr A-Z a-z
```

#### 88: 半角スペース区切りの 3 つの入力

```sh
tr ' ' $'\n'
```

#### 89: 半角スペース区切りの 10 個の入力

```sh
tr ' ' $'\n'
```

#### 90: 1 行の整数の入力

```sh
dd
```

#### 91: 2 行の整数の入力

```sh
dd
```

#### 92: 5 行の整数の入力

```sh
dd
```

### D-SQL (93-102)

#### 93: 注文履歴を取得しよう

```sql
SELECT * FROM ordered;
```

#### 94: 注文内容を取得しよう

```sql
SELECT * FROM ordered_menu;
```

#### 95: メニューを取得しよう

```sql
SELECT * FROM menu;
```

#### 96: カテゴリを取得しよう

```sql
SELECT * FROM category;
```

#### 97: 会員のリストを取得しよう

```sql
SELECT * FROM customer;
```

#### 98: 合計金額を取得しよう

```sql
SELECT bill FROM ordered;
```

#### 99: 注文番号を取得しよう

```sql
SELECT ordered_id FROM ordered_menu;
```

#### 100: メニュー名を取得しよう

```sql
SELECT name FROM menu;
```

#### 101: カテゴリ名を取得しよう

```sql
SELECT name FROM category;
```

#### 102: 居住地を取得しよう

```sql
SELECT residence FROM customer;
```

## Boss

### boss1: 総攻撃

```sql
SELECT Players.id AS id, SUM(Items.damage*Inventories.count) AS inventory_sum_damage FROM Inventories
  INNER JOIN Players ON Players.id = Inventories.user_id
  INNER JOIN Items ON Items.id = Inventories.item_id
  GROUP BY Players.id;
```

唐突に登場するINNER JOIN。というか練習問題に複数テーブルを組み合わせる問題がないのおかしいやろ…まあ https://paiza.jp/code_and_sql やってれば問題ないんだけどさ。。。

### boss2: 戦闘結果

```rb
x,y,a,b=`dd`.split.map &:to_i
puts [[(a*x-b*y)/a,:Player],[(b*y-a*x)/b,:Enemy]].max.reverse
```

x=y=b=1; a=100などとするとわかりますが、`x-b*y/a`と`(a*x-b*y)/a`は異なるので十分に注意してください(1WA)。

### boss3: 数の分割

```rb
s=gets.chomp
p (1..s.size-2).map{|i|
(s[0,i].to_i-s[i..-1].to_i).abs
}.min
```

### boss4: 危険度調査

```rb
T=[[-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1]]
H,W=gets.split.map &:to_i
M=H.times.map{gets.chomp}
H.times{|y|W.times{|x|
M[y][x]!='#' && M[y][x]=T.count{|dy,dx|ny=dy+y;nx=dx+x;0<=ny&&ny<H&&0<=nx&&nx<W&&M[ny][nx]=='#'}.to_s
}}
puts M
```

[^1]: 導入としてのPaizaProgrammingGamesだと思うので本末転倒っぽいですが
[^2]: ddで倒せる問題、多すぎやろ