diff --git a/kadai3/xlune/001/main.go b/kadai3/xlune/001/main.go new file mode 100644 index 0000000..b23c00f --- /dev/null +++ b/kadai3/xlune/001/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "bufio" + "flag" + "fmt" + "io" + "os" + "time" + + "github.com/xlune/dojo1/kadai3/xlune/001/word" +) + +var ( + limitSec int +) + +func init() { + flag.IntVar(&limitSec, "t", 30, "ゲームの制限時間") +} + +func main() { + flag.Parse() + + // 入力チャネル + ch := input(os.Stdin) + // タイムアウト設定 + timeout := time.After(time.Duration(limitSec) * time.Second) + // 最初の問題生成 + makeQuestion() + + fmt.Printf("英語タイピングスタート!!\n(制限時間: %d 秒)\n\n", limitSec) + for { + fmt.Printf("出題 > %s\n", word.GetLatest()) + select { + case result := <-ch: + if word.CheckLatest(result) { + fmt.Println("=> OK!!") + // 次の問題生成 + makeQuestion() + } else { + fmt.Println("=> NG...") + } + case <-timeout: + fmt.Printf("終了それまで!!\n--\n正解数は %d 問でした。\n\n", word.CountHistory()-1) + os.Exit(0) + } + } +} + +func makeQuestion() { + _, err := word.Issue() + if err != nil { + fmt.Println("Error: 出題できませんでした") + os.Exit(1) + } +} + +func input(r io.Reader) <-chan string { + ch := make(chan string) + go func() { + s := bufio.NewScanner(r) + for s.Scan() { + ch <- s.Text() + } + close(ch) + }() + return ch +} diff --git a/kadai3/xlune/001/word/word.go b/kadai3/xlune/001/word/word.go new file mode 100644 index 0000000..df80788 --- /dev/null +++ b/kadai3/xlune/001/word/word.go @@ -0,0 +1,2749 @@ +package word + +import ( + "errors" + "math/rand" + "sort" + "time" +) + +var ( + list = []string{ + "be", + "the", + "and", + "to", + "a", + "of", + "you", + "it", + "in", + "have", + "that", + "we", + "they", + "not", + "do", + "he", + "this", + "for", + "on", + "but", + "know", + "go", + "so", + "with", + "say", + "get", + "think", + "I", + "there", + "will", + "at", + "as", + "what", + "about", + "she", + "like", + "just", + "one", + "if", + "or", + "well", + "all", + "from", + "people", + "would", + "can", + "out", + "because", + "up", + "when", + "who", + "now", + "some", + "right", + "see", + "very", + "come", + "thing", + "more", + "make", + "time", + "want", + "by", + "no", + "really", + "then", + "year", + "good", + "mean", + "take", + "here", + "other", + "which", + "look", + "work", + "could", + "way", + "how", + "talk", + "lot", + "where", + "back", + "much", + "yes", + "use", + "into", + "something", + "over", + "give", + "pause", + "call", + "any", + "than", + "day", + "kind", + "first", + "unclear", + "tell", + "down", + "need", + "also", + "try", + "put", + "only", + "actually", + "should", + "last", + "even", + "let", + "find", + "little", + "sort", + "why", + "new", + "today", + "many", + "still", + "after", + "thank", + "through", + "start", + "point", + "question", + "most", + "happen", + "off", + "feel", + "big", + "before", + "too", + "week", + "problem", + "hear", + "part", + "ask", + "country", + "long", + "issue", + "yeah", + "different", + "change", + "again", + "same", + "another", + "great", + "might", + "number", + "man", + "show", + "never", + "around", + "bit", + "next", + "school", + "place", + "money", + "end", + "play", + "interest", + "help", + "life", + "may", + "fact", + "keep", + "live", + "government", + "home", + "state", + "sure", + "world", + "leave", + "always", + "write", + "child", + "course", + "report", + "every", + "probably", + "woman", + "own", + "meet", + "case", + "move", + "book", + "run", + "anything", + "pay", + "job", + "seem", + "bring", + "old", + "both", + "believe", + "late", + "maybe", + "quite", + "read", + "house", + "kid", + "story", + "whether", + "high", + "month", + "family", + "speak", + "between", + "bad", + "important", + "few", + "group", + "away", + "turn", + "though", + "president", + "understand", + "okay", + "able", + "ago", + "become", + "area", + "night", + "laugh", + "name", + "idea", + "term", + "hour", + "remember", + "deal", + "program", + "whole", + "begin", + "company", + "against", + "hard", + "early", + "love", + "side", + "plan", + "far", + "enough", + "vote", + "word", + "buy", + "set", + "ever", + "build", + "system", + "real", + "test", + "close", + "guy", + "since", + "minute", + "hope", + "student", + "line", + "else", + "business", + "pretty", + "person", + "while", + "second", + "reason", + "everything", + "under", + "spend", + "lose", + "open", + "young", + "public", + "car", + "half", + "stuff", + "each", + "together", + "care", + "sit", + "certainly", + "support", + "such", + "war", + "win", + "nice", + "least", + "news", + "percent", + "hold", + "hand", + "friend", + "send", + "already", + "watch", + "once", + "political", + "example", + "morning", + "somebody", + "stop", + "sense", + "member", + "couple", + "join", + "black", + "city", + "small", + "stay", + "nothing", + "concern", + "continue", + "exactly", + "yet", + "guess", + "someone", + "community", + "head", + "past", + "break", + "until", + "must", + "top", + "market", + "matter", + "information", + "record", + "expect", + "without", + "level", + "force", + "lead", + "learn", + "include", + "whatever", + "answer", + "process", + "large", + "party", + "stand", + "cause", + "clear", + "law", + "agree", + "listen", + "mind", + "almost", + "moment", + "policy", + "during", + "everybody", + "situation", + "wait", + "game", + "grow", + "walk", + "less", + "experience", + "campaign", + "true", + "cut", + "sound", + "water", + "across", + "decide", + "either", + "face", + "order", + "service", + "music", + "involve", + "parent", + "cost", + "power", + "sometimes", + "phone", + "nation", + "health", + "price", + "allow", + "drive", + "obviously", + "decision", + "absolutely", + "kill", + "view", + "along", + "study", + "military", + "suppose", + "pick", + "basically", + "election", + "room", + "team", + "sell", + "office", + "wrong", + "rather", + "within", + "perhaps", + "fall", + "follow", + "leader", + "base", + "figure", + "certain", + "low", + "national", + "easy", + "fight", + "difficult", + "die", + "history", + "official", + "local", + "train", + "dollar", + "create", + "control", + "tomorrow", + "raise", + "movie", + "difference", + "anyway", + "often", + "white", + "rate", + "pass", + "provide", + "general", + "security", + "food", + "sign", + "worry", + "possible", + "eat", + "major", + "consider", + "mother", + "film", + "sing", + "police", + "particular", + "economic", + "yesterday", + "cover", + "rule", + "strong", + "age", + "hit", + "wonder", + "charge", + "round", + "increase", + "drug", + "piece", + "check", + "type", + "several", + "mention", + "position", + "form", + "girl", + "outside", + "step", + "future", + "town", + "ahead", + "attack", + "front", + "site", + "economy", + "fire", + "full", + "result", + "class", + "anybody", + "short", + "former", + "conversation", + "air", + "especially", + "sorry", + "human", + "chance", + "court", + "paper", + "please", + "light", + "themselves", + "teach", + "picture", + "behind", + "race", + "debate", + "offer", + "address", + "language", + "add", + "road", + "effect", + "forward", + "bill", + "effort", + "happy", + "teacher", + "comment", + "share", + "administration", + "opportunity", + "boy", + "free", + "focus", + "everyone", + "carry", + "father", + "door", + "myself", + "save", + "list", + "pound", + "toward", + "amount", + "visit", + "suggest", + "action", + "street", + "laughter", + "death", + "soon", + "fund", + "develop", + "bank", + "role", + "rest", + "particularly", + "doctor", + "tonight", + "individual", + "special", + "industry", + "choice", + "research", + "fine", + "college", + "return", + "education", + "finish", + "yourself", + "center", + "act", + "computer", + "realize", + "tax", + "ready", + "although", + "trouble", + "federal", + "message", + "land", + "international", + "discussion", + "foreign", + "present", + "relationship", + "press", + "body", + "pull", + "among", + "discuss", + "event", + "bear", + "middle", + "reach", + "usually", + "push", + "wife", + "explain", + "draw", + "project", + "travel", + "huge", + "surprise", + "miss", + "trade", + "crime", + "ground", + "itself", + "response", + "letter", + "period", + "song", + "value", + "wear", + "weekend", + "challenge", + "space", + "forget", + "nobody", + "himself", + "serve", + "drop", + "item", + "shop", + "strike", + "station", + "simply", + "church", + "benefit", + "table", + "foot", + "weapon", + "affect", + "likely", + "committee", + "near", + "describe", + "produce", + "oil", + "remain", + "instead", + "baby", + "eye", + "organization", + "hi", + "choose", + "inside", + "statement", + "card", + "television", + "risk", + "agreement", + "throw", + "release", + "medium", + "stick", + "catch", + "funny", + "serious", + "credit", + "standard", + "peace", + "anyone", + "heart", + "personal", + "welcome", + "sport", + "enjoy", + "pressure", + "receive", + "worker", + "financial", + "page", + "budget", + "stage", + "director", + "social", + "son", + "clearly", + "note", + "single", + "speech", + "accept", + "definitely", + "player", + "mine", + "appear", + "product", + "detail", + "politics", + "character", + "board", + "mile", + "prepare", + "key", + "evidence", + "field", + "shoot", + "recently", + "attention", + "technology", + "hospital", + "fun", + "radio", + "interview", + "husband", + "society", + "cell", + "voter", + "fast", + "wonderful", + "private", + "depend", + "dad", + "dog", + "finally", + "staff", + "stock", + "color", + "tape", + "troop", + "drink", + "fair", + "voice", + "measure", + "summer", + "development", + "imagine", + "approach", + "claim", + "available", + "final", + "region", + "nearly", + "require", + "crisis", + "main", + "further", + "store", + "science", + "patient", + "subject", + "quickly", + "respect", + "score", + "worth", + "series", + "afternoon", + "rise", + "poll", + "arm", + "officer", + "tend", + "completely", + "limit", + "condition", + "brother", + "sale", + "tough", + "somewhere", + "energy", + "degree", + "poor", + "notice", + "judge", + "protect", + "account", + "argument", + "season", + "folk", + "plant", + "correct", + "fly", + "document", + "box", + "design", + "recent", + "however", + "culture", + "cold", + "nuclear", + "wish", + "presidential", + "quality", + "population", + "violence", + "date", + "gas", + "trial", + "lie", + "exist", + "common", + "clean", + "marry", + "minister", + "straight", + "represent", + "fill", + "hot", + "beat", + "bomb", + "department", + "argue", + "gun", + "daughter", + "current", + "weather", + "goal", + "unless", + "demand", + "per", + "trip", + "fear", + "practice", + "count", + "dead", + "specific", + "treat", + "track", + "touch", + "park", + "ought", + "safe", + "access", + "holiday", + "recognize", + "manage", + "art", + "evening", + "capital", + "disease", + "activity", + "ring", + "relate", + "material", + "machine", + "newspaper", + "sleep", + "respond", + "warm", + "union", + "review", + "necessarily", + "accord", + "legal", + "simple", + "beyond", + "hang", + "cool", + "video", + "target", + "oppose", + "red", + "movement", + "similar", + "south", + "fit", + "tree", + "audience", + "responsibility", + "email", + "fail", + "medical", + "star", + "opinion", + "announce", + "majority", + "balance", + "hate", + "model", + "quick", + "hurt", + "blue", + "insurance", + "complete", + "various", + "century", + "reduce", + "district", + "reform", + "improve", + "average", + "animal", + "sentence", + "direct", + "independent", + "quote", + "agency", + "floor", + "wall", + "beautiful", + "bed", + "wind", + "writer", + "apply", + "indeed", + "lawyer", + "fairly", + "bottom", + "promise", + "size", + "ability", + "operation", + "commit", + "career", + "totally", + "damage", + "magazine", + "paint", + "contract", + "positive", + "data", + "seat", + "file", + "range", + "schedule", + "direction", + "deep", + "mark", + "environment", + "amaze", + "block", + "soldier", + "encourage", + "rain", + "fish", + "network", + "excite", + "generation", + "sister", + "senior", + "compare", + "assume", + "therefore", + "suffer", + "fan", + "source", + "clock", + "instance", + "basic", + "image", + "primary", + "breath", + "window", + "handle", + "option", + "apparently", + "normal", + "separate", + "lady", + "defense", + "favorite", + "mix", + "contact", + "council", + "appreciate", + "aware", + "university", + "link", + "chief", + "camp", + "basis", + "civil", + "threat", + "resource", + "roll", + "factor", + "solution", + "expert", + "scene", + "nature", + "prison", + "extend", + "regard", + "cross", + "quarter", + "progress", + "extra", + "influence", + "neighborhood", + "brief", + "reporter", + "throughout", + "entire", + "author", + "green", + "doubt", + "popular", + "treatment", + "hair", + "mom", + "cancer", + "occur", + "appeal", + "ticket", + "proposal", + "significant", + "double", + "smoke", + "purpose", + "post", + "truth", + "mostly", + "jump", + "total", + "central", + "advance", + "sex", + "governor", + "conservative", + "warn", + "global", + "dream", + "plus", + "identify", + "income", + "except", + "customer", + "secretary", + "success", + "mistake", + "suspect", + "prove", + "anymore", + "gain", + "blow", + "struggle", + "alone", + "leadership", + "eventually", + "upon", + "attempt", + "seek", + "mathematics", + "structure", + "ball", + "bus", + "scientist", + "fix", + "investigation", + "heavy", + "strategy", + "anywhere", + "professor", + "arrive", + "consumer", + "match", + "taxi", + "possibly", + "expensive", + "investment", + "grade", + "bar", + "solve", + "army", + "possibility", + "express", + "loss", + "dinner", + "lay", + "plane", + "growth", + "background", + "loan", + "none", + "feed", + "trust", + "ice", + "manager", + "generally", + "conflict", + "afraid", + "brain", + "terrible", + "border", + "determine", + "performance", + "article", + "regular", + "band", + "bet", + "supply", + "rock", + "bag", + "flight", + "north", + "cheap", + "chair", + "actual", + "ride", + "successful", + "decade", + "cook", + "burn", + "safety", + "mission", + "slow", + "reaction", + "football", + "studio", + "unit", + "somehow", + "guest", + "potential", + "refer", + "introduce", + "section", + "firm", + "club", + "forth", + "due", + "necessary", + "executive", + "neighbor", + "ad", + "blood", + "professional", + "murder", + "operate", + "citizen", + "propose", + "ship", + "county", + "afford", + "aid", + "reality", + "battle", + "arrest", + "lift", + "admit", + "justice", + "heat", + "earn", + "favor", + "glad", + "intelligence", + "tie", + "above", + "indicate", + "storm", + "ourselves", + "unfortunately", + "natural", + "copy", + "deliver", + "traffic", + "property", + "extent", + "relation", + "elect", + "extremely", + "skill", + "prevent", + "advantage", + "engage", + "shot", + "weight", + "critical", + "organize", + "victim", + "load", + "pain", + "dance", + "rich", + "dress", + "democracy", + "responsible", + "search", + "otherwise", + "resolution", + "religious", + "context", + "criminal", + "memory", + "adult", + "exercise", + "shut", + "screen", + "prime", + "lack", + "element", + "spread", + "achieve", + "mass", + "pleasure", + "discover", + "institution", + "gather", + "normally", + "appropriate", + "avoid", + "connection", + "bother", + "immediately", + "enter", + "twice", + "tour", + "knowledge", + "dangerous", + "negative", + "artist", + "spot", + "shape", + "vehicle", + "agenda", + "excuse", + "colleague", + "agent", + "associate", + "awful", + "crowd", + "corner", + "abuse", + "apart", + "shift", + "invite", + "specifically", + "northern", + "perfect", + "establish", + "alright", + "onto", + "version", + "jury", + "village", + "perform", + "wide", + "effective", + "dozen", + "dark", + "leg", + "convention", + "original", + "labor", + "despite", + "employee", + "politician", + "blame", + "farm", + "approve", + "marriage", + "production", + "define", + "busy", + "function", + "camera", + "estimate", + "remind", + "commission", + "joke", + "earth", + "stress", + "deny", + "survive", + "pack", + "coach", + "sick", + "famous", + "snow", + "reflect", + "chairman", + "broad", + "powerful", + "west", + "equal", + "restaurant", + "advice", + "convince", + "ban", + "legislation", + "divide", + "hopefully", + "directly", + "style", + "launch", + "hire", + "suddenly", + "connect", + "faith", + "engineer", + "truck", + "package", + "male", + "glass", + "behavior", + "collect", + "hotel", + "title", + "tire", + "cough", + "nurse", + "kick", + "finance", + "novel", + "honest", + "conduct", + "suit", + "boat", + "editor", + "management", + "maintain", + "facility", + "fuel", + "odd", + "lesson", + "cup", + "dry", + "mortgage", + "alternative", + "topic", + "grant", + "cent", + "horse", + "till", + "feature", + "opposition", + "female", + "driver", + "graduate", + "square", + "commitment", + "secret", + "quiet", + "overall", + "request", + "additional", + "difficulty", + "personally", + "terrorist", + "speed", + "attitude", + "survey", + "recommend", + "lunch", + "advertise", + "comfortable", + "cry", + "knock", + "waste", + "actor", + "retire", + "remove", + "threaten", + "traditional", + "bloody", + "rid", + "shock", + "accuse", + "tool", + "seriously", + "previous", + "resident", + "cash", + "profit", + "shall", + "competition", + "accident", + "strange", + "circumstance", + "climate", + "owner", + "medicine", + "destroy", + "refuse", + "journalist", + "text", + "freedom", + "everywhere", + "temperature", + "partner", + "expand", + "winter", + "pop", + "coverage", + "mountain", + "careful", + "participate", + "lovely", + "monitor", + "theater", + "principle", + "session", + "settlement", + "replace", + "wave", + "attend", + "sexual", + "river", + "sir", + "host", + "enormous", + "scale", + "incident", + "theory", + "upset", + "communication", + "task", + "wake", + "bridge", + "cat", + "commercial", + "print", + "coffee", + "critic", + "confidence", + "wash", + "recommendation", + "analyst", + "dear", + "currently", + "notion", + "illegal", + "danger", + "flat", + "spring", + "taste", + "literally", + "hole", + "hide", + "negotiation", + "crazy", + "left", + "album", + "flow", + "content", + "shoe", + "wage", + "map", + "emergency", + "lock", + "perspective", + "exchange", + "protest", + "variety", + "fully", + "religion", + "pattern", + "speaker", + "slightly", + "vice", + "intend", + "sector", + "bird", + "wine", + "noise", + "complicate", + "sad", + "telephone", + "tune", + "sea", + "procedure", + "supporter", + "modern", + "familiar", + "easily", + "ultimately", + "somewhat", + "relief", + "switch", + "complex", + "hall", + "gold", + "gift", + "aim", + "honor", + "southern", + "witness", + "judgment", + "smart", + "bottle", + "draft", + "fellow", + "complain", + "sample", + "guarantee", + "sanction", + "jail", + "plenty", + "domestic", + "active", + "invest", + "healthy", + "chemical", + "affair", + "edge", + "mail", + "equipment", + "brand", + "clothes", + "farmer", + "lucky", + "relative", + "status", + "assessment", + "settle", + "priority", + "celebrate", + "breathe", + "resolve", + "award", + "debt", + "defend", + "online", + "bunch", + "photograph", + "mess", + "broadcast", + "consequence", + "east", + "tradition", + "negotiate", + "update", + "mayor", + "scare", + "environmental", + "application", + "daily", + "addition", + "decline", + "minority", + "division", + "physical", + "below", + "luck", + "unusual", + "prefer", + "panel", + "grand", + "victory", + "coast", + "garden", + "concept", + "island", + "yard", + "volunteer", + "strength", + "cast", + "pool", + "theme", + "guilty", + "disaster", + "urge", + "alive", + "sun", + "milk", + "guard", + "rent", + "multiple", + "massive", + "promote", + "gentleman", + "delay", + "representative", + "tear", + "label", + "fashion", + "fat", + "producer", + "flood", + "tiny", + "license", + "useful", + "proud", + "motion", + "kitchen", + "reasonable", + "root", + "analysis", + "whereas", + "herself", + "immigrant", + "smell", + "proceed", + "pair", + "pilot", + "relatively", + "obvious", + "repeat", + "duty", + "recall", + "protection", + "contribute", + "moral", + "row", + "investigate", + "bond", + "ethnic", + "distance", + "finger", + "failure", + "confirm", + "liberal", + "spirit", + "trend", + "wood", + "pursue", + "disagree", + "split", + "shout", + "register", + "ignore", + "initiative", + "horrible", + "highly", + "steal", + "excellent", + "category", + "crack", + "chicken", + "skin", + "code", + "expectation", + "belong", + "object", + "fresh", + "mouth", + "meal", + "counsel", + "payment", + "compete", + "percentage", + "confuse", + "surround", + "freeze", + "predict", + "sheet", + "technical", + "civilian", + "fascinate", + "contain", + "regulation", + "winner", + "photo", + "cultural", + "suggestion", + "abortion", + "angry", + "sudden", + "veteran", + "channel", + "egg", + "stupid", + "capture", + "tea", + "acknowledge", + "virus", + "reject", + "adopt", + "shower", + "entirely", + "investor", + "impossible", + "complaint", + "weird", + "factory", + "reference", + "announcement", + "dialog", + "opposite", + "rush", + "chapter", + "purchase", + "conclusion", + "penalty", + "library", + "path", + "experiment", + "injury", + "guide", + "annual", + "advocate", + "crash", + "proper", + "surface", + "strongly", + "god", + "researcher", + "criticism", + "neither", + "dispute", + "closely", + "gene", + "universal", + "criticize", + "presence", + "ally", + "importance", + "belief", + "method", + "bright", + "tank", + "versus", + "shake", + "museum", + "enemy", + "insist", + "amendment", + "signal", + "extraordinary", + "borrow", + "throat", + "contribution", + "airline", + "wed", + "ensure", + "educate", + "cycle", + "employer", + "objective", + "apartment", + "secure", + "vision", + "corporate", + "chip", + "properly", + "forecast", + "generate", + "tip", + "brilliant", + "meat", + "construction", + "beach", + "device", + "ear", + "swim", + "requirement", + "originally", + "helpful", + "crew", + "collection", + "sweet", + "route", + "birth", + "rank", + "definition", + "industrial", + "swing", + "democratic", + "mental", + "occasion", + "plate", + "communicate", + "wild", + "tension", + "engine", + "phrase", + "reader", + "plastic", + "league", + "chain", + "ordinary", + "declare", + "emerge", + "impression", + "stone", + "beer", + "truly", + "hill", + "column", + "surgery", + "western", + "wire", + "musician", + "prisoner", + "circle", + "hat", + "passage", + "fundamental", + "revenue", + "location", + "net", + "minimum", + "capacity", + "combine", + "react", + "spell", + "unique", + "wrap", + "master", + "initial", + "whenever", + "aircraft", + "carefully", + "concert", + "desire", + "typical", + "deserve", + "ill", + "collapse", + "qualify", + "refugee", + "racial", + "transfer", + "zone", + "appointment", + "classic", + "differently", + "partly", + "mainly", + "inch", + "stretch", + "satisfy", + "empty", + "cable", + "disappear", + "dig", + "impose", + "aside", + "flower", + "regional", + "unemployment", + "bone", + "welfare", + "fee", + "mad", + "technique", + "estate", + "association", + "hardly", + "rely", + "gap", + "frame", + "mate", + "combination", + "nor", + "largely", + "bid", + "elsewhere", + "exam", + "bore", + "youth", + "revolution", + "grab", + "violent", + "attract", + "atmosphere", + "disappoint", + "fault", + "meanwhile", + "electricity", + "defeat", + "climb", + "poverty", + "succeed", + "salary", + "identity", + "escape", + "injure", + "era", + "joint", + "planet", + "musical", + "user", + "carbon", + "outcome", + "tight", + "demonstrate", + "toy", + "inform", + "singer", + "unite", + "wound", + "branch", + "effectively", + "self", + "forever", + "smile", + "explore", + "provision", + "compromise", + "desk", + "king", + "consideration", + "overseas", + "implement", + "urban", + "province", + "personality", + "emotional", + "talent", + "manufacture", + "wing", + "software", + "sky", + "athlete", + "select", + "withdraw", + "recover", + "immediate", + "command", + "boss", + "coal", + "inflation", + "reserve", + "weak", + "illness", + "giant", + "dramatic", + "territory", + "virtually", + "accomplish", + "weigh", + "scream", + "rural", + "golf", + "bin", + "native", + "extreme", + "bike", + "remark", + "soft", + "length", + "concentrate", + "deficit", + "rescue", + "loud", + "cooperation", + "button", + "cream", + "pocket", + "assistance", + "diet", + "usual", + "statistic", + "ocean", + "hero", + "scientific", + "assistant", + "stake", + "instrument", + "core", + "eliminate", + "foundation", + "perfectly", + "plain", + "historical", + "bedroom", + "bread", + "confident", + "transition", + "appoint", + "sponsor", + "lend", + "lake", + "employment", + "repair", + "march", + "inspire", + "brown", + "increasingly", + "expose", + "internal", + "rare", + "nervous", + "controversial", + "pension", + "owe", + "bind", + "teenager", + "severe", + "prior", + "hunt", + "improvement", + "pump", + "curious", + "attach", + "opponent", + "phase", + "initially", + "metal", + "listener", + "nose", + "slip", + "briefly", + "indication", + "intention", + "scheme", + "sight", + "forest", + "shoulder", + "soul", + "roof", + "deeply", + "principal", + "cigarette", + "competitive", + "perception", + "cancel", + "fruit", + "tall", + "narrow", + "adviser", + "destruction", + "flag", + "plot", + "strip", + "advise", + "rough", + "conclude", + "frighten", + "constantly", + "accurate", + "asset", + "export", + "breast", + "friendly", + "practical", + "sugar", + "educational", + "boom", + "thin", + "eastern", + "reveal", + "restore", + "independence", + "vast", + "apologize", + "literature", + "tooth", + "retirement", + "bless", + "bowl", + "primarily", + "alcohol", + "embarrass", + "examine", + "expression", + "display", + "dirty", + "seed", + "electronic", + "expense", + "slide", + "yellow", + "historic", + "journey", + "wherever", + "silly", + "poem", + "badly", + "passenger", + "sensitive", + "crop", + "academic", + "roughly", + "involvement", + "exception", + "sweep", + "portion", + "wheel", + "reduction", + "string", + "hello", + "resign", + "wet", + "chocolate", + "instruction", + "harm", + "approval", + "minor", + "slowly", + "contest", + "currency", + "drag", + "relax", + "absolute", + "moderate", + "depression", + "calm", + "tap", + "permit", + "remarkable", + "stem", + "shirt", + "permanent", + "pitch", + "tennis", + "formal", + "reverse", + "anger", + "explanation", + "allege", + "creative", + "pro", + "nowhere", + "recruit", + "aggressive", + "neck", + "consistent", + "employ", + "entertainment", + "ski", + "exact", + "breakfast", + "uniform", + "presumably", + "fantastic", + "tourist", + "appearance", + "assess", + "therapy", + "reward", + "emphasize", + "pregnant", + "incentive", + "solid", + "cow", + "false", + "prize", + "potentially", + "guideline", + "dish", + "fence", + "swear", + "alarm", + "piano", + "tone", + "comedy", + "highlight", + "cake", + "prospect", + "coat", + "emotion", + "essential", + "hook", + "translate", + "arrange", + "anticipate", + "surely", + "upper", + "framework", + "ceremony", + "maker", + "corporation", + "construct", + "discipline", + "abroad", + "mystery", + "pen", + "trail", + "grandmother", + "relevant", + "unlike", + "fiction", + "van", + "web", + "pot", + "error", + "enable", + "chase", + "privilege", + "cope", + "formula", + "ideal", + "visitor", + "muscle", + "obligation", + "meter", + "unlikely", + "potato", + "mood", + "slave", + "impress", + "sum", + "reputation", + "champion", + "consultant", + "cap", + "import", + "arrangement", + "knee", + "isolate", + "restriction", + "moon", + "pose", + "description", + "index", + "cheese", + "implication", + "demonstration", + "elderly", + "assumption", + "previously", + "dominate", + "gear", + "component", + "substantial", + "profile", + "pour", + "lecture", + "electric", + "counter", + "household", + "fancy", + "desert", + "spin", + "justify", + "trap", + "blind", + "radical", + "grass", + "mouse", + "orange", + "concrete", + "thick", + "everyday", + "divorce", + "log", + "constant", + "stable", + "pile", + "cousin", + "sink", + "distinction", + "perceive", + "silver", + "childhood", + "capable", + "criterion", + "cloud", + "episode", + "efficient", + "lean", + "infection", + "chart", + "vary", + "heavily", + "platform", + "crucial", + "intellectual", + "float", + "observe", + "gate", + "emphasis", + "nearby", + "proof", + "submit", + "vegetable", + "gray", + "integrate", + "bury", + "typically", + "interpret", + "pray", + "dealer", + "volume", + "clinical", + "preserve", + "valuable", + "boot", + "personnel", + "bite", + "substance", + "secondly", + "transport", + "philosophy", + "salt", + "innocent", + "random", + "drama", + "distribute", + "shelter", + "locate", + "sharp", + "protein", + "guitar", + "assure", + "presentation", + "besides", + "kiss", + "chat", + "trick", + "achievement", + "mechanism", + "acceptable", + "symbol", + "wise", + "digital", + "regret", + "gender", + "bell", + "burden", + "persuade", + "manufacturer", + "tournament", + "embrace", + "abandon", + "capability", + "stamp", + "recovery", + "comprehensive", + "pace", + "analyze", + "regardless", + "biological", + "assist", + "margin", + "sake", + "wipe", + "whisper", + "occasionally", + "discovery", + "adjust", + "inner", + "steel", + "barrier", + "dedicate", + "recognition", + "reckon", + "poetry", + "equally", + "historian", + "strengthen", + "beauty", + "motivate", + "routine", + "behave", + "selection", + "delivery", + "depress", + "manner", + "wealth", + "charity", + "precisely", + "boundary", + "boost", + "cite", + "consult", + "frequently", + "shelf", + "essay", + "trigger", + "transportation", + "sustain", + "panic", + "permission", + "extension", + "comfort", + "equivalent", + "paragraph", + "spare", + "preparation", + "overcome", + "contrast", + "habit", + "intense", + "phenomenon", + "literary", + "stroke", + "govern", + "pollution", + "evolve", + "humor", + "ease", + "regulate", + "genetic", + "praise", + "format", + "diversity", + "edition", + "championship", + "wealthy", + "disturb", + "interpretation", + "resistance", + "segment", + "pub", + "symptom", + "offense", + "stream", + "outline", + "suspend", + "comparison", + "iron", + "attractive", + "bias", + "encounter", + "nevertheless", + "creation", + "angle", + "passion", + "stability", + "dramatically", + "equation", + "twist", + "magic", + "expansion", + "partnership", + "dare", + "celebration", + "bend", + "layer", + "widely", + "strict", + "rival", + "naturally", + "stomach", + "loose", + "deposit", + "evil", + "craft", + "landscape", + "delight", + "arise", + "membership", + "journal", + "opera", + "bath", + "seal", + "prompt", + "temporary", + "compound", + "unable", + "maximum", + "pride", + "voluntary", + "barely", + "entitle", + "universe", + "pretend", + "install", + "specialist", + "discount", + "pig", + "convert", + "evolution", + "brush", + "reply", + "dust", + "dismiss", + "regularly", + "pipe", + "restrict", + "sand", + "depth", + "occupy", + "soil", + "dependent", + "intervention", + "grateful", + "nerve", + "port", + "festival", + "proportion", + "alter", + "rice", + "poet", + "pure", + "belt", + "ancient", + "disk", + "inquiry", + "significantly", + "strain", + "tackle", + "twin", + "distinguish", + "observation", + "invent", + "nowadays", + "sigh", + "slight", + "tent", + "altogether", + "height", + "sequence", + "retail", + "weekly", + "jacket", + "disorder", + "chest", + "joy", + "rapidly", + "entry", + "carpet", + "buyer", + "input", + "dimension", + "anxiety", + "devote", + "ugly", + "pink", + "introduction", + "motor", + "flash", + "entertain", + "remote", + "calculate", + "tube", + "mirror", + "clothing", + "publisher", + "breed", + "sufficient", + "representation", + "resist", + "exhibit", + "exclude", + "resort", + "shell", + "scan", + "imply", + "awareness", + "silence", + "peak", + "uncle", + "admire", + "fool", + "automatically", + "parallel", + "database", + "tower", + "acquire", + "tail", + "sail", + "profession", + "rail", + "ruin", + "classical", + "existence", + "enhance", + "evaluate", + "mobile", + "exhibition", + "participation", + "rarely", + "steady", + "characteristic", + "psychological", + "knife", + "interaction", + "peer", + "underlie", + "consume", + "conventional", + "considerable", + "vital", + "trace", + "fortune", + "enterprise", + "imagination", + "edit", + "compensation", + "fulfill", + "visual", + "retain", + "shore", + "summary", + "establishment", + "accommodation", + "registration", + "unknown", + "adapt", + "furniture", + "exposure", + "luxury", + "incorporate", + "transform", + "raw", + "valley", + "snap", + "survival", + "scholar", + "undertake", + "tale", + "fortunate", + "leap", + "insight", + "approximately", + "shadow", + "tissue", + "excitement", + "successfully", + "hint", + "confusion", + "mount", + "gradually", + "sheep", + "decrease", + "concentration", + "origin", + "designer", + "invitation", + "adequate", + "curve", + "tendency", + "grain", + "laboratory", + "characterize", + "extensive", + "weakness", + "motivation", + "species", + "greet", + "impressive", + "slice", + "filter", + "monthly", + "participant", + "assign", + "narrative", + "friendship", + "visible", + "rat", + "detect", + "reflection", + "ownership", + "differ", + "stair", + "coin", + "thus", + "measurement", + "fold", + "accompany", + "silent", + "apparent", + "shine", + "reasonably", + "promotion", + "maintenance", + "menu", + "keen", + "liability", + "competitor", + "contemporary", + "secondary", + "premise", + "adventure", + "hurry", + "mutual", + "agricultural", + "anxious", + "significance", + "pleasant", + "absence", + "preference", + "undergo", + "examination", + "exhaust", + "illustrate", + "scope", + "merely", + "burst", + "evaluation", + "pregnancy", + "chamber", + "determination", + "substitute", + "specialize", + "stranger", + "efficiency", + "reliable", + "revise", + "genuine", + "golden", + "publication", + "catalog", + "via", + "stir", + "wander", + "mature", + "skirt", + "operator", + "charm", + "interior", + "modify", + "numerous", + "newly", + "gallery", + "vessel", + "curtain", + "insure", + "smooth", + "clause", + "aunt", + "mixture", + "yield", + "architecture", + "variation", + "excess", + "creature", + "mode", + "uncertainty", + "wooden", + "romantic", + "quantity", + "storage", + "attribute", + "stare", + "envelope", + "innovation", + "liquid", + "flexible", + "lip", + "stimulate", + "greatly", + "venture", + } + history = []int{} +) + +// Issue ワードを履歴に発行する +func Issue() (string, error) { + totalCount := len(list) + usedCount := len(history) + randCount := totalCount - usedCount + if randCount <= 0 { + return "", errors.New("no available words") + } + // 有効数内からランダム値生成 + t := time.Now().UnixNano() + rand.Seed(t) + index := rand.Intn(randCount) + // ランダム値を有効インデックス化 + h := make([]int, len(history)) + copy(h, history) + sort.Ints(h) + for _, i := range h { + if i <= index { + index++ + } else { + break + } + } + // 履歴追加してワードを正常返却 + history = append(history, index) + return GetLatest(), nil +} + +// GetLatest 直近の発行ワードを取得 +func GetLatest() string { + if len(history) == 0 { + return "" + } + latestIndex := history[len(history)-1] + return list[latestIndex] +} + +// ClearHistory ワード発行履歴をクリア +func ClearHistory() { + history = []int{} +} + +// CountHistory ワード発行履歴数を取得 +func CountHistory() int { + return len(history) +} + +// CountTotal 総ワード数 +func CountTotal() int { + return len(list) +} + +// CheckLatest 入力文字列と直近の発行文字列の同一チェック +func CheckLatest(input string) bool { + if input == "" { + return false + } + return input == GetLatest() +} diff --git a/kadai3/xlune/001/word/word_test.go b/kadai3/xlune/001/word/word_test.go new file mode 100644 index 0000000..02e92dc --- /dev/null +++ b/kadai3/xlune/001/word/word_test.go @@ -0,0 +1,74 @@ +package word_test + +import ( + "testing" + + "github.com/xlune/dojo1/kadai3/xlune/001/word" +) + +func TestIssue(t *testing.T) { + word.ClearHistory() + c := word.CountTotal() + words := []string{} + for i := 0; i < c; i++ { + str, err := word.Issue() + if err != nil { + t.Fatal("return value invalid") + } + for _, w := range words { + if w == str { + t.Fatal("duplicate words") + } + } + words = append(words, str) + } + _, err := word.Issue() + if err == nil { + t.Fatal("need error") + } +} + +func TestGetLatest(t *testing.T) { + word.ClearHistory() + if word.GetLatest() != "" { + t.Fatal("need empty string") + } + str, err := word.Issue() + if err != nil { + t.Fatal("return value invalid") + } + if str != word.GetLatest() { + t.Fatal("return value not match") + } +} + +func TestCountHistory(t *testing.T) { + word.ClearHistory() + if word.CountHistory() != 0 { + t.Fatal("need count 0") + } + _, err := word.Issue() + if err != nil { + t.Fatal("return value invalid") + } + if word.CountHistory() != 1 { + t.Fatal("need count 1") + } +} + +func TestCheckLatest(t *testing.T) { + word.ClearHistory() + if word.CheckLatest("") { + t.Fatal("need return false") + } + str, err := word.Issue() + if err != nil { + t.Fatal("return value invalid") + } + if !word.CheckLatest(str) { + t.Fatal("need return true") + } + if word.CheckLatest("hoge") { + t.Fatal("need return false") + } +} diff --git a/kadai3/xlune/002/client/client.go b/kadai3/xlune/002/client/client.go new file mode 100644 index 0000000..9bcfa7a --- /dev/null +++ b/kadai3/xlune/002/client/client.go @@ -0,0 +1,149 @@ +package client + +import ( + "errors" + "fmt" + "io/ioutil" + "math" + "net/http" + "path" + "strconv" + "strings" + "time" +) + +const ( + // UnitSize ダウンロードサイズ最小値 + UnitSize = 1024 +) + +// TargetInfo 対象の情報 +type TargetInfo struct { + URL string + Name string + Size int64 + IsRanges bool +} + +// DownloadRange ダウンロードレンジ +type DownloadRange struct { + Start int64 + End int64 +} + +// DownloadItem ダウンロード管理アイテム +type DownloadItem struct { + URL string + RangeIndex int + Range DownloadRange + Body []byte +} + +// DownloadByItem ターゲット情報でダウンロードする +func DownloadByItem(item *DownloadItem) error { + + req, err := http.NewRequest("GET", item.URL, nil) + if err != nil { + return err + } + req.Header.Add("Range", fmt.Sprintf("bytes=%d-%d", item.Range.Start, item.Range.End)) + + var client http.Client + resp, err := client.Do(req) + if err != nil { + return err + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return err + } + item.Body = body + return nil +} + +// MakeDownloadRange 分割ダウンロードレンジリスト生成 +func MakeDownloadRange(size int64, count int) ([]DownloadRange, error) { + result := []DownloadRange{} + if count <= 0 { + return result, errors.New("invalid argument") + } + unitCount := size / UnitSize + if size%UnitSize > 0 { + unitCount++ + } + + fillCount := unitCount % int64(count) + if fillCount != 0 { + fillCount = int64(count) - fillCount + } + singleCount := (unitCount + fillCount) / int64(count) + + for i := 0; i < count; i++ { + s := int64(i) * singleCount * UnitSize + e := int64(i+1)*singleCount*UnitSize - 1 + result = append(result, DownloadRange{ + Start: s, + End: int64(math.Min(float64(e), float64(size))), + }) + } + + return result, nil +} + +// GetSourceURL 実態URLの取得 +func GetSourceURL(url string) (string, error) { + req, err := http.NewRequest("HEAD", url, nil) + if err != nil { + return "", err + } + resp, err := http.DefaultTransport.RoundTrip(req) + if err != nil { + return "", err + } + defer resp.Body.Close() + if resp.StatusCode == 301 || + resp.StatusCode == 302 || + resp.StatusCode == 303 || + resp.StatusCode == 307 { + + source := resp.Header["Location"] + if len(source) > 0 { + return GetSourceURL(source[0]) + } + return "", errors.New("redirect location empty") + } + return url, nil +} + +// GetInfo ファイルサイズ取得 +func GetInfo(url string) (TargetInfo, error) { + info := TargetInfo{ + URL: url, + } + c := &http.Client{ + Timeout: time.Duration(10) * time.Second, + } + + resp, err := c.Head(url) + info.Name = path.Base(resp.Request.URL.Path) + if err != nil { + return info, err + } + defer resp.Body.Close() + + if ar, ok := resp.Header["Accept-Ranges"]; ok && strings.ToLower(ar[0]) == "bytes" { + info.IsRanges = true + } + + if cl, ok := resp.Header["Content-Length"]; ok { + size, err := strconv.ParseInt(cl[0], 10, 64) + if err != nil { + return info, err + } + info.Size = size + } + + return info, nil +} diff --git a/kadai3/xlune/002/client/client_test.go b/kadai3/xlune/002/client/client_test.go new file mode 100644 index 0000000..764f886 --- /dev/null +++ b/kadai3/xlune/002/client/client_test.go @@ -0,0 +1,91 @@ +package client_test + +import ( + "testing" + + "github.com/xlune/dojo1/kadai3/xlune/002/client" +) + +const ( + targetUrl = "https://dl.google.com/go/go1.10.2.src.tar.gz" + targetLightWeightUrl = "https://getbootstrap.com/docs/4.0/getting-started/download/" +) + +func TestDownloadByTargetInfo(t *testing.T) { + url, err := client.GetSourceURL(targetLightWeightUrl) + if err != nil { + t.Fatal("Get Header failed") + } + info, err := client.GetInfo(url) + if err != nil { + t.Fatal("Get TargetInfo failed") + } + + item := &client.DownloadItem{ + URL: url, + RangeIndex: 0, + Range: client.DownloadRange{ + Start: 0, + End: info.Size, + }, + } + err = client.DownloadByItem(item) + if err != nil { + t.Fatal("Download failed") + } +} + +var downloadRangeSample = []struct { + size int64 + count int + ranges []client.DownloadRange + isError bool +}{ + {1234567890, 1, []client.DownloadRange{ + client.DownloadRange{Start: 0, End: 1234567890}, + }, false}, + {1234567890, 0, []client.DownloadRange{ + client.DownloadRange{Start: 0, End: 0}, + }, true}, + {1234567890, 3, []client.DownloadRange{ + client.DownloadRange{Start: 0, End: 411523071}, + client.DownloadRange{Start: 411523072, End: 823046143}, + client.DownloadRange{Start: 823046144, End: 1234567890}, + }, false}, +} + +func TestMakeDownloadRange(t *testing.T) { + for _, rs := range downloadRangeSample { + dr, err := client.MakeDownloadRange(rs.size, rs.count) + if (err != nil) != rs.isError { + t.Fatal("error result not match") + } + if !rs.isError { + for index, r := range rs.ranges { + if r != dr[index] { + t.Fatal("range not match") + } + } + } + } +} + +func TestGetSourceURL(t *testing.T) { + _, err := client.GetSourceURL(targetUrl) + if err != nil { + t.Fatal("Get Header failed") + } + +} + +func TestGetInfo(t *testing.T) { + url, err := client.GetSourceURL(targetUrl) + if err != nil { + t.Fatal("Get Header failed") + } + + _, err = client.GetInfo(url) + if err != nil { + t.Fatal("Get TargetInfo failed") + } +} diff --git a/kadai3/xlune/002/main.go b/kadai3/xlune/002/main.go new file mode 100644 index 0000000..c901ec4 --- /dev/null +++ b/kadai3/xlune/002/main.go @@ -0,0 +1,95 @@ +package main + +import ( + "flag" + "fmt" + "os" + + "github.com/xlune/dojo1/kadai3/xlune/002/client" + "golang.org/x/sync/errgroup" +) + +var ( + splitCount int +) + +func init() { + flag.IntVar(&splitCount, "d", 3, "分割数") +} + +func main() { + flag.Parse() + + sourcePath := flag.Arg(0) + + url, err := client.GetSourceURL(sourcePath) + if err != nil { + fmt.Printf("URLチェックに失敗しました...(%s)\n", err.Error()) + os.Exit(1) + } + + info, err := client.GetInfo(url) + if err != nil { + fmt.Printf("ファイル情報取得に失敗しました...(%s)\n", err.Error()) + os.Exit(1) + } + + err = download(info, splitCount) + if err != nil { + fmt.Printf("ダウンロードに失敗しました...(%s)\n", err.Error()) + os.Exit(1) + } + + fmt.Printf("ダウンロード完了しました! (%s)\n", info.Name) +} + +func download(info client.TargetInfo, count int) error { + + // レンジ取得未対応かファイルサイズが小さいものは分割しない + if !info.IsRanges || info.Size < int64(count)*client.UnitSize { + count = 1 + } + + // 分割サイズリスト取得 + ranges, err := client.MakeDownloadRange(info.Size, count) + if err != nil { + return err + } + + // アイテム情報を生成して分割ダウンロード + eg := errgroup.Group{} + items := []*client.DownloadItem{} + for index, r := range ranges { + item := &client.DownloadItem{ + URL: info.URL, + RangeIndex: index, + Range: r, + } + eg.Go(func() error { + return client.DownloadByItem(item) + }) + items = append(items, item) + } + + // 処理を待ってエラー判定 + err = eg.Wait() + if err != nil { + return err + } + + // 書き込み先を新規でオープン + file, err := os.OpenFile(info.Name, os.O_WRONLY|os.O_CREATE, 0644) + if err != nil { + return err + } + defer file.Close() + // 書き込み + for _, item := range items { + _, err := file.WriteAt(item.Body, item.Range.Start) + if err != nil { + return err + } + } + + return nil +}