20201010のGoに関する記事は6件です。

HHKB プログラミングコンテスト 2020のメモ

前置き

Atcoderをやってみたので、自分用のメモです。
あとから加筆・修正する予定です。

問題

https://atcoder.jp/contests/hhkb2020

A

Q_A.go
package main

import (
    "fmt"
)

func main() {
    var s string
    fmt.Scan(&s)

    var t string
    fmt.Scan(&t)

    if s == "Y"{
        if t == "a"{
            t = "A"
        } else if t == "b"{
            t = "B"
        } else if t == "c"{
            t = "C"
        }
    }

    fmt.Printf("%s\n", t)
}

B

Q_B.go
package main

import (
    "fmt"
    "strings"
)

func main() {
    var H, W int
    fmt.Scanf("%d %d", &H, &W)

    S := make([][]string, H)
    for i := 0; i < H; i++ {
        var tmp string
        fmt.Scanf("%s", &tmp)           

        S[i] = strings.Split(tmp, "")
    }

    var count int
    // 横方向
    for i := 0; i < H; i++ {
        for j := 0; j<W-1; j++{
            if S[i][j] == "." && S[i][j+1] == "."{
                count += 1
            }
        }
    }

    // 縦方向
    for j := 0; j<W; j++{
        for i := 0; i < H-1; i++ {
            if S[i][j] == "." && S[i+1][j] == "."{
                count += 1
            }
        }
    }

    fmt.Printf("%d\n", count)
}

C

Q_C.go
package main

import (
    "fmt"
)

func main() {
    var n int
    fmt.Scanf("%d", &n)

    p := [200001] int{}

    min := 0
    var s int
    for i := 0; i<n; i++{
        fmt.Scanf("%d", &s)
        p[s] = 1

        for j:=min; j<2000001; j++{
            if p[min] == 1{
                min ++
            }else{
                fmt.Printf("%d\n", min)
                break
            }
        }
    }
}

D

覚えてたら後で書きます。

E

覚えてたら後で書きます。

F

覚えてたら後で書きます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AtCoder HHKB プログラミングコンテスト 2020 参戦記

AtCoder HHKB プログラミングコンテスト 2020 参戦記

HHKB2020A - Keyboard

2分で突破. 書くだけ.

S = input()
T = input()

if S == 'Y':
    print(T.upper())
elif S == 'N':
    print(T)

HHKB2020B - Futon

3分で突破. 書くだけ.

H, W = map(int, input().split())
S = [input() for _ in range(H)]

result = 0
for h in range(H):
    for w in range(W - 1):
        if S[h][w] == '.' and S[h][w + 1] == '.':
            result += 1
for h in range(H - 1):
    for w in range(W):
        if S[h][w] == '.' and S[h + 1][w] == '.':
            result += 1
print(result)

HHKB2020C - Neq Min

6分半で突破. 制限からして O(N) にしないとダメそうだなあと思いつつ、一目でその方法が見えなくて悩んだ記憶がある割にそれほど時間がかかってないのが不思議. 毎行0から考え直していたらO(1)になる気がしなかったので、前の行の結果は受け継ぐとして、単調増加だからと考えた辺りでわかった.

N, *p = map(int, open(0).read().split())

result = []
t = 0
s = set()
for x in p:
    s.add(x)
    while t in s:
        t += 1
    result.append(t)
print(*result, sep='\n')

HHKB2020D - Squares

30分くらい悩んだけど、端の処理が難しくてどうにも解けなかった. 問題文を読んだ感触でも、順位表でもEのほうが簡単そうだったのでそっちへ.

HHKB2020E - Lamps

60分くらい悩んだけど、交差している部分の処理が難しくてどうにも解けなかった.

追記: 各マスごとに灯りがついていないパターン数を引いていくのか. なるほどなあ. それが分かれば実装は難しくなかった.

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

const (
    m = 1000000007
)

