Là một dev Fullstack Nodejs và đang cảm thấy hiện tại Nodejs đang khó kiếm việc nên mình bắt đầu học ngôn ngữ mới, tại sao lại là Go thì mình có đi tìm vài ngôn ngữ tiềm năng để học thì thấy có Go và Rust nhưng rust có vẻ thiên về hệ thống hơn còn với Go thì làm web mà mình là dev web nên mình chọn học Go, hơn nữa cú pháp của nó có vẻ khá dễ học.
Mình bắt đầu chọn học qua trang Exercism, sau khi học qua hết cái phần lộ trình cơ bản rồi nên giờ sẽ đi giải các bài tập để hiểu rõ hơn, vì cũng đã quá quen với Nodejs rồi nên giờ khá là lú trong nhiều phần như xử lý chuỗi của 2 ngôn ngữ này -.-
Bổ sung: Ban đầu mình chỉ định là làm mấy câu rồi quay ra LeetCode để giải nhưng mà hiện tại sếp lại kêu chuyển đổi công nghệ nên mình phải học thêm Remix React, tiện là mình cũng định học Golang nên mình có ý định sẽ làm luôn 1 thứ gì đó gồm Front-end, Back-end và Mobile app, lộ trình như sau:
- Thời điểm đầu tiên mình học cú pháp của Golang sẽ là phần 1 này, nói là cú pháp vì mình làm Nodejs mấy năm rồi nên các thứ nó cũng giống giống nhau cả khác khái niệm và cú pháp thôi.
- Sau khi hoàn thành phần học Golang mình sẽ chuyển qua học Remix, nhìn chung cũng thấy kha khá giống với Next, mình cũng thử tạo project Remix rồi và người ta sử dụng mặc định là Tailwind nên mình cũng sẽ học thêm cả Tailwind nữa, gọi là học nhưng có lẽ giống kiểu cưỡi ngựa xem hoa thôi và có vấn đề ở đâu tìm hiểu và giải quyết đến đó sau. Mình cũng sẽ thử nghĩ xem làm gì đó để kết hợp cả FE với BE có thể là 1 trang gì đó như chia sẻ hình ảnh sau đó người dùng có thể vào vào like và bình luận, đăng ký đăng nhập, tự nhiên thấy giống giống cái facebook nhưng làm sida phake thôi, học là chính.
- Phần tiếp theo là làm Back-end mình sẽ làm 1 cái BE bằng Golang sử dụng database để lưu trữ quản lý tài khoản, hình ảnh, bình luận... có lẽ là sử dụng JWT làm authen. Mới nghĩ thôi mình cũng chưa biết sẽ làm thế nào nữa :D
- Sau khi ổn ổn chấp nhận được thì mình sẽ làm 1 cái app mobile bằng React Native vì cũng tiện nó là React luôn chứ nghĩ thôi là đã thấy lười học thêm cái nữa lắm rồi.
Hy vọng mình sẽ hoàn thành dự định này trong vòng 1 năm tới, tại mình cũng chỉ có ý định code thêm vào 2 ngày nghỉ cuối tuần thôi.
Thôi thì bắt đầu giải bài hiện tại
ETL
Introduction
You work for a company that makes an online multiplayer game called Lexiconia.
To play the game, each player is given 13 letters, which they must rearrange to create words. Different letters have different point values, since it's easier to create words with some letters than others.
The game was originally launched in English, but it is very popular, and now the company wants to expand to other languages as well.
Different languages need to support different point values for letters. The point values are determined by how often letters are used, compared to other letters in that language.
For example, the letter 'C' is quite common in English, and is only worth 3 points. But in Norwegian it's a very rare letter, and is worth 10 points.
To make it easier to add new languages, your team needs to change the way letters and their point values are stored in the game.
Instructions
Your task is to change the data format of letters and their point values in the game.
Currently, letters are stored in groups based on their score, in a one-to-many mapping.
- 1 point: "A", "E", "I", "O", "U", "L", "N", "R", "S", "T",
- 2 points: "D", "G",
- 3 points: "B", "C", "M", "P",
- 4 points: "F", "H", "V", "W", "Y",
- 5 points: "K",
- 8 points: "J", "X",
- 10 points: "Q", "Z",
This needs to be changed to store each individual letter with its score in a one-to-one mapping.
- "a" is worth 1 point.
- "b" is worth 3 points.
- "c" is worth 3 points.
- "d" is worth 2 points.
- etc.
As part of this change, the team has also decided to change the letters to be lower-case rather than upper-case.
func Transform(in map[int][]string) map[string]int {
panic("Please implement the Transform function")
}
Hiểu bài toán
Ý tưởng thực hiện
Code
import (
"strings"
)
func Transform(in map[int][]string) map[string]int {
res := map[string]int{}
for key, value := range in {
for _, v := range value {
res[strings.ToLower(v)] = key
}
}
return res
}
Bob
Introduction
Bob is a lackadaisical teenager. He likes to think that he's very cool. And he definitely doesn't get excited about things. That wouldn't be cool.
When people talk to him, his responses are pretty limited.
Instructions
Your task is to determine what Bob will reply to someone when they say something to him or ask him a question.
Bob only ever answers one of five things:
- "Sure." This is his response if you ask him a question, such as "How are you?" The convention used for questions is that it ends with a question mark.
- "Whoa, chill out!" This is his answer if you YELL AT HIM. The convention used for yelling is ALL CAPITAL LETTERS.
- "Calm down, I know what I'm doing!" This is what he says if you yell a question at him.
- "Fine. Be that way!" This is how he responds to silence. The convention used for silence is nothing, or various combinations of whitespace characters.
- "Whatever." This is what he answers to anything else.
func Hey(remark string) string {
return ""
}
Hiểu bài toán
Ý tưởng thực hiện
Code
import (
"fmt"
"regexp"
"strings"
)
func IsUpper(s string) bool {
reg := regexp.MustCompile(`[a-zA-Z]`)
if !reg.MatchString(s) {
return false
}
return s == strings.ToUpper(s)
}func Hey(remark string) string {
remark = strings.TrimSpace(remark)
isUpper := IsUpper(remark)
hasSuffix := strings.HasSuffix(remark, "?")
switch {
case remark == "":
return "Fine. Be that way!"
case isUpper && hasSuffix:
return "Calm down, I know what I'm doing!"
case isUpper:
return "Whoa, chill out!"
case hasSuffix:
return "Sure."
default:
return "Whatever."
}
}
Grains
Instructions
Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.
There once was a wise servant who saved the life of a prince. The king promised to pay whatever the servant could dream up. Knowing that the king loved chess, the servant told the king he would like to have grains of wheat. One grain on the first square of a chess board, with the number of grains doubling on each successive square.
There are 64 squares on a chessboard (where square 1 has one grain, square 2 has two grains, and so on).
Write code that shows:
- how many grains were on a given square, and
- the total number of grains on the chessboard
func Square(number int) (uint64, error) {
panic("Please implement the Square function")
}
func Total() uint64 {
panic("Please implement the Total function")
}
Hiểu bài toán
Ý tưởng thực hiện
Code
import (
"errors"
"math"
)
func Square(number int) (uint64, error) {
if number < 1 || number > 64 {
return 0, errors.New("square must be between 1 and 64")
}
return uint64(math.Pow(2, float64(number-1))), nil
}
func Total() uint64 {
var sum uint64 = 0
for i := 1; i <= 64; i++ {
res, err := Square(i)
if err != nil {
return 0
}
sum += res
}
return sum
}
Roman Numerals
Introduction
Today, most people in the world use Arabic numerals (0–9). But if you travelled back two thousand years, you'd find that most Europeans were using Roman numerals instead.
To write a Roman numeral we use the following Latin letters, each of which has a value:
A Roman numeral is a sequence of these letters, and its value is the sum of the letters' values. For example, XVIII
has the value 18 (10 + 5 + 1 + 1 + 1 = 18
).
There's one rule that makes things trickier though, and that's that the same letter cannot be used more than three times in succession. That means that we can't express numbers such as 4 with the seemingly natural IIII
. Instead, for those numbers, we use a subtraction method between two letters. So we think of 4
not as 1 + 1 + 1 + 1
but instead as 5 - 1
. And slightly confusingly to our modern thinking, we write the smaller number first. This applies only in the following cases: 4 (IV
), 9 (IX
), 40 (XL
), 90 (XC
), 400 (CD
) and 900 (CM
).
Order matters in Roman numerals! Letters (and the special compounds above) must be ordered by decreasing value from left to right.
Here are some examples:
And a final more complex example:
Instructions
Your task is to convert a number from Arabic numerals to Roman numerals.
For this exercise, we are only concerned about traditional Roman numerals, in which the largest number is MMMCMXCIX (or 3,999).
Hiểu bài toán
Ý tưởng thực hiện
Code
import (
"errors"
"fmt"
)
type RomanNumeral struct {
Value int
Symbol string
}
func ToRomanNumeral(input int) (string, error) {
if input <= 0 || input >= 4000 {
return "", errors.New("out of range")
}
m := []RomanNumeral{{1000, "M"}, {900, "CM"}, {500, "D"}, {400, "CD"}, {100, "C"}, {90, "XC"}, {50, "L"}, {40, "XL"}, {10, "X"}, {9, "IX"}, {5, "V"}, {4, "IV"}, {1, "I"}}
res := ""
for _, numeral := range m {
value, symbol := numeral.Value, numeral.Symbol
for input >= value {
res += symbol
input -= value
}
}
return res, nil
}
func RomanToArabic(input string) int {
m := map[string]int{"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
res := 0
prev := 0
for i := len(input) - 1; i >= 0; i-- {
curr := m[string(input[i])]
if curr < prev {
res -= curr
} else {
res += curr
}
prev = curr
}
return res
}
ISBN
Instructions
The ISBN-10 verification process is used to validate book identification numbers. These normally contain dashes and look like: 3-598-21508-8
ISBN
The ISBN-10 format is 9 digits (0 to 9) plus one check character (either a digit or an X only). In the case the check character is an X, this represents the value '10'. These may be communicated with or without hyphens, and can be checked for their validity by the following formula:
If the result is 0, then it is a valid ISBN-10, otherwise it is invalid.
Example
Let's take the ISBN-10 3-598-21508-8
. We plug it in to the formula, and get:
Since the result is 0, this proves that our ISBN is valid.
Task
Given a string the program should check if the provided string is a valid ISBN-10. Putting this into place requires some thinking about preprocessing/parsing of the string prior to calculating the check digit for the ISBN.
The program should be able to verify ISBN-10 both with and without separating dashes.
Caveats
Converting from strings to numbers can be tricky in certain languages. Now, it's even trickier since the check digit of an ISBN-10 may be 'X' (representing '10'). For instance 3-598-21507-X
is a valid ISBN-10.
Hiểu bài toán
Ý tưởng thực hiện
Code
import (
"fmt"
"strings"
)
func IsValidISBN(isbn string) bool {
isbn2 := strings.ReplaceAll(isbn, "-", "")
if len(isbn2) != 10 {
return false
}
i := 10
sum := 0
for index, value := range isbn2 {
if value >= '0' && value <= '9' {
sum += int(value-'0') * i
} else if value == 'X' && index == 9 {
sum += 10
} else {
return false
}
i--
}
return sum%11 == 0
}
Word Count
Introduction
You teach English as a foreign language to high school students.
You've decided to base your entire curriculum on TV shows. You need to analyze which words are used, and how often they're repeated.
This will let you choose the simplest shows to start with, and to gradually increase the difficulty as time passes.
Instructions
Your task is to count how many times each word occurs in a subtitle of a drama.
The subtitles from these dramas use only ASCII characters.
The characters often speak in casual English, using contractions like they're or it's. Though these contractions come from two words (e.g. we are), the contraction (we're) is considered a single word.
Words can be separated by any form of punctuation (e.g. ":", "!", or "?") or whitespace (e.g. "\t", "\n", or " "). The only punctuation that does not separate words is the apostrophe in contractions.
Numbers are considered words. If the subtitles say It costs 100 dollars. then 100 will be its own word.
Words are case insensitive. For example, the word you occurs three times in the following sentence:
You come back, you hear me? DO YOU HEAR ME?
The ordering of the word counts in the results doesn't matter.
Here's an example that incorporates several of the elements discussed above:
- simple words
- contractions
- numbers
- case insensitive words
- punctuation (including apostrophes) to separate words
- different forms of whitespace to separate words
"That's the password: 'PASSWORD 123'!", cried the Special Agent.\nSo I fled.
The mapping for this subtitle would be:
Hiểu bài toán
Ý tưởng thực hiện
\b[\w']+\b
Code
import (
"regexp"
"strings"
)
type Frequency map[string]int
func WordCount(phrase string) Frequency {
re := regexp.MustCompile(`\b[\w']+\b`)
phrase = strings.ToLower(phrase)
phrase = strings.ReplaceAll(phrase, "\\n", " ")
arr := re.FindAllString(phrase, -1)
res := make(Frequency)
for _, val := range arr {
res[val] = res[val] + 1
}
return res
}
0 Nhận xét