├── .gitignore ├── README.md ├── week0001 ├── Code2ProStudent │ └── week0001.py ├── DangKhoa │ └── DangKhoa.cpp ├── FizzBuzzMichal.php ├── FizzBuzzMichalGo.go ├── FizzBuzzThao.java ├── FizzBuzzThao.js ├── FizzBuzzThao.py ├── README.md ├── correct_output.dat ├── dbugxpert │ └── week0001.py ├── fizz-buzz-saidadaki.py ├── fizz_buzz_congpine.rb ├── fizz_buzz_haond.rb ├── fizz_buzz_haond1.rb ├── fizz_buzz_matt.php ├── fizz_buzz_phuocnt.php ├── fizzbuzz_daudau.php ├── fizzbuzz_nam.py ├── haond_benchmark.md ├── quiz001-Ryan-Python.py ├── quiz001-Ryan.cs └── truongngodang │ └── week0001.java ├── week0002 ├── README.md ├── atapie │ └── java │ │ └── week0002.java ├── daudau │ └── php │ │ └── daudau.php ├── dbugxpert │ └── python │ │ └── week0002.py ├── giaosudau │ └── python │ │ ├── README.md │ │ ├── test_case_01.dat │ │ ├── test_case_02.dat │ │ ├── test_case_03.dat │ │ ├── test_case_04.dat │ │ ├── test_case_05.dat │ │ ├── test_case_06.dat │ │ ├── test_case_07.dat │ │ └── week0002.py ├── hienhpss │ └── python │ │ └── week0002.py ├── hieuvo │ └── php │ │ └── week0002.php ├── hoangdangduy │ └── java │ │ └── Week0002.java ├── mattfanz │ └── php │ │ └── week0002.php ├── pertsodian │ └── java │ │ └── src │ │ ├── BaseMatrixPrinter.java │ │ ├── BaseMatrixPrinterTest.java │ │ ├── ConsoleMatrixPrinter.java │ │ ├── SpiralMatrixApp.java │ │ ├── SpiralMatrixGenerator.java │ │ └── SpiralMatrixGeneratorTest.java ├── phucnm │ └── cpp │ │ └── week002.cpp ├── sample.php ├── test_case_01.dat ├── thainguyentran │ └── CSharp │ │ └── week0002.cs ├── thaotran │ └── java │ │ └── week0002.java └── truongngodang │ └── java │ └── week0002.java ├── week0003 ├── README.md ├── daudau │ └── php │ │ └── daudau.php ├── giaosudau │ └── python │ │ └── week0003.py ├── hoangdangduy │ └── java │ │ ├── Account.java │ │ ├── Process.java │ │ ├── Response.java │ │ └── Week0003.java ├── mattfanz │ └── php │ │ ├── .gitignore │ │ └── src │ │ ├── FinTech │ │ ├── Account.php │ │ ├── AccountManager.php │ │ └── Action.php │ │ ├── autoload.php │ │ └── index.php ├── nhantd │ └── python │ │ └── week003.py ├── pertsodian │ └── java │ │ ├── pom.xml │ │ ├── src │ │ ├── fintech │ │ │ ├── domain │ │ │ │ ├── Account.java │ │ │ │ ├── Action.java │ │ │ │ ├── Instruction.java │ │ │ │ └── Response.java │ │ │ ├── exceptions │ │ │ │ └── InsufficientBalanceException.java │ │ │ └── processors │ │ │ │ ├── AccountManager.java │ │ │ │ └── BankAccountApp.java │ │ └── week0003.java │ │ └── test │ │ └── fintech │ │ ├── domain │ │ ├── AccountTest.java │ │ ├── ActionTest.java │ │ └── InstructionTest.java │ │ └── processors │ │ ├── AccountManagerTest.java │ │ └── BankAccountAppTest.java ├── test_case_01.input ├── test_case_01.output ├── thainguyentran │ └── CSharp │ │ └── week0003.cs └── truongngodang │ └── java │ └── Week0003.java ├── week0004 ├── README.md ├── event1.input ├── event2.input ├── guests.output ├── hoangdangduy │ └── java │ │ ├── Client.java │ │ ├── ProcessData.java │ │ ├── SortUtil.java │ │ └── Week0004.java ├── nhantd │ └── python │ │ └── week0004.py ├── pertsodian │ └── java │ │ └── src │ │ ├── event │ │ └── management │ │ │ ├── domain │ │ │ └── Guest.java │ │ │ └── processors │ │ │ └── RegistrationExtractor.java │ │ └── week0004.java ├── thainguyentran │ └── CSharp │ │ └── week0004.cs └── truongngodang │ └── java │ └── Week0004.java └── why-you-should-write-readable-code.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.pyc 3 | *.pyd 4 | *.so 5 | *.a 6 | *.dylib 7 | *.bat 8 | *.exe 9 | *.out 10 | *.class 11 | *.DS_Store 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # weekly - Repo for weekly quizzes 2 | 3 | ## Intro 4 | 5 | Developers love fun and nothing stimulates learning as fun and challenging problems. This repo provides weekly quizzes for developers to practice their coding skills. The problems will be bite-sized and challenging enough to cause people to make mistakes and learn from them. The results will be provided so developers can learn and improve. 6 | 7 | ## Submission 8 | 9 | Submit your code in any of the following languages: 10 | 11 | * C 12 | * C# 13 | * C++ 14 | * Go 15 | * Java 16 | * Javascript (browser/Node.JS) 17 | * Objective-C 18 | * OCaml 19 | * Perl 20 | * PHP 21 | * Python 22 | * Ruby 23 | * Swift 24 | * Unix shells & tools: sh/ksh/bash/zsh, awk, sed, uniq, ... 25 | 26 | You can submit by creating a pull request. 27 | 28 | Please direct your ideas, suggestions, collaboration requests to: viet@code2.pro 29 | -------------------------------------------------------------------------------- /week0001/Code2ProStudent/week0001.py: -------------------------------------------------------------------------------- 1 | for i in range(1, 101): 2 | if i % 3 == 0: 3 | print "Fizz" 4 | if i % 5 == 0: 5 | print "Buzz" 6 | -------------------------------------------------------------------------------- /week0001/DangKhoa/DangKhoa.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() { 4 | for (int i = 1; i <= 100; ++i) { 5 | if (i % 3 == 0) 6 | std::cout << "Fizz" << std::endl; 7 | if(i % 5 == 0) 8 | std::cout << "Buzz" << std::endl; 9 | } 10 | return 0; 11 | } -------------------------------------------------------------------------------- /week0001/FizzBuzzMichal.php: -------------------------------------------------------------------------------- 1 | '; 7 | if (0 == $counter % 5) 8 | echo 'Buzz
'; 9 | } 10 | -------------------------------------------------------------------------------- /week0001/FizzBuzzMichalGo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | for i := 1; i <= 100; i++ { 9 | if 0 == i % 3 { 10 | fmt.Println("Fizz") 11 | } 12 | if 0 == i % 5 { 13 | fmt.Println("Buzz") 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /week0001/FizzBuzzThao.java: -------------------------------------------------------------------------------- 1 | public class Week1 { 2 | public static void main (String[] args) { 3 | for(int i = 1; i < 101; i++) { 4 | if (i % 3 == 0 ) { 5 | System.out.println("Fizz"); 6 | } 7 | if (i % 5 == 0 ) { 8 | System.out.println("Buzz"); 9 | } 10 | } 11 | } 12 | } 13 | 14 | -------------------------------------------------------------------------------- /week0001/FizzBuzzThao.js: -------------------------------------------------------------------------------- 1 | for (i = 1; i < 101; i++) { 2 | if (i % 3 == 0 ) { 3 | console.log("Fizz"); 4 | } 5 | if (i % 5 == 0 ){ 6 | console.log("Buzz"); 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /week0001/FizzBuzzThao.py: -------------------------------------------------------------------------------- 1 | for x in range (1, 101): 2 | if x % 3 == 0: 3 | print "Fizz" 4 | if x % 5 == 0: 5 | print "Buzz" 6 | 7 | -------------------------------------------------------------------------------- /week0001/README.md: -------------------------------------------------------------------------------- 1 | # Week 0001 2 | 3 | This week we will start with a very simple quiz and this one still managed to fail many candidates during interviews. 4 | 5 | ## Fizz-Buzz 6 | 7 | Write a piece of code that does the following: 8 | 9 | 1. Runs a counter from 1 to 100 10 | 2. When the counter is a multiple of 3, prints the string "Fizz" followed by new line 11 | 3. When the counter is a multiple of 5, prints the string "Buzz" followed by new line 12 | 13 | ## Submission 14 | 15 | Submit your code in any of the following languages: 16 | 17 | * C 18 | * C# 19 | * C++ 20 | * Go 21 | * Java 22 | * Javascript (browser/Node.JS) 23 | * Objective-C 24 | * OCaml 25 | * Perl 26 | * PHP 27 | * Python 28 | * Ruby 29 | * Swift 30 | * Unix shells & tools: sh/ksh/bash/zsh, awk, sed, uniq, ... 31 | 32 | You can submit by creating a pull request. 33 | 34 | Please direct your ideas, suggestions, collaboration requests to: viet@code2.pro 35 | -------------------------------------------------------------------------------- /week0001/correct_output.dat: -------------------------------------------------------------------------------- 1 | Fizz 2 | Buzz 3 | Fizz 4 | Fizz 5 | Buzz 6 | Fizz 7 | Fizz 8 | Buzz 9 | Fizz 10 | Buzz 11 | Fizz 12 | Fizz 13 | Buzz 14 | Fizz 15 | Fizz 16 | Buzz 17 | Fizz 18 | Buzz 19 | Fizz 20 | Fizz 21 | Buzz 22 | Fizz 23 | Fizz 24 | Buzz 25 | Fizz 26 | Buzz 27 | Fizz 28 | Fizz 29 | Buzz 30 | Fizz 31 | Fizz 32 | Buzz 33 | Fizz 34 | Buzz 35 | Fizz 36 | Fizz 37 | Buzz 38 | Fizz 39 | Fizz 40 | Buzz 41 | Fizz 42 | Buzz 43 | Fizz 44 | Fizz 45 | Buzz 46 | Fizz 47 | Fizz 48 | Buzz 49 | Fizz 50 | Buzz 51 | Fizz 52 | Fizz 53 | Buzz 54 | -------------------------------------------------------------------------------- /week0001/dbugxpert/week0001.py: -------------------------------------------------------------------------------- 1 | for x in range(1, 101): 2 | if not (x % 3): 3 | print('Fizz') 4 | if not (x % 5): 5 | print('Buzz') 6 | -------------------------------------------------------------------------------- /week0001/fizz-buzz-saidadaki.py: -------------------------------------------------------------------------------- 1 | for i in range(1, 101): 2 | if i % 3 == 0: 3 | print ("Fizz") 4 | if i % 5 == 0: 5 | print ("Buzz") 6 | -------------------------------------------------------------------------------- /week0001/fizz_buzz_congpine.rb: -------------------------------------------------------------------------------- 1 | for counter in 1..100 2 | 3 | if counter % 3 == 0 4 | puts "Fizz" 5 | end 6 | 7 | if counter % 5 == 0 8 | puts "Buzz" 9 | end 10 | 11 | end 12 | -------------------------------------------------------------------------------- /week0001/fizz_buzz_haond.rb: -------------------------------------------------------------------------------- 1 | def fizz_buzz(n) 2 | x = 0 3 | y = 0 4 | while(x + 3 <= n || y + 5 <= n) 5 | if(x + 3 <= y + 5) 6 | x += 3 7 | puts "Fizz" 8 | else 9 | y += 5 10 | puts "Buzz" 11 | end 12 | end 13 | end 14 | fizz_buzz(100) 15 | 16 | -------------------------------------------------------------------------------- /week0001/fizz_buzz_haond1.rb: -------------------------------------------------------------------------------- 1 | FIZZ = ["Fizz","Fizz\nFizz","Fizz\nFizz"] 2 | 3 | def fizz_buzz(n) 4 | t = n/5 5 | t.times{|i| 6 | puts FIZZ[i%3] 7 | puts "Buzz" 8 | } 9 | end 10 | 11 | fizz_buzz(100) 12 | -------------------------------------------------------------------------------- /week0001/fizz_buzz_matt.php: -------------------------------------------------------------------------------- 1 | "; 5 | } 6 | if ($i % 5 == 0) { 7 | echo "Buzz
"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /week0001/fizz_buzz_phuocnt.php: -------------------------------------------------------------------------------- 1 | $end) { 6 | throw new Exception('Begin number cannot be greater than end number'); 7 | } 8 | for ($i = $begin; $i <= $end; $i++) { 9 | foreach ($requirementData as $numberDivided => $stringEcho) { 10 | if ($i % $numberDivided == 0) { 11 | echo $stringEcho . '
'; 12 | } 13 | } 14 | } 15 | } 16 | } 17 | 18 | $requirementData = [ 19 | '3' => 'Fizz', 20 | '5' => 'Buzz' 21 | ]; 22 | printFizzBuzz(1, 100, $requirementData); 23 | -------------------------------------------------------------------------------- /week0001/fizzbuzz_daudau.php: -------------------------------------------------------------------------------- 1 | = 1) 19 | 3. Extra: Provide integer parameters M (number of rows) & N (number of columns) to create a spiral from numbers 1 to M*N (M >= 1 and N >= 1) 20 | 21 | ## Submission 22 | 23 | ### Acceptance condition 24 | 25 | * You must solve at least requirement `1.` 26 | * Feel free to solve `2.` and `3.` if you fancy 27 | * Make sure to test against the provided test case `test_case_01.dat` before submitting 28 | 29 | Sample command to test: 30 | 31 | ``` 32 | diff <(python week0002.py) test_case_01.dat 33 | ``` 34 | 35 | ### Folder structure 36 | 37 | Please structure your code like this: 38 | 39 | * Have your own folder named after your GitHub ID 40 | * Each language has own folder 41 | * Keep the files named week0002/Week0002. 42 | 43 | ``` 44 | week0002/ 45 | |--YourGitHubID/ 46 | |--php/ 47 | |--week0002.php 48 | |--cpp/ 49 | |--week0002.cpp 50 | |--python/ 51 | |--week0002.py 52 | |--ruby/ 53 | |--week0002.rb 54 | ``` 55 | 56 | ### To PHP fans 57 | 58 | * If you want your submission accepted, please do not use `
` and `echo` 59 | * You must use `php://stdin` & `php://stdout`! 60 | * For your reading pleasure: http://php.net/manual/en/features.commandline.io-streams.php 61 | 62 | ### Languages 63 | 64 | Submit your code in any of the following languages: 65 | 66 | * C 67 | * C# 68 | * C++ 69 | * Go 70 | * Java 71 | * Javascript (browser/Node.JS) 72 | * Objective-C 73 | * OCaml 74 | * Perl 75 | * PHP 76 | * Python 77 | * Ruby 78 | * Swift 79 | * Unix shells & tools: sh/ksh/bash/zsh, awk, sed, uniq, ... 80 | 81 | You can submit by creating a pull request. 82 | 83 | Please direct your ideas, suggestions, collaboration requests to: viet@code2.pro 84 | -------------------------------------------------------------------------------- /week0002/atapie/java/week0002.java: -------------------------------------------------------------------------------- 1 | import java.lang.*; 2 | import java.io.*; 3 | import java.util.*; 4 | 5 | public class week0002 { 6 | public static void main(String[] args) { 7 | int M = Integer.parseInt(args[0]); 8 | int N = Integer.parseInt(args[1]); 9 | // DIRECTIONS: RIGHT DOWN LEFT UP 10 | int[][] DIR = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} }; 11 | 12 | // r: current row; c: current col; d: current direction 13 | int r = 0, c = 0, d = 0; 14 | // output matrix 15 | int[][] res = new int[M][N]; 16 | // last number filled in 17 | int curr = 0; 18 | while(curr < M*N) { 19 | ++curr; 20 | res[r][c] = curr; 21 | int newR = r + DIR[d][0]; 22 | int newC = c + DIR[d][1]; 23 | if(newR < 0 || newC < 0 || newR >= M || newC >= N || res[newR][newC] > 0) 24 | { 25 | // change direction: out of bounds or hit outer "layer" 26 | d = (d+1) % DIR.length; 27 | } 28 | r = r + DIR[d][0]; 29 | c = c + DIR[d][1]; 30 | } 31 | 32 | // pretty print 33 | int numLen = String.valueOf(M*N).length(); 34 | for(int[] row : res) { 35 | for(int i = 0; i < row.length; i++) { 36 | if(i > 0) System.out.print(" "); 37 | String s = String.valueOf(row[i]); 38 | for(int j = 0; j < numLen - s.length(); j++) { 39 | System.out.print(" "); 40 | } 41 | System.out.print(row[i]); 42 | } 43 | System.out.println(); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /week0002/daudau/php/daudau.php: -------------------------------------------------------------------------------- 1 | ý tưởng là dựa vào tọa độ của điểm trong array, ta cần xác định nó thuộc lớp thứ mấy của hình xoắn ốc và xác định giá trị tại điểm đó. 6 | Example data: 7 | N = 3; M = 4; 8 | ------------- 9 | 1 2 3 4 10 | 11 | 10 11 12 5 12 | 13 | 9 8 7 6 14 | ------------- 15 | */ 16 | 17 | //nhập giá trị từ user. 18 | fwrite(STDOUT, 'Input the number of rows N: '); 19 | fscanf(STDIN, "%d", $n); 20 | 21 | fwrite(STDOUT, 'Input the number of columns M: '); 22 | fscanf(STDIN, "%d", $m); 23 | 24 | $min = min($m, $n); //tìm min của hàng và cột 25 | $circle = ceil($min / 2.0); //xác định số vòng mà xoắn ốc sẽ có, dựa vào giá trị min. 26 | $length = strlen($n*$m); //sử dụng để in giá trị 27 | $roundFirstValue = array(); //mảng này để lưu giá trị bắt đầu của mỗi vòng. VD vòng thứ 0 là 1, vòng thứ 1 là 11. 28 | 29 | $roundFirstValue[0] = 1; //giá trị vòng đầu tiên luôn là 1. 30 | for ($i = 1; $i < $circle; $i++) { 31 | /** 32 | * giá trị bắt đầu mỗi vòng = giá trị bắt đầu của vòng trước đó + số số của vòng đó. 33 | * vd Vòng 1 là 1, và có số trong vòng đó => giá trị bắt đầu của vòng 2 là 1 + 10. 34 | * số lưọng phần tử trong 1 vòng bằng : ($n-($i-1)*2 + $m-($i-1)*2)*2 - 4 35 | */ 36 | $roundFirstValue[$i] = $roundFirstValue[$i - 1] + ($n - ($i - 1) * 2 + $m - ($i - 1) * 2) * 2 - 4; 37 | } 38 | 39 | $spiralArray = array(); 40 | 41 | for ($y = 0; $y < $n; $y++) 42 | for ($x = 0; $x < $m; $x++) { 43 | // $tmpi = $i > ($n - 1) / 2 ? $n - 1 - $i : $i; 44 | // $tmpj = $j > ($m - 1) / 2 ? $m - 1 - $j : $j; 45 | // $round = $tmpi > $tmpj ? $tmpj : $tmpi; //xác định 1 điểm thuộc vòng thứ mấy 46 | $round = min( min($n - $y - 1, $y), min($m - $x - 1, $x) ); 47 | //ta "đâm" vào vòng của nó 48 | //they đổi tọa độ thành $ix, $jx, $nx, $mx. 49 | $dy = $y - $round; 50 | $dx = $x - $round; 51 | $dn = $n - $round * 2; 52 | $dm = $m - $round * 2; 53 | /** 54 | * Ta tính giá trị 1 điểm thuộc 1 vòng bằng cách xác định xem nó nằm trên hay nằm dưói đưòng chéo của nó. 55 | * Nếu nằm "trên" (nghĩa là cả 2 điểm chéo) thỉ giá trị của nó bằng giá trị start của vòng + tọa độ cuản ó 56 | * Nếu nằm dưới thì sẽ bằng giá trị bắt đầu + số phần tử của vòng trừ đi tọa độ của nó. 57 | */ 58 | if ( ($dy + 1) * $dm < ($dx + 1) * $dn || $dy == 0 ) // nằm trên 59 | $spiralArray[$y][$x] = $roundFirstValue[$round] + $dy + $dx; // forget refactor this :D 60 | else // nằm dưới 61 | $spiralArray[$y][$x] = $roundFirstValue[$round] + ($dn + $dm) * 2 - 4 - $dy - $dx; // 62 | } 63 | 64 | //finally print it to terminal. 65 | for ($y = 0; $y < $n; $y++) { 66 | for ($x = 0; $x < $m; $x++) { 67 | if ($x == 0) $pad = 0; 68 | else $pad = 1; 69 | fwrite(STDOUT, str_pad($spiralArray[$y][$x], $length + $pad, ' ', STR_PAD_LEFT)); 70 | } 71 | 72 | fwrite(STDOUT, PHP_EOL); 73 | } 74 | -------------------------------------------------------------------------------- /week0002/dbugxpert/python/week0002.py: -------------------------------------------------------------------------------- 1 | n, m = 4, 4 2 | # n, m = map(int, input().strip().split()) 3 | grid = [[0 for cell in range(n)] for row in range(m)] 4 | top_row, bottom_row, left_column, right_column, counter = 0, m - 1, 0, n - 1, 1 5 | PADDING_SIZE = len(str(n*m)) 6 | 7 | # loop around the grid 8 | for _ in range(m // 2): 9 | for t in range(left_column, right_column + 1): 10 | grid[top_row][t] = counter 11 | counter += 1 12 | 13 | top_row += 1 14 | 15 | for t in range(top_row, bottom_row + 1): 16 | grid[t][right_column] = counter 17 | counter += 1 18 | 19 | right_column -= 1 20 | 21 | for t in range(right_column, left_column - 1, -1): 22 | grid[bottom_row][t] = counter 23 | counter += 1 24 | 25 | bottom_row -= 1 26 | 27 | for t in range(bottom_row, top_row - 1, -1): 28 | grid[t][left_column] = counter 29 | counter += 1 30 | 31 | left_column += 1 32 | 33 | for row in grid: 34 | print(" ".join(str(cell).rjust(PADDING_SIZE) for cell in row)) 35 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/README.md: -------------------------------------------------------------------------------- 1 | ## RUN 2 | ``` 3 | python week0002.py m n 4 | ``` 5 | ## TEST CASE 6 | ```bash 7 | diff <(python week0002.py 4 4) test_case_01.dat 8 | diff <(python week0002.py 1 1) test_case_03.dat 9 | diff <(python week0002.py 1 2) test_case_03.dat 10 | diff <(python week0002.py 1 3) test_case_04.dat 11 | diff <(python week0002.py 3 5) test_case_05.dat 12 | diff <(python week0002.py 5 5) test_case_06.dat 13 | diff <(python week0002.py 5 10) test_case_07.dat 14 | ``` 15 | 16 | ## THANKS FOR REVIEWING MY CODE -------------------------------------------------------------------------------- /week0002/giaosudau/python/test_case_01.dat: -------------------------------------------------------------------------------- 1 | 1 2 3 4 2 | 12 13 14 5 3 | 11 16 15 6 4 | 10 9 8 7 5 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/test_case_02.dat: -------------------------------------------------------------------------------- 1 | 1 2 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/test_case_03.dat: -------------------------------------------------------------------------------- 1 | 1 2 2 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/test_case_04.dat: -------------------------------------------------------------------------------- 1 | 1 2 3 2 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/test_case_05.dat: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 2 | 12 13 14 15 6 3 | 11 10 9 8 7 4 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/test_case_06.dat: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 2 | 16 17 18 19 6 3 | 15 24 25 20 7 4 | 14 23 22 21 8 5 | 13 12 11 10 9 6 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/test_case_07.dat: -------------------------------------------------------------------------------- 1 | 1 2 3 4 5 6 7 8 9 10 2 | 26 27 28 29 30 31 32 33 34 11 3 | 25 44 45 46 47 48 49 50 35 12 4 | 24 43 42 41 40 39 38 37 36 13 5 | 23 22 21 20 19 18 17 16 15 14 6 | -------------------------------------------------------------------------------- /week0002/giaosudau/python/week0002.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def generate(m, n): 5 | row = 0 6 | # init array with m rows and n columns assign -1 for every position 7 | a = [[-1 for o in range(n)] for o in range(m)] 8 | val = 1 9 | flag = 0 10 | while flag < m / 2 + (m <= n and m % 2 or 0): 11 | for col in range(flag, n - flag): 12 | a[row][col] = val 13 | val += 1 14 | for row in range(flag + 1, m - flag): 15 | a[row][col] = val 16 | val += 1 17 | if val > n * m: # stuck and could't get anyway better 18 | break 19 | for col in range(n - 1 - flag - 1, flag - 1, -1): 20 | a[row][col] = val 21 | val += 1 22 | if val > n * m: # stuck and could't get anyway better 23 | break 24 | for row in range(m - 2 - flag, flag, -1): 25 | a[row][col] = val 26 | val += 1 27 | flag += 1 28 | 29 | return a 30 | 31 | 32 | def print_array(a): 33 | print('\n'.join([' '.join(['{:2}'.format(item) for item in row]) 34 | for row in a])) 35 | 36 | 37 | if __name__ == '__main__': 38 | args = sys.argv[1:] 39 | m = int(args[0]) 40 | n = int(args[1]) 41 | b = generate(m, n) 42 | print_array(b) 43 | -------------------------------------------------------------------------------- /week0002/hienhpss/python/week0002.py: -------------------------------------------------------------------------------- 1 | def spi_round(n=4, m=4, x=0): 2 | '''Looping through the spiral path to return the next 3 | cell''' 4 | if (x >= (n+1) / 2) or (x >= (m+1) / 2): 5 | return 6 | for i in range(x, m - x -1): 7 | yield (x, i) 8 | for i in range(x, n - x - 1): 9 | yield(i, m - x - 1) 10 | for i in range(m - x - 1, x, -1): 11 | yield(n - x - 1, i) 12 | for i in range(n - x - 1, x, -1): 13 | yield(i, x) 14 | 15 | def spiral(n=4, m=4): 16 | '''Return the n*m board with numbers 17 | arrange in spiral format''' 18 | board = [[False for x in range(m)] for y in range(n)] 19 | limit = int((n+1) / 2) 20 | count = 1 21 | for i in range(limit): 22 | for next_row, next_col in spi_round(n, m, i): 23 | if not board[next_row][next_col]: 24 | board[next_row][next_col] = count 25 | count += 1 26 | else: 27 | return board 28 | return board 29 | 30 | def test_spiral(n, m): 31 | result = spiral(n, m) 32 | print('\n'.join([' '.join(['{:2}'.format(item) for item in row]) 33 | for row in result])) 34 | 35 | if __name__=="__main__": 36 | test_spiral(4, 4) 37 | 38 | -------------------------------------------------------------------------------- /week0002/hieuvo/php/week0002.php: -------------------------------------------------------------------------------- 1 | [0, 1], 16 | 'down' => [1, 0], 17 | 'left' => [0, -1], 18 | 'up' => [-1, 0] 19 | ]; 20 | 21 | return [ 22 | $x+$moves[$direction][0], 23 | $y+$moves[$direction][1], 24 | ]; 25 | } 26 | 27 | while ($n >= 1 && $m >= 1) { 28 | $path[] = 'right'; 29 | 30 | for ($i=1; $i<=$n-1; $i++) $path[] = 'right'; 31 | 32 | if ($m > 1) { 33 | for ($i=1; $i<=$m-1; $i++) $path[] = 'down'; 34 | for ($i=1; $i<=$n-1; $i++) $path[] = 'left'; 35 | for ($i=1; $i<=$m-2; $i++) $path[] = 'up'; 36 | } 37 | 38 | $n -= 2; 39 | $m -= 2; 40 | } 41 | 42 | 43 | foreach ($path as $direction) { 44 | list($x, $y) = move($x, $y, $direction); 45 | $spiral[$x][$y] = str_pad($v++, $length, " ", STR_PAD_LEFT); 46 | } 47 | 48 | $stdout = fopen('php://stdout', 'w'); 49 | 50 | foreach ($spiral as $row) { 51 | fwrite($stdout, implode(' ', $row)); 52 | fwrite($stdout, "\n"); 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /week0002/hoangdangduy/java/Week0002.java: -------------------------------------------------------------------------------- 1 | public class Week0002 { 2 | public void Spiral(int M, int N){ 3 | 4 | int[][] arr = new int[M][N]; 5 | 6 | int upperLeftCorner = 0; 7 | int bottomLeftCorner = 0; 8 | int upperRightCorner = N - 1; 9 | int bottomRightCorner = M - 1; 10 | 11 | int numRun = 1; 12 | int i = 0, j = 0; 13 | 14 | if (M == 1) { 15 | for (int k = 1; k <= N; k++) { 16 | System.out.print(k + " "); 17 | } 18 | return; 19 | } 20 | 21 | if (N == 1) { 22 | for (int k = 1; k <= M; k++) { 23 | System.out.println(k); 24 | } 25 | return; 26 | } 27 | 28 | while (numRun <= (M * N)) { 29 | /* 30 | * run from left to right 31 | */ 32 | while (j <= upperRightCorner && numRun <= (M * N)) { 33 | arr[i][j] = numRun++; 34 | j++; 35 | } 36 | upperRightCorner--; 37 | j--; 38 | i++; 39 | 40 | /* 41 | * run from above to below 42 | */ 43 | while (i <= bottomRightCorner && numRun <= (M * N)) { 44 | arr[i][j] = numRun++; 45 | i++; 46 | } 47 | bottomRightCorner--; 48 | i--; 49 | j--; 50 | 51 | /* 52 | * run from right to left 53 | */ 54 | while (j >= bottomLeftCorner && numRun <= (M * N)) { 55 | arr[i][j] = numRun++; 56 | j--; 57 | } 58 | bottomLeftCorner++; 59 | i--; 60 | j++; 61 | 62 | /* 63 | * run from below to above 64 | */ 65 | while (i > upperLeftCorner && numRun <= (M * N)) { 66 | arr[i][j] = numRun++; 67 | i--; 68 | } 69 | i++; 70 | upperLeftCorner++; 71 | j++; 72 | } 73 | 74 | int widthNumber = 0; 75 | int temp = M * N; 76 | while ( temp > 0 ){ 77 | widthNumber++; 78 | temp /= 10; 79 | } 80 | 81 | for (int temp1 = 0; temp1 < M; temp1++) { 82 | for (int temp2 = 0; temp2 < N; temp2++) { 83 | System.out.format("%"+widthNumber+"d ", arr[temp1][temp2]); 84 | } 85 | System.out.println(); 86 | } 87 | } 88 | 89 | public static void main(String[] args) { 90 | Week0002 week0002 = new Week0002(); 91 | week0002.Spiral(100, 10); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /week0002/mattfanz/php/week0002.php: -------------------------------------------------------------------------------- 1 | 0".PHP_EOL); 7 | exit(1); 8 | } 9 | } 10 | 11 | // MAIN 12 | $handleIn = fopen("php://stdin", "r"); 13 | $handleOut = fopen('php://stdout', 'w'); 14 | 15 | fwrite($handleOut, "Input the number of rows N:"); 16 | fscanf($handleIn, "%d", $n); 17 | checkValidInput($n); 18 | 19 | fwrite($handleOut, "Input the number of columns M:"); 20 | fscanf($handleIn, "%d", $m); 21 | checkValidInput($m); 22 | 23 | $length = $n * $m; 24 | $left = 0; 25 | $right = $m-1; 26 | $up = 0; 27 | $down = $n-1; 28 | $i = 0; 29 | $j = 0; 30 | $direction = 'right'; 31 | $result = []; 32 | 33 | for ($l = 1; $l <= $length; $l++) { 34 | $result[$i][$j] = $l; 35 | switch ($direction) { 36 | case 'right': 37 | $j++; 38 | if ($j == $right) { 39 | $direction = 'down'; 40 | $up++; 41 | } 42 | break; 43 | case 'down': 44 | $i++; 45 | if ($i == $down) { 46 | $direction = 'left'; 47 | $right--; 48 | } 49 | break; 50 | case 'left': 51 | $j--; 52 | if ($j == $left) { 53 | $direction = 'up'; 54 | $down--; 55 | } 56 | break; 57 | case 'up': 58 | $i--; 59 | if ($i == $up) { 60 | $direction = 'right'; 61 | $left++; 62 | } 63 | break; 64 | } 65 | } 66 | 67 | foreach ($result as &$row) { 68 | ksort($row); 69 | $rs = implode(' ', $row); 70 | fwrite($handleOut, $rs); 71 | fwrite($handleOut, PHP_EOL); 72 | } 73 | -------------------------------------------------------------------------------- /week0002/pertsodian/java/src/BaseMatrixPrinter.java: -------------------------------------------------------------------------------- 1 | import java.util.Arrays; 2 | import java.util.StringJoiner; 3 | 4 | public abstract class BaseMatrixPrinter { 5 | 6 | private String delimiter = " "; 7 | private String lineSeparator = "\n"; 8 | 9 | public abstract void printMatrix(int[][] matrix); 10 | 11 | protected final void setDelimiter(String delimiter) { 12 | this.delimiter = delimiter; 13 | } 14 | 15 | protected final void setLineSeparator(String lineSeparator) { 16 | this.lineSeparator = lineSeparator; 17 | } 18 | 19 | /** 20 | * 21 | * @param non-empty matrix of non-negative numbers 22 | * @return formatted String representation of input matrix 23 | */ 24 | protected final String print(int[][] matrix) { 25 | if (matrix.length == 0 || matrix[0].length == 0) 26 | throw new IllegalArgumentException("Input matrix must be non-empty"); 27 | 28 | if (Arrays.stream(matrix).mapToInt(row -> Arrays.stream(row).min().getAsInt()).min().getAsInt() < 0) 29 | throw new IllegalArgumentException("Input matrix must be non-negative"); 30 | 31 | int spacePerElement = (int) Math.log10(Arrays.stream(matrix).mapToInt(row -> Arrays.stream(row).max().getAsInt()).max().getAsInt()) + 1; 32 | String format = "%" + spacePerElement + "d"; 33 | StringJoiner lineJoiner = new StringJoiner(lineSeparator); 34 | Arrays.stream(matrix).forEach(row -> lineJoiner.add(printRow(row, format))); 35 | return lineJoiner.toString(); 36 | } 37 | 38 | private String printRow(int[] row, String format) { 39 | StringJoiner elementJoiner = new StringJoiner(delimiter); 40 | Arrays.stream(row).forEach(element -> elementJoiner.add(String.format(format, element))); 41 | return elementJoiner.toString(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /week0002/pertsodian/java/src/BaseMatrixPrinterTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.assertEquals; 2 | 3 | import org.junit.Rule; 4 | import org.junit.Test; 5 | import org.junit.rules.ExpectedException; 6 | 7 | public class BaseMatrixPrinterTest { 8 | 9 | private final BaseMatrixPrinter matrixPrinter = new ConsoleMatrixPrinter(); 10 | 11 | @Rule 12 | public final ExpectedException expectedException = ExpectedException.none(); 13 | 14 | @Test 15 | public void testInvalidMatrix_ZeroRows() { 16 | expectedException.expect(IllegalArgumentException.class); 17 | expectedException.expectMessage("Input matrix must be non-empty"); 18 | matrixPrinter.print(new int[0][5]); 19 | } 20 | 21 | @Test 22 | public void testInvalidMatrix_ZeroCols() { 23 | expectedException.expect(IllegalArgumentException.class); 24 | expectedException.expectMessage("Input matrix must be non-empty"); 25 | matrixPrinter.print(new int[5][0]); 26 | } 27 | 28 | @Test 29 | public void testInvalidMatrix_Negative() { 30 | expectedException.expect(IllegalArgumentException.class); 31 | expectedException.expectMessage("Input matrix must be non-negative"); 32 | 33 | int[][] matrix = new int[2][]; 34 | matrix[0] = new int[] {1}; 35 | matrix[1] = new int[] {-1}; 36 | matrixPrinter.print(matrix); 37 | } 38 | 39 | @Test 40 | public void testSingleDigit() { 41 | String expected = "1 2 3\n8 9 4\n7 6 5"; 42 | int[][] matrix = new int[3][]; 43 | matrix[0] = new int[] {1,2,3}; 44 | matrix[1] = new int[] {8,9,4}; 45 | matrix[2] = new int[] {7,6,5}; 46 | assertEquals(expected, matrixPrinter.print(matrix)); 47 | } 48 | 49 | @Test 50 | public void testDoubleDigit() { 51 | String expected = " 1 2 3 4\n12 13 14 5\n11 16 15 6\n10 9 8 7"; 52 | int[][] matrix = new int[4][]; 53 | matrix[0] = new int[] {1,2,3,4}; 54 | matrix[1] = new int[] {12,13,14,5}; 55 | matrix[2] = new int[] {11,16,15,6}; 56 | matrix[3] = new int[] {10,9,8,7}; 57 | assertEquals(expected, matrixPrinter.print(matrix)); 58 | } 59 | 60 | @Test 61 | public void testMixDigit() { 62 | String expected = " 11 2 333 0\n1234 13 145 5"; 63 | int[][] matrix = new int[2][]; 64 | matrix[0] = new int[] {11,2,333,0}; 65 | matrix[1] = new int[] {1234,13,145,5}; 66 | assertEquals(expected, matrixPrinter.print(matrix)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /week0002/pertsodian/java/src/ConsoleMatrixPrinter.java: -------------------------------------------------------------------------------- 1 | public class ConsoleMatrixPrinter extends BaseMatrixPrinter { 2 | @Override 3 | public void printMatrix(int[][] matrix) { 4 | System.out.print(print(matrix)); 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /week0002/pertsodian/java/src/SpiralMatrixApp.java: -------------------------------------------------------------------------------- 1 | public class SpiralMatrixApp { 2 | 3 | private final SpiralMatrixGenerator matrixGenerator; 4 | private final BaseMatrixPrinter matrixPrinter; 5 | 6 | public SpiralMatrixApp(SpiralMatrixGenerator matrixGenerator, BaseMatrixPrinter matrixPrinter) { 7 | this.matrixGenerator = matrixGenerator; 8 | this.matrixPrinter = matrixPrinter; 9 | } 10 | 11 | public void printSquareSpiralMatrixOfSize(int size) { 12 | matrixPrinter.printMatrix(matrixGenerator.generate(size, size)); 13 | } 14 | 15 | public void printSpiralMatrixOfSize(int rows, int cols) { 16 | matrixPrinter.printMatrix(matrixGenerator.generate(rows, cols)); 17 | } 18 | 19 | public void printUsage() { 20 | System.out.println("****************************"); 21 | System.out.println("Usage: size/rows/cols >= 1"); 22 | System.out.println("SpiralMatrixApp size"); 23 | System.out.println("or"); 24 | System.out.println("SpiralMatrixApp rows cols"); 25 | System.out.println("****************************"); 26 | } 27 | 28 | public static void main(String arg[]) { 29 | // TODO: add Options to configure element/line separator and OutPrinter 30 | 31 | SpiralMatrixGenerator matrixGenerator = new SpiralMatrixGenerator(); 32 | BaseMatrixPrinter matrixPrinter = new ConsoleMatrixPrinter(); 33 | SpiralMatrixApp spiralMatrixApp = new SpiralMatrixApp(matrixGenerator, matrixPrinter); 34 | 35 | if (arg.length == 1) { 36 | try { 37 | int size = Integer.parseInt(arg[0]); 38 | if (size < 1) 39 | spiralMatrixApp.printUsage(); 40 | else 41 | spiralMatrixApp.printSquareSpiralMatrixOfSize(size); 42 | } 43 | catch (NumberFormatException e) { 44 | spiralMatrixApp.printUsage(); 45 | } 46 | } 47 | else if (arg.length == 2) { 48 | try { 49 | int rows = Integer.parseInt(arg[0]); 50 | int cols = Integer.parseInt(arg[1]); 51 | if (rows < 1 || cols < 1) 52 | spiralMatrixApp.printUsage(); 53 | else 54 | spiralMatrixApp.printSpiralMatrixOfSize(rows, cols); 55 | } 56 | catch (NumberFormatException e) { 57 | spiralMatrixApp.printUsage(); 58 | } 59 | } 60 | else 61 | spiralMatrixApp.printUsage(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /week0002/pertsodian/java/src/SpiralMatrixGenerator.java: -------------------------------------------------------------------------------- 1 | public class SpiralMatrixGenerator { 2 | public int[][] generate(int rows, int cols) { 3 | if (rows <= 0 || cols <= 0) 4 | throw new IllegalArgumentException("Matrix rols/cols must be positive"); 5 | 6 | int[][] matrix = new int[rows][cols]; 7 | 8 | int layer = 0; 9 | int startElement = 1; 10 | while (layer <= rows/2 && layer <= cols/2) 11 | startElement = fillLayer(matrix, layer++, startElement); 12 | 13 | return matrix; 14 | } 15 | 16 | private int fillLayer(int[][] matrix, int layer, int startElement) { 17 | assert matrix.length > 0; 18 | assert matrix[0].length > 0; 19 | 20 | int rows = matrix.length; 21 | int cols = matrix[0].length; 22 | 23 | for (int i = layer; i <= cols-1-layer; i++) 24 | matrix[layer][i] = startElement++; 25 | 26 | for (int i = layer+1; i <= rows-1-layer; i++) 27 | matrix[i][cols-1-layer] = startElement++; 28 | 29 | if (layer < rows/2) 30 | for (int i = cols-layer-2; i >= layer; i--) 31 | matrix[rows-layer-1][i] = startElement++; 32 | 33 | if (layer < cols/2) 34 | for (int i = rows-layer-2; i > layer; i--) 35 | matrix[i][layer] = startElement++; 36 | 37 | return startElement; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /week0002/pertsodian/java/src/SpiralMatrixGeneratorTest.java: -------------------------------------------------------------------------------- 1 | import static org.junit.Assert.assertArrayEquals; 2 | import static org.junit.Assert.assertEquals; 3 | 4 | import org.junit.Test; 5 | 6 | public class SpiralMatrixGeneratorTest { 7 | 8 | private final SpiralMatrixGenerator matrixGenerator = new SpiralMatrixGenerator(); 9 | 10 | @Test(expected=IllegalArgumentException.class) 11 | public void testZeroMatrix_ZeroRows() { 12 | assertEquals(0, matrixGenerator.generate(0, 5).length); 13 | } 14 | 15 | @Test(expected=IllegalArgumentException.class) 16 | public void testZeroMatrix_ZeroCols() { 17 | assertEquals(0, matrixGenerator.generate(5, 0).length); 18 | } 19 | 20 | @Test 21 | public void testSingleSquareMatrix() { 22 | int[][] matrix = matrixGenerator.generate(1, 1); 23 | assertEquals(1, matrix.length); 24 | assertArrayEquals(new int[] {1}, matrix[0]); 25 | } 26 | 27 | @Test 28 | public void testEvenSquareMatrix() { 29 | int[][] matrix = matrixGenerator.generate(4, 4); 30 | assertEquals(4, matrix.length); 31 | assertArrayEquals(new int[] {1,2,3,4}, matrix[0]); 32 | assertArrayEquals(new int[] {12,13,14,5}, matrix[1]); 33 | assertArrayEquals(new int[] {11,16,15,6}, matrix[2]); 34 | assertArrayEquals(new int[] {10,9,8,7}, matrix[3]); 35 | } 36 | 37 | @Test 38 | public void testOddSquareMatrix() { 39 | int[][] matrix = matrixGenerator.generate(5, 5); 40 | assertEquals(5, matrix.length); 41 | assertArrayEquals(new int[] {1,2,3,4,5}, matrix[0]); 42 | assertArrayEquals(new int[] {16,17,18,19,6}, matrix[1]); 43 | assertArrayEquals(new int[] {15,24,25,20,7}, matrix[2]); 44 | assertArrayEquals(new int[] {14,23,22,21,8}, matrix[3]); 45 | assertArrayEquals(new int[] {13,12,11,10,9}, matrix[4]); 46 | } 47 | 48 | @Test 49 | public void testSingleRowMatrix() { 50 | int[][] matrix = matrixGenerator.generate(1, 5); 51 | assertEquals(1, matrix.length); 52 | assertArrayEquals(new int[] {1,2,3,4,5}, matrix[0]); 53 | } 54 | 55 | @Test 56 | public void testHorizontalMatrix() { 57 | int[][] matrix = matrixGenerator.generate(3, 5); 58 | assertEquals(3, matrix.length); 59 | assertArrayEquals(new int[] {1,2,3,4,5}, matrix[0]); 60 | assertArrayEquals(new int[] {12,13,14,15,6}, matrix[1]); 61 | assertArrayEquals(new int[] {11,10,9,8,7}, matrix[2]); 62 | } 63 | 64 | @Test 65 | public void testSingleColMatrix() { 66 | int[][] matrix = matrixGenerator.generate(5, 1); 67 | assertEquals(5, matrix.length); 68 | assertArrayEquals(new int[] {1}, matrix[0]); 69 | assertArrayEquals(new int[] {2}, matrix[1]); 70 | assertArrayEquals(new int[] {3}, matrix[2]); 71 | assertArrayEquals(new int[] {4}, matrix[3]); 72 | assertArrayEquals(new int[] {5}, matrix[4]); 73 | } 74 | 75 | @Test 76 | public void testVerticalMatrix() { 77 | int[][] matrix = matrixGenerator.generate(5, 3); 78 | assertEquals(5, matrix.length); 79 | assertArrayEquals(new int[] {1,2,3}, matrix[0]); 80 | assertArrayEquals(new int[] {12,13,4}, matrix[1]); 81 | assertArrayEquals(new int[] {11,14,5}, matrix[2]); 82 | assertArrayEquals(new int[] {10,15,6}, matrix[3]); 83 | assertArrayEquals(new int[] {9,8,7}, matrix[4]); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /week0002/phucnm/cpp/week002.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void spiralPrinting(size_t nRow, size_t nCol) { 5 | int **spiralArray; 6 | spiralArray = new int *[nRow]; 7 | for (int i = 0; i < nRow; i++) { 8 | spiralArray[i] = new int[nCol]; 9 | } 10 | 11 | //value to print 12 | int value = 1; 13 | int colIdx = 0, rowIdx = 0, lastColIdx = nCol - 1, lastRowIdx = nRow - 1; 14 | int i; 15 | while (value <= nRow * nCol) { 16 | //do the first row 17 | int num = nCol - colIdx; 18 | for (i = colIdx; i < num; i++) { 19 | spiralArray[rowIdx][i] = value++; 20 | } 21 | rowIdx++; 22 | 23 | //do the last column 24 | num = nRow - rowIdx; 25 | int did = 0; 26 | for (i = rowIdx; i <= lastRowIdx && colIdx <= lastColIdx; i++) { 27 | spiralArray[i][lastColIdx] = value++; 28 | did = 1; 29 | } 30 | lastColIdx -= did; 31 | 32 | //do the last row 33 | did = 0; 34 | for (i = lastColIdx; i >= colIdx && rowIdx <= lastRowIdx; i--) { 35 | spiralArray[lastRowIdx][i] = value++; 36 | did =1; 37 | } 38 | lastRowIdx -= did; 39 | 40 | //do the first column 41 | for (i = lastRowIdx; i >= rowIdx && colIdx <= lastColIdx; i--) { 42 | spiralArray[i][colIdx] = value++; 43 | } 44 | colIdx++; 45 | } 46 | 47 | int maxValueDigits = (value - 1) >= 100 ? 3 : 2; 48 | for (i = 0; i < nRow; i++) { 49 | for (int j = 0; j < nCol; j++) { 50 | if (j > 0) 51 | printf(" "); 52 | printf("%*d", maxValueDigits, spiralArray[i][j]); 53 | } 54 | printf("\n"); 55 | } 56 | 57 | for( int i = 0; i < nRow; i++ ) { 58 | delete [] spiralArray[i] ; 59 | } 60 | delete [] spiralArray ; 61 | } 62 | 63 | int main(int argc, const char * argv[]) { 64 | spiralPrinting(4, 4); 65 | return 0; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /week0002/sample.php: -------------------------------------------------------------------------------- 1 | = column; i--) 33 | { 34 | spiral[posX, i] = value++; 35 | } 36 | //going up 37 | for (int j = posX - 1; j >= row + 1; j--) 38 | { 39 | spiral[j, column] = value++; 40 | } 41 | row++; 42 | column++; 43 | posX--; 44 | posY--; 45 | } 46 | int maxLen = (N * M).ToString().Length; 47 | for (int i = 0; i < N; i++) 48 | { 49 | for (int j = 0; j < M; j++) 50 | { 51 | Console.Write("{0}", spiral[i, j].ToString().PadLeft(maxLen + 1,' ')); 52 | } 53 | Console.Write("\n"); 54 | } 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /week0002/thaotran/java/week0002.java: -------------------------------------------------------------------------------- 1 | public class week0002 { 2 | public static void main(String[] args) { 3 | printSpiralRectangle(7, 8); 4 | } 5 | 6 | public static void printSpiralRectangle (int m, int n){ 7 | int[][] direction = new int[][] {{0, 1},{1, 0},{0, -1},{-1, 0}}; 8 | int i = 0, j = 0, k = 0, l = 0; 9 | int[][] spiralArray = new int[m][n]; 10 | 11 | for (int x = 1; x <= m*n; x++){ 12 | spiralArray[i][j] = x; 13 | 14 | if(direction[k][0] == 0){ 15 | if ((direction[k][1] == 1 && j == n - 1 - l) || (direction[k][1] == -1 && j == l)){ 16 | k = (k + 1) % 4; 17 | } 18 | } else { 19 | if ((direction[k][0] == 1 && i == m - 1 - l) || (direction[k][0] == -1 && i == l + 1)) { 20 | if (k == 3) l++; 21 | k = (k + 1) % 4; 22 | } 23 | } 24 | 25 | i = i + direction[k][0]; 26 | j = j + direction[k][1]; 27 | } 28 | 29 | int numberLength = String.valueOf(m*n).length(); 30 | 31 | for(int[] row : spiralArray) { 32 | for (int a = 0; a < row.length; a++) { 33 | if (a > 0) 34 | System.out.print(" "); 35 | String c = String.valueOf(row[a]); 36 | for (int b = 0; b < numberLength - c.length(); b++) { 37 | System.out.print(" "); 38 | } 39 | System.out.print(row[a]); 40 | } 41 | 42 | System.out.println(); 43 | } 44 | } 45 | } 46 | 47 | -------------------------------------------------------------------------------- /week0002/truongngodang/java/week0002.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by truon on 03/10/2016. 3 | */ 4 | 5 | public class week0002 { 6 | 7 | public static void main(String[] args) { 8 | int[][] array = new int[4][4]; 9 | createSpiralRectangle(array, 1); 10 | displayArrayToConsole(array); 11 | } 12 | 13 | private static void createSpiralRectangle(int[][] array, int numStart) { 14 | drawTopRight(array, numStart, 0, array[0].length - 1, 0, array.length - 1); 15 | } 16 | 17 | private static void drawTopRight(int[][] matrix, int numStart, int x1, int x2, int y1, int y2) { 18 | for (int col = x1; col <= x2; col++) { 19 | matrix[y1][col] = numStart++; 20 | } 21 | for (int row = y1 + 1; row <= y2; row++) { 22 | matrix[row][x2] = numStart++; 23 | } 24 | if (x2 - x1 > 0 && y2 - y1 > 0) { 25 | y1++; 26 | x2--; 27 | drawBottomLeft(matrix, numStart, x1, x2, y1, y2); 28 | } 29 | } 30 | 31 | private static void drawBottomLeft(int[][] matrix, int numStart, int x1, int x2, int y1, int y2) { 32 | for (int col = x2; col >= x1 ; col--) { 33 | matrix[y2][col] = numStart++; 34 | } 35 | for (int row = y2 - 1; row >= y1 ; row--) { 36 | matrix[row][x1] = numStart++; 37 | } 38 | if (x2 - x1 > 0 && y2 - y1 > 0) { 39 | x1++; 40 | y2--; 41 | drawTopRight(matrix, numStart, x1, x2, y1, y2); 42 | } 43 | } 44 | 45 | private static void displayArrayToConsole(int[][] array) { 46 | int numberLength = String.valueOf(array.length * array[0].length).length(); 47 | for (int[] row : array) { 48 | for (int i = 0; i < row.length; i++) { 49 | if (i > 0) 50 | System.out.print(" "); 51 | String s = String.valueOf(row[i]); 52 | for (int j = 0; j < numberLength - s.length(); j++) { 53 | System.out.print(" "); 54 | } 55 | System.out.print(row[i]); 56 | } 57 | System.out.println(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /week0003/README.md: -------------------------------------------------------------------------------- 1 | # Week 0003 2 | 3 | This week we will have fun with I/O and build a simple query application. Make sure your code is extensible so we can reuse and expand in in the next week's problem set. 4 | 5 | ## FinTech 101 6 | 7 | Now you have launched a new FinTech start-up that will shake grounds with its new and innovative retail baking system. The system and process the following commands via STDIN/STDOUT: 8 | 9 | 1. Add a new client 10 | 11 | ``` 12 | A Name InitialAmount 13 | ``` 14 | 15 | * `A` is the keyword, triggering an action to add 16 | * `Name` is the name of the client, only alphabetic characters allowed. It contains no spaces. Names are case-insensitive 17 | * `InitialAmount` is the amount of money (USD) at the time of account opening. It's a positive `double` 18 | * If the user attempts to add the same name again, reject 19 | 20 | 2. Deposit money 21 | 22 | ``` 23 | D Name Amount 24 | ``` 25 | 26 | * `D` is the keyword, triggering an action to deposit 27 | * `Name` is the name of the client, only alphabetic characters allowed. It contains no spaces. Names are case-insensitive 28 | * `Amount` is the amount of money (USD) to deposit. It's a positive `double` 29 | * Reject if the user attempts to deposit for an invalid client 30 | 31 | 3. Withdraw money 32 | 33 | ``` 34 | W Name Amount 35 | ``` 36 | 37 | * `W` is the keyword, triggering an action to withdraw 38 | * `Name` is the name of the client, only alphabetic characters allowed. It contains no spaces. Names are case-insensitive 39 | * `Amount` is the amount of money (USD) to withdraw. It's a positive `double` 40 | * Reject if the user attempts to withdraw from an invalid client 41 | * Reject if the user attempts to withdraw a larger amount than the actual amount of the client 42 | 43 | 4. Success/Failure handling 44 | 45 | * If an action/command was successful, print to STDOUT `True`, followed by a newline 46 | * If an action/command failed, print to STDOUT `False`, followed by a newline 47 | * If the amount is non-positive, print to STDOUT `False`, followed by a newline 48 | * Reject unrecognized keywords by printing to STDOUT `Invalid`, followed by a newline 49 | 50 | ## Submission 51 | 52 | ### Acceptance condition 53 | 54 | * You must implement all required tasks 55 | * Make sure to test against the provided test case `test_case_01.input` before submitting 56 | 57 | Sample commands to test: 58 | 59 | ``` 60 | diff <(python week0003.py < test_case_01.input) test_case_01.output 61 | 62 | diff <(php week0003.php < test_case_01.input) test_case_01.output 63 | 64 | diff <(./week0003.exe < test_case_01.input) test_case_01.output 65 | 66 | diff <(java week0003 < test_case_01.input) test_case_01.output 67 | 68 | diff <(./week0003.sh < test_case_01.input) test_case_01.output 69 | ``` 70 | 71 | ### Folder structure 72 | 73 | Please structure your code like this: 74 | 75 | * Have your own folder named after your GitHub ID 76 | * Each language has own folder 77 | * Keep the files named week0003/week0003. 78 | 79 | ``` 80 | week0003/ 81 | |--YourGitHubID/ 82 | |--cpp/ 83 | |--week0003.cpp 84 | |--php/ 85 | |--week0003.php 86 | |--python/ 87 | |--week0003.py 88 | |--ruby/ 89 | |--week0003.rb 90 | ``` 91 | 92 | ### To PHP fans 93 | 94 | * If you want your submission accepted, please do not use `
` and `echo` 95 | * You must use `php://stdin` & `php://stdout`! 96 | * For your reading pleasure: http://php.net/manual/en/features.commandline.io-streams.php 97 | 98 | ### Languages 99 | 100 | Submit your code in any of the following languages: 101 | 102 | * C 103 | * C# 104 | * C++ 105 | * Go 106 | * Java 107 | * Javascript (browser/Node.JS) 108 | * Objective-C 109 | * OCaml 110 | * Perl 111 | * PHP 112 | * Python 113 | * Ruby 114 | * Swift 115 | * Unix shells & tools: sh/ksh/bash/zsh, awk, sed, uniq, ... 116 | 117 | You can submit by creating a pull request. 118 | 119 | Please direct your ideas, suggestions, collaboration requests to: viet@code2.pro 120 | -------------------------------------------------------------------------------- /week0003/daudau/php/daudau.php: -------------------------------------------------------------------------------- 1 | run(); 5 | 6 | class Account 7 | { 8 | private $_name; 9 | private $_money; 10 | 11 | function __construct($name, $money) { 12 | $this->_name = $name; 13 | $this->_money = $money; 14 | } 15 | 16 | public function withdraw($amount) { 17 | if ($amount <= 0 || $amount > $this->_money) 18 | return false; 19 | $this->_money -= $amount; 20 | return true; 21 | } 22 | 23 | public function deposite($amount) { 24 | if ($amount < 0) 25 | return false; 26 | $this->_money += $amount; 27 | return true; 28 | } 29 | 30 | public function save() { 31 | $bank = Bank::getInstance(); 32 | $bank->accounts()[strtolower($this->getName())] = $this; 33 | } 34 | 35 | public function getName() { 36 | return $this->_name; 37 | } 38 | 39 | public function getMoney() { 40 | return $this->_money; 41 | } 42 | } 43 | 44 | /** 45 | * using bank instance 46 | */ 47 | class Bank 48 | { 49 | private $_accounts; 50 | const ACTION_ADD_CLIENT = 'A'; 51 | const ACTION_WITHDRAW_CLIENT = 'W'; 52 | const ACTION_DEPOSIT_CLIENT = 'D'; 53 | 54 | private static $_instance; 55 | 56 | protected function __construct() { 57 | $this->_accounts = array(); 58 | } 59 | 60 | public static function getInstance() { 61 | if (null === self::$_instance) { 62 | self::$_instance = new self(); 63 | } 64 | return self::$_instance; 65 | } 66 | 67 | public function add(Account $account) { 68 | if ( $this->_accounts[strtolower($account->getName())] ) 69 | return false; 70 | else 71 | $this->_accounts[strtolower( $account->getName() )] = $account; 72 | return true; 73 | } 74 | 75 | public function save($account) { 76 | if ( $this->_accounts[strtolower($account->getName())] ) { 77 | $this->_accounts[strtolower($account->getName())] = $account; 78 | return true; 79 | } 80 | return false; 81 | } 82 | 83 | public function run() { 84 | while ($command = dd_read()) { 85 | 86 | if ($command == 'dump') { 87 | print_r($this->_accounts); 88 | continue; 89 | } 90 | 91 | if ($command = $this->parseCommand($command)) { 92 | $name = strtolower($command['accountName']); //this name use as key of bank per account. 93 | 94 | switch ($command['action']) { 95 | case self::ACTION_ADD_CLIENT: 96 | $account = new Account($command['accountName'], $command['amount']); 97 | if ($this->add($account)) 98 | dd_linef('True'); 99 | else 100 | dd_linef('False'); 101 | break; 102 | 103 | case self::ACTION_DEPOSIT_CLIENT: 104 | if ($acc = $this->findAccountByName($name)) { 105 | if ($acc->deposite($command['amount'])) { 106 | $acc->save(); 107 | dd_linef('True'); 108 | } else 109 | dd_linef('False'); 110 | } else 111 | dd_linef('False'); 112 | break; 113 | 114 | case self::ACTION_WITHDRAW_CLIENT: 115 | if ($acc = $this->findAccountByName($name)) { 116 | if ($acc->withdraw($command['amount'])) { 117 | $acc->save(); 118 | dd_linef('True'); 119 | } else 120 | dd_linef('False'); 121 | } else 122 | dd_linef('False'); 123 | break; 124 | 125 | default: 126 | dd_linef('Invalid'); 127 | break; 128 | } 129 | } 130 | } 131 | } 132 | 133 | public function findAccountByName($name) { 134 | if ($this->_accounts[$name]) 135 | return $this->_accounts[$name]; 136 | return false; 137 | } 138 | 139 | private function parseCommand($string) { 140 | $string = preg_split('/\s+/', $string); 141 | $errors = array(); 142 | 143 | //just usefull when all commands have 3 arguments 144 | if (count($string) != 3) { 145 | dd_error("Wrong structure command!"); 146 | return false; 147 | } 148 | 149 | $command = array(); 150 | $command['action'] = $string[0]; 151 | $command['accountName'] = $string[1]; 152 | $command['amount'] = $string[2]; 153 | 154 | if (!in_array($command['action'], $this->getActions())) 155 | $errors[] = 'Invalid'; 156 | if (!preg_match("/^([a-zA-Z]+)/", $command['accountName'])) 157 | $errors[] = 'Invalid name'; 158 | if ((double)$command['amount']."" != $command['amount']) 159 | $errors[] = 'Invalid amount of money'; 160 | if (count($errors)) { 161 | foreach ($errors as $error) 162 | dd_error($error); 163 | return false; 164 | } 165 | return $command; 166 | } 167 | 168 | public function accounts() { 169 | return $this->_accounts; 170 | } 171 | 172 | public function getActions() { 173 | return array(self::ACTION_ADD_CLIENT, self::ACTION_DEPOSIT_CLIENT, self::ACTION_WITHDRAW_CLIENT); 174 | } 175 | 176 | } 177 | 178 | //helper function, dd just is my prefix :D 179 | function dd_line($text) { //no new line 180 | fwrite(STDOUT, $text); 181 | } 182 | function dd_linef($text) { //enter new line 183 | fwrite(STDOUT, $text.PHP_EOL); 184 | } 185 | function dd_error($text) { //printt error 186 | fwrite(STDERR, $text.PHP_EOL); 187 | } 188 | function dd_read() { 189 | // fflush(STDIN); 190 | return trim(fgets(STDIN)); 191 | } -------------------------------------------------------------------------------- /week0003/giaosudau/python/week0003.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | ACTION_ADD_CLIENT = 'A' 4 | ACTION_CLIENT_DEPOSIT = 'D' 5 | ACTION_CLIENT_WITHDRAW = 'W' 6 | 7 | 8 | class Client(): 9 | def __init__(self, name, amount): 10 | self.name = name 11 | self.amount = amount 12 | 13 | def deposit(self, amount): 14 | if amount > 0: 15 | self.amount += amount 16 | return True 17 | else: 18 | return False 19 | 20 | def withdraw(self, amount): 21 | if 0 < amount <= self.amount: 22 | self.amount -= amount 23 | return True 24 | else: 25 | return False 26 | 27 | 28 | class Bank(object): 29 | def __init__(self): 30 | self.clients = {} 31 | 32 | def process(self, input): 33 | for line in input: 34 | data = line.split(" ") 35 | action = data[0] 36 | name = data[1].lower() 37 | amount = float(data[2]) 38 | if amount > 0: 39 | if action == ACTION_ADD_CLIENT: 40 | print self.add_client(name, amount) 41 | elif action == ACTION_CLIENT_DEPOSIT: 42 | print self.deposit(name, amount) 43 | elif action == ACTION_CLIENT_WITHDRAW: 44 | print self.withdraw(name, amount) 45 | else: 46 | print 'Invalid' 47 | else: 48 | print 'Invalid' 49 | 50 | def add_client(self, name, amount): 51 | if name in self.clients: 52 | return False 53 | else: 54 | client = Client(name, amount) 55 | self.clients[name] = client 56 | return True 57 | 58 | def deposit(self, name, amount): 59 | if name in self.clients: 60 | client = self.clients[name] 61 | return client.deposit(amount) 62 | else: 63 | return False 64 | 65 | def withdraw(self, name, amount): 66 | if name in self.clients: 67 | client = self.clients[name] 68 | return client.withdraw(amount) 69 | else: 70 | return False 71 | 72 | 73 | if __name__ == '__main__': 74 | bank = Bank() 75 | bank.process(sys.stdin) 76 | -------------------------------------------------------------------------------- /week0003/hoangdangduy/java/Account.java: -------------------------------------------------------------------------------- 1 | public class Account { 2 | private String name; 3 | private Double money; 4 | 5 | public String getName() { 6 | return name; 7 | } 8 | 9 | public void setName(String name) { 10 | this.name = name; 11 | } 12 | 13 | public double getMoney() { 14 | return money; 15 | } 16 | 17 | public void setMoney(Double money) { 18 | this.money = money; 19 | } 20 | 21 | public Account(String name, Double money) { 22 | super(); 23 | this.name = name; 24 | this.money = money; 25 | } 26 | 27 | public Account() { 28 | super(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /week0003/hoangdangduy/java/Process.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | 3 | public class Process { 4 | private static final String CREATE_ACCOUNT = "A"; 5 | private static final String DEPOSIT_MONEY = "D"; 6 | private static final String WITHDRAW_MONEY = "W"; 7 | 8 | public HashMap process(String data, HashMap listAccount) { 9 | Account account = new Account(); 10 | String[] inforTransaction = data.split(" "); 11 | String action = inforTransaction[0]; 12 | String nameClient = inforTransaction[1].toUpperCase(); 13 | Double amountMoney = Double.parseDouble(inforTransaction[2]); 14 | 15 | switch (action) { 16 | case CREATE_ACCOUNT: 17 | account = createAccount(nameClient, amountMoney, listAccount); 18 | return editListAccAfterAction(account, listAccount); 19 | case DEPOSIT_MONEY: 20 | account = depositMoney(nameClient, amountMoney, listAccount); 21 | return editListAccAfterAction(account, listAccount); 22 | case WITHDRAW_MONEY: 23 | account = withdrawMoney(nameClient, amountMoney, listAccount); 24 | return editListAccAfterAction(account, listAccount); 25 | default: 26 | Response response = new Response(); 27 | response.showMessage("Invalid"); 28 | break; 29 | } 30 | return listAccount; 31 | } 32 | 33 | public Account createAccount(String name, Double money, HashMap listAccount){ 34 | Response response = new Response(); 35 | if (!listAccount.containsKey(name) && validate(name, money)){ 36 | response.showMessage("True"); 37 | return new Account(name, money); 38 | }else{ 39 | response.showMessage("False"); 40 | } 41 | 42 | return null; 43 | } 44 | 45 | public Account depositMoney(String name, Double money, HashMap listAccount){ 46 | Response response = new Response(); 47 | if (listAccount.containsKey(name) && validate(name, money)){ 48 | response.showMessage("True"); 49 | Double currentMoney = listAccount.get(name); 50 | return new Account(name, currentMoney + money); 51 | }else if(!validate(name, money)){ 52 | response.showMessage("Invalid"); 53 | }else{ 54 | response.showMessage("False"); 55 | } 56 | 57 | return null; 58 | } 59 | 60 | public Account withdrawMoney(String name, Double money, HashMap listAccount){ 61 | Response response = new Response(); 62 | Double currentMoney = listAccount.get(name); 63 | if (listAccount.containsKey(name) && validate(name, money) && currentMoney >= money){ 64 | response.showMessage("True"); 65 | return new Account(name, currentMoney - money); 66 | }else if(!validate(name, money)){ 67 | response.showMessage("Invalid"); 68 | }else{ 69 | response.showMessage("False"); 70 | } 71 | return null; 72 | } 73 | 74 | public HashMap editListAccAfterAction(Account account, HashMap listAccount){ 75 | if (account != null){ 76 | listAccount.put(account.getName(), account.getMoney()); 77 | return listAccount; 78 | } 79 | return listAccount; 80 | } 81 | 82 | public boolean validate(String name, Double money){ 83 | boolean checkName = name.matches("^[A-Za-z]+$"); 84 | boolean checkMoney = money > 0 ? true : false; 85 | return checkName && checkMoney; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /week0003/hoangdangduy/java/Response.java: -------------------------------------------------------------------------------- 1 | public class Response { 2 | public void showMessage(String mess){ 3 | System.out.println(mess); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /week0003/hoangdangduy/java/Week0003.java: -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | import java.util.Scanner; 3 | 4 | public class Week0003 { 5 | public static void main(String[] args) { 6 | HashMap accounts = new HashMap<>(); 7 | Process process = new Process(); 8 | 9 | Scanner sc = new Scanner(System.in); 10 | while (sc.hasNext()) { 11 | accounts = process.process(sc.nextLine(), accounts); 12 | } 13 | sc.close(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /week0003/mattfanz/php/.gitignore: -------------------------------------------------------------------------------- 1 | .idea -------------------------------------------------------------------------------- /week0003/mattfanz/php/src/FinTech/Account.php: -------------------------------------------------------------------------------- 1 | name = $name; 31 | $this->amount = (double) $amount; 32 | } 33 | 34 | /** 35 | * @param $amount 36 | * @return bool 37 | */ 38 | public function deposit($amount) 39 | { 40 | if ($this->checkTransaction($amount)) { 41 | $this->amount += $amount; 42 | return true; 43 | } 44 | return false; 45 | } 46 | 47 | /** 48 | * @param $amount 49 | * @return bool 50 | */ 51 | public function withdraw($amount) 52 | { 53 | if ($this->checkTransaction($amount) && $this->amount - $amount >= 0) { 54 | $this->amount -= $amount; 55 | return true; 56 | } 57 | return false; 58 | } 59 | 60 | /** 61 | * @param $amount 62 | * @return bool 63 | */ 64 | protected function checkTransaction($amount) 65 | { 66 | return (is_numeric($amount) && $amount > 0); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /week0003/mattfanz/php/src/FinTech/AccountManager.php: -------------------------------------------------------------------------------- 1 | getKeyName($name); 36 | if (array_key_exists($keyName, $this->accounts)) { 37 | return $this->accounts[$keyName]; 38 | } 39 | return false; 40 | } 41 | 42 | /** 43 | * @param $name 44 | * @param $amount 45 | * @return bool 46 | */ 47 | public function addAccount($name, $amount) 48 | { 49 | if (ctype_alpha($name) && !$this->findOrFail($name) && is_numeric($amount) && $amount > 0) { 50 | $newAccount = new Account($name, $amount); 51 | $this->accounts[$this->getKeyName($name)] = $newAccount; 52 | return true; 53 | } 54 | return false; 55 | } 56 | 57 | /** 58 | * @param $name 59 | * @param $amount 60 | * @return bool 61 | */ 62 | public function depositMoney($name, $amount) 63 | { 64 | if ($account = $this->findOrFail($name)) { 65 | return $account->deposit($amount); 66 | } 67 | return false; 68 | } 69 | 70 | /** 71 | * @param $name 72 | * @param $amount 73 | * @return bool 74 | */ 75 | public function withdrawMoney($name, $amount) 76 | { 77 | if ($account = $this->findOrFail($name)) { 78 | return $account->withdraw($amount); 79 | } 80 | return false; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /week0003/mattfanz/php/src/FinTech/Action.php: -------------------------------------------------------------------------------- 1 | action = $action; 48 | $this->name = $name; 49 | $this->amount = $amount; 50 | $this->accountManager = $accountManager; 51 | } 52 | 53 | /** 54 | * @return string 55 | */ 56 | public function performAction() 57 | { 58 | switch ($this->action) { 59 | case self::ACTION_ADD_CLIENT: 60 | return $this->actionAddAccount(); 61 | break; 62 | case self::ACTION_DEPOSIT_MONEY: 63 | return $this->actionDepositMoney(); 64 | break; 65 | case self::ACTION_WITHDRAW_MONEY: 66 | return $this->actionWithdrawMoney(); 67 | break; 68 | default: 69 | return 'Invalid'; 70 | break; 71 | } 72 | } 73 | 74 | /** 75 | * @return string 76 | */ 77 | protected function actionAddAccount() 78 | { 79 | return ($this->accountManager->addAccount($this->name, $this->amount)) ? 'True' : 'False'; 80 | } 81 | 82 | /** 83 | * @return string 84 | */ 85 | protected function actionDepositMoney() 86 | { 87 | return ($this->accountManager->depositMoney($this->name, $this->amount)) ? 'True' : 'False'; 88 | } 89 | 90 | /** 91 | * @return string 92 | */ 93 | protected function actionWithdrawMoney() 94 | { 95 | return ($this->accountManager->withdrawMoney($this->name, $this->amount)) ? 'True' : 'False'; 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /week0003/mattfanz/php/src/autoload.php: -------------------------------------------------------------------------------- 1 | performAction(); 12 | fwrite(STDOUT, $output.PHP_EOL); 13 | } 14 | -------------------------------------------------------------------------------- /week0003/nhantd/python/week003.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | ACTION_ADD_ACCOUNT = 'A' 4 | ACTION_DEPOSIT_MONEY = 'D' 5 | ACTION_WITHDRAW_MONEY = 'W' 6 | 7 | 8 | class Accounts(): 9 | 10 | def __init__(self): 11 | self.data = dict() 12 | 13 | def addAccount(self, name, amount): 14 | if name not in self.data and amount > 0: 15 | self.data[name] = amount 16 | return 'True' 17 | else: 18 | return 'False' 19 | 20 | def depositMoney(self, name, amount): 21 | if name in self.data and amount > 0: 22 | self.data[name] += amount 23 | return 'True' 24 | else: 25 | return 'False' 26 | 27 | def withdrawMoney(self, name, amount): 28 | if name in self.data and amount > 0 and amount <= self.data[name]: 29 | self.data[name] -= amount 30 | return 'True' 31 | else: 32 | return 'False' 33 | 34 | 35 | def executeTransaction(accounts, inputTransaction): 36 | key, name, amount = inputTransaction.strip().split(' ') 37 | amount = float(amount) 38 | name = name.lower() 39 | if key == ACTION_ADD_ACCOUNT: 40 | return accounts.addAccount(name, amount) 41 | elif key == ACTION_DEPOSIT_MONEY: 42 | return accounts.depositMoney(name, amount) 43 | elif key == ACTION_WITHDRAW_MONEY: 44 | return accounts.withdrawMoney(name, amount) 45 | else: 46 | return 'Invalid' 47 | 48 | if __name__ == "__main__": 49 | sampleAccounts = Accounts() 50 | for line in sys.stdin: 51 | print executeTransaction(sampleAccounts, line) 52 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | DVRK-Week3 4 | DVRK-Week3 5 | 0.0.1-SNAPSHOT 6 | 7 | 8 | 9 | org.mockito 10 | mockito-all 11 | 1.10.19 12 | 13 | 14 | 15 | 16 | src 17 | test 18 | 19 | 20 | maven-compiler-plugin 21 | 3.1 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/fintech/domain/Account.java: -------------------------------------------------------------------------------- 1 | package fintech.domain; 2 | 3 | import java.math.BigDecimal; 4 | 5 | import fintech.exceptions.InsufficientBalanceException; 6 | 7 | public class Account { 8 | 9 | private final String name; 10 | private BigDecimal balanceAmount; 11 | 12 | public Account(String name, String initialAmount) { 13 | if (name == null) 14 | throw new IllegalArgumentException("Invalid input name"); 15 | this.name = name; 16 | this.balanceAmount = parseAmount(initialAmount); 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | 23 | public BigDecimal getCurrentBalance() { 24 | return balanceAmount; 25 | } 26 | 27 | public void deposit(String amount) { 28 | adjustBalance(parseAmount(amount)); 29 | } 30 | 31 | public void withdraw(String amount) { 32 | adjustBalance(parseAmount(amount).negate()); 33 | } 34 | 35 | private void adjustBalance(BigDecimal amount) { 36 | BigDecimal adjustedBalance = balanceAmount.add(amount); 37 | if (adjustedBalance.compareTo(BigDecimal.ZERO) < 0) 38 | throw new InsufficientBalanceException(); 39 | balanceAmount = adjustedBalance; 40 | } 41 | 42 | private BigDecimal parseAmount(String amountStr) { 43 | try { 44 | BigDecimal amount = new BigDecimal(amountStr); 45 | if (isNegative(amount)) 46 | throw new IllegalArgumentException("Amount must be positive"); 47 | return amount; 48 | } 49 | catch (NumberFormatException e) { 50 | throw new IllegalArgumentException("Invalid input amount"); 51 | } 52 | } 53 | 54 | private boolean isNegative(BigDecimal amount) { 55 | return amount.compareTo(BigDecimal.ZERO) <= 0; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/fintech/domain/Action.java: -------------------------------------------------------------------------------- 1 | package fintech.domain; 2 | 3 | import java.util.Arrays; 4 | import java.util.Optional; 5 | 6 | public enum Action { 7 | ADD_ACCOUNT("A"), DEPOSIT("D"), WITHDRAW("W"); 8 | 9 | private String strValue; 10 | 11 | private Action(String strValue) { 12 | this.strValue = strValue; 13 | } 14 | 15 | public static Action getAction(String strValue) { 16 | Optional matchedAction = Arrays.stream(Action.values()) 17 | .filter(action -> action.strValue.endsWith(strValue)).findAny(); 18 | return matchedAction.isPresent() ? matchedAction.get() : null; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/fintech/domain/Instruction.java: -------------------------------------------------------------------------------- 1 | package fintech.domain; 2 | 3 | public class Instruction { 4 | 5 | private static final String DELIMITER = " "; 6 | private static final int INSTRUCTION_PARTS = 3; 7 | 8 | private final Action action; 9 | private final String accountName; 10 | private final String instructionDetail; 11 | 12 | public Instruction(String instruction) { 13 | if (instruction == null) 14 | throw new IllegalArgumentException("Invalid request"); 15 | 16 | String[] parts = instruction.split(DELIMITER); 17 | if (parts.length != INSTRUCTION_PARTS) 18 | throw new IllegalArgumentException("Invalid request"); 19 | 20 | action = Action.getAction(parts[0]); 21 | if (action == null) 22 | throw new IllegalArgumentException("Invalid request"); 23 | 24 | accountName = parts[1]; 25 | instructionDetail = parts[2]; 26 | } 27 | 28 | public Action getAction() { 29 | return action; 30 | } 31 | 32 | public String getAccountName() { 33 | return accountName; 34 | } 35 | 36 | public String getInstructionDetail() { 37 | return instructionDetail; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/fintech/domain/Response.java: -------------------------------------------------------------------------------- 1 | package fintech.domain; 2 | 3 | public enum Response { 4 | SUCCESSFUL("True"), FAILED("False"), INVALID("Invalid"); 5 | 6 | private String responseMsg; 7 | 8 | private Response(String responseMsg) { 9 | this.responseMsg = responseMsg; 10 | } 11 | 12 | public String getResponseMsg() { 13 | return responseMsg; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/fintech/exceptions/InsufficientBalanceException.java: -------------------------------------------------------------------------------- 1 | package fintech.exceptions; 2 | 3 | public class InsufficientBalanceException extends RuntimeException { 4 | private static final long serialVersionUID = -1895651876503172100L; 5 | } 6 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/fintech/processors/AccountManager.java: -------------------------------------------------------------------------------- 1 | package fintech.processors; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import fintech.domain.Account; 7 | import fintech.exceptions.InsufficientBalanceException; 8 | 9 | public class AccountManager { 10 | 11 | private final Map accounts = new HashMap<>(); 12 | 13 | public AccountManager() { 14 | this.accounts.clear(); 15 | } 16 | 17 | public boolean addAccount(String name, String initialAmount) { 18 | try { 19 | Account existingAccount = 20 | accounts.putIfAbsent(getAccountKey(name), new Account(name, initialAmount)); 21 | return existingAccount == null; 22 | } 23 | catch (IllegalArgumentException ex) { 24 | return false; 25 | } 26 | } 27 | 28 | public boolean depositForAccount(String name, String amount) { 29 | try { 30 | Account updatedAccount = 31 | accounts.computeIfPresent( 32 | getAccountKey(name), 33 | (key, account) -> { 34 | account.deposit(amount); 35 | return account; 36 | } 37 | ); 38 | return updatedAccount != null; 39 | } 40 | catch (IllegalArgumentException ex) { 41 | return false; 42 | } 43 | } 44 | 45 | public boolean withdrawFromAccount(String name, String amount) { 46 | try { 47 | Account updatedAccount = 48 | accounts.computeIfPresent( 49 | getAccountKey(name), 50 | (key, account) -> { 51 | account.withdraw(amount); 52 | return account; 53 | } 54 | ); 55 | return updatedAccount != null; 56 | } 57 | catch (IllegalArgumentException | InsufficientBalanceException ex) { 58 | return false; 59 | } 60 | } 61 | 62 | private String getAccountKey(String name) { 63 | if (name == null) 64 | throw new IllegalArgumentException("Invalid input name"); 65 | return name.toUpperCase(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/fintech/processors/BankAccountApp.java: -------------------------------------------------------------------------------- 1 | package fintech.processors; 2 | 3 | import fintech.domain.Instruction; 4 | import fintech.domain.Response; 5 | 6 | public class BankAccountApp { 7 | 8 | private final AccountManager accountManager; 9 | 10 | public BankAccountApp(AccountManager accountManager) { 11 | this.accountManager = accountManager; 12 | } 13 | 14 | public Response processRequest(String request) { 15 | Instruction instruction; 16 | try { 17 | instruction = new Instruction(request); 18 | } 19 | catch (IllegalArgumentException ex) { 20 | return Response.INVALID; 21 | } 22 | 23 | boolean result; 24 | switch (instruction.getAction()) { 25 | case ADD_ACCOUNT: 26 | result = accountManager.addAccount(instruction.getAccountName(), instruction.getInstructionDetail()); 27 | break; 28 | case DEPOSIT: 29 | result = accountManager.depositForAccount(instruction.getAccountName(), instruction.getInstructionDetail()); 30 | break; 31 | case WITHDRAW: 32 | result = accountManager.withdrawFromAccount(instruction.getAccountName(), instruction.getInstructionDetail()); 33 | break; 34 | default: 35 | return Response.INVALID; 36 | } 37 | 38 | return result ? Response.SUCCESSFUL : Response.FAILED; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/src/week0003.java: -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | import fintech.domain.Response; 4 | import fintech.processors.AccountManager; 5 | import fintech.processors.BankAccountApp; 6 | 7 | public class week0003 { 8 | 9 | public static void main(String[] arg) { 10 | BankAccountApp bankAccountApp = createBankAccountApp(); 11 | 12 | Scanner scanner = new Scanner(System.in); 13 | while (scanner.hasNext()) { 14 | Response response = bankAccountApp.processRequest(scanner.nextLine()); 15 | System.out.println(response.getResponseMsg()); 16 | } 17 | scanner.close(); 18 | } 19 | 20 | public static BankAccountApp createBankAccountApp() { 21 | AccountManager accountManager = new AccountManager(); 22 | return new BankAccountApp(accountManager); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/test/fintech/domain/AccountTest.java: -------------------------------------------------------------------------------- 1 | package fintech.domain; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.math.BigDecimal; 6 | 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | import org.junit.rules.ExpectedException; 10 | 11 | import fintech.domain.Account; 12 | import fintech.exceptions.InsufficientBalanceException; 13 | 14 | public class AccountTest { 15 | 16 | private static final String TEST_NAME = "TEST_NAME"; 17 | 18 | @Rule 19 | public ExpectedException expectedException = ExpectedException.none(); 20 | 21 | @Test 22 | public void testAccountInit() { 23 | Account account = new Account(TEST_NAME, "1000"); 24 | assertEquals(TEST_NAME, account.getName()); 25 | assertEquals(new BigDecimal("1000"), account.getCurrentBalance()); 26 | } 27 | 28 | @Test 29 | public void testAccountInit_NullName() { 30 | expectedException.expect(IllegalArgumentException.class); 31 | expectedException.expectMessage("Invalid input name"); 32 | new Account(null, "1000"); 33 | } 34 | 35 | @Test 36 | public void testAccountInit_NonNumericInitialAmount() { 37 | expectedException.expect(IllegalArgumentException.class); 38 | expectedException.expectMessage("Invalid input amount"); 39 | new Account(TEST_NAME, TEST_NAME); 40 | } 41 | 42 | @Test 43 | public void testAccountInit_NegativeInitialAmount() { 44 | expectedException.expect(IllegalArgumentException.class); 45 | expectedException.expectMessage("Amount must be positive"); 46 | new Account(TEST_NAME, "-1000"); 47 | } 48 | 49 | @Test 50 | public void testAccountInit_ZeroInitialAmount() { 51 | expectedException.expect(IllegalArgumentException.class); 52 | expectedException.expectMessage("Amount must be positive"); 53 | new Account(TEST_NAME, "0.000000"); 54 | } 55 | 56 | @Test 57 | public void testDeposit() { 58 | Account account = new Account(TEST_NAME, "1000"); 59 | account.deposit("500"); 60 | 61 | assertEquals(TEST_NAME, account.getName()); 62 | assertEquals(new BigDecimal("1500"), account.getCurrentBalance()); 63 | } 64 | 65 | @Test 66 | public void testDeposit_NonNumericAmount() { 67 | Account account = new Account(TEST_NAME, "1000"); 68 | 69 | expectedException.expect(IllegalArgumentException.class); 70 | expectedException.expectMessage("Invalid input amount"); 71 | account.deposit(TEST_NAME); 72 | } 73 | 74 | @Test 75 | public void testDeposit_NegativeAmount() { 76 | Account account = new Account(TEST_NAME, "1000"); 77 | 78 | expectedException.expect(IllegalArgumentException.class); 79 | expectedException.expectMessage("Amount must be positive"); 80 | account.deposit("-500"); 81 | } 82 | 83 | @Test 84 | public void testDeposit_ZeroAmount() { 85 | Account account = new Account(TEST_NAME, "1000"); 86 | 87 | expectedException.expect(IllegalArgumentException.class); 88 | expectedException.expectMessage("Amount must be positive"); 89 | account.deposit("0.000"); 90 | } 91 | 92 | @Test 93 | public void testWithdraw() throws InsufficientBalanceException { 94 | Account account = new Account(TEST_NAME, "1000"); 95 | account.withdraw("500"); 96 | 97 | assertEquals(TEST_NAME, account.getName()); 98 | assertEquals(new BigDecimal("500"), account.getCurrentBalance()); 99 | } 100 | 101 | @Test 102 | public void testWithdraw_NonNumericAmount() throws InsufficientBalanceException { 103 | Account account = new Account(TEST_NAME, "1000"); 104 | 105 | expectedException.expect(IllegalArgumentException.class); 106 | expectedException.expectMessage("Invalid input amount"); 107 | account.withdraw(TEST_NAME); 108 | } 109 | 110 | @Test 111 | public void testWithdraw_NegativeAmount() throws InsufficientBalanceException { 112 | Account account = new Account(TEST_NAME, "1000"); 113 | 114 | expectedException.expect(IllegalArgumentException.class); 115 | expectedException.expectMessage("Amount must be positive"); 116 | account.withdraw("-500"); 117 | } 118 | 119 | @Test 120 | public void testWithdraw_ZeroAmount() throws InsufficientBalanceException { 121 | Account account = new Account(TEST_NAME, "1000"); 122 | 123 | expectedException.expect(IllegalArgumentException.class); 124 | expectedException.expectMessage("Amount must be positive"); 125 | account.withdraw("0.000"); 126 | } 127 | 128 | @Test 129 | public void testWithdraw_InsufficientBalance() throws InsufficientBalanceException { 130 | Account account = new Account(TEST_NAME, "1000"); 131 | 132 | expectedException.expect(InsufficientBalanceException.class); 133 | account.withdraw("1500"); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/test/fintech/domain/ActionTest.java: -------------------------------------------------------------------------------- 1 | package fintech.domain; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNull; 5 | 6 | import org.junit.Test; 7 | 8 | import fintech.domain.Action; 9 | 10 | public class ActionTest { 11 | 12 | @Test 13 | public void testGetAction() { 14 | assertEquals(Action.ADD_ACCOUNT, Action.getAction("A")); 15 | assertEquals(Action.DEPOSIT, Action.getAction("D")); 16 | assertEquals(Action.WITHDRAW, Action.getAction("W")); 17 | assertNull(Action.getAction("INVALID")); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/test/fintech/domain/InstructionTest.java: -------------------------------------------------------------------------------- 1 | package fintech.domain; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertNotNull; 5 | 6 | import org.junit.Rule; 7 | import org.junit.Test; 8 | import org.junit.rules.ExpectedException; 9 | 10 | import fintech.domain.Action; 11 | import fintech.domain.Instruction; 12 | 13 | public class InstructionTest { 14 | 15 | @Rule 16 | public ExpectedException expectedException = ExpectedException.none(); 17 | 18 | @Test 19 | public void testInstruction_NullInput() { 20 | expectedException.expect(IllegalArgumentException.class); 21 | expectedException.expectMessage("Invalid request"); 22 | new Instruction(null); 23 | } 24 | 25 | @Test 26 | public void testInstruction_InvalidInput() { 27 | expectedException.expect(IllegalArgumentException.class); 28 | expectedException.expectMessage("Invalid request"); 29 | new Instruction(""); 30 | } 31 | 32 | @Test 33 | public void testInstruction_InvalidAction() { 34 | expectedException.expect(IllegalArgumentException.class); 35 | expectedException.expectMessage("Invalid request"); 36 | new Instruction("Z Z Z"); 37 | } 38 | 39 | @Test 40 | public void testInstruction() { 41 | verifyInstruction(new Instruction("A Z Z"), Action.ADD_ACCOUNT, "Z", "Z"); 42 | verifyInstruction(new Instruction("D Z Z"), Action.DEPOSIT, "Z", "Z"); 43 | verifyInstruction(new Instruction("W Z Z"), Action.WITHDRAW, "Z", "Z"); 44 | } 45 | 46 | private void verifyInstruction(Instruction instruction, Action action, String accountName, String instructionDetail) { 47 | assertNotNull(instruction); 48 | assertEquals(action, instruction.getAction()); 49 | assertEquals(accountName, instruction.getAccountName()); 50 | assertEquals(instructionDetail, instruction.getInstructionDetail()); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/test/fintech/processors/AccountManagerTest.java: -------------------------------------------------------------------------------- 1 | package fintech.processors; 2 | 3 | import static org.junit.Assert.assertFalse; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import org.junit.Before; 7 | import org.junit.Test; 8 | 9 | import fintech.processors.AccountManager; 10 | 11 | public class AccountManagerTest { 12 | 13 | private static final String TEST_NAME = "TEST_NAME"; 14 | private static final String TEST_NAME_DUPLICATE = TEST_NAME.toLowerCase(); 15 | private AccountManager accountManager; 16 | 17 | @Before 18 | public void setUp() { 19 | accountManager = new AccountManager(); 20 | } 21 | 22 | @Test 23 | public void testAddAccount() { 24 | // Invalid input 25 | assertFalse(accountManager.addAccount(null, "1000")); 26 | assertFalse(accountManager.addAccount(TEST_NAME, TEST_NAME)); 27 | assertFalse(accountManager.addAccount(TEST_NAME, "0.000")); 28 | assertFalse(accountManager.addAccount(TEST_NAME, "-1000")); 29 | 30 | // Success 31 | assertTrue(accountManager.addAccount(TEST_NAME, "1000")); 32 | 33 | // Duplicate 34 | assertFalse(accountManager.addAccount(TEST_NAME, "1000")); 35 | assertFalse(accountManager.addAccount(TEST_NAME_DUPLICATE, "1000")); 36 | } 37 | 38 | @Test 39 | public void testDeposit() { 40 | // Invalid input 41 | assertFalse(accountManager.depositForAccount(null, "1000")); 42 | assertFalse(accountManager.depositForAccount(TEST_NAME, TEST_NAME)); 43 | assertFalse(accountManager.depositForAccount(TEST_NAME, "0.000")); 44 | assertFalse(accountManager.depositForAccount(TEST_NAME, "-1000")); 45 | 46 | // Non-existing account 47 | assertFalse(accountManager.depositForAccount(TEST_NAME, "1000")); 48 | 49 | // Add account 50 | assertTrue(accountManager.addAccount(TEST_NAME, "1000")); 51 | 52 | // Success 53 | assertTrue(accountManager.depositForAccount(TEST_NAME, "1000")); 54 | } 55 | 56 | @Test 57 | public void testWithdraw() { 58 | // Invalid input 59 | assertFalse(accountManager.withdrawFromAccount(null, "1000")); 60 | assertFalse(accountManager.withdrawFromAccount(TEST_NAME, TEST_NAME)); 61 | assertFalse(accountManager.withdrawFromAccount(TEST_NAME, "0.000")); 62 | assertFalse(accountManager.withdrawFromAccount(TEST_NAME, "-1000")); 63 | 64 | // Non-existing account 65 | assertFalse(accountManager.withdrawFromAccount(TEST_NAME, "1000")); 66 | 67 | // Add account 68 | assertTrue(accountManager.addAccount(TEST_NAME, "1000")); 69 | 70 | // Insufficient 71 | assertFalse(accountManager.withdrawFromAccount(TEST_NAME, "2000")); 72 | 73 | // Success 74 | assertTrue(accountManager.withdrawFromAccount(TEST_NAME, "1000")); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /week0003/pertsodian/java/test/fintech/processors/BankAccountAppTest.java: -------------------------------------------------------------------------------- 1 | package fintech.processors; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.mockito.Mockito; 8 | 9 | import fintech.domain.Response; 10 | import fintech.processors.AccountManager; 11 | import fintech.processors.BankAccountApp; 12 | 13 | public class BankAccountAppTest { 14 | 15 | private AccountManager accountManager; 16 | private BankAccountApp bankAccountApp; 17 | 18 | @Before 19 | public void setUp() { 20 | accountManager = Mockito.mock(AccountManager.class); 21 | Mockito.when(accountManager.addAccount(Mockito.any(), Mockito.any())).thenReturn(true); 22 | Mockito.when(accountManager.depositForAccount(Mockito.any(), Mockito.any())).thenReturn(true); 23 | Mockito.when(accountManager.withdrawFromAccount(Mockito.any(), Mockito.any())).thenReturn(false); 24 | 25 | bankAccountApp = new BankAccountApp(accountManager); 26 | } 27 | 28 | @Test 29 | public void testProcessRequest() { 30 | // INVALID request 31 | assertEquals(Response.INVALID, bankAccountApp.processRequest(null)); 32 | assertEquals(Response.INVALID, bankAccountApp.processRequest("")); 33 | assertEquals(Response.INVALID, bankAccountApp.processRequest("Z Z Z")); 34 | 35 | // FAILED request 36 | assertEquals(Response.FAILED, bankAccountApp.processRequest("W Z Z")); 37 | 38 | // SUCCESSFUL request 39 | assertEquals(Response.SUCCESSFUL, bankAccountApp.processRequest("A Z Z")); 40 | assertEquals(Response.SUCCESSFUL, bankAccountApp.processRequest("D Z Z")); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /week0003/test_case_01.input: -------------------------------------------------------------------------------- 1 | A Viet 10000 2 | D Jenny 1000 3 | A Jenny 1000 4 | W An 256 5 | A Viet 9999 6 | W Viet 1000 7 | D Jenny 256 8 | A An 567 9 | W Jenny 2000 10 | D Viet 345 11 | B An 123456 12 | Q Stark 999999999 13 | -------------------------------------------------------------------------------- /week0003/test_case_01.output: -------------------------------------------------------------------------------- 1 | True 2 | False 3 | True 4 | False 5 | False 6 | True 7 | True 8 | True 9 | False 10 | True 11 | Invalid 12 | Invalid 13 | -------------------------------------------------------------------------------- /week0003/thainguyentran/CSharp/week0003.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace DVRK 6 | { 7 | class Program 8 | { 9 | public static Dictionary clients; 10 | const char ACTION_ADDCLIENT = 'A'; 11 | const char ACTION_DEPOSIT = 'D'; 12 | const char ACTION_WITHDRAW = 'W'; 13 | 14 | static void Main(string[] args) 15 | { 16 | clients = new Dictionary(StringComparer.OrdinalIgnoreCase); 17 | string input = ""; 18 | do { 19 | input = Console.ReadLine(); 20 | if (input != "") 21 | Console.WriteLine(bankingProcess(input)); 22 | } while (input != "") ; 23 | } 24 | 25 | public static string bankingProcess (string input) 26 | { 27 | string[] keyword = input.Split(' '); 28 | char Trigger = Convert.ToChar(keyword[0]); 29 | string Name = keyword[1]; 30 | double Amount = Convert.ToDouble(keyword[2]); 31 | 32 | 33 | switch (Trigger) 34 | { 35 | case ACTION_ADDCLIENT: 36 | if (Name.All(char.IsLetter) && Amount > 0) 37 | if (!clients.ContainsKey(Name)) 38 | { 39 | clients.Add(Name, Amount); 40 | return("True"); 41 | } 42 | else return ("False"); 43 | else return ("Invaild"); 44 | case ACTION_DEPOSIT: 45 | if (Name.All(char.IsLetter) && Amount > 0) 46 | if (clients.ContainsKey(Name)) 47 | { 48 | clients[Name] += Amount; 49 | return ("True"); 50 | } 51 | else return ("False"); 52 | else return ("Invaild"); 53 | case ACTION_WITHDRAW: 54 | if (Name.All(char.IsLetter) && Amount > 0) 55 | if (clients.ContainsKey(Name)) 56 | if (clients[Name] >= Amount) 57 | { 58 | clients[Name] -= Amount; 59 | return ("True"); 60 | } 61 | else return ("False"); 62 | else return ("False"); 63 | else return ("False"); 64 | default: 65 | return ("Invaild"); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /week0003/truongngodang/java/Week0003.java: -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Week0003 { 4 | public static void main(String[] args) { 5 | Scanner scan = new Scanner(System.in); 6 | HashMap clientList = new HashMap(); 7 | ClientManagement clientManagement = new ClientManagement(clientList); 8 | while (scan.hasNext()) { 9 | System.out.println(clientManagement.processRequest(scan.nextLine())); 10 | } 11 | } 12 | } 13 | 14 | class ClientManagement { 15 | 16 | private static final String ADD_NEW_CLIENT = "A"; 17 | private static final String DEPOSIT_MONEY = "D"; 18 | private static final String WITHDRAW_MONEY = "W"; 19 | 20 | private HashMap clientList; 21 | 22 | public ClientManagement(HashMap clientList) { 23 | this.clientList = clientList; 24 | } 25 | 26 | public boolean addNewClient(String name, Double money) { 27 | if (this.clientList.get(name) == null) { 28 | this.clientList.put(name, new Client(name, money)); 29 | return true; 30 | } 31 | return false; 32 | } 33 | 34 | public String processRequest(String request) { 35 | ProcessStringRequest processString = new ProcessStringRequest(request); 36 | switch (processString.getDefineRequest()) { 37 | case ADD_NEW_CLIENT : { 38 | if (addNewClient(processString.getName(), processString.getMoney())) { 39 | return "True"; 40 | } else { 41 | return "False"; 42 | } 43 | } 44 | case DEPOSIT_MONEY : { 45 | if (this.clientList.get(processString.getName()) != null) { 46 | this.clientList.get(processString.getName()).depositMoney(processString.getMoney()); 47 | return "True"; 48 | } else { 49 | return "False"; 50 | } 51 | } 52 | case WITHDRAW_MONEY : { 53 | if (this.clientList.get(processString.getName()) != null) { 54 | this.clientList.get(processString.getName()).withdrawMoney(processString.getMoney()); 55 | return "True"; 56 | } else { 57 | return "False"; 58 | } 59 | } 60 | default: 61 | return "Invalid"; 62 | } 63 | } 64 | } 65 | 66 | class Client { 67 | private String name; 68 | private Double amount; 69 | 70 | public Client() { 71 | } 72 | 73 | public Client(String name, Double amount) { 74 | this.name = name; 75 | this.amount = amount; 76 | } 77 | 78 | public String getName() { 79 | return name; 80 | } 81 | 82 | public void setName(String name) { 83 | this.name = name; 84 | } 85 | 86 | public Double getAmount() { 87 | return amount; 88 | } 89 | 90 | public void setAmount(Double amount) { 91 | this.amount = amount; 92 | } 93 | 94 | public boolean depositMoney(Double money) { 95 | if (money > 0) { 96 | this.amount += money; 97 | return true; 98 | } 99 | return false; 100 | } 101 | 102 | public boolean withdrawMoney(Double money) { 103 | if (money > 0 && this.amount >= money) { 104 | this.amount -= money; 105 | return true; 106 | } 107 | return false; 108 | } 109 | } 110 | 111 | class ProcessStringRequest { 112 | private String defineRequest; 113 | private String name; 114 | private double money; 115 | 116 | public ProcessStringRequest(String defineRequest, String name, double amount) { 117 | this.defineRequest = defineRequest; 118 | this.name = name; 119 | this.money = amount; 120 | } 121 | 122 | public ProcessStringRequest(String string) { 123 | String[] value = string.split(" "); 124 | this.defineRequest = value[0]; 125 | this.name = value[1]; 126 | this.money = Double.valueOf(value[2]); 127 | } 128 | 129 | public String getDefineRequest() { 130 | return defineRequest; 131 | } 132 | 133 | public void setDefineRequest(String defineRequest) { 134 | this.defineRequest = defineRequest; 135 | } 136 | 137 | public String getName() { 138 | return name; 139 | } 140 | 141 | public void setName(String name) { 142 | this.name = name; 143 | } 144 | 145 | public double getMoney() { 146 | return money; 147 | } 148 | 149 | public void setMoney(double amount) { 150 | this.money = amount; 151 | } 152 | } -------------------------------------------------------------------------------- /week0004/README.md: -------------------------------------------------------------------------------- 1 | # Week 0004 2 | 3 | This week you will be doing a basic sample interview question for an event management company. Aim to write efficient and reusable code. 4 | 5 | ## Event Guests 6 | 7 | Now you are in event management business. You have 2 events taking place on the same day, at the same time. You noticed some guests registered for both events and want to notify them so they can pick either of the events. 8 | 9 | 1. Input 10 | 11 | ``` 12 | fname,lname,email 13 | Bob,Dylan,bob.dylan@abc.com 14 | Bill,Gates,bill@xyz.com 15 | ... 16 | ``` 17 | 18 | * There is 1 CSV file for each event 19 | * All CSV files contain valid data 20 | * Names and emails do not contain comma `,` 21 | * Names and emails are case-insensitive 22 | * Some highly esteemed guests have interesting names: O'Reilly, da Gama, van Derks, ... 23 | * All foreign names are transliterated to English. Don't worry about Vietnamese, Chinese or Russian ;) 24 | * One guest can have only one email 25 | 26 | 2. Output 27 | 28 | ``` 29 | Bill Gates 30 | Bob Dylan 31 | ... 32 | ``` 33 | 34 | * Print to STDOUT 35 | * Print the guests who registered for both events in the format above 36 | * Note that there are no more `,` in the output and emails are wrapped in `<>` 37 | * Sort the guests by first name and then by the last name, and then by email 38 | 39 | ## Submission 40 | 41 | ### Acceptance condition 42 | 43 | * The program must take files via `argv` (the order does not matter): 44 | 45 | ``` 46 | ./week0004.py event1.input event2.input 47 | ./week0004.py event2.input event1.input 48 | ``` 49 | 50 | * Make sure to test against the provided test case `event1.input`, `event2.input` and the output `guests.output` before submitting 51 | 52 | Sample commands to test: 53 | 54 | ``` 55 | diff <(python week0004.py event1.input event2.input) guests.output 56 | 57 | diff <(php week0004.php event1.input event2.input) guests.output 58 | 59 | diff <(./week0004.exe event1.input event2.input) guests.output 60 | 61 | diff <(java week0004 event1.input event2.input) guests.output 62 | 63 | diff <(./week0004.sh event1.input event2.input) guests.output 64 | ``` 65 | 66 | ### Folder structure 67 | 68 | Please structure your code like this: 69 | 70 | * Have your own folder named after your GitHub ID 71 | * Each language has own folder 72 | * Keep the files named week0004/week0004. 73 | 74 | ``` 75 | week0004/ 76 | |--YourGitHubID/ 77 | |--cpp/ 78 | |--week0004.cpp 79 | |--php/ 80 | |--week0004.php 81 | |--python/ 82 | |--week0004.py 83 | |--ruby/ 84 | |--week0004.rb 85 | ``` 86 | 87 | ### To PHP fans 88 | 89 | * If you want your submission accepted, please do not use `
` and `echo` 90 | * You must use `php://stdin` & `php://stdout`! 91 | * For your reading pleasure: http://php.net/manual/en/features.commandline.io-streams.php 92 | 93 | ### Languages 94 | 95 | Submit your code in any of the following languages: 96 | 97 | * C 98 | * C# 99 | * C++ 100 | * Go 101 | * Java 102 | * Javascript (browser/Node.JS) 103 | * Objective-C 104 | * OCaml 105 | * Perl 106 | * PHP 107 | * Python 108 | * Ruby 109 | * Swift 110 | * Unix shells & tools: sh/ksh/bash/zsh, awk, sed, uniq, ... 111 | 112 | You can submit by creating a pull request. 113 | 114 | Please direct your ideas, suggestions, collaboration requests to: viet@code2.pro 115 | -------------------------------------------------------------------------------- /week0004/event1.input: -------------------------------------------------------------------------------- 1 | fname,lname,email 2 | Bill,Gates,bill@xyz.com 3 | Alice,Wondergirl,alice@wonderland.net 4 | Julius,Caesar,caesar@rome.com 5 | Bob,Dylan,bob.dylan@abc.com 6 | -------------------------------------------------------------------------------- /week0004/event2.input: -------------------------------------------------------------------------------- 1 | fname,lname,email 2 | Mike,Tyson,boxer@legend.com 3 | Bob,Dylan,bob.dylan@abc.com 4 | Neo,Anderson,neo@thematrix.net 5 | Bill,Gates,bill@xyz.com 6 | -------------------------------------------------------------------------------- /week0004/guests.output: -------------------------------------------------------------------------------- 1 | Bill Gates 2 | Bob Dylan 3 | -------------------------------------------------------------------------------- /week0004/hoangdangduy/java/Client.java: -------------------------------------------------------------------------------- 1 | public class Client { 2 | private String fname; 3 | private String lname; 4 | private String email; 5 | 6 | public String getFname() { 7 | return fname; 8 | } 9 | 10 | public void setFname(String fname) { 11 | this.fname = fname; 12 | } 13 | 14 | public String getLname() { 15 | return lname; 16 | } 17 | 18 | public void setLname(String lname) { 19 | this.lname = lname; 20 | } 21 | 22 | public String getEmail() { 23 | return email; 24 | } 25 | 26 | public void setEmail(String email) { 27 | this.email = email; 28 | } 29 | 30 | public Client(String fname, String lname, String email) { 31 | super(); 32 | this.fname = fname; 33 | this.lname = lname; 34 | this.email = email; 35 | } 36 | 37 | public Client() { 38 | super(); 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return fname + " " + lname + " <" + email +">"; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /week0004/hoangdangduy/java/ProcessData.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.IOException; 3 | import java.nio.charset.Charset; 4 | import java.nio.file.Files; 5 | import java.nio.file.Path; 6 | import java.nio.file.Paths; 7 | import java.util.ArrayList; 8 | 9 | public class ProcessData { 10 | public Client convertDataToEntityClient(String data) { 11 | String[] inforClient = data.split(","); 12 | StringBuilder fname = new StringBuilder(inforClient[0].toLowerCase()); 13 | StringBuilder lname = new StringBuilder(inforClient[1].toLowerCase()); 14 | StringBuilder email = new StringBuilder(inforClient[2].toLowerCase()); 15 | 16 | fname.setCharAt(0, Character.toUpperCase(fname.charAt(0))); 17 | lname.setCharAt(0, Character.toUpperCase(lname.charAt(0))); 18 | if (email.toString().contains("@")) { 19 | Client client = new Client(); 20 | client.setFname(fname.toString()); 21 | client.setLname(lname.toString()); 22 | client.setEmail(email.toString()); 23 | return client; 24 | } 25 | return null; 26 | } 27 | 28 | public ArrayList readDataFromFile(String nameFileInput) { 29 | ArrayList listClient = new ArrayList<>(); 30 | Client client = new Client(); 31 | 32 | Path currentRelativePath = Paths.get(""); 33 | String folderPath = currentRelativePath.toAbsolutePath().toString(); 34 | Path path = Paths.get(folderPath, nameFileInput); 35 | Charset charset = Charset.forName("UTF-8"); 36 | String strLine; 37 | 38 | try (BufferedReader reader = Files.newBufferedReader(path, charset)) { 39 | while ((strLine = reader.readLine()) != null) { 40 | client = convertDataToEntityClient(strLine); 41 | if (client != null) { 42 | listClient.add(client); 43 | } 44 | } 45 | return listClient; 46 | } catch (IOException e) { 47 | e.printStackTrace(); 48 | } 49 | return null; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /week0004/hoangdangduy/java/SortUtil.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Collections; 3 | import java.util.Comparator; 4 | 5 | public class SortUtil { 6 | 7 | public ArrayList sort(ArrayList listClient) { 8 | Collections.sort(listClient, new Comparator() { 9 | 10 | @Override 11 | public int compare(Client client1, Client client2) { 12 | if (client1.getFname().compareTo(client2.getFname()) == 0 && client1.getLname().compareTo(client2.getLname()) == 0) { 13 | return client1.getEmail().compareTo(client2.getEmail()); 14 | } else if (client1.getFname().compareTo(client2.getFname()) == 0) { 15 | return client1.getLname().compareTo(client2.getLname()); 16 | } 17 | return client1.getFname().compareTo(client2.getFname()); 18 | } 19 | }); 20 | return listClient; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /week0004/hoangdangduy/java/Week0004.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.HashMap; 3 | import java.util.Map; 4 | 5 | public class Week0004 { 6 | public static void main(String[] args) { 7 | Week0004 week0004 = new Week0004(); 8 | week0004.action(args); 9 | } 10 | 11 | public void action(String ... nameFile) { 12 | SortUtil sortUtil = new SortUtil(); 13 | ProcessData processData = new ProcessData(); 14 | ArrayList listClientTemporary = new ArrayList<>(); 15 | ArrayList listClient = new ArrayList<>(); 16 | Map hashmapClient2Event = new HashMap<>(); 17 | 18 | for (int i = 0; i < nameFile.length; i++) { 19 | listClientTemporary = processData.readDataFromFile(nameFile[i]); 20 | if (listClientTemporary != null && !listClientTemporary.isEmpty()) { 21 | for (int j = 0; j < listClientTemporary.size(); j++) { 22 | if (hashmapClient2Event.containsKey(listClientTemporary.get(j).getEmail()) && hashmapClient2Event.get(listClientTemporary.get(j).getEmail()) == 1 ) { 23 | listClient.add(listClientTemporary.get(j)); 24 | int total = hashmapClient2Event.get(listClientTemporary.get(j).getEmail()); 25 | hashmapClient2Event.put(listClientTemporary.get(j).getEmail(), total++); 26 | } else if (!hashmapClient2Event.containsKey(listClientTemporary.get(j).getEmail())) { 27 | hashmapClient2Event.put(listClientTemporary.get(j).getEmail(), 1); 28 | } 29 | } 30 | } 31 | } 32 | 33 | listClient = sortUtil.sort(listClient); 34 | 35 | for (int i = 0; i < listClient.size(); i++) { 36 | System.out.println(listClient.get(i).toString()); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /week0004/nhantd/python/week0004.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | class Guest(): 5 | 6 | def __init__(self, firstName, lastName, email): 7 | self.firstName = firstName 8 | self.lastName = lastName 9 | self.email = email 10 | self.eventFiles = dict() 11 | 12 | def __str__(self): 13 | return '{firstName} {lastName} <{email}>'.format( 14 | firstName=self.firstName, lastName=self.lastName, email=self.email) 15 | 16 | def getKey(self): 17 | return self.email 18 | 19 | 20 | class EventManagement(): 21 | 22 | def __init__(self): 23 | self.guests = dict() 24 | 25 | def isValidGuest(self, newGuest): 26 | newGuestKey = newGuest.getKey() 27 | if newGuestKey in self.guests: 28 | if newGuest.firstName != self.guests[newGuestKey].firstName \ 29 | or newGuest.lastName != self.guests[newGuestKey].lastName: 30 | raise Exception( 31 | 'IO Error', 'Duplicated users with the same email') 32 | return False 33 | return True 34 | 35 | def addGuest(self, newGuest): 36 | newGuestKey = newGuest.getKey() 37 | if newGuestKey in self.guests: 38 | self.guests[newGuestKey].eventFiles.update( 39 | newGuest.eventFiles) 40 | else: 41 | self.guests[newGuestKey] = newGuest 42 | 43 | def readFile(self, fileName): 44 | try: 45 | f = open(fileName) 46 | f.readline() 47 | content = f.readlines() 48 | for line in content: 49 | firstName, lastName, email = line.strip().split(',') 50 | newGuest = Guest(firstName, lastName, email) 51 | newGuest.eventFiles[fileName] = True 52 | if self.isValidGuest(newGuest): 53 | self.addGuest(newGuest) 54 | except IOError: 55 | raise Exception('IO Error', 'Error reading file') 56 | 57 | def findCommonGuests(self, firstFile, secondFile): 58 | 59 | self.readFile(firstFile) 60 | self.readFile(secondFile) 61 | commonGuests = [] 62 | for key in self.guests.keys(): 63 | if firstFile in self.guests[key].eventFiles and secondFile in self.guests[key].eventFiles: 64 | commonGuests.append(self.guests[key]) 65 | return sorted(commonGuests) 66 | 67 | if __name__ == "__main__": 68 | eventManager = EventManagement() 69 | commonGuests = eventManager.findCommonGuests(sys.argv[1], sys.argv[2]) 70 | for guest in commonGuests: 71 | print guest 72 | -------------------------------------------------------------------------------- /week0004/pertsodian/java/src/event/management/domain/Guest.java: -------------------------------------------------------------------------------- 1 | package event.management.domain; 2 | 3 | public class Guest implements Comparable { 4 | 5 | private String firstName; 6 | private String lastName; 7 | private String emailAddress; 8 | 9 | public Guest(String firstName, String lastName, String emailAddress) { 10 | this.firstName = firstName; 11 | this.lastName = lastName; 12 | this.emailAddress = emailAddress; 13 | } 14 | 15 | public String getFirstName() { 16 | return firstName; 17 | } 18 | 19 | public String getLastName() { 20 | return lastName; 21 | } 22 | 23 | public String getEmailAddress() { 24 | return emailAddress; 25 | } 26 | 27 | @Override 28 | public int hashCode() { 29 | final int prime = 31; 30 | int result = 1; 31 | result = prime * result + 32 | ((emailAddress == null) ? 0 : emailAddress.hashCode()); 33 | result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); 34 | result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); 35 | return result; 36 | } 37 | 38 | @Override 39 | public boolean equals(Object obj) { 40 | if (this == obj) 41 | return true; 42 | if (obj == null) 43 | return false; 44 | if (getClass() != obj.getClass()) 45 | return false; 46 | Guest other = (Guest) obj; 47 | if (emailAddress == null) { 48 | if (other.emailAddress != null) 49 | return false; 50 | } else if (!emailAddress.equals(other.emailAddress)) 51 | return false; 52 | if (firstName == null) { 53 | if (other.firstName != null) 54 | return false; 55 | } else if (!firstName.equals(other.firstName)) 56 | return false; 57 | if (lastName == null) { 58 | if (other.lastName != null) 59 | return false; 60 | } else if (!lastName.equals(other.lastName)) 61 | return false; 62 | return true; 63 | } 64 | 65 | @Override 66 | public int compareTo(Guest another) { 67 | if (this.firstName.equals(another.firstName)) { 68 | if (this.lastName.equals(another.lastName)) 69 | return this.emailAddress.compareTo(another.emailAddress); 70 | return this.lastName.compareTo(another.lastName); 71 | } 72 | return this.firstName.compareTo(another.firstName); 73 | } 74 | 75 | @Override 76 | public String toString() { 77 | return String.format("%s %s <%s>", firstName, lastName, emailAddress); 78 | } 79 | } -------------------------------------------------------------------------------- /week0004/pertsodian/java/src/event/management/processors/RegistrationExtractor.java: -------------------------------------------------------------------------------- 1 | package event.management.processors; 2 | 3 | import java.io.IOException; 4 | import java.nio.file.Files; 5 | import java.nio.file.Paths; 6 | import java.util.List; 7 | import java.util.stream.Collectors; 8 | import java.util.stream.Stream; 9 | 10 | import event.management.domain.Guest; 11 | 12 | public class RegistrationExtractor { 13 | 14 | private static final String REGISTRATION_ENTRY_DELIMETER = ","; 15 | private static final int HEADER_LINES = 1; 16 | 17 | public List extractGuestsFromFile(String registrationFileName) throws Exception { 18 | try (Stream stream = Files.lines(Paths.get(registrationFileName))) { 19 | return extractGuests(stream.skip(HEADER_LINES)); 20 | } catch (IOException e) { 21 | throw new Exception( 22 | String.format("Error while processing file [%s]", registrationFileName), e); 23 | } 24 | } 25 | 26 | private List extractGuests(Stream registrationStream) { 27 | return registrationStream.map(this::parseRegistrationEntry) 28 | .collect(Collectors.toList()); 29 | } 30 | 31 | private Guest parseRegistrationEntry(String registrationEntry) { 32 | if (registrationEntry == null || registrationEntry.isEmpty()) 33 | throw new IllegalArgumentException("Guest input is null or empty"); 34 | 35 | String[] inputs = registrationEntry.split(REGISTRATION_ENTRY_DELIMETER); 36 | if (inputs.length != 3) 37 | throw new IllegalArgumentException("Invalid registration entry"); 38 | 39 | return new Guest(inputs[0], inputs[1], inputs[2]); 40 | } 41 | } -------------------------------------------------------------------------------- /week0004/pertsodian/java/src/week0004.java: -------------------------------------------------------------------------------- 1 | import java.util.ArrayList; 2 | import java.util.Collections; 3 | import java.util.List; 4 | 5 | import event.management.domain.Guest; 6 | import event.management.processors.RegistrationExtractor; 7 | 8 | public class week0004 { 9 | 10 | public static void main(String[] inputArguments) { 11 | if (inputArguments.length != 2) { 12 | System.out.println("Require 2 events to find their duplicate guests"); 13 | return; 14 | } 15 | 16 | RegistrationExtractor extractor = new RegistrationExtractor(); 17 | 18 | List firstEventGuests, secondEventGuests; 19 | try { 20 | firstEventGuests = extractor.extractGuestsFromFile(inputArguments[0]); 21 | secondEventGuests = extractor.extractGuestsFromFile(inputArguments[1]); 22 | } 23 | catch (Exception e) { 24 | System.err.println(e.getMessage()); 25 | return; 26 | } 27 | 28 | List duplicatedGuests = new ArrayList<>(firstEventGuests); 29 | duplicatedGuests.retainAll(secondEventGuests); 30 | 31 | Collections.sort(duplicatedGuests); 32 | duplicatedGuests.forEach(System.out::println); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /week0004/thainguyentran/CSharp/week0004.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace DVRK 6 | { 7 | class Program 8 | { 9 | static void Main(string[] args) 10 | { 11 | string[] event1 = File.ReadAllLines(args[0]); 12 | string[] event2 = File.ReadAllLines(args[1]); 13 | 14 | EventHandling eventHandling = new EventHandling(); 15 | eventHandling.showDoubleRegisterGuest(event1, event2); 16 | } 17 | } 18 | class EventHandling 19 | { 20 | Dictionary guestList = new Dictionary(StringComparer.OrdinalIgnoreCase); 21 | 22 | public void showDoubleRegisterGuest(string[] guestOfEvent1, string[] guestOfEvent2) 23 | { 24 | string fName, lName, email; 25 | 26 | for(int i = 1; i < guestOfEvent1.Length; i++) 27 | { 28 | for(int j = 1; j < guestOfEvent2.Length; j++) 29 | { 30 | if (guestOfEvent1[i] == guestOfEvent2[j]) 31 | { 32 | string[] guestInfo = guestOfEvent1[i].Split(','); 33 | fName = guestInfo[0]; 34 | lName = guestInfo[1]; 35 | email = guestInfo[2]; 36 | guestList.Add(string.Concat(fName, " ", lName), email); 37 | } 38 | } 39 | } 40 | 41 | foreach (KeyValuePair info in guestList) 42 | { 43 | Console.WriteLine("{0} <{1}>", info.Key, info.Value); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /week0004/truongngodang/java/Week0004.java: -------------------------------------------------------------------------------- 1 | import java.io.BufferedReader; 2 | import java.io.File; 3 | import java.io.FileReader; 4 | import java.io.IOException; 5 | import java.util.ArrayList; 6 | import java.util.Objects; 7 | 8 | public class Week0004 { 9 | 10 | public static void main(String[] args) { 11 | if (args.length == 2) { 12 | ArrayList guestsEvent1 = ReaderCVS.read(args[0]); 13 | ArrayList guestsEvent2 = ReaderCVS.read(args[1]); 14 | Response response = new Response(); 15 | Checker checker = new Checker(); 16 | checker.check(guestsEvent1, guestsEvent2); 17 | System.out.println(response.standardPrint(checker.getGuestErrors())); 18 | } 19 | } 20 | } 21 | 22 | class Guest { 23 | private String fname; 24 | private String lname; 25 | private String email; 26 | 27 | public Guest(String fname, String lname, String email) { 28 | this.fname = fname; 29 | this.lname = lname; 30 | this.email = email; 31 | } 32 | 33 | public Guest() { 34 | } 35 | 36 | public String getFname() { 37 | return fname; 38 | } 39 | 40 | public void setFname(String fname) { 41 | this.fname = fname; 42 | } 43 | 44 | public String getLname() { 45 | return lname; 46 | } 47 | 48 | public void setLname(String lname) { 49 | this.lname = lname; 50 | } 51 | 52 | public String getEmail() { 53 | return email; 54 | } 55 | 56 | public void setEmail(String email) { 57 | this.email = email; 58 | } 59 | } 60 | 61 | class ReaderCVS { 62 | 63 | public static ArrayList read(String csvFilename) { 64 | String line = ""; 65 | String cvsSplitBy = ","; 66 | ArrayList guests = new ArrayList(); 67 | try { 68 | BufferedReader br = new BufferedReader(new FileReader(new File(csvFilename))); 69 | for (int i = 0; (line = br.readLine()) != null; i++) { 70 | if (i > 0) { 71 | String[] infos = line.split(cvsSplitBy); 72 | guests.add(new Guest(infos[0], infos[1], infos[2])); 73 | } 74 | } 75 | } catch (IOException e) { 76 | e.printStackTrace(); 77 | } 78 | return guests; 79 | } 80 | } 81 | 82 | class Checker { 83 | private ArrayList guestErrors = new ArrayList(); 84 | 85 | public ArrayList getGuestErrors() { 86 | return guestErrors; 87 | } 88 | 89 | public void check(ArrayList guestEvent1, ArrayList guestEvent2) { 90 | boolean temp = guestEvent1.size() > guestEvent2.size(); 91 | if (temp) { 92 | for (int i = 0; i < guestEvent2.size(); i++) { 93 | for (int j = 0; j < guestEvent1.size(); j++) { 94 | if (Objects.equals(guestEvent2.get(i).getEmail(), guestEvent1.get(j).getEmail())) { 95 | this.guestErrors.add(guestEvent2.get(i)); 96 | } 97 | } 98 | } 99 | } else { 100 | for (int i = 0; i < guestEvent1.size(); i++) { 101 | for (int j = 0; j < guestEvent2.size(); j++) { 102 | if (Objects.equals(guestEvent1.get(i).getEmail(), guestEvent2.get(j).getEmail())) { 103 | this.guestErrors.add(guestEvent1.get(i)); 104 | } 105 | } 106 | } 107 | } 108 | } 109 | } 110 | 111 | class Response { 112 | private String result; 113 | 114 | public String getResult() { 115 | return result; 116 | } 117 | 118 | public String standardPrint(ArrayList guestErrors) { 119 | StringBuilder sb = new StringBuilder(); 120 | for (int i = 0; i < guestErrors.size(); i++) { 121 | sb.append(guestErrors.get(i).getFname()).append(" "); 122 | sb.append(guestErrors.get(i).getLname()).append(" "); 123 | sb.append("<").append(guestErrors.get(i).getEmail()).append(">"); 124 | if (i != guestErrors.size() - 1) { 125 | sb.append("\n"); 126 | } 127 | } 128 | this.result = String.valueOf(sb); 129 | return String.valueOf(sb); 130 | } 131 | } -------------------------------------------------------------------------------- /why-you-should-write-readable-code.md: -------------------------------------------------------------------------------- 1 | # Sống bằng nghề viết trong thế kỷ XXI: Code 2 | 3 | Nếu ai đó tự giới thiệu sống bằng nghề viết thì chắc hẳn mọi nguời sẽ nghĩ anh chàng hay cô nàng ấy là nhà văn hay nhà báo. Nhưng ngày nay người đó lại là kỹ sư phần mềm. Việc viết code trở thành nghề giao tiếp với máy tính và thông ngôn giữa người sử dụng, khách hàng, product manager và với hệ thống máy tính. 4 | 5 | Nghĩ được như vậy đã hay, nhưng chưa đủ. Kỹ sư phần mềm không còn một mình một chiếu mà làm theo nhóm và bạn phải viết code sao cho người khác cũng hiểu chứ không chỉ cái máy tính đọc đuợc. Sau đây là những hệ luỵ nếu bạn không thể viết code sao cho người khác hiểu: 6 | 7 | 1. Bạn không thể làm việc theo nhóm. Viết code tệ cũng như người hôi hám vậy, chả ai muốn ở gần 8 | 9 | 2. Bạn không thể chuyển giao code cho người khác một cách suôn sẻ và phải ôm nó cho đến khi bỏ việc 10 | 11 | 3. Bạn không thể dạy đệ tử và junior vì không ai hiểu những dòng code vi diệu của bạn 12 | 13 | 4. Bạn không thể nổi tiếng vì chả ai thèm đọc code của bạn vì quá khó hiểu và khó refactor 14 | 15 | ## Vậy làm sao để người khác hiểu code của bạn? 16 | 17 | Sau đây là những điều nên làm, chia theo các cấp độ từ lính trơn khi bạn mới học code cho đến khi thành senior: 18 | 19 | 1. Có code style nhất quán. Mỗi công ty hay team đều có code style cho mỗi ngôn ngữ. Miễn bạn chọn một style nhất quán và scalable 20 | 21 | 2. Tên biến, lớp, hàm rõ ràng và ngắn gọn 22 | 23 | 3. Dùng các quy ước phổ thông trong toán, lý, hoá hay các domain (lĩnh vực) liên quan khi viết tên biến, lớp, hàm 24 | 25 | 4. Với thuật toán hay hàm phức tạp thì nên có comment trong code giải thích và minh hoạ bằng biểu đồ hoặc Markdown kèm theo 26 | 27 | 5. Nên chia lớp, hàm theo nguyên tắc S-O-LI-D (đặc biệt hữu ích với OOP): 28 | 5.1. The Single Responsibility Principle: https://code.tutsplus.com/tutorials/solid-part-1-the-single-responsibility-principle--net-36074 29 | 5.2. The Open/Closed Principle: https://code.tutsplus.com/tutorials/solid-part-2-the-openclosed-principle--net-36600 30 | 5.3. Liskov Substitution & Interface Segregation Principles: https://code.tutsplus.com/tutorials/solid-part-3-liskov-substitution-interface-segregation-principles--net-36710 31 | 5.4. The Dependency Inversion Principle: https://code.tutsplus.com/tutorials/solid-part-4-the-dependency-inversion-principle--net-36872 32 | 33 | 6. Sử dụng các Design Patterns. Khi đã nắm vững SOLID thì các bạn có thể chuyển sang để làm các project tầm cỡ. Không thể nào trở thành senior nếu bạn không nắm được Design Patterns. Các bạn nên đọc Design Patterns của Gang of Four: https://www.amazon.co.uk/Design-patterns-elements-reusable-object-oriented/dp/0201633612 34 | 35 | Quan niệm của tôi là Code is **Compassion & Code is Communication**. Theo tôi chúng ta viết code vì chúng ta muốn giúp đỡ, muốn giải quyết vấn đề của bản thân, gia đình, khách hàng & thế giới, vì vậy: **Code is Compassion**. Chúng ta viết code vì chúng ta giao tiếp với các kỹ sư phần mềm nhiều thế hệ khác nhau và có nhiều trải nghiệm khác nhau. Khi đọc code, chúng ta có thể truyền tải và hiểu những ý tưởng để học hỏi lẫn nhau, vì vậy: **Code is Communication**. 36 | 37 | Chắc hẳn các bạn đã học code ở Việt Nam, ở Singapore, ở Vương quốc Anh, ở Mỹ, Coursera, edX và vô số các trang online khác. Nhưng có một điểm thiếu sót chung của các trường và các hệ thống đó là: **Không có code review**. Khi bạn học tiếng Việt, tiếng Anh thì đều có thầy cô giáo chấm bài và sửa lỗi cho bạn. Đến khi bạn học và tập tành làm kỹ sư thì không có ai sửa lỗi cho bạn từ khi còn thơ. Ở Code2Pro và trong chương trình đặc biệt Dev Việt Ra Khơi chúng tôi có phương châm: Code is Compassion & Code is Communication. Code2Pro và Dev Việt Ra Khơi là nơi duy nhất các bạn có thể học code và được làm code review để rèn luyện kỹ năng hoàn thiện để trở thành kỹ sư phần mềm có tầm quốc tế. 38 | 39 | Để được cập nhật thông tin, mời các bạn theo dõi page: https://www.facebook.com/Code2Pro/ 40 | 41 | Bạn nào muốn code thử vào biết mình viết có chuyên nghiệp không, có thể tham gia: https://www.facebook.com/groups/DevVietRaKhoi/ 42 | 43 | Những bạn nào nung nấu vươn ra khỏi Việt Nam có thể đăng ký xem video & slides của sự kiện Dev Việt Ra Khơi: http://www.code2.pro/p/dev-viet-ra-khoi-uk-singapore 44 | 45 | Các bạn chia sẻ đến với nhiều bạn sinh viên và các kỹ sư phần mềm Việt Nam để mọi người cùng học hỏi và vươn ra thế giới nhé! 46 | --------------------------------------------------------------------------------