func main() {
    defer flush()

    H := readInt()
    W := readInt()
    S := make([]string, H)
    for i := 0; i < H; i++ {
        S[i] = readString()
    }

    K := H * W
    for i := 0; i < H; i++ {
        for j := 0; j < W; j++ {
            if S[i][j] == '#' {
                K--
            }
        }
    }

    yoko := make([][]int, H)
    tate := make([][]int, H)
    for i := 0; i < H; i++ {
        yoko[i] = make([]int, W)
        tate[i] = make([]int, W)
    }

    for i := 0; i < H; i++ {
        s := 0
        l := 0
        for j := 0; j < W; j++ {
            if S[i][j] == '#' {
                for k := s; k < j; k++ {
                    yoko[i][k] = l
                }
                s = j + 1
                l = 0
            } else if S[i][j] == '.' {
                l++
            }
        }
        for k := s; k < W; k++ {
            yoko[i][k] = l
        }
    }

    for i := 0; i < W; i++ {
        s := 0
        l := 0
        for j := 0; j < H; j++ {
            if S[j][i] == '#' {
                for k := s; k < j; k++ {
                    tate[k][i] = l
                }
                s = j + 1
                l = 0
            } else if S[j][i] == '.' {
                l++
            }
        }
        for k := s; k < H; k++ {
            tate[k][i] = l
        }
    }

    t := make([]int, K+1)
    t[0] = 1
    for i := 1; i < K+1; i++ {
        t[i] = t[i-1] * 2
        t[i] %= m
    }

    c := 0
    for i := 0; i < H; i++ {
        for j := 0; j < W; j++ {
            if S[i][j] == '#' {
                continue
            }
            c += t[K-tate[i][j]-yoko[i][j]+1]
            c %= m
        }
    }

    result := K * t[K]
    result %= m
    result -= c
    result += m
    result %= m
    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...)
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DockerでのRailsアプリケーション構築

概要

Dockerの勉強会の際、作成したリポジトリがありそのまま埋めてるの勿体無いと思ったので記事にしました。
どなたかの参考になればいいなぁと思ってます。

https://github.com/yodev21/docker_tutorial_rails

作業手順

ファイル作成

下記ファイルを作成

Dockerfile
docker-compose.yml
Gemfile
Gemfile.lock
# イメージ名にRuby(Ver2.6.5)の実行環境のイメージを指定
FROM ruby:2.6.5

# パッケージのリストを更新しrailsの環境構築に必要なパッケージをインストール
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs

# プロジェクト用のディレクトリを作成
RUN mkdir /myapp

# ワーキングディレクトリに設定
WORKDIR /myapp

# プロジェクトのディレクトリにコピー
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock

# bundle install実行
RUN bundle install

# ビルドコンテキストの内容を全てmyappにコピー
COPY . /myapp
docker-compose.yml
version: '3'
services:
  db:
    # postgresのイメージを取得
    image: postgres
    environment:
      POSTGRES_USER: 'postgresql'
      POSTGRES_PASSWORD: 'postgresql-pass'
    restart: always
    volumes:
      - pgdatavol:/var/lib/postgresql/data
  web:
    # Dockerfileからイメージをビルドして使用
    build: .
    # コンテナ起動時に実行
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    # カレントディレクトリを/myappにバインドマウント
    volumes:
      - .:/myapp
    # 3000で公開して、コンテナの3000へ転送
    ports:
      - "3000:3000"
    # Webサービスを起動する前にdbサービスを起動
    depends_on:
      - db
# データ永続化のためにpgdatabolのvolumeを作成し、postgresqlのデータ領域をマウント
volumes:
  pgdatavol:
source 'https://rubygems.org'
gem 'rails', '5.2.4.2'
Gemfile.lock

railsアプリケーション作成

docker-compose run web rails new . --force --database=postgresql

railsプロジェクトに使用するデータベースの設定ファイルを修正

