- 投稿日:2020-10-17T21:44:21+09:00
AtCoder Beginner Contest 180のメモ
前置き
Atcoderをやってみたので、自分用のメモです。
あとから加筆・修正する予定です。問題
https://atcoder.jp/contests/abc180
A
Q_A.gopackage main import ( "fmt" ) func main() { var n, a, b int fmt.Scanf("%d %d %d", &n,&a,&b) fmt.Printf("%d\n", n-a+b) }B
Q_B.gopackage main import ( "fmt" "math" ) func main() { var n int fmt.Scanf("%d", &n) var t int manhattan :=0 euqulid :=0 chebishev :=0 for i := 0; i < n; i++ { fmt.Scanf("%d", &t) if t > 0 { manhattan += t }else{ manhattan -= t } euqulid += t*t if t > 0 { if t > chebishev{ chebishev = t } }else{ if -t > chebishev{ chebishev = -t } } } fmt.Printf("%d\n", manhattan) fmt.Printf("%.10f\n", math.Sqrt(float64(euqulid))) fmt.Printf("%d\n", chebishev) }C
Q_C.gopackage main import ( "fmt" ) func main() { var n int fmt.Scanf("%d", &n) max := make([]int, 1) for i:=1; i*i<n+1; i++{ if n % i == 0{ if n/i != i{ max = append(max, n/i) } fmt.Printf("%d\n", i) } } for i:=len(max)-1; i>0; i--{ if max[i] != 0{ fmt.Printf("%d\n", max[i]) } } }D
Q_D.gopackage main import ( "fmt" ) func main() { var x, y, a, b uint64 fmt.Scanf("%d %d %d %d", &x, &y, &a, &b) var cnt uint64 = 0 for x < y/a & b/(a-1) { cnt++ x *= a } cnt += (y-1-x)/b fmt.Printf("%d\n", cnt) }E
覚えてたら後で書きます。
F
覚えてたら後で書きます。
- 投稿日:2020-10-17T21:41:13+09:00
AtCoder Beginner Contest 180 参戦記
AtCoder Beginner Contest 180 参戦記
ABC180A - box
1分で突破. 書くだけ.
N, A, B = map(int, input().split()) print(N - A + B)ABC180B - Various distances
3分で突破. 書くだけ.
N, *x = map(int, open(0).read().split()) print(sum(abs(a) for a in x)) print(sum(a * a for a in x) ** 0.5) print(max(abs(a) for a in x))ABC180C - Cream puff
3分で突破. 書くだけ. Nの二乗根まで回すと分かっていれば難しいことはないんじゃないかな.
N = int(input()) result = set() for i in range(1, int(N ** 0.5) + 1): if N % i == 0: result.add(i) result.add(N // i) print(*sorted(result), sep='\n')ABC180D - Takahashi Unevolved
14分で突破. 時間かかりすぎ. 素直にシミュレートするナイーブなコードだと B が小さい場合に TLE になることは火を見るよりも明らか. となると、
+ B
より* A
のほうが増分が小さいうちは* A
をして、残りはまとめて足せば良いんじゃないのという結論に落ち着く. A は少なくとも2なので、素直にシミュレートしても O(logN) なので問題ない.X, Y, A, B = map(int, input().split()) result = 0 while X * A < Y and X * A < X + B: X *= A result += 1 result += ((Y - 1) - X) // B print(result)追記: どうにもD問題でペナ食らった人が多いなあと思っていたが、工夫せずに書くと
X * A
が int64 でもオーバーフローするせいなのね. なるほど.package main import ( "bufio" "fmt" "os" "strconv" ) func main() { defer flush() X := readInt() Y := readInt() A := readInt() B := readInt() result := 0 for X <= (Y-1)/A && X*A < X+B { X *= A result++ } result += ((Y - 1) - X) / B println(result) } const ( ioBufferSize = 1 * 1024 * 1024 // 1 MB ) var stdinScanner = func() *bufio.Scanner { result := bufio.NewScanner(os.Stdin) result.Buffer(make([]byte, ioBufferSize), ioBufferSize) result.Split(bufio.ScanWords) return result }() func readString() string { stdinScanner.Scan() return stdinScanner.Text() } func readInt() int { result, err := strconv.Atoi(readString()) if err != nil { panic(err) } return result } var stdoutWriter = bufio.NewWriter(os.Stdout) func flush() { stdoutWriter.Flush() } func println(args ...interface{}) (int, error) { return fmt.Fprintln(stdoutWriter, args...) }ABC180E - Traveling Salesman among Aerial Cities
39分半で突破. 蟻本のコードを写経して解いた. 写経してあれば黄色パフォとか取れたかな、くそー.
#include <bits/stdc++.h> #define rep(i, a) for (int i = (int)0; i < (int)a; ++i) using ll = long long; using namespace std; #define MAX_N 17 #define INF 2147483647 ll N; ll dp[1 << MAX_N][MAX_N]; ll d[MAX_N][MAX_N]; void solve() { rep(i, 1 << N) rep(j, N) dp[i][j] = INF; dp[(1 << N) - 1][0] = 0; for (int S = (1 << N) - 2; S >= 0; S--) { for (int v = 0; v < N; v++) { for (int u = 0; u < N; u++) { dp[S][v] = min(dp[S][v], dp[S | 1 << u][u] + d[v][u]); } } } cout << dp[0][0] << endl; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> N; vector<ll> X(N), Y(N), Z(N); rep(i, N) { cin >> X[i] >> Y[i] >> Z[i]; } rep(i, N) { rep(j, N) { d[i][j] = abs(X[i] - X[j]) + abs(Y[i] - Y[j]) + max(0ll, Z[i] - Z[j]); } } solve(); return 0; }
- 投稿日:2020-10-17T21:31:29+09:00
GoでローカルWebServerを立てた
初めに
GoでWebServerを立てて、Androidアプリからアクセスする
環境
PC Windows10
Android Studio 4.0
Kotlin 1.3.72
Android端末 Emulator(API Level 29)
Go 1.11.1構成図
Androidアプリからファイルを送信して、サーバー側で保存、サーバーからアプリにステータスコードを返却する実装
ローカルサーバー
Server.gopackage controllers import ( "fmt" "net/http" "io/ioutil" "os" ) func apiSampleHandler(w http.ResponseWriter, r *http.Request) { switch(r.Method) { case "POST": fmt.Println("POST") // アップロードしたファイルとヘッダーを取得 file, fileHeader, _ := r.FormFile ("upload_file") fileName := fileHeader.Filename // ヘッダーからファイル名を取得 defer file.Close() // ファイルを最後にClose data, _ := ioutil.ReadAll(file) // ファイルを読み出し saveFile, _ := os.Create(fileName) // 保存用のファイルを生成 defer saveFile.Close() // 保存用のファイルを最後にClose _, err = saveFile.Write(data) // ファイルに書き込み if err != nil { fmt.Println("can not write file") w.WriteHeader(http.StatusBadRequest) return } case "GET": fmt.Println("GET") } // 200:OKを返す w.WriteHeader(http.StatusOK) } // main.goから呼び出してサーバーを起動 func StartWebServer() error { http.HandleFunc("/", apiSampleHandler) return http.ListenAndServe(":8080", nil) }main.goを実行し、サーバーを起動
http://localhost:8080 にアクセスして、サーバーが起動していることを確認Android アプリ
1.Androidmanifest.xml
インターネットにアクセスするためのPermissionを定義
AndroidManifest.xml<uses-permission android:name="android.permission.INTERNET" />Android 9.0からhttpの通信の設定がOFFになるので
usesCleartextTrafic
をtrueに設定AndroidManifest.xml<application 省略 android:usesCleartextTraffic="true"> <activity android:name=".MainActivity"> 省略 </activity> </application>2.ファイルを生成
Android端末のアプリ固有領域(
/data/data/{package_name}/files
配下)にテキストファイルを生成File.ktconst val FILE_EXPAND = ".txt" class File { fun makeTxtFile(context: Context, fileName: String, str: String) { try { context.openFileOutput(fileName + FILE_EXPAND, Context.MODE_PRIVATE).use { it.write(str.toByteArray()) } } catch (e: IOException) { Log.e("File", "#makeTxtFile $e") } } }ファイルの生成を確認
Device File Explorer でデバイス上のファイルを表示する3.サーバーアクセス
ファイルを読み込んで、http通信でファイルを送信する
Net.ktfun startConnection(context: Context, requestUrl: String, requestMethod: String, fileName: String): Pair<Int, String> { val url = URL(requestUrl) // URLオブジェクト生成 // UrlConnectionオブジェクト生成 val urlConnection = url.openConnection() as HttpURLConnection var result = "" var responseCode = 0 try { val boundary = "--------------------------" urlConnection.requestMethod = requestMethod // POST, GETなど urlConnection.doOutput = true // リクエストボディの送信 urlConnection.doInput = true // レスポンスボディの受信 urlConnection.useCaches = false // キャッシュの利用 // multipart/form-data:複数のデータを送信、boundary:複数データ間の区切り urlConnection.setRequestProperty( "Content-Type", "multipart/form-data; boundary=$boundary" ) val filePath = context.filesDir // アプリ固有領域のパス val file = File("$filePath/$fileName$FILE_EXPAND") // ファイルオブジェクトを生成 FileInputStream(file).use { fileInputStream -> urlConnection.connect() // コネクションを確立 DataOutputStream(urlConnection.outputStream).use { it.writeBytes( // headerを設定 TWO_HYPHEN + boundary + LINE_END + "Content-Disposition: form-data; name=\"upload_file\"; " + "filename=\"$fileName$FILE_EXPAND\"$LINE_END" + "Content-Type: application/octet-stream$LINE_END$LINE_END" ) // ファイル書き込み val buffer = ByteArray(BUFFER_SIZE) var bytesRead: Int do { bytesRead = fileInputStream.read(buffer) if (bytesRead == -1) break it.write(buffer, 0, bytesRead) } while (true) it.writeBytes( // footerの設定 LINE_END + TWO_HYPHEN + boundary + TWO_HYPHEN + LINE_END ) it.flush() } } responseCode = urlConnection.responseCode // レスポンスコードを取得 BufferedReader(InputStreamReader(urlConnection.inputStream)).use { val sb = StringBuffer() for (line in it.readLines()) { line.let { sb.append(line) } } result = sb.toString() } } catch (e: Exception) { Log.e("Net", "#startConnection$e") } finally { urlConnection.disconnect() } return responseCode to result } }4.IPアドレスの確認
アクセスしたいサーバー(PC)のIPアドレスをcommand promptで以下を実行し確認
>ipconfig5.PCとAndroid端末を同一のネットワーク環境に接続
6.Androidにて接続
Net#startConnectionのrequestUrlにhttp://{確認したIPアドレス}:8080を設定してアプリを実行
ファイルのアップロードを確認
PCにてmain.goと同じディレクトリを確認する
ファイルが作成されていれば完了最後に
全体ソースはこちら
アクセス先やRequestMethod、ファイル名はアプリで動的に変更できるようにしています。参考文献
Goサーバー側
Androidアプリ側
[Android] アプリ内にファイルを保存する FileOutputStream, FileInputStream
Upload File To Server - Android Example
[Android]kotlinでのwhile-FileInputStream.readエラー
【Kotlin】複数の値を返したい!
- 投稿日:2020-10-17T21:31:29+09:00
GoでローカルWebServerを立てた~ファイルアップロード~
初めに
GoでWebServerを立てて、Androidアプリからファイルのアップロードを行う
環境
PC Windows10
Android Studio 4.0
Kotlin 1.3.72
Android端末 Emulator(API Level 29)
Go 1.11.1構成図
Androidアプリからファイルを送信して、サーバー側で保存、サーバーからアプリにステータスコードを返却する実装
ローカルサーバー
Server.gopackage controllers import ( "fmt" "net/http" "io/ioutil" "os" ) func apiSampleHandler(w http.ResponseWriter, r *http.Request) { switch(r.Method) { case "POST": fmt.Println("POST") // アップロードしたファイルとヘッダーを取得 file, fileHeader, _ := r.FormFile ("upload_file") fileName := fileHeader.Filename // ヘッダーからファイル名を取得 defer file.Close() // ファイルを最後にClose data, _ := ioutil.ReadAll(file) // ファイルを読み出し saveFile, _ := os.Create(fileName) // 保存用のファイルを生成 defer saveFile.Close() // 保存用のファイルを最後にClose _, err = saveFile.Write(data) // ファイルに書き込み if err != nil { fmt.Println("can not write file") w.WriteHeader(http.StatusBadRequest) return } case "GET": fmt.Println("GET") } // 200:OKを返す w.WriteHeader(http.StatusOK) } // main.goから呼び出してサーバーを起動 func StartWebServer() error { http.HandleFunc("/", apiSampleHandler) return http.ListenAndServe(":8080", nil) }main.goを実行し、サーバーを起動
http://localhost:8080 にアクセスして、サーバーが起動していることを確認Android アプリ
1.Androidmanifest.xml
インターネットにアクセスするためのPermissionを定義
AndroidManifest.xml<uses-permission android:name="android.permission.INTERNET" />Android 9.0からhttpの通信の設定がOFFになるので
usesCleartextTrafic
をtrueに設定AndroidManifest.xml<application 省略 android:usesCleartextTraffic="true"> <activity android:name=".MainActivity"> 省略 </activity> </application>2.ファイルを生成
Android端末のアプリ固有領域(
/data/data/{package_name}/files
配下)にテキストファイルを生成File.ktconst val FILE_EXPAND = ".txt" class File { fun makeTxtFile(context: Context, fileName: String, str: String) { try { context.openFileOutput(fileName + FILE_EXPAND, Context.MODE_PRIVATE).use { it.write(str.toByteArray()) } } catch (e: IOException) { Log.e("File", "#makeTxtFile $e") } } }ファイルの生成を確認
Device File Explorer でデバイス上のファイルを表示する3.サーバーアクセス
ファイルを読み込んで、http通信でファイルを送信する
Net.ktfun startConnection(context: Context, requestUrl: String, requestMethod: String, fileName: String): Pair<Int, String> { val url = URL(requestUrl) // URLオブジェクト生成 // UrlConnectionオブジェクト生成 val urlConnection = url.openConnection() as HttpURLConnection var result = "" var responseCode = 0 try { val boundary = "--------------------------" urlConnection.requestMethod = requestMethod // POST, GETなど urlConnection.doOutput = true // リクエストボディの送信 urlConnection.doInput = true // レスポンスボディの受信 urlConnection.useCaches = false // キャッシュの利用 // multipart/form-data:複数のデータを送信、boundary:複数データ間の区切り urlConnection.setRequestProperty( "Content-Type", "multipart/form-data; boundary=$boundary" ) val filePath = context.filesDir // アプリ固有領域のパス val file = File("$filePath/$fileName$FILE_EXPAND") // ファイルオブジェクトを生成 FileInputStream(file).use { fileInputStream -> urlConnection.connect() // コネクションを確立 DataOutputStream(urlConnection.outputStream).use { it.writeBytes( // headerを設定 TWO_HYPHEN + boundary + LINE_END + "Content-Disposition: form-data; name=\"upload_file\"; " + "filename=\"$fileName$FILE_EXPAND\"$LINE_END" + "Content-Type: application/octet-stream$LINE_END$LINE_END" ) // ファイル書き込み val buffer = ByteArray(BUFFER_SIZE) var bytesRead: Int do { bytesRead = fileInputStream.read(buffer) if (bytesRead == -1) break it.write(buffer, 0, bytesRead) } while (true) it.writeBytes( // footerの設定 LINE_END + TWO_HYPHEN + boundary + TWO_HYPHEN + LINE_END ) it.flush() } } responseCode = urlConnection.responseCode // レスポンスコードを取得 BufferedReader(InputStreamReader(urlConnection.inputStream)).use { val sb = StringBuffer() for (line in it.readLines()) { line.let { sb.append(line) } } result = sb.toString() } } catch (e: Exception) { Log.e("Net", "#startConnection$e") } finally { urlConnection.disconnect() } return responseCode to result } }4.IPアドレスの確認
アクセスしたいサーバー(PC)のIPアドレスをcommand promptで以下を実行し確認
>ipconfig5.PCとAndroid端末を同一のネットワーク環境に接続
6.Androidにて接続
Net#startConnectionのrequestUrlにhttp://{確認したIPアドレス}:8080を設定してアプリを実行
ファイルのアップロードを確認
PCにてmain.goと同じディレクトリを確認する
ファイルが作成されていれば完了最後に
全体ソースはこちら
アクセス先やRequestMethod、ファイル名はアプリで動的に変更できるようにしています。参考文献
Goサーバー側
Androidアプリ側
[Android] アプリ内にファイルを保存する FileOutputStream, FileInputStream
Upload File To Server - Android Example
[Android]kotlinでのwhile-FileInputStream.readエラー
【Kotlin】複数の値を返したい!
- 投稿日:2020-10-17T18:30:41+09:00
Golangの環境構築【goenv】
goenvとは
goenvはGoのバージョン管理バージョン管理ツールです。
goenvのインストール
Home brewの場合
$ brew install goenvgitの場合
goenvのinstallation$ git clone https://github.com/syndbg/goenv.git ~/.goenvgoenvのPATHを通す
設定ファイルにpathを記述します。(自身の使用しているシェルに記述)
$ echo 'export GOENV_ROOT="$HOME/.goenv"' >> ~/.zshrc $ echo 'export PATH="$GOENV_ROOT/bin:$PATH"' >> ~/.zshrc $ echo 'eval "$(goenv init -)"' >> ~/.zshrc $ source ~/.zshrc //変更を更新$ goenv -v goenv 2.0.0beta11バージョンが確認できたら完了です。
Goをインストール
下記のコマンドでインストールできるバージョンのリストを表示
$ goenv install -l 1.2.2 1.3.0 1.3.1 〜 1.15rc2 1.15.1 1.15.2任意のバージョンをインストールします。
$ goenv install 1.**.*GoのPATHを通す
~/.zshrc$ echo 'export PATH="$GOROOT/bin:$PATH"' >> ~/.zshrc $ echo 'export PATH="$PATH:$GOPATH/bin"' >> ~/.zshrc $ source ~/.zshrc使用するバージョンを選択
インストールしたバージョンをglobalに設定します。また、バージョンへの切り替えとか。
$goenv global 1.**.*$ go version go version go1.**.* darwin/amd64バージョンが確認できたら完了です。
VSCodeの環境構築
Toolのインストール
次に、便利なtoolたちをインストールしていきます。まず、設定を開き
go.use language server
と検索してチェックがついているか確認します。
確認したらshift + ⌘ + P
ですべてのコマンドの表示を開き、Go: Install/Update Tools
と打ちこんだらgocode
とgocode-gomod
以外(コードの補完機能はgoplsで行うため)を選択してインストールします。もし、ここにgoplsがなければ検索タブにgoplsと打ってみてください。
任意でsettings.jsonの設定
インストールが終わったら、下記をsettings.jsonに追記します。
settings.json"go.useLanguageServer": true, "[go]": { "editor.formatOnSave": true, "editor.codeActionsOnSave": { "source.organizeImports": true, }, "editor.snippetSuggestions": "none" }, "gopls": { "hoverKind": "SynopsisDocumentation", "usePlaceholders": true, "linkTarget": "pkg.go.dev", "staticcheck": false, "completionDocumentation": true, "completeUnimported": true, "deepCompletion": true }, "files.autoSave": "afterDelay"以上で完了です!
- 投稿日:2020-10-17T16:11:53+09:00
[Golang] go test -cover 時にカバレッジが指定したパーセンテージ以下の場合に失敗(ステータスを1)にしたい
Go 言語でカバレッジの合格ラインを指定したい
go test -cover
でカバレッジ率が低くてもステータス 0(ゼロ)で正常終了してしまう。$ # カバレッジ付きでユニットテストを実行する $ go test -cover ./src ok github.com/KEINOS/sample/src coverage: 62.5% of statements $ # ステータス 0 で正常終了してしまう $ echo $? 0「
n パーセント以下は失敗
」もしくは「n% より高い場合にパスさせる
」といった、指定したパーセンテージよりカバレッジが低い場合にステータス 1 で終了させたい。Golang に標準装備されているユニット・テストで、カバレッジを表示させる際に、カバー率が低い場合に失敗させたかったのです。Travis CI や GitHub Actions などの CI とか。
「go test cover カバレッジ パーセンテージ 指定」とググってもカバレッジの説明ばかりで、カバレッジの合格ラインの指定方法について分からなかったので、自分のググラビリティとして。
TL; DR
Go v1.15.2 現在、
go test
の-cover
には合格ラインを指定するオプションを標準で持っていません。しかし、
testing.CoverMode()
でカバー率を取得できるのでTestMain()
に条件文を組み込むことでパーセンテージを指定することができます。TS; DR
メインのテストに以下を指定package ( "fmt" "testing" ) // カバー率(0.8 以上で合格) var thresholdCoverage = 0.8 func TestMain(m *testing.M) { var returnCode = m.Run() if returnCode == 0 && testing.CoverMode() != "" { var rateCoverage = testing.Coverage() if rateCoverage < thresholdCoverage { fmt.Println("テストはパスしましたが。カバレッジに失敗しました。カバレッジ率:", rateCoverage) returnCode = -1 } } os.Exit(returnCode) }
- 動作確認: Go v1.15.2 @ Alpine Linux v3.12
- 参考文献: 回答 | "fail unit tests if coverage is below certain percentage" @ StackOverflow
参考文献
- 投稿日:2020-10-17T16:11:53+09:00
【Golang】指定したカバレッジ以下で失敗(終了ステータスを1に)させる go test -cover 時のパーセンテージ指定
Go 言語でカバレッジの合格ラインを指定したい
go test -cover
でカバレッジ率が低くてもステータス 0(ゼロ)で正常終了してしまう。$ # カバレッジ付きでユニットテストを実行する $ go test -cover ./src ok github.com/KEINOS/sample/src coverage: 62.5% of statements $ # ステータス 0 で正常終了してしまう $ echo $? 0「
n パーセント以下は失敗
」もしくは「n% より高い場合にパスさせる
」といった、指定したパーセンテージよりカバレッジが低い場合にステータス 1 で終了させたい。Golang に標準装備されているユニット・テストで、カバレッジを表示させる際に、カバー率が低い場合に失敗させたかったのです。Travis CI や GitHub Actions などの CI とか。
「go test cover カバレッジ パーセンテージ 指定」とググってもカバレッジの説明ばかりで、カバレッジの合格ラインの指定方法について分からなかったので、自分のググラビリティとして。
TL; DR
Go v1.15.2 現在、
go test
の-cover
には合格ラインを指定するオプションを標準で持っていません。しかし、
testing.CoverMode()
でカバー率を取得できるのでTestMain()
に条件文を組み込むことでパーセンテージを指定することができます。TS; DR
メインのテストに以下を指定package ( "fmt" "testing" ) // カバー率(0.8 以上で合格) var thresholdCoverage = 0.8 func TestMain(m *testing.M) { var returnCode = m.Run() if returnCode == 0 && testing.CoverMode() != "" { var rateCoverage = testing.Coverage() if rateCoverage < thresholdCoverage { fmt.Println("テストはパスしましたが。カバレッジに失敗しました。カバレッジ率:", rateCoverage) returnCode = -1 } } os.Exit(returnCode) }
- 動作確認: Go v1.15.2 @ Alpine Linux v3.12
- 参考文献: 回答 | "fail unit tests if coverage is below certain percentage" @ StackOverflow
参考文献