コードレビューBINGO!!


プレゼント期間終了後, 6/26に公開されました.

## (私が独自に課す)条件

- for文の使用禁止
    - forトークンとしてはPython内包表記のみ可
- if文の使用禁止
    - if式(3項演算子相当)は可
- JavsScript以外は「+」文字禁止
    - 必然的にC++はaccumulate、C#はLinq Sum、Javaはstream sumを使うことが前提となります

## 解答

なぜかpaizaの並び順がなぜかPython/C#/C++/Ruby/JavaScript/Rust/Java/PHPの順なのでこちらもそれに習います

[20240403] 採点対象外ですがPerlも掲載しました。[初恋プログラミング研究会](https://qiita.com/cielavenir/items/7ed13c0009c60e0ae2e3)に流用するためです。

### 基本

- C++は\#includeではなく\#import、`using namespace std`上等
- C#のクラス名は1文字
- Javaは`interface Main{static void main(String[]z){}}`
- JavaScriptのセミカンマはつけない
- PHPのワンライナーは`<?=式`
- Python、JavaScriptの入力はfile descriptor 0

Pythonのopen(0).read()は知ってましたが、JavaScriptのreadFileSync(0)は @TwoSquirrels 氏の情報です。

https://twitter.com/TwoSquirrels/status/1695961787370463246

### 1

`Hello BINGO!`と出力せよ

PHPはタグ無しで直接出力。

```py
#!/usr/bin/python3
print("Hello BINGO!")
```

```csharp
class K{public static void Main(){System.Console.WriteLine("Hello BINGO!");}}
```

```cpp
//usr/bin/env true; tmpfile=$(mktemp); g++ -O2 -std=gnu++11 -xc++ -o $tmpfile $0 && $tmpfile "$@"; rm $tmpfile; exit
#import<iostream>
using namespace std;
int main(){cout<<"Hello BINGO!"<<endl;}
```

```rb
#!/usr/bin/ruby
$><<"Hello BINGO!"
```

```js
#!/usr/bin/env node
console.log("Hello BINGO!")
```

```rust
//usr/bin/env true; tmpfile=$(mktemp); rustc -o $tmpfile $0 && $tmpfile "$@"; rm $tmpfile; exit
fn main(){println!("{}","Hello BINGO!");}
```

```java
//usr/bin/env java $0 $@;exit
interface Main{static void main(String[]a){System.out.println("Hello BINGO!");}}
```

```php
Hello BINGO!
```

```perl
#!/usr/bin/perl
print"Hello BINGO!\n"
```

なお、C#は以下のような方法でchmod +xできます(このときMainがpublicでないとエラーになります、答案ではpublicは本来不要なのですがchmod +xを優先し、付けています)

```csharp
//usr/bin/env csi $0 $@;exit
#load "1.cs"
K.Main()
```

PHPは以下でも良いです

```php
#!/usr/bin/env php
<?="Hello BINGO!";
```

以下ではShebang行は省略します

### 2

N回`BINGO!`と出力せよ

"BINGO!\n"に対しrepeat使えば良い。Perlは`x`で可能。

```py
print("BINGO!\n"*int(input()))
```

```csharp
using System;
using System.Linq;
class K{public static void Main(){Console.Write(string.Concat(Enumerable.Repeat("BINGO!\n",int.Parse(Console.ReadLine()))));}}
```

```cpp
#import<iostream>
#import<vector>
#import<string>
#import<numeric>
using namespace std;
int main(){int n;cin>>n;vector<string>v(n,"BINGO!\n");cout<<accumulate(v.begin(),v.end(),string());}
```

```rb
$><<"BINGO!\n"*gets.to_i
```

```js
I=require('fs').readFileSync(0)
console.log("BINGO!\n".repeat(I))
```

```rust
fn l()->String{let mut x=String::new();std::io::stdin().read_line(&mut x).ok();return x;}
fn main(){print!("{}","BINGO!\n".repeat(l().trim().parse().unwrap()));}
```

```java
import java.util.*;
interface Main{static void main(String[]a){Scanner x=new Scanner(System.in);System.out.println(String.join("\n",Collections.nCopies(x.nextInt(),"BINGO!")));}}
```

```php
<?=str_repeat("BINGO!\n",intval(readline()));
```

```perl
print"BINGO!\n"x<>
```

### 3

スペース区切りで与えられる整数の和を求めよ(**ただしpaizaでの問題設定と異なり個数は2つとは限らないものとする**)

C++はreturn auto使ってるのでC++14(-std=gnu++14)が必要です

```py
print(sum(map(int,input().split())))
```

```csharp
using System;
using System.Linq;
class K{public static void Main(){Console.WriteLine(Console.ReadLine().Split(' ').Select(int.Parse).Sum());}}
```

```cpp
#import<iostream>
#import<string>
#import<vector>
#import<numeric>
#import<cstring>
using namespace std;
#ifdef BOOST
#import<boost/algorithm/string.hpp>
#endif
auto f(istream &in){
string s;
getline(in,s);
vector<int>v;
#ifdef BOOST
vector<string>v_;
boost::split(v_,s,boost::is_space());
transform(v_.begin(),v_.end(),back_inserter(v),[](const string &s){return stoi(s);});
#else
char *t=strtok((char*)s.c_str()," ");
while(t){v.push_back(strtol(t,nullptr,0));t=strtok(nullptr," ");}
#endif
return v;}
int main(){
auto a=f(cin);
cout<<accumulate(a.begin(),a.end(),0)<<endl;}
```

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

```js
I=require('fs').readFileSync(0)+''
a=I.split(' ').map(Number)
console.log(a.reduce((x,y)=>x+y))
```

```rust
fn l()->String{let mut x=String::new();std::io::stdin().read_line(&mut x).ok();return x;}
fn main(){println!("{}",l().trim().split(' ').map(|e|e.parse::<i32>().unwrap()).sum::<i32>());}
```

```java
import java.util.*;
interface Main{static void main(String[]a){Scanner x=new Scanner(System.in);System.out.println(Arrays.asList(x.nextLine().split(" ")).stream().mapToInt(e->Integer.parseInt(e)).sum());}}
```

```php
<?=array_sum(array_map("intval",explode(" ",readline())));
```

```perl
use List::Util 'sum';
print sum(glob<>)
```

### 4

改行区切りで与えられる整数の最大値を求めよ(**ただしpaizaでの問題設定と異なり個数は2つとは限らないものとする**)

標準入力を最後まで読み切り、trimしてsplit("\n")するのが良いと思う。

C++ではistreambuf_iteratorを使うことで最後まで読み切ることができるようです。

Perlはlist contextとscalar contextというものがあり、list contextを使えば楽。

```py
print(max(map(int,open(0).read().split())))
```

```csharp
using System;
using System.Linq;
class K{public static void Main(){Console.WriteLine(Console.In.ReadToEnd().Split('\n').Select(int.Parse).Max());}}
```

```cpp
#import<iostream>
#import<string>
#import<vector>
#import<algorithm>
#import<cstring>
using namespace std;
#ifdef BOOST
#import<boost/algorithm/string.hpp>
#endif
auto f(string &s){
vector<int>v;
#ifdef BOOST
vector<string>v_;
boost::split(v_,boost::trim_copy(s),boost::is_space());
transform(v_.begin(),v_.end(),back_inserter(v),[](const string &s){return stoi(s);});
#else
char *t=strtok((char*)s.c_str(),"\n");
while(t){v.push_back(strtol(t,nullptr,0));t=strtok(nullptr,"\n");}
#endif
return v;}
int main(){
istreambuf_iterator<char>B(cin),E;
string s(B,E);
auto a=f(s);
cout<<*max_element(a.begin(),a.end())<<endl;}
```

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

```js
I=require('fs').readFileSync(0)+''
a=I.trim().split('\n').map(Number)
console.log(Math.max(...a))
```

```rust
use std::io::Read;
fn s()->String{let mut x=String::new();std::io::stdin().read_to_string(&mut x).ok();return x;}
fn main(){println!("{}",s().trim().split_whitespace().map(|e|e.parse::<i32>().unwrap()).max().unwrap());}
```

```java
import java.util.*;
interface Main{static void main(String[]a){Scanner x=new Scanner(System.in).useDelimiter("\\Z");System.out.println(Arrays.asList(x.next().split("\n")).stream().mapToInt(e->Integer.parseInt(e)).max().getAsInt());}}
```

```php
<?=max(array_map("intval",explode("\n",stream_get_contents(STDIN))));
```

```perl
use List::Util 'max';
print max(<>)
```

### 5

1からNまでの和を求めよ

range(1,N).sum()が基本。C++はiotaで代用。JavaScriptは再帰を使用。

```py
print(sum(range(int(input()),0,-1)))
```

```csharp
using System;
using System.Linq;
class K{public static void Main(){Console.WriteLine(Enumerable.Range(1,int.Parse(Console.ReadLine())).Sum());}
```

```cpp
#import<iostream>
#import<vector>
#import<numeric>
using namespace std;
int main(){
int n;cin>>n;
vector<int>v;v.resize(n);
iota(v.begin(),v.end(),1);
cout<<accumulate(v.begin(),v.end(),0)<<endl;}
```

```rb
p (1..gets.to_i).sum
```

```js
I=require('fs').readFileSync(0)
console.log((function(n){return n<=0?0:n+arguments.callee(n-1);})(Number(I)))
```

```rust
fn l()->String{let mut x=String::new();std::io::stdin().read_line(&mut x).ok();return x;}
fn main(){println!("{}",(1..=l().trim().parse().unwrap()).sum::<i32>());}
```

```java
import java.util.*;
import java.util.stream.*;
interface Main{static void main(String[]a){Scanner x=new Scanner(System.in);System.out.println(IntStream.rangeClosed(1,x.nextInt()).sum());}}
```

```php
<?=array_sum(range(1,intval(readline())));
```

```perl
use List::Util 'sum';
print sum(1..<>)
```

### 6

スペース区切りの単語列が2行与えられるので共通部分があるか答えよ[^1]

intersectが実装されている言語ならそれを使う。なければany(contains)で代用。

```py
print('YNeos'[not set(input().split())&set(input().split())::2])
```

```csharp
using System;
using System.Linq;
class K{public static void Main(){Console.WriteLine(Console.ReadLine().Split(' ').Intersect(Console.ReadLine().Split(' ')).Any()?"Yes":"No");}}
```

```cpp
#import<iostream>
#import<vector>
#import<string>
#import<algorithm>
#import<cstring>
using namespace std;
#ifdef BOOST
#import<boost/algorithm/string.hpp>
#endif
auto f(istream &in){
string s;
getline(in,s);
vector<string>v;
#ifdef BOOST
boost::split(v,s,boost::is_space());
#else
char *t=strtok((char*)s.c_str()," ");
while(t){v.push_back(t);t=strtok(nullptr," ");}
#endif
return v;}
int main(){
auto a=f(cin);
auto b=f(cin);
cout<<(any_of(b.begin(),b.end(),[&](string &e){return find(a.begin(),a.end(),e)!=a.end();})?"Yes":"No")<<endl;}
```

```rb
puts (gets.split&gets.split).empty? ? :No: :Yes
```

```js
I=(require('fs').readFileSync(0)+'').split('\n')
A=I[0].split(' ')
B=I[1].split(' ')
console.log(B.some(e=>A.includes(e))?"Yes":"No")
```

```rust
fn l()->String{let mut x=String::new();std::io::stdin().read_line(&mut x).ok();return x;}
fn main(){
let a_=l();let a:Vec<_>=a_.trim().split(' ').collect();
let b_=l();let b:Vec<_>=b_.trim().split(' ').collect();
println!("{}",if b.iter().any(|e|a.contains(e)){"Yes"}else{"No"});
}
```

```java
import java.util.*;
interface Main{static void main(String[]z){
Scanner x=new Scanner(System.in);
String[]a=x.nextLine().split(" ");
String[]b=x.nextLine().split(" ");
System.out.println(Arrays.asList(b).stream().anyMatch(e->Arrays.asList(a).contains(e))?"Yes":"No");
}}
```

```php
<?=array_intersect(explode(" ",readline()),explode(" ",readline()))?"Yes":"No";
```

```perl
use List::Util 'any';
@a=glob<>;
@b=glob<>;
print((any {$k=$_;grep {$_ eq $k} @b} @a)?'Yes':'No')
```

### 7

2行目の文字列を並び替えたものと3行目の文字列を並び替えたものが等しいか答えよ

```py
input()
print('YNeos'[sorted(input())!=sorted(input())::2])
```

```csharp
using System;
using System.Linq;
class K{public static void Main(){
Console.ReadLine();
var a=Console.ReadLine().ToCharArray();Array.Sort(a);
var b=Console.ReadLine().ToCharArray();Array.Sort(b);
Console.WriteLine(a.SequenceEqual(b)?"Yes":"No");
}}
```

```cpp
#import<iostream>
#import<string>
#import<algorithm>
using namespace std;
int main(){
int n;string s,t;cin>>n>>s>>t;
sort(s.begin(),s.end());
sort(t.begin(),t.end());
cout<<(s==t?"Yes":"No")<<endl;}
```

```rb
gets
puts gets.chars.sort==gets.chars.sort ? :Yes : :No
```

```js
I=(require('fs').readFileSync(0)+'').split('\n')
console.log(I[1].split('').sort().join()==I[2].split('').sort().join()?"Yes":"No")
```

```rust
fn l()->String{let mut x=String::new();std::io::stdin().read_line(&mut x).ok();return x;}
fn main(){
l();
let mut a:Vec<char>=l().trim().chars().collect();a.sort();
let mut b:Vec<char>=l().trim().chars().collect();b.sort();
println!("{}",if a==b{"Yes"}else{"No"});
}
```

```java
import java.util.*;
interface Main{static void main(String[]z){
Scanner x=new Scanner(System.in);
x.next();
char[]a=x.next().toCharArray();Arrays.sort(a);
char[]b=x.next().toCharArray();Arrays.sort(b);
System.out.println(Arrays.equals(a,b)?"Yes":"No");
}}
```

```php
<?php
function f($a){sort($a);return $a;}
readline();
echo f(str_split(readline()))==f(str_split(readline()))?"Yes":"No";
```

```perl
use List::Util 'all', 'zip';
<>;
@a=sort split'',glob<>;
@b=sort split'',glob<>;
print((all {$_->[0] eq $_->[1]} zip(\@a,\@b))?'Yes':'No')
```

[PaizaのPerlは5.30と少し古い](https://paiza.jp/guide/language)ため、zipが実装されていない。最終行を`print @a~~@b?'Yes':'No'`とすれば良い。なお`~~`はPerl 5.38以降ではdeprecatedとのことです。

※Perl 5.36以降だと標準

### 8

3行ビンゴカードの状態が与えられる(\.->0,\#->1)のでビンゴ数を求めよ

愚直に比較するとしんどいので、01とみなして2進数数値変換してビット積を取るのが良いと思う。

Perlでは、`local $/;`を使うと`<>`で終端まで読めます。また、scalarを使うと配列の要素数が取れます。基数変換はPOSIX::strtolを使います。
あと、`tr///r`を使うと非破壊的に使えるんだそうです。これは知らなかったです。

```py
B=[448,56,7,292,146,73,273,84]
A=int(open(0).read().replace("\n","").replace('.','0').replace('#','1'),2)
print(sum(A&b==b for b in B))
```

```csharp
using System;
using System.Linq;
class K{public static void Main(){
int a=Convert.ToInt32(Console.In.ReadToEnd().Replace("\n","").Replace('.','0').Replace('#','1'),2);
Console.WriteLine(new int[]{448,56,7,292,146,73,273,84}.Count(e=>(a&e)==e));
}}
```

```cpp
#import<iostream>
#import<string>
#import<vector>
#import<algorithm>
#import<regex>
using namespace std;
int main(){
const vector<int>v={448,56,7,292,146,73,273,84};
istreambuf_iterator<char>B(cin),E;
string s(B,E);s=regex_replace(s,regex("\n"),"");
transform(s.begin(),s.end(),s.begin(),[](char c){return c=='.'?'0':'1';});
int a=stoi(s,nullptr,2);
cout<<count_if(v.begin(),v.end(),[&](int e){return(a&e)==e;})<<endl;}
```

```rb
B=[448,56,7,292,146,73,273,84]
A=ARGF.read.tr("\n","").tr('.#','01').to_i(2)
p B.count{|b|A&b==b}
```

```js
B=[448,56,7,292,146,73,273,84]
A=parseInt((require('fs').readFileSync(0)+'').replaceAll(/./sg,e=>e=='\n'?'':+(e=='#')),2)
console.log(B.filter(b=>(A&b)==b).length)
```

```rust
use std::io::Read;
fn s()->String{let mut x=String::new();std::io::stdin().read_to_string(&mut x).ok();return x;}
fn main(){
let b:Vec<i32>=vec![448,56,7,292,146,73,273,84];
let x=s().replace("\n","").replace(".","0").replace("#","1");
let a=i32::from_str_radix(&x,2).unwrap();
println!("{}",b.iter().filter(|&&e|(a&e)==e).count());
}
```

```java
import java.util.*;
interface Main{static void main(String[]z){
Scanner x=new Scanner(System.in).useDelimiter("\\Z");
int a=Integer.valueOf(x.next().replace("\n","").replace(".","0").replace("#","1"),2);
System.out.println(Arrays.asList(new Integer[]{448,56,7,292,146,73,273,84}).stream().filter(e->(a&e)==e).count());
}}
```

```php
<?php
$b=[448,56,7,292,146,73,273,84];
$a=intval(str_replace([".","#","\n"],[0,1,""],stream_get_contents(STDIN)),2);
echo count(array_filter($b,fn($e)=>($a&$e)==$e));
```

```perl
#!/usr/bin/perl
use POSIX;
@b=(448,56,7,292,146,73,273,84);
local$/;$a=POSIX::strtol(<>=~tr/.#\n/01/dr,2);
print scalar grep{($a&$_)==$_}@b;
```

[^1]: 問題文がサンプルコードの意図と違ってへんか、まあ吾もCodeIQの間違い探し問題で問題文間違って出したことあるから人のこと言えへんけど。。
[^2]: (20240419に追記します)