database.yml
default: &default
  adapter: postgresql
  encoding: unicode
  # -------- 追加 --------
  host: db
  username: postgresql
  password: postgresql-pass
  # -------- ここまで --------

デタッチモード(バックグラウンド)で起動

docker-compose up -d

bundle installが反映されない場合の対応

docker-compose build --no-cache

データベース作成コマンド

docker-compose run web rails db:create

Scaffoldにて簡易的なアプリケーション作成

docker-compose run web bin/rails g scaffold User name:string
docker-compose run web bin/rails db:migrate

http://localhost:3000/users

コンテナの停止

docker-compose stop

コンテナ削除

docker-compose down

コンテナ内に移動

docker-compose run web bash

Go言語を使用してみる

ディレクトリ移動

cd doc/golang/
FROM golang:1.9

RUN mkdir /echo
COPY main.go /echo
CMD ["go", "run", "/echo/main.go"]

イメージのビルド

docker image build -t example/echo:latest .

イメージの確認

docker image ls

コンテナの起動

docker container run -d -p 9000:8080 example/echo:latest

GETリクエストの確認

curl http://localhost:9000
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

絶対に転職すると心に誓ったのでgolangで"hello word" してみた

自社開発web系企業へ転職したいSES、受託開発企業で働く20代男性です。
今のスキルが伸びにくい環境と給料に不満を覚えたので、文句ばかり言わないで行動に移そうと心に誓ったのでGo言語を勉強することにしました。
Qiitaへ記事を書くことの練習を兼ねております。

早速 hello word しましょう!

とりあえず準備

※エディター、homebrewはすでにインストールされていることを想定しております。
下記コマンドをターミナルに流す。

# homebrewのアップデート
$ brew update

# goをインストール
$ brew install go

以上でgoの準備は整いました。

コードを書いていこう

以下がコード

hello.go
package main

import (
    "fmt"
)

func main() {
    fmt.Println("hello world")
}

以下コマンドで実行!

$ go run hello.go
#以下、実行結果
hello world

今日はこれまで。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Go言語(net/http)でWebサーバーを作成(1)

当たり前ですが、webプログラミングが可能なgolang(Go言語)ではWebサーバーを立てることができます。

私もgolangで簡易webサーバーを作成し、サービスを開発した経験があります
その時は「gin」というwebフレームワークを使用しました。

ginはコチラ

今回はwebフレームワークに頼らなず、ライブラリのみ(純粋なgolang)でwebサーバーを作ってみたいと思います。
参考にしたのは公式ドキュメントhttps://golang.org/doc/articles/wiki/です。英語の原文で学習したい方は是非

なお、golangの基本文法をここでは取り上げません。あらかじめ勉強しておいてください。
私のおすすめはこちらも公式ドキュメントである「A Tour of Go」です。
リンクはコチラ → 「A Tour of Go

また、今回はWindows環境上でプログラミングを行うのでコマンドなどが違う場合はその都度自分のOSにあったコマンドでお試しください。

1.サーバーを立てるプログラムを作成

まずはGOPATHに「golang_server」というディレクトリを作成します。
私は「GOPATH/src/Go_Scripts/golang_server」というディレクトリ構成をとらせていただきます。皆様も任意の場所にディレクトリを作成しディレクトリへ移動してください。

GOPATH\src\Go_Scripts>mkdir golang_server
GOPATH\src\Go_Scripts>cd golang_server
GOPATH\src\Go_Scripts\golang_server>

このディレクトリ内にプログラムを組んでいきます。

server1.go
package main

import (
    "fmt"
    "log"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    text := "You-saku."
    fmt.Fprint(w, "Hi there, I'm ", text)
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

ではコードを解説していきます。
まずはwebサーバーを立てるために必要なパッケージ


1."log"
2."net/http"

をインポートします。これがないと始まりません。

次に関数「handler」,「main」を考えます。

func handler(w http.ResponseWriter, r *http.Request) {
    text := "You-saku."
    fmt.Fprint(w, "Hi there, I'm ", text)
}

func main() {
    http.HandleFunc("/", handler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

main関数で「http.HandleFunc("/",handler)」という記述があります。
こちらはhttpモジュールの持つHandleFuncというメソッドで引数が("アクセスするURL",リクエストの処理方法)です。

ちなみ第1引数を"/"にするとlocalhostになります。また、例えば第1引数を"/profile"と指定すれば 「localhost:ポート/profile」でアクセスした時にリクエスト処理を行います。自分でコードを変更してみるとより理解が深まります。

次にhttp.HandleFuncで呼ばれる「handler」関数です。こちらは実際のリクエスト処理を行う関数です。通例として引数が(変数 http.ResponseWriter, 変数 *http.Request)となります。ルールのようなものですので覚えておきましょう。

ちなみにhttp.ResponceWriterによってwebサーバー上に書き込みを行う場所を確保します。
なのでhandler関数内のfmt.Fprintfでは引数に「w」を受け取っています。このwに書き込みを行い、webページに表示しています。

最後に「log.Fatal」の説明です。こちらは通信のログを記録するものです。引数に「http.ListenAndServe(":8080", nil)」をとっていますが、http.ListenAndServeでエラーが発生した場合、記録を行うようになっています。
また、「http.ListenAndServe()」は実際にどのポート番号でhttp通信を行うのか設定する関数です。引数は(":ポート番号",エラー)になります。今回はポート番号8080番を指定しました。
ここで注意ですが、ポート番号を指定する時 :ポート番号 にしてください 『 : 』 が抜けるとエラーを引き起こします。

2.プログラムの実行、確認

それではプログラムを実行します。

GOPATH\src\Go_Scripts\golang_server>go run server1.go

すると人によってはセキュリティの警告が出ます。その場合、「アクセスを許可する」をクリックしてください。

そしてブラウザで http://localhost:8080/ へアクセスしてください。
するとこのようなページへアクセスできると思います。
go_http1.png

自分で表示する文字を変更してみるのも良いと思います。

最後に

いかだったでしょうか。ginを使ったことのある自分からするとコードを書く部分が多い印象を持ちました。
自分で色々自作しなければいけないですが、その分深くgolangについて知ることができた気がします。次は .html ファイルとの連携を行う「html/template」パッケージを使い、よりwebページっぽくしていきます。

最後まで読んでいただきありがとうございました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Golang] 当番を乱数で決定するプログラム

はじめに

名簿一覧からx人組作って欲しいという要望があったので折角だしgo言語で書いてみました。

package main

import (
    "fmt"
    "math/rand"
    "time"

)

func main() {
    list := [...]string{"mano", "hiori", "meguru",
        "kogane", "mmm", "mitsumine", "sakuya", "kiriko",
        "kaho", "choko", "jyuri", "rinze", "natsuha",
        "amana", "tenka", "chiyuki",
        "asahi", "huyu", "mei",
        "toru", "higuchi", "pya", "hinana"}

    // 何等分するか
    parse := 5
    // 出現した乱数を保持するスライス
    var slice []int
    rand.Seed(time.Now().UnixNano())

    for i := 1; i < len(list)+1; i++ {

        var r int
        // 乱数生成
        for {
            r = rand.Intn(len(list))
            if !contains(slice, r) {
                slice = append(slice, r)
                break
            }
        }

        fmt.Printf("%v ", list[r])

        if i%parse == 0 {
            fmt.Println("")
        }
    }

}

func contains(s []int, e int) bool {
    for _, v := range s {
        if e == v {
            return true
        }
    }
    return false
}

出力結果 例

huyu amana kaho asahi toru
kogane kiriko mano rinze meguru
hiori mitsumine sakuya higuchi jyuri
natsuha tenka chiyuki pya choko
mei mmm hinana

https://gawawa124.hatenablog.com/entry/2015/04/08/193237

https://takeshiyako.blogspot.com/2015/10/go-lang-rand.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む