├── scrabble ├── scrabble └── scrabble.rs ├── 17-scores ├── cpp │ ├── median.h │ ├── grade.h │ ├── StudentInfo.h │ ├── median.cpp │ ├── grade.cpp │ ├── StudentInfo.cpp │ └── main.cpp ├── scores │ ├── Cargo.toml │ └── src │ │ ├── average.rs │ │ ├── Student.rs │ │ └── main.rs └── py │ └── scores.py ├── 19-primes ├── cpp │ ├── sieve.h │ ├── sieve.cpp │ └── primes.cpp ├── primes │ ├── Cargo.toml │ └── src │ │ └── main.rs └── py │ └── primes.py ├── 18-encryption ├── cpp │ ├── rot13.h │ ├── main.cpp │ ├── rot13.cpp │ └── secret.txt ├── encrypt │ ├── Cargo.toml │ ├── src │ │ ├── main.rs │ │ └── rot13.rs │ └── secret.txt └── py │ ├── __pycache__ │ └── rot13.cpython-35.pyc │ ├── main.py │ ├── rot13.py │ └── secret.txt ├── 21-html ├── cpp │ ├── html.h │ ├── util.h │ ├── util.cpp │ ├── html.cpp │ └── main.cpp ├── html │ ├── util │ │ ├── Cargo.toml │ │ └── src │ │ │ └── lib.rs │ ├── Cargo.toml │ └── src │ │ ├── main.rs │ │ └── html.rs ├── reddit.html └── deas.html ├── 10-root ├── root │ ├── Cargo.toml │ └── src │ │ └── main.rs └── root.cpp ├── 14-calc ├── calc │ ├── Cargo.toml │ └── src │ │ ├── calc.rs │ │ └── main.rs └── calc.cpp ├── 8-fibonacci ├── fib │ ├── Cargo.toml │ └── src │ │ └── main.rs └── fibonacci.cpp ├── 11-combo ├── combo │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── perms.py └── combo.cpp ├── 12-circle ├── circle │ ├── Cargo.toml │ └── src │ │ └── main.rs └── circle.cpp ├── 22-matrix ├── cpp │ ├── matrix.cpp │ ├── main.cpp │ └── matrix.h └── matrix │ ├── matrix │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── util │ ├── Cargo.toml │ └── src │ │ └── lib.rs │ ├── Cargo.toml │ └── src │ └── main.rs ├── 26-todo ├── todo │ ├── Cargo.toml │ └── src │ │ ├── store.rs │ │ ├── todo.rs │ │ └── main.rs └── todo-web │ ├── Cargo.toml │ └── src │ ├── template.rs │ ├── todo.rs │ ├── todos.tpl │ ├── store.rs │ └── main.rs ├── 9-vowels ├── vowel │ ├── Cargo.toml │ └── src │ │ └── main.rs └── count.cpp ├── 15-piggy-bank ├── piggy │ ├── Cargo.toml │ └── src │ │ └── main.rs └── piggy.cpp ├── 6-random-func ├── rand │ ├── Cargo.toml │ └── src │ │ └── main.rs └── random.cpp ├── 7-guessing-game ├── guess │ ├── Cargo.toml │ └── src │ │ └── main.rs └── guess.cpp ├── 20-quiz ├── quiz │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── cpp │ └── main.cpp └── quiz.json ├── 28-markov ├── histogram │ ├── Cargo.toml │ └── src │ │ ├── main.rs │ │ └── histogram.rs └── markov │ ├── Cargo.toml │ └── src │ └── main.rs ├── 29-noughts-and-crosses └── noughts-and-crosses │ ├── screenshot.png │ ├── Cargo.toml │ ├── readme.md │ └── src │ ├── ai.rs │ ├── store.rs │ ├── board.rs │ └── main.rs ├── 16-palindrome ├── palindrome │ ├── Cargo.toml │ └── src │ │ └── main.rs └── palindrome.cpp ├── 30-youtube └── youtube │ ├── Cargo.toml │ └── src │ └── main.rs ├── 4-bottomup-triangle ├── triangle.cpp └── triangle.rs ├── 5-odd-triangle ├── triangle.cpp └── triangle.rs ├── .gitignore ├── 3-topdown-triangle ├── triangle.cpp └── triangle.rs ├── 13-recursive-text ├── text.cpp └── text.rs ├── 1-factorial ├── factorial.rs └── factorial.cpp ├── LICENSE ├── 2-currency ├── currency.rs └── currency.cpp └── Readme.md /scrabble/scrabble: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whostolemyhat/learning-projects/HEAD/scrabble/scrabble -------------------------------------------------------------------------------- /17-scores/cpp/median.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | double median(std::vector); -------------------------------------------------------------------------------- /19-primes/cpp/sieve.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | std::vector createSieve(int limit); -------------------------------------------------------------------------------- /18-encryption/cpp/rot13.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | std::string rot13(std::string message); -------------------------------------------------------------------------------- /21-html/cpp/html.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | std::string strip_tags(std::string html); -------------------------------------------------------------------------------- /10-root/root/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "root" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /14-calc/calc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "calc" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /21-html/cpp/util.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | std::stringstream open_file(std::string filename); -------------------------------------------------------------------------------- /8-fibonacci/fib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fib" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /11-combo/combo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "combo" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /12-circle/circle/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "circle" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /17-scores/scores/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "scores" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /19-primes/primes/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "primes" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /22-matrix/cpp/matrix.cpp: -------------------------------------------------------------------------------- 1 | #include "matrix.h" 2 | 3 | template 4 | Matrix::Matrix(unsigned _rows, unsigned _cols, const T& _initial) { 5 | 6 | } -------------------------------------------------------------------------------- /26-todo/todo/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "todo" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /9-vowels/vowel/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "vowel" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /15-piggy-bank/piggy/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "piggy" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /18-encryption/encrypt/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "encrypt" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /18-encryption/py/__pycache__/rot13.cpython-35.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whostolemyhat/learning-projects/HEAD/18-encryption/py/__pycache__/rot13.cpython-35.pyc -------------------------------------------------------------------------------- /6-random-func/rand/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rand" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | rand = "0.3" -------------------------------------------------------------------------------- /7-guessing-game/guess/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "guess" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | rand = "0.3" -------------------------------------------------------------------------------- /20-quiz/quiz/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "quiz" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | rustc-serialize = "0.3" -------------------------------------------------------------------------------- /22-matrix/matrix/matrix/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "matrix" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | rand = "0.3" -------------------------------------------------------------------------------- /28-markov/histogram/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["James Tease "] 3 | name = "histogram" 4 | version = "0.1.0" 5 | [dependencies] 6 | regex = "0.2" 7 | -------------------------------------------------------------------------------- /29-noughts-and-crosses/noughts-and-crosses/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whostolemyhat/learning-projects/HEAD/29-noughts-and-crosses/noughts-and-crosses/screenshot.png -------------------------------------------------------------------------------- /16-palindrome/palindrome/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "palindrome" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | regex = "0.1" -------------------------------------------------------------------------------- /21-html/html/util/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "util" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [lib] 7 | name = "util" 8 | path="src/lib.rs" -------------------------------------------------------------------------------- /22-matrix/matrix/util/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "util" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [lib] 7 | name = "util" 8 | path="src/lib.rs" -------------------------------------------------------------------------------- /28-markov/markov/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["James Tease "] 3 | name = "markov" 4 | version = "0.1.0" 5 | [dependencies] 6 | regex = "0.2" 7 | rand="0.3" 8 | -------------------------------------------------------------------------------- /29-noughts-and-crosses/noughts-and-crosses/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "noughts-and-crosses" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | rand = "0.3" 8 | -------------------------------------------------------------------------------- /26-todo/todo-web/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["James Tease "] 3 | name = "todo" 4 | version = "0.1.0" 5 | [dependencies] 6 | handlebars = "*" 7 | nickel = "*" 8 | rustc-serialize = "*" 9 | -------------------------------------------------------------------------------- /21-html/cpp/util.cpp: -------------------------------------------------------------------------------- 1 | #include "util.h" 2 | 3 | std::stringstream open_file(std::string filename) { 4 | std::ifstream text(filename); 5 | std::stringstream buffer; 6 | buffer << text.rdbuf(); 7 | 8 | return buffer; 9 | } -------------------------------------------------------------------------------- /21-html/html/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "html" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | regex = "0.1" 8 | 9 | [dependencies.util] 10 | path = "util" -------------------------------------------------------------------------------- /17-scores/cpp/grade.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "StudentInfo.h" 5 | 6 | double grade(double, double, double); 7 | double grade(double, double, const std::vector&); 8 | double grade(const StudentInfo&); -------------------------------------------------------------------------------- /22-matrix/matrix/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "matrix_main" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies.matrix] 7 | path = "matrix" 8 | 9 | [dependencies.util] 10 | path = "util" -------------------------------------------------------------------------------- /22-matrix/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | class Matrix { 2 | private: 3 | int _rows; 4 | int _cols; 5 | int _intial; 6 | 7 | public: 8 | Matrix(int rows, int cols, int initial = 0) 9 | : _rows(rows), _cols(cols), _intial(intial) {} 10 | 11 | ~Matrix() {} 12 | } -------------------------------------------------------------------------------- /30-youtube/youtube/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "youtube" 3 | version = "0.1.0" 4 | authors = ["James Tease "] 5 | 6 | [dependencies] 7 | reqwest = "0.6.2" 8 | select = "0.4.1" 9 | regex = "0.2" 10 | serde_json = "1.0" 11 | url = "1.0" -------------------------------------------------------------------------------- /21-html/cpp/html.cpp: -------------------------------------------------------------------------------- 1 | #include "html.h" 2 | 3 | std::string strip_tags(std::string html) { 4 | std::regex tag("(]+>)"); 5 | std::regex new_lines("(\\n\\s+)"); 6 | std::string replaced = std::regex_replace(std::regex_replace(html, tag, ""), new_lines, "\n"); 7 | 8 | return replaced; 9 | } -------------------------------------------------------------------------------- /21-html/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "util.h" 3 | #include "html.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | if(argc == 1) { 7 | std::cerr << "Provide a file" << std::endl; 8 | return 1; 9 | } 10 | 11 | std::stringstream contents = open_file(argv[1]); 12 | 13 | std::cout << strip_tags(contents.str()) << std::endl; 14 | } -------------------------------------------------------------------------------- /4-bottomup-triangle/triangle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | std::cout << "Enter a number:"; 6 | 7 | int num; 8 | std::cin >> num; 9 | 10 | if(!std::cin) { 11 | std::cout << "That's no number!"; 12 | return 1; 13 | } 14 | 15 | for(int i = 1; i < num + 1; i++) { 16 | std::cout << std::string(i, '*') << std::endl; 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /5-odd-triangle/triangle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() { 5 | std::cout << "Enter a number: "; 6 | 7 | int num; 8 | std::cin >> num; 9 | 10 | if(!std::cin) { 11 | std::cout << "That's no number!"; 12 | return 1; 13 | } 14 | 15 | for(int i = 1; i < num + 1; i += 2) { 16 | std::cout << std::string(i, '*') << std::endl; 17 | } 18 | 19 | return 0; 20 | } -------------------------------------------------------------------------------- /10-root/root.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | float fifthRoot(float x) { 5 | return pow(x, 1.0/5.0); 6 | } 7 | 8 | int main() { 9 | int sum = 0; 10 | 11 | for(int i = 0; i < 100; i++) { 12 | if(i % 2 == 0) { 13 | sum += i * i; 14 | } 15 | } 16 | 17 | std::cout << "5th root of " << sum << " is: " 18 | << fifthRoot((float) sum) << std::endl; 19 | 20 | return 0; 21 | } -------------------------------------------------------------------------------- /17-scores/cpp/StudentInfo.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | struct StudentInfo { 8 | std::string name; 9 | double final; 10 | double midterm; 11 | std::vector homework; 12 | }; 13 | 14 | bool compare(const StudentInfo&, const StudentInfo&); 15 | std::istream& read(std::istream&, StudentInfo&); 16 | std::istream& read_homework(std::istream&, std::vector&); -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Cargo.lock 3 | 4 | # Prerequisites 5 | *.d 6 | 7 | # Compiled Object files 8 | *.slo 9 | *.lo 10 | *.o 11 | *.obj 12 | 13 | # Precompiled Headers 14 | *.gch 15 | *.pch 16 | 17 | # Compiled Dynamic libraries 18 | *.so 19 | *.dylib 20 | *.dll 21 | 22 | # Fortran module files 23 | *.mod 24 | *.smod 25 | 26 | # Compiled Static libraries 27 | *.lai 28 | *.la 29 | *.a 30 | *.lib 31 | 32 | # Executables 33 | *.exe 34 | *.out 35 | *.app -------------------------------------------------------------------------------- /3-topdown-triangle/triangle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::cout; 5 | using std::cin; 6 | using std::endl; 7 | using std::string; 8 | 9 | int main() { 10 | cout << "Enter a number:"; 11 | 12 | int num; 13 | cin >> num; 14 | 15 | if(!cin) { 16 | cout << "That's no number!"; 17 | return 1; 18 | } 19 | 20 | while (num > 0) { 21 | cout << string(num, '*') << endl; 22 | num--; 23 | } 24 | 25 | return 0; 26 | } -------------------------------------------------------------------------------- /19-primes/cpp/sieve.cpp: -------------------------------------------------------------------------------- 1 | #include "sieve.h" 2 | 3 | std::vector createSieve(int limit) { 4 | std::vector primes(limit + 1, true); 5 | 6 | primes[0] = false; 7 | primes[1] = false; 8 | 9 | int i = 0; 10 | for(auto item : primes) { 11 | if(item == true) { 12 | int step = i; 13 | int n = i * i; 14 | 15 | while(n <= limit ) { 16 | primes[n] = false; 17 | n += step; 18 | } 19 | } 20 | 21 | i++; 22 | } 23 | 24 | return primes; 25 | } -------------------------------------------------------------------------------- /21-html/html/util/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{ stdin, Read, Result }; 3 | 4 | pub fn open_file(filename: &String) -> Result { 5 | let mut content = String::new(); 6 | let mut file = try!(File::open(filename)); 7 | try!(file.read_to_string(&mut content)); 8 | 9 | Ok(content) 10 | } 11 | 12 | pub fn read_input() -> String { 13 | let mut input = String::new(); 14 | stdin() 15 | .read_line(&mut input) 16 | .expect("Enter text!"); 17 | 18 | input 19 | } 20 | -------------------------------------------------------------------------------- /13-recursive-text/text.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using std::string; 5 | 6 | string reverse(string output, string input, int n) { 7 | if(n == 0) { 8 | return output + input.at(0); 9 | } 10 | 11 | output += input.at(n); 12 | return reverse(output, input, n - 1); 13 | } 14 | 15 | int main() { 16 | std::cout << "Enter some text: "; 17 | 18 | string input; 19 | std::cin >> input; 20 | 21 | std::cout << reverse("", input, input.length() - 1) << std::endl; 22 | 23 | return 0; 24 | } -------------------------------------------------------------------------------- /1-factorial/factorial.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn factorial(num: u64) -> u64 { 4 | if num <= 1 { 5 | return 1; 6 | } 7 | 8 | num * factorial(num - 1) 9 | } 10 | 11 | fn main() { 12 | println!("Enter a number: "); 13 | 14 | let mut input_text = String::new(); 15 | io::stdin() 16 | .read_line(&mut input_text) 17 | .expect("Failed to read input"); 18 | 19 | // todo: better error handling 20 | let num = input_text.trim().parse::().expect("That's not a number"); 21 | 22 | println!("{}", factorial(num)); 23 | } 24 | -------------------------------------------------------------------------------- /21-html/html/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate regex; 2 | extern crate util; 3 | 4 | mod html; 5 | 6 | use std::env; 7 | use html::strip_tags; 8 | use util::open_file; 9 | 10 | fn main() { 11 | let args: Vec = env::args().collect(); 12 | 13 | if args.len() < 2 { 14 | println!("Enter a source file as argument"); 15 | return; 16 | } 17 | 18 | let text = match open_file(&args[1]) { 19 | Ok(content) => content, 20 | Err(e) => panic!("Error opening {}: {}", &args[1], e) 21 | }; 22 | 23 | println!("{}", strip_tags(text)); 24 | } -------------------------------------------------------------------------------- /17-scores/cpp/median.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "median.h" 5 | 6 | using std::domain_error; 7 | using std::sort; 8 | using std::vector; 9 | 10 | double median(vector vec) { 11 | typedef vector::size_type vec_size; 12 | 13 | vec_size size = vec.size(); 14 | 15 | if(size == 0) { 16 | throw domain_error("Median of empty vec"); 17 | } 18 | 19 | sort(vec.begin(), vec.end()); 20 | vec_size mid = size / 2; 21 | 22 | return size % 2 == 0 ? (vec[mid] + vec[mid - 1]) / 2 : vec[mid]; 23 | } -------------------------------------------------------------------------------- /4-bottomup-triangle/triangle.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn line(num: u64) -> String { 4 | let mut buf = String::with_capacity(num as usize); 5 | 6 | for _ in 0..num { 7 | buf.push('*'); 8 | } 9 | 10 | buf 11 | } 12 | 13 | fn main() { 14 | println!("Enter a number:"); 15 | 16 | let mut input_text = String::new(); 17 | io::stdin() 18 | .read_line(&mut input_text) 19 | .expect("Failed to read input"); 20 | 21 | let num = input_text.trim().parse::().expect("That's no number"); 22 | 23 | for i in 1..num + 1 { 24 | println!("{}", line(i)); 25 | } 26 | } -------------------------------------------------------------------------------- /6-random-func/rand/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | 3 | use rand::Rng; 4 | 5 | fn first() -> String { 6 | "I'm in the first function".to_string() 7 | } 8 | 9 | fn second() -> String { 10 | "I'm the second".to_string() 11 | } 12 | 13 | fn third() -> String { 14 | "Tertiary".to_string() 15 | } 16 | 17 | fn main() { 18 | let num = rand::thread_rng().gen_range(1, 3); 19 | 20 | match num { 21 | 1 => println!("{}", first()), 22 | 2 => println!("{}", second()), 23 | 3 => println!("{}", third()), 24 | _ => println!("I'm sure you won't see this") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /17-scores/scores/src/average.rs: -------------------------------------------------------------------------------- 1 | pub fn median(data: &Vec) -> f64 { 2 | // sort vec - in-place so clone data 3 | let mut sorted_data = data.clone(); 4 | sorted_data.sort(); 5 | // find middle 6 | let size = sorted_data.len(); 7 | 8 | if size == 0 { 9 | return 0.0; 10 | } 11 | 12 | let middle = size / 2; 13 | 14 | if size % 2 == 0 { 15 | (sorted_data.get(middle).unwrap() + sorted_data.get(middle - 1).unwrap()) as f64 / 2f64 16 | } else { 17 | // returns a point &i16 so deref to be able to cast 18 | *sorted_data.get(middle).unwrap() as f64 19 | } 20 | } -------------------------------------------------------------------------------- /22-matrix/matrix/util/src/lib.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::io::{ stdin, Read, Result }; 3 | 4 | pub fn open_file(filename: &String) -> Result { 5 | let mut content = String::new(); 6 | let mut file = try!(File::open(filename)); 7 | try!(file.read_to_string(&mut content)); 8 | 9 | Ok(content) 10 | } 11 | 12 | pub fn read_input() -> String { 13 | let mut input = String::new(); 14 | stdin() 15 | .read_line(&mut input) 16 | .expect("Enter text!"); 17 | 18 | input 19 | } 20 | 21 | pub fn read_number() -> i32 { 22 | read_input().trim().parse().ok().expect("Enter a number") 23 | } -------------------------------------------------------------------------------- /17-scores/cpp/grade.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "grade.h" 3 | #include "StudentInfo.h" 4 | #include "median.h" 5 | 6 | double grade(double midterm, double final, double homework) { 7 | return 0.2 * midterm + 8 | 0.4 * final + 9 | 0.4 * homework; 10 | } 11 | 12 | double grade(double midterm, double final, const std::vector& homework) { 13 | if(homework.size() == 0) { 14 | throw std::domain_error("No homework!"); 15 | } 16 | 17 | return grade(midterm, final, median(homework)); 18 | } 19 | 20 | double grade(const StudentInfo& s) { 21 | return grade(s.midterm, s.final, s.homework); 22 | } -------------------------------------------------------------------------------- /1-factorial/factorial.cpp: -------------------------------------------------------------------------------- 1 | // 1. Write a programme which finds the factorial of a number entered by the user 2 | // g++ -Wall name.cpp -o name 3 | #include 4 | 5 | using std::cout; 6 | using std::cin; 7 | using std::endl; 8 | 9 | int factorial(int num) { 10 | if (num <= 1) { 11 | return 1; 12 | } 13 | 14 | return num * factorial(num - 1); 15 | } 16 | 17 | int main() { 18 | cout << "Enter a number: "; 19 | 20 | int num; 21 | cin >> num; 22 | 23 | if(!cin) { 24 | cout << "That's not a number." << endl; 25 | 26 | return 1; 27 | } 28 | 29 | cout << factorial(num) << endl;; 30 | 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /22-matrix/cpp/matrix.h: -------------------------------------------------------------------------------- 1 | // https://www.quantstart.com/articles/Matrix-Classes-in-C-The-Header-File 2 | // http://code.activestate.com/recipes/578131-a-simple-matrix-class/ 3 | #pragma once 4 | #include 5 | 6 | template class Matrix { 7 | private: 8 | std::vector > mat; 9 | unsigned rows; 10 | unsigned cols; 11 | 12 | public: 13 | Matrix(unsigned _rows, unsigned _cols, const T& _initial); 14 | Matrix(const Matrix& rhs); 15 | virtual ~Matrix(); 16 | 17 | Matrix& operator=(const Matrix& rhs); 18 | 19 | unsigned get_rows() const; 20 | unsigned get_cols() const; 21 | } -------------------------------------------------------------------------------- /17-scores/cpp/StudentInfo.cpp: -------------------------------------------------------------------------------- 1 | #include "StudentInfo.h" 2 | 3 | using std::istream; 4 | using std::vector; 5 | 6 | bool compare(const StudentInfo& x, const StudentInfo& y) { 7 | return x.name < y.name; 8 | } 9 | 10 | istream& read(istream& in, StudentInfo& student) { 11 | in >> student.name >> student.midterm >> student.final; 12 | read_homework(in, student.homework); 13 | 14 | return in; 15 | } 16 | 17 | istream& read_homework(istream& in, vector& homework) { 18 | if(in) { 19 | homework.clear(); 20 | 21 | double x; 22 | while(in >> x) { 23 | homework.push_back(x); 24 | } 25 | 26 | in.clear(); 27 | } 28 | 29 | return in; 30 | } -------------------------------------------------------------------------------- /18-encryption/py/main.py: -------------------------------------------------------------------------------- 1 | """Converts a file using a rot13 algorithm""" 2 | 3 | import sys 4 | import rot13 5 | 6 | def main(): 7 | """Run the programme""" 8 | if len(sys.argv) < 2: 9 | print("Provide the name of a file to convert") 10 | sys.exit() 11 | 12 | filename = sys.argv[1] 13 | 14 | try: 15 | file = open(filename, "r+") 16 | text = file.read() 17 | file.seek(0) # go to start of file 18 | file.write(rot13.convert(text)) 19 | file.close() 20 | print("Converted {}".format(filename)) 21 | except IOError: 22 | print("Can't open file") 23 | 24 | if __name__ == '__main__': 25 | main() 26 | -------------------------------------------------------------------------------- /9-vowels/vowel/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn main() { 4 | println!("Enter some text:"); 5 | 6 | let mut input_text = String::new(); 7 | io::stdin() 8 | .read_line(&mut input_text) 9 | .expect("Failed to read input"); 10 | 11 | let vowels = vec!['a', 'e', 'i', 'o', 'u']; 12 | let mut vowel_count = 0; 13 | let mut consonant_count = 0; 14 | 15 | for c in input_text.chars() { 16 | if c.is_alphabetic() { 17 | if vowels.contains(&c) { 18 | vowel_count += 1; 19 | } else { 20 | consonant_count += 1; 21 | } 22 | } 23 | } 24 | 25 | println!("Vowel count: {}", vowel_count); 26 | println!("Consonant count: {}", consonant_count); 27 | } 28 | -------------------------------------------------------------------------------- /8-fibonacci/fibonacci.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // print out fibonacci sequence up til 4 | int main() { 5 | std::cout << "Enter target number: "; 6 | int target; 7 | std::cin >> target; 8 | 9 | if(!std::cin) { 10 | std::cout << "That's no number" << std::endl; 11 | } 12 | 13 | int first = 0; 14 | int second = 1; 15 | int output = 0; 16 | int i = 0; 17 | 18 | while(output < target) { 19 | if(i <= 1) { 20 | output = i; 21 | } else { 22 | output = first + second; 23 | 24 | first = second; 25 | second = output; 26 | } 27 | 28 | if(output < target) { 29 | std::cout << output << " "; 30 | } 31 | 32 | i++; 33 | } 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /10-root/root/src/main.rs: -------------------------------------------------------------------------------- 1 | // Find the Fifth root of the sum of the squares of the first 100 ODD numbers only 2 | 3 | // nth root: x^1/a 4 | // math.pow(25, 1/2) == sqrt(25) == 5 5 | // math.pow(27, 1/3) == cbrt(27) == 3 6 | fn fifth_root(x: f64) -> f64 { 7 | // cast 1/5 as f64 otherwise everything just resolves as 1 :( 8 | x.powf(1f64/5f64) 9 | } 10 | 11 | fn main() { 12 | let mut sum: i64 = 0; 13 | 14 | for n in 0..100 { 15 | if n % 2 == 0 { 16 | sum += n * n; 17 | } 18 | } 19 | 20 | println!("5th root of {}: {}", sum, fifth_root(sum as f64)); 21 | } 22 | 23 | #[test] 24 | fn find_root() { 25 | assert!(fifth_root(161700 as f64) == 11.008851258678556); 26 | assert!(fifth_root(25 as f64) == 1.9036539387158786); 27 | } -------------------------------------------------------------------------------- /3-topdown-triangle/triangle.rs: -------------------------------------------------------------------------------- 1 | // Write a programme that print out the following, user will input the top number: 2 | // ***** 3 | // **** 4 | // *** 5 | // ** 6 | // * 7 | 8 | use std::io; 9 | 10 | fn line(num: u64) -> String { 11 | let mut buf = String::with_capacity(num as usize); 12 | 13 | for _ in 0..num { 14 | buf.push('*'); 15 | } 16 | 17 | buf 18 | } 19 | 20 | fn main() { 21 | println!("Enter a number:"); 22 | 23 | let mut input_text = String::new(); 24 | io::stdin() 25 | .read_line(&mut input_text) 26 | .expect("Failed to read input"); 27 | 28 | let num = input_text.trim().parse::().expect("That's not a number"); 29 | 30 | for i in 0..num { 31 | println!("{}", line(num - i)); 32 | } 33 | } -------------------------------------------------------------------------------- /11-combo/perms.py: -------------------------------------------------------------------------------- 1 | # algorithm from http://stackoverflow.com/questions/14008521/please-explain-this-algorithm-to-get-all-permutations-of-a-string 2 | def permutations(word): 3 | if len(word)<=1: 4 | return [word] 5 | 6 | #get all permutations of length N-1 7 | perms=permutations(word[1:]) 8 | char=word[0] 9 | result=[] 10 | #iterate over all permutations of length N-1 11 | for perm in perms: 12 | #insert the character into every possible location 13 | for i in range(len(perm)+1): 14 | print(perm, i, len(perm)+1) 15 | print('{} {} {}'.format(perm[:i], char, perm[i:])) 16 | 17 | result.append(perm[:i] + char + perm[i:]) 18 | return result 19 | 20 | print(permutations("bar")) -------------------------------------------------------------------------------- /18-encryption/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | // g++ -std=c++11 -Wall *.cpp -o output 2 | #include "rot13.h" 3 | #include 4 | #include 5 | #include 6 | 7 | int main(int argc, char* argv[]) { 8 | if(argc == 0) { 9 | std::cerr << "Provide a file to convert.\nUsage: (programme) filename.txt" << std::endl; 10 | return 1; 11 | } 12 | 13 | std::string filename = argv[1]; 14 | 15 | std::ifstream text(filename); 16 | std::stringstream buffer; 17 | buffer << text.rdbuf(); 18 | 19 | std::string converted = rot13(buffer.str()); 20 | 21 | std::ofstream output; 22 | output.open(filename); 23 | output << converted; 24 | output.close(); 25 | 26 | std::cout << "Converted " << filename << std::endl; 27 | 28 | return 0; 29 | } -------------------------------------------------------------------------------- /29-noughts-and-crosses/noughts-and-crosses/readme.md: -------------------------------------------------------------------------------- 1 | # Noughts and crosses game 2 | 3 | ![](screenshot.png) 4 | 5 | Command-line noughts and crosses game, written in Rust. Play by entering a board position (a1 - c3) and win by getting three in a row (horizontal, vertical or diagonal). 6 | 7 | ## Usage 8 | - You will need [Rust and cargo installed](https://www.rust-lang.org/en-US/) (tested with v1.16) 9 | - `cargo run` 10 | 11 | ## Overview 12 | Based on Redux architecture - state is stored in the store (`store.rs`), and is immutable. Any changes are requested via a reducer method which returns a new version of the state in the store. For further details see Redux and [this great Rust tutorial](http://fredrik.anderzon.se/2016/05/10/rust-for-node-developers-part-1-introduction/). 13 | -------------------------------------------------------------------------------- /21-html/html/src/html.rs: -------------------------------------------------------------------------------- 1 | use regex::Regex; 2 | 3 | // main.rs has declared this mod already 4 | // ie imagine there's a pub mod html {} here 5 | // pub so we can import into test mod 6 | pub fn strip_tags(html: String) -> String { 7 | // regex: (]+>) - matches + captures any tag 8 | let re = Regex::new(r"(]+>)").unwrap(); 9 | let new_lines = Regex::new(r"(\n\s+)").unwrap(); 10 | 11 | // &html[..] - convert String to &str (slice of entire string) 12 | let modified = re.replace_all(&html[..], ""); 13 | 14 | new_lines.replace_all(&modified[..], "\n") 15 | } 16 | 17 | 18 | #[cfg(test)] 19 | mod test { 20 | use super::*; 21 | 22 | #[test] 23 | fn strip_html() { 24 | assert_eq!(strip_tags("Hello world".to_string()), "Hello world"); 25 | } 26 | } -------------------------------------------------------------------------------- /5-odd-triangle/triangle.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn line(num: u64) -> String { 4 | let mut buf = String::with_capacity(num as usize); 5 | 6 | for _ in 0..num { 7 | buf.push('*'); 8 | } 9 | 10 | buf 11 | } 12 | 13 | // don't compile for tests 14 | #[cfg(not(test))] 15 | fn main() { 16 | println!("Enter a number: "); 17 | 18 | let mut input_text = String::new(); 19 | 20 | io::stdin() 21 | .read_line(&mut input_text) 22 | .expect("Failed to read input"); 23 | 24 | let num = input_text.trim().parse::().expect("That's no number"); 25 | 26 | for i in 1..num + 1 { 27 | if i % 2 != 0 { 28 | println!("{}", line(i)); 29 | } 30 | } 31 | } 32 | 33 | // cargo test or rustc --test 34 | #[cfg(test)] 35 | #[test] 36 | fn it_works() { 37 | assert!(line(3) == "***"); 38 | assert!(line(1) == "*"); 39 | } 40 | -------------------------------------------------------------------------------- /6-random-func/random.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // rand, srand 4 | #include // time 5 | 6 | std::string first() { 7 | return "I'm from the first function!"; 8 | } 9 | 10 | std::string second() { 11 | return "Hello, I'm the second"; 12 | } 13 | 14 | std::string third() { 15 | return "I'm tertiary"; 16 | } 17 | 18 | int main() { 19 | // seed random 20 | srand(time(NULL)); 21 | 22 | int num = rand() % 3 + 1; 23 | 24 | switch(num) { 25 | case 1: 26 | std::cout << first() << std::endl; 27 | break; 28 | 29 | case 2: 30 | std::cout << second() << std::endl; 31 | break; 32 | 33 | case 3: 34 | std::cout << third() << std::endl; 35 | break; 36 | 37 | default: 38 | std::cout << "You will definitely never see this" << std::endl; 39 | break; 40 | } 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /17-scores/scores/src/Student.rs: -------------------------------------------------------------------------------- 1 | // add 'mod average' to main.rs to use median 2 | use average::median; 3 | use std::fmt; 4 | 5 | #[derive(Debug)] 6 | pub struct Student { 7 | name: String, 8 | midterm_score: i16, 9 | final_score: i16, 10 | pub homework: Vec 11 | } 12 | 13 | impl Student { 14 | pub fn new(name: String, midterm_score: i16, final_score: i16, homework: Vec) -> Student { 15 | Student { 16 | name: name, 17 | midterm_score: midterm_score, 18 | final_score: final_score, 19 | homework: homework 20 | } 21 | } 22 | 23 | pub fn grade(&self) -> f64 { 24 | self.midterm_score as f64 * 0.2 + self.final_score as f64 * 0.4 + median(&self.homework) * 0.4 25 | } 26 | } 27 | 28 | impl fmt::Display for Student { 29 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 30 | write!(f, "{}: {:.2}", self.name, self.grade()) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /13-recursive-text/text.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | // lifetimes! we want output to live long enough to be printed 4 | // since we're passing it in as a reference 5 | // so the return String needs to live that long as well 6 | // which means we also need to annotate reverse to show where the lifetime comes from 7 | 8 | fn reverse<'a>(output: &'a mut String, input: &String, n: i32) -> &'a mut String { 9 | if n == 0 { 10 | return output; 11 | } 12 | 13 | output.push(input.chars().nth((n - 1) as usize).unwrap()); 14 | reverse(output, input, n - 1) 15 | } 16 | 17 | fn main() { 18 | println!("Enter some text:"); 19 | 20 | let mut input = String::new(); 21 | io::stdin() 22 | .read_line(&mut input) 23 | .expect("Failed to read input"); 24 | input = input.trim().to_string(); 25 | 26 | let mut output = String::new(); 27 | println!("{}", reverse(&mut output, &input, input.len() as i32)); 28 | } -------------------------------------------------------------------------------- /29-noughts-and-crosses/noughts-and-crosses/src/ai.rs: -------------------------------------------------------------------------------- 1 | //! Contains the AI logic 2 | 3 | // rand crate is imported in main (extern crate rand) 4 | // so can just use here 5 | // need 'use rand' here as well since there's no extern decl 6 | use rand; 7 | use rand::Rng; 8 | 9 | use store::{ Store }; 10 | use board::{ Pieces }; 11 | 12 | /// Pick an empty space on the board and put a piece there 13 | pub fn place(mut store: &mut Store) { 14 | let mut pos = choose_space(); 15 | while !store.state.board.can_place(pos.0, pos.1 - 1) { 16 | pos = choose_space(); 17 | } 18 | 19 | // TODO: bit pants coupling 20 | super::place_piece(pos, &mut store, Pieces::AI); 21 | } 22 | 23 | /// Pick a random x,y co-ord on the board 24 | fn choose_space() -> (u8, u8) { 25 | let x: u8 = rand::thread_rng().gen_range(0, 3); 26 | let y: u8 = rand::thread_rng().gen_range(1, 4); 27 | 28 | (x, y) 29 | } 30 | -------------------------------------------------------------------------------- /14-calc/calc/src/calc.rs: -------------------------------------------------------------------------------- 1 | pub struct Calc; 2 | impl Calc { 3 | pub fn add(x: i64, y: i64) -> i64 { 4 | x + y 5 | } 6 | 7 | pub fn multiply(x: i64, y: i64) -> i64 { 8 | x * y 9 | } 10 | 11 | pub fn subtract(x: i64, y: i64) -> i64 { 12 | x - y 13 | } 14 | 15 | pub fn divide(x: i64, y: i64) -> f64 { 16 | x as f64 / y as f64 17 | } 18 | } 19 | 20 | #[cfg(test)] 21 | mod test { 22 | use calc::Calc; 23 | 24 | #[test] 25 | fn addition() { 26 | assert!(Calc::add(10, 2) == 12); 27 | assert!(Calc::add(-10, -2) == -12); 28 | assert!(Calc::add(-10, 2) == -8); 29 | } 30 | 31 | #[test] 32 | fn multiplication() { 33 | assert!(Calc::multiply(10, 2) == 20); 34 | assert!(Calc::multiply(10, -2) == -20); 35 | assert!(Calc::multiply(-10, -2) == 20); 36 | } 37 | 38 | #[test] 39 | fn subtraction() { 40 | assert!(Calc::subtract(10, 2) == 8); 41 | assert!(Calc::subtract(2, 10) == -8); 42 | } 43 | 44 | #[test] 45 | fn division() { 46 | assert!(Calc::divide(10, 2) == 5f64); 47 | assert!(Calc::divide(2, 10) == 0.2); 48 | } 49 | } -------------------------------------------------------------------------------- /19-primes/py/primes.py: -------------------------------------------------------------------------------- 1 | """Finds pairs of prime numbers which add up to a target number""" 2 | import sys 3 | 4 | # ooh type annotations 5 | def create_sieve(limit: int) -> [bool]: 6 | """Creates a Sieve of Eratosthenes""" 7 | 8 | primes = [True] * (limit + 1) 9 | primes[0] = primes[1] = False 10 | 11 | for(i, is_prime) in enumerate(primes): 12 | if is_prime: 13 | # if you want a generator, yield here 14 | # we need to work from both ends, so use a list 15 | # yield i 16 | for num in range(i * i, limit, i): 17 | primes[num] = False 18 | 19 | return primes 20 | 21 | def main(): 22 | if len(sys.argv) < 2: 23 | input_string = input("Enter a target number: ") 24 | else: 25 | input_string = sys.argv[1] 26 | 27 | target = int(input_string) 28 | sieve = create_sieve(target) 29 | 30 | results = [] 31 | for i in range(1, int(len(sieve) / 2) + 1): 32 | if sieve[i] and sieve[target - i]: 33 | results.append((i, target - i)) 34 | 35 | print(results) 36 | 37 | if __name__ == '__main__': 38 | main() -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 James Tease 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /11-combo/combo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include // sort, unique 5 | 6 | using std::string; 7 | 8 | std::vector permutations(string word) { 9 | size_t len = word.length(); 10 | 11 | if(len <= 1) { 12 | return std::vector { word }; 13 | } 14 | 15 | string trimmed = word.substr(1, len); 16 | 17 | std::vector perms = permutations(trimmed); 18 | string current_char = word.substr(0, 1); 19 | std::vector result; 20 | 21 | for(string perm : perms) { 22 | for(int i = 0; i < (int)perm.size() + 1; i++) { 23 | // substr(x, y) : start at pos x, take y chars. y NOT position! 24 | string front = perm.substr(0, i); 25 | string rest = perm.substr(i, perm.size()); 26 | 27 | result.push_back(front + current_char + rest); 28 | } 29 | } 30 | 31 | return result; 32 | 33 | } 34 | 35 | int main() { 36 | auto results = permutations("TEST"); 37 | for(string result : results) { 38 | std::cout << result << ", "; 39 | } 40 | 41 | std::cout << "\nTotal permutations: " << results.size() << std::endl; 42 | 43 | return 0; 44 | } -------------------------------------------------------------------------------- /9-vowels/count.cpp: -------------------------------------------------------------------------------- 1 | // Given a string, determine how many of the characters are vowels and 2 | // how many are consonants. 3 | #include 4 | #include 5 | #include 6 | #include // std::find 7 | #include // isalpha 8 | 9 | int main() { 10 | std::cout << "Enter a string:" << std::endl; 11 | 12 | std::string input; 13 | getline(std::cin, input); 14 | 15 | if(!std::cin) { 16 | std::cout << "That's no string!" << std::endl; 17 | } 18 | 19 | std::vector vowels = {'a', 'e', 'i', 'o', 'u'}; 20 | std::vector::iterator it; 21 | int vowel_count = 0; 22 | int consonant_count = 0; 23 | 24 | for(auto c : input) { 25 | it = std::find(vowels.begin(), vowels.end(), c); 26 | 27 | if (isalpha(c)) { 28 | // not in vector = returns index of end 29 | if(it != vowels.end()) { 30 | vowel_count++; 31 | } else { 32 | // ignore non-chars 33 | consonant_count++; 34 | } 35 | } 36 | } 37 | 38 | std::cout << "Vowels: " << vowel_count << std::endl; 39 | std::cout << "Consonants: " << consonant_count << std::endl; 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /18-encryption/encrypt/src/main.rs: -------------------------------------------------------------------------------- 1 | mod rot13; 2 | 3 | use rot13::rot13; 4 | use std::fs::File; 5 | use std::io::{ Read, Write }; 6 | use std::env; 7 | 8 | fn main() { 9 | let args: Vec = env::args().collect(); 10 | 11 | if args.len() < 2 { 12 | println!("Provide a file to convert.\nUsage: {} filename", args[0]); 13 | } else { 14 | let ref filename = args[1]; 15 | match File::open(filename) { 16 | Ok(mut file) => { 17 | let mut content = String::new(); 18 | file.read_to_string(&mut content).unwrap(); 19 | 20 | let converted = rot13(&content); 21 | 22 | // create opens file as write-only, deletes existing content 23 | match File::create(filename) { 24 | Err(e) => panic!("Couldn't create {}: {}", filename, e), 25 | Ok(mut file) => { 26 | match file.write_all(converted.as_bytes()) { 27 | Err(e) => panic!("Couldn't write to {}: {}", filename, e), 28 | Ok(_) => println!("Converted {}!", filename) 29 | }; 30 | } 31 | }; 32 | }, 33 | Err(e) => println!("Error opening file {}: {}", filename, e) 34 | }; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /16-palindrome/palindrome.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // tolower 4 | #include 5 | #include // back_inserter 6 | #include 7 | 8 | using namespace std; 9 | 10 | bool isPalindrome(string text) { 11 | std::transform(text.begin(), text.end(), text.begin(), ::tolower); 12 | 13 | regex re("[^a-zA-Z0-9]"); 14 | string stripped = std::regex_replace(text, re, ""); 15 | 16 | int length = (int) stripped.length(); 17 | int i = length - 1; 18 | 19 | for(auto letter : stripped) { 20 | if(i >= length / 2) { 21 | if(letter != stripped[i]) { 22 | return false; 23 | } 24 | 25 | i--; 26 | } else { 27 | break; 28 | } 29 | } 30 | 31 | return true; 32 | } 33 | 34 | int main() { 35 | cout << "Enter some text: "; 36 | string input; 37 | 38 | // cin >> input only reads to first whitespace 39 | // so any spaces in phrase will break it 40 | getline(cin, input); 41 | 42 | if(!cin) { 43 | cout << "Failed to read input" << endl; 44 | } 45 | 46 | if(isPalindrome(input)) { 47 | cout << "Yep!" << endl; 48 | } else { 49 | cout << "Nope" << endl; 50 | } 51 | 52 | return 0; 53 | } -------------------------------------------------------------------------------- /8-fibonacci/fib/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | fn fib(target: u64) -> String { 4 | let mut output_string = String::new(); 5 | 6 | let mut first = 0; 7 | let mut second = 1; 8 | let mut output = 0; 9 | let mut i = 0; 10 | 11 | while output < target { 12 | if i <= 1 { 13 | output = i; 14 | } else { 15 | output = first + second; 16 | 17 | first = second; 18 | second = output; 19 | } 20 | 21 | if output < target { 22 | // println!("{}", output); 23 | output_string = format!("{} {}", output_string, output); 24 | } 25 | i += 1; 26 | } 27 | 28 | output_string.trim().to_string() 29 | } 30 | 31 | fn main() { 32 | println!("Enter a number:"); 33 | 34 | let mut input_text = String::new(); 35 | 36 | io::stdin() 37 | .read_line(&mut input_text) 38 | .expect("Failed to read input"); 39 | 40 | let target: u64 = input_text.trim().parse().expect("That's no number!"); 41 | 42 | let sequence = fib(target); 43 | 44 | println!("{}", sequence); 45 | } 46 | 47 | 48 | #[test] 49 | fn it_calculates_sequence() { 50 | assert!(fib(5) == "0 1 1 2 3"); 51 | assert!(fib(50) == "0 1 1 2 3 5 8 13 21 34"); 52 | assert!(fib(0) == ""); 53 | } -------------------------------------------------------------------------------- /21-html/reddit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Too Many Requests 6 | 18 | 19 | 20 |

whoa there, pardner!

21 | 22 | 23 | 24 |

we're sorry, but you appear to be a bot and we've seen too many requests 25 | from you lately. we enforce a hard speed limit on requests that appear to come 26 | from bots to prevent abuse.

27 | 28 |

if you are not a bot but are spoofing one via your browser's user agent 29 | string: please change your user agent string to avoid seeing this message 30 | again.

31 | 32 |

please wait 6 second(s) and try again.

33 | 34 |

as a reminder to developers, we recommend that clients make no 35 | more than one 36 | request every two seconds to avoid seeing this message.

37 | 38 | 39 | -------------------------------------------------------------------------------- /28-markov/histogram/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate regex; 2 | 3 | use std::path::Path; 4 | use std::env; 5 | 6 | mod histogram; 7 | 8 | fn main() { 9 | let args: Vec = env::args().collect(); 10 | 11 | if args.len() < 2 { 12 | println!("Enter a file name"); 13 | } else { 14 | let ref filename = args[1]; 15 | let mut phrase_length: u8 = 2; 16 | 17 | if args.len() == 3 { 18 | phrase_length = args[2].parse().expect("Enter a number"); 19 | } 20 | 21 | let histogram = histogram::process_file(&Path::new(filename)); 22 | let sorted = histogram::sort_histogram(&histogram); 23 | let total_words = histogram::get_total_words(&histogram); 24 | 25 | 26 | println!("Occurences {:?}", histogram::keyword_occurences(&"alive", &histogram, &total_words)); 27 | println!("Occurences {:?}", histogram::keyword_occurences(&"frankenstein", &histogram, &total_words)); 28 | println!("Total words: {:?}", total_words); 29 | println!("Unique words: {}", sorted.len()); 30 | 31 | println!("Most used words:"); 32 | for i in 0..20 { 33 | println!("{:?}", histogram::keyword_occurences(&sorted[i].0, &histogram, &total_words)); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /17-scores/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | // g++ *.cpp -o output 2 | // This is example from Accelerated C++ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "StudentInfo.h" 11 | #include "grade.h" 12 | 13 | using namespace std; 14 | 15 | int main() { 16 | vector students; 17 | StudentInfo record; 18 | string::size_type maxLength = 0; 19 | 20 | cout << "Hello! Please enter name, midterm, final and all homework grades.\n" << 21 | "When you have finished, press Ctrl+D." << endl; 22 | 23 | while(read(cin, record)) { 24 | maxLength = max(maxLength, record.name.size()); 25 | students.push_back(record); 26 | } 27 | 28 | sort(students.begin(), students.end(), compare); 29 | 30 | for(vector::size_type i = 0; i != students.size(); i++) { 31 | cout << students[i].name << string(maxLength + 1 - students[i].name.size(), ' '); 32 | 33 | try { 34 | double final_grade = grade(students[i]); 35 | streamsize prec = cout.precision(); 36 | cout << setprecision(3) << final_grade << setprecision(prec); 37 | } catch (domain_error e) { 38 | cout << e.what(); 39 | } 40 | 41 | cout << endl; 42 | } 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /7-guessing-game/guess.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // rand, srand 3 | #include // time 4 | #include // abs 5 | 6 | int main() { 7 | srand(time(NULL)); 8 | 9 | int target = rand() % 100 + 1; 10 | bool correct = false; 11 | int guesses = 0; 12 | 13 | while(!correct) { 14 | std::cout << "Enter your guess: "; 15 | int guess; 16 | std::cin >> guess; 17 | guesses++; 18 | 19 | if(!std::cin) { 20 | std::cout << "That's not a number!" << std::endl; 21 | break; 22 | } 23 | 24 | int difference = abs(target - guess); 25 | if(difference < 10) { 26 | std::cout << "Close!" << std::endl; 27 | } else if(difference < 25) { 28 | std::cout << "Nearly." << std::endl; 29 | } else if(difference < 50) { 30 | std::cout << "Nope" << std:: endl; 31 | } 32 | 33 | if(guess < target) { 34 | std::cout << "Too low! Try again." << std::endl; 35 | } else if(guess > target) { 36 | std::cout << "Too high! Try again." << std::endl; 37 | } else { 38 | std::cout << "Correct! The magic number is " << target << std::endl; 39 | std::cout << "You found the magic number in " << guesses << " guesses" << std::endl; 40 | correct = true; 41 | } 42 | } 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /16-palindrome/palindrome/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate regex; 2 | 3 | use std::io; 4 | use regex::Regex; 5 | 6 | fn is_palindrome(text: String) -> bool { 7 | let lower = text.to_lowercase(); 8 | let re = Regex::new(r"[^a-zA-Z0-9]").unwrap(); 9 | // take full slice, ie convert String to str 10 | let stripped = re.replace_all(&lower[..], ""); 11 | 12 | let mut i = 0; 13 | 14 | for letter in stripped.chars() { 15 | if i <= stripped.len() / 2 { 16 | if letter != stripped.chars().rev().nth(i).unwrap() { 17 | return false; 18 | } 19 | i = i + 1; 20 | } else { 21 | break; 22 | } 23 | } 24 | 25 | true 26 | } 27 | 28 | fn main() { 29 | println!("Enter some text:"); 30 | let mut input_text = String::new(); 31 | io::stdin() 32 | .read_line(&mut input_text) 33 | .expect("Failed to read input"); 34 | 35 | if is_palindrome(input_text) { 36 | println!("Yep!"); 37 | } else { 38 | println!("Nope"); 39 | } 40 | } 41 | 42 | #[test] 43 | fn check_it() { 44 | assert!(is_palindrome("hello".to_string()) == false); 45 | assert!(is_palindrome("racecar".to_string()) == true); 46 | assert!(is_palindrome("Race car".to_string()) == true); 47 | assert!(is_palindrome("Hello! Ol, le +H".to_string()) == true); 48 | assert!(is_palindrome("1331".to_string()) == true); 49 | } -------------------------------------------------------------------------------- /18-encryption/py/rot13.py: -------------------------------------------------------------------------------- 1 | LETTERS = { 2 | "A": "N", 3 | "B": "O", 4 | "C": "P", 5 | "D": "Q", 6 | "E": "R", 7 | "F": "S", 8 | "G": "T", 9 | "H": "U", 10 | "I": "V", 11 | "J": "W", 12 | "K": "X", 13 | "L": "Y", 14 | "M": "Z", 15 | "N": "A", 16 | "O": "B", 17 | "P": "C", 18 | "Q": "D", 19 | "R": "E", 20 | "S": "F", 21 | "T": "G", 22 | "U": "H", 23 | "V": "I", 24 | "W": "J", 25 | "X": "K", 26 | "Y": "L", 27 | "Z": "M", 28 | "a": "n", 29 | "b": "o", 30 | "c": "p", 31 | "d": "q", 32 | "e": "r", 33 | "f": "s", 34 | "g": "t", 35 | "h": "u", 36 | "i": "v", 37 | "j": "w", 38 | "k": "x", 39 | "l": "y", 40 | "m": "z", 41 | "n": "a", 42 | "o": "b", 43 | "p": "c", 44 | "q": "d", 45 | "r": "e", 46 | "s": "f", 47 | "t": "g", 48 | "u": "h", 49 | "v": "i", 50 | "w": "j", 51 | "x": "k", 52 | "y": "l", 53 | "z": "m" 54 | } 55 | 56 | def convert(text): 57 | """Encrypts text with a rot13 algorithm - letters are 58 | rotated by 13 places.""" 59 | converted = "" 60 | 61 | for letter in text: 62 | if letter.isalpha(): 63 | converted += LETTERS[letter] 64 | else: 65 | converted += letter 66 | 67 | return converted 68 | -------------------------------------------------------------------------------- /7-guessing-game/guess/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | 3 | use rand::Rng; 4 | use std::io; 5 | use std::cmp::Ordering; 6 | 7 | fn main() { 8 | let num = rand::thread_rng().gen_range(1, 100); 9 | 10 | let mut correct = false; 11 | let mut guesses = 0; 12 | 13 | while !correct { 14 | println!("Enter your guess: "); 15 | guesses += 1; 16 | let mut input_text = String::new(); 17 | io::stdin() 18 | .read_line(&mut input_text) 19 | .expect("Failed to read input"); 20 | 21 | // Don't crash on expected error! 22 | let guess: i32 = match input_text.trim().parse() { 23 | Ok(num) => num, 24 | Err(_) => continue 25 | }; 26 | 27 | let difference = (num - guess).abs(); 28 | 29 | match difference { 30 | 0 => println!("Correct!"), 31 | 1 ... 10 => println!("Almost!"), 32 | 11 ... 25 => println!("Getting there."), 33 | 26 ... 50 => println!("Nowhere near."), 34 | _ => println!("Nope.") 35 | } 36 | 37 | match guess.cmp(&num) { 38 | Ordering::Less => println!("{} is too low! Try again.", guess), 39 | Ordering::Greater => println!("{} is too high! Try again.", guess), 40 | Ordering::Equal => { 41 | println!("{} is the magic number.", num); 42 | println!("You got the magic number in {} guesses.", guesses); 43 | correct = true; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /scrabble/scrabble.rs: -------------------------------------------------------------------------------- 1 | // http://dtrace.org/blogs/ahl/2015/06/22/first-rust-program-pain/ 2 | use std::fs::File; 3 | use std::path::Path; 4 | use std::io::BufReader; 5 | use std::io::BufRead; 6 | use std::collections::HashMap; 7 | use std::io::stdin; 8 | 9 | fn sort_str(s: &String) -> String { 10 | let mut v: Vec = s.chars().collect(); 11 | v.sort(); 12 | v.into_iter().collect() 13 | } 14 | 15 | fn main() { 16 | let path = Path::new("./dictionary.txt"); 17 | let file = match File::open(&path) { 18 | Err(e) => panic!("Failed to open {}: {}", path.display(), e), 19 | Ok(f) => f 20 | }; 21 | 22 | // for each word, create a hashmap of letters 23 | // in alphabetical order: original word 24 | // there can be more than one word per input string eg beisstu 25 | let mut dict: HashMap> = HashMap::new(); 26 | for line in BufReader::new(file).lines() { 27 | let s = line.unwrap(); 28 | dict.entry(sort_str(&s)).or_insert(Vec::new()).push(s); 29 | } 30 | 31 | // println!("{:?}", dict); 32 | 33 | // input must be capitalised and in alphabetical order 34 | // eg beisstu -> busiest 35 | let sin = stdin(); 36 | for line in sin.lock().lines() { 37 | let s = line.unwrap().to_uppercase(); 38 | 39 | match dict.get(&sort_str(&s)) { 40 | Some(v) => println!("anagrams for {}: {}", s, v.join(" ")), 41 | None => println!("Nothing found") 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /17-scores/scores/src/main.rs: -------------------------------------------------------------------------------- 1 | // this basically imports the student.rs file 2 | // equiv of import Student from student 3 | mod student; 4 | 5 | // use mod average here to allow Student access to median 6 | mod average; 7 | 8 | use std::io; 9 | use student::Student; 10 | 11 | fn main() { 12 | println!("Enter student name, midterm, final and homework results. Q to finish"); 13 | 14 | let mut students: Vec = Vec::new(); 15 | 16 | loop { 17 | let mut input_text = String::new(); 18 | io::stdin() 19 | .read_line(&mut input_text) 20 | .expect("Failed to read input"); 21 | 22 | if input_text.trim() == "q" { 23 | break; 24 | } 25 | 26 | let line: Vec<&str> = input_text.trim().split(' ').collect(); 27 | if line.len() > 2 { 28 | let (args, homework) = line.split_at(3); 29 | let name = args[0]; 30 | let midterm: i16 = args[1].parse().expect("Enter midterm mark as number"); 31 | let final_score: i16 = args[2].parse().expect("Enter final mark as number"); 32 | 33 | // todo: handle parse error 34 | let homework_scores: Vec = homework.iter().map(|val| val.parse().unwrap()).collect(); 35 | 36 | let student = Student::new(name.to_string(), midterm, final_score, homework_scores); 37 | students.push(student); 38 | } else { 39 | println!("Enter name and all results one one line!"); 40 | } 41 | } 42 | 43 | for student in students { 44 | println!("{}", student); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /18-encryption/cpp/rot13.cpp: -------------------------------------------------------------------------------- 1 | #include "rot13.h" 2 | #include 3 | #include 4 | 5 | std::unordered_map letters = { 6 | {'A', 'N'}, 7 | {'B', 'O'}, 8 | {'C', 'P'}, 9 | {'D', 'Q'}, 10 | {'E', 'R'}, 11 | {'F', 'S'}, 12 | {'G', 'T'}, 13 | {'H', 'U'}, 14 | {'I', 'V'}, 15 | {'J', 'W'}, 16 | {'K', 'X'}, 17 | {'L', 'Y'}, 18 | {'M', 'Z'}, 19 | {'N', 'A'}, 20 | {'O', 'B'}, 21 | {'P', 'C'}, 22 | {'Q', 'D'}, 23 | {'R', 'E'}, 24 | {'S', 'F'}, 25 | {'T', 'G'}, 26 | {'U', 'H'}, 27 | {'V', 'I'}, 28 | {'W', 'J'}, 29 | {'X', 'K'}, 30 | {'Y', 'L'}, 31 | {'Z', 'M'}, 32 | {'a', 'n'}, 33 | {'b', 'o'}, 34 | {'c', 'p'}, 35 | {'d', 'q'}, 36 | {'e', 'r'}, 37 | {'f', 's'}, 38 | {'g', 't'}, 39 | {'h', 'u'}, 40 | {'i', 'v'}, 41 | {'j', 'w'}, 42 | {'k', 'x'}, 43 | {'l', 'y'}, 44 | {'m', 'z'}, 45 | {'n', 'a'}, 46 | {'o', 'b'}, 47 | {'p', 'c'}, 48 | {'q', 'd'}, 49 | {'r', 'e'}, 50 | {'s', 'f'}, 51 | {'t', 'g'}, 52 | {'u', 'h'}, 53 | {'v', 'i'}, 54 | {'w', 'j'}, 55 | {'x', 'k'}, 56 | {'y', 'l'}, 57 | {'z', 'm'} 58 | }; 59 | 60 | char switchChar(char letter) { 61 | if(std::isalpha(letter)) { 62 | return letters[letter]; 63 | } else { 64 | return letter; 65 | } 66 | } 67 | 68 | std::string rot13(std::string message) { 69 | std::string converted = ""; 70 | 71 | for(auto letter : message) { 72 | converted += switchChar(letter); 73 | } 74 | 75 | return converted; 76 | } -------------------------------------------------------------------------------- /17-scores/py/scores.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import statistics 3 | 4 | class Student: 5 | name = '' 6 | midterm = 0 7 | final = 0 8 | homework = None # list 9 | 10 | def __init__(self, name, midterm, final, homework): 11 | self.name = name 12 | self.midterm = midterm 13 | self.final = final 14 | # make sure homework is int 15 | self.homework = [int(i) for i in homework] 16 | 17 | def __repr__(self): 18 | return "{}: {}".format(self.name, self.grade()) 19 | 20 | def grade(self): 21 | """Calculates grade of student""" 22 | if len(self.homework) == 0: 23 | print("No homework!") 24 | return 0.2 * float(self.midterm) + 0.4 * float(self.final) + 0.4 * float(statistics.median(self.homework)) 25 | 26 | def main(): 27 | students = [] 28 | 29 | print("Enter student's name, midterm, final and homework followed by Enter. Press Ctrl+Z to finish") 30 | 31 | lines = sys.stdin.readlines() 32 | for line in lines: 33 | args = line.split() 34 | 35 | # only create student if there's enough input (eg blank line) 36 | if len(args) >= 4: 37 | name, midterm, final, *homework = args 38 | student = Student(name, midterm, final, homework) 39 | students.append(student) 40 | 41 | # sorts in-place 42 | students.sort(key=lambda student: student.name) 43 | 44 | for student in students: 45 | print(student) 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /26-todo/todo-web/src/template.rs: -------------------------------------------------------------------------------- 1 | use rustc_serialize::json::ToJson; 2 | use nickel::{ Response, MiddlewareResult }; 3 | use std::path::Path; 4 | use std::collections::{ VecDeque }; 5 | use handlebars::{ Handlebars, Renderable, RenderError, RenderContext, Helper, Context, JsonRender }; 6 | 7 | pub fn render<'mw, T:ToJson>(res: Response<'mw>, path: &str, data: &T) -> MiddlewareResult<'mw> { 8 | let mut handlebars = Handlebars::new(); 9 | handlebars.register_template_file("template", &Path::new(path)).ok().unwrap(); 10 | handlebars.register_helper("filter_todo", Box::new(filter_todo)); 11 | let result = handlebars.render("template", data).ok().unwrap(); 12 | 13 | res.send(result) 14 | } 15 | 16 | fn filter_todo(c: &Context, h: &Helper, ha: &Handlebars, rc: RenderContext) -> Result<(), RenderError> { 17 | let active_filter = c.navigate(".", &VeqDeque::new(), "visibility_filter").as_string().unwrap(); 18 | // let active_filter = h.param(0).and_then(|v| v.value().as_string()).unwrap_or(""); 19 | let is_completed = c.navigate(rc.get_path(), &VecDeque::new(), "completed").as_boolean().unwrap(); 20 | // let is_completed = h.param(0).and_then(|v| v.value().as_string()).unwrap_or(""); 21 | let show_todo: bool = match active_filter { 22 | "ShowAll" => true, 23 | "ShowCompleted" => is_completed, 24 | "ShowActive" => !is_completed, 25 | _ => false 26 | }; 27 | 28 | if show_todo { 29 | h.template().unwrap().render(c, ha, rc) 30 | } else { 31 | Ok(()) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /2-currency/currency.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | 3 | const DOLLARS_TO_POUNDS: f64 = 0.75; 4 | const POUNDS_TO_DOLLARS: f64 = 1.32; 5 | 6 | fn convert(amount: f64, choice: &str) -> f64 { 7 | match choice { 8 | "pounds" => amount * POUNDS_TO_DOLLARS, 9 | "dollars" => amount * DOLLARS_TO_POUNDS, 10 | _ => amount 11 | } 12 | } 13 | 14 | fn main() { 15 | println!("Choose from the following options (type number to begin):"); 16 | println!("(1) Pounds to dollars"); 17 | println!("(2) Dollars to pounds"); 18 | 19 | let mut input_text = String::new(); 20 | io::stdin() 21 | .read_line(&mut input_text) 22 | .expect("Failed to read input"); 23 | 24 | let num = input_text.trim().parse::().expect("That's not a number"); 25 | 26 | // TODO: use struct instead 27 | let choice; 28 | let sign; 29 | let converted_sign; 30 | 31 | match num { 32 | 1 => { 33 | choice = "pounds"; 34 | sign = "£"; 35 | converted_sign = "$"; 36 | }, 37 | 38 | 2 => { 39 | choice = "dollars"; 40 | sign = "$"; 41 | converted_sign = "£"; 42 | }, 43 | 44 | _ => { 45 | println!("Please choose an option from the list"); 46 | return; 47 | } 48 | }; 49 | 50 | println!("Enter amount to convert:"); 51 | let mut amount_text = String::new(); 52 | io::stdin() 53 | .read_line(&mut amount_text) 54 | .expect("Failed to read input"); 55 | 56 | let amount = amount_text.trim().parse::().expect("That's not a number"); 57 | 58 | // :.2 = print dp 59 | println!("{}{} is {}{:.2}", sign, amount, converted_sign, convert(amount, choice)); 60 | } -------------------------------------------------------------------------------- /14-calc/calc/src/main.rs: -------------------------------------------------------------------------------- 1 | // this tells rust to look for calc.rs or calc/mod.rs 2 | mod calc; 3 | 4 | use std::io; 5 | 6 | // look in calc for Calc 7 | // if there was a module in calc.rs, this would be use calc::modName::Calc 8 | use calc::Calc; 9 | 10 | fn main() { 11 | println!("Enter a sum, or 'q' to quit:"); 12 | 13 | loop { 14 | let mut input_text = String::new(); 15 | io::stdin() 16 | .read_line(&mut input_text) 17 | .expect("Failed to read input"); 18 | 19 | if input_text.trim() == "q" { 20 | break; 21 | } 22 | 23 | let operators = vec!["+", "-", "/", "*"]; 24 | 25 | for op in operators { 26 | 27 | match input_text.find(op) { 28 | Some(_) => { 29 | // only handle one operator 30 | let parts: Vec<&str> = input_text.split(op).collect(); 31 | 32 | // need at least two numbers 33 | if parts.len() < 2 { 34 | panic!("Enter two numbers!"); 35 | } 36 | 37 | let x:i64 = parts[0].trim().parse().ok().expect("Enter a number!"); 38 | let y: i64 = parts[1].trim().parse().ok().expect("Enter a number!");; 39 | 40 | match op { 41 | "+" => println!("{}", Calc::add(x, y)), 42 | "-" => println!("{}", Calc::subtract(x, y)), 43 | "/" => println!("{}", Calc::divide(x, y)), 44 | "*" => println!("{}", Calc::multiply(x, y)), 45 | _ => println!("Sorry, only addition, subtraction, multiplication and division are supported") 46 | }; 47 | 48 | }, 49 | // ignore input if it doesn't contain operator in array 50 | None => {} 51 | }; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /15-piggy-bank/piggy.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // exceptions 4 | #include // setprecision, fixed 5 | 6 | class Coin { 7 | private: 8 | int amount; 9 | int value; 10 | 11 | public: 12 | Coin(int amount = 0, int value = 0) : amount(amount), value(value) {} 13 | 14 | int total() { 15 | return amount * value; 16 | } 17 | }; 18 | 19 | int get_input() { 20 | int input; 21 | std::cin >> input; 22 | 23 | if(!std::cin) { 24 | throw std::invalid_argument("That's no number!"); 25 | } 26 | 27 | return input; 28 | } 29 | 30 | 31 | int get_total(std::vector coins) { 32 | int total = 0; 33 | for(auto coin : coins) { 34 | total += coin.total(); 35 | } 36 | 37 | return total; 38 | } 39 | 40 | int main() { 41 | std::vector coins; 42 | std::cout << "Enter number of coins: " << std::endl; 43 | 44 | try { 45 | std::cout << "£2: "; 46 | coins.push_back(Coin(get_input(), 200)); 47 | 48 | std::cout << "£1: "; 49 | coins.push_back(Coin(get_input(), 100)); 50 | 51 | std::cout << "50p: "; 52 | coins.push_back(Coin(get_input(), 50)); 53 | 54 | std::cout << "20p: "; 55 | coins.push_back(Coin(get_input(), 20)); 56 | 57 | std::cout << "10p: "; 58 | coins.push_back(Coin(get_input(), 10)); 59 | 60 | std::cout << "5p: "; 61 | coins.push_back(Coin(get_input(), 5)); 62 | } catch(const std::invalid_argument& e) { 63 | std::cout << e.what() << std::endl; 64 | } 65 | 66 | // setprecision: max dp 67 | // fixed: always show 2 dp 68 | std::cout << std::setprecision(2) << std::fixed 69 | << "£" << get_total(coins) / 100.0 << std::endl; 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /2-currency/currency.cpp: -------------------------------------------------------------------------------- 1 | // Develop a programme to convert currency X to currency Y and vice versa 2 | // £1 = £1.32 lol 3 | #include 4 | #include 5 | #include 6 | 7 | using std::cout; 8 | using std::cin; 9 | using std::endl; 10 | using std::string; 11 | 12 | const float POUNDS_TO_DOLLARS = 1.32; 13 | const float DOLLARS_TO_POUNDS = 0.75; 14 | 15 | float convert(float amount, string type) { 16 | if(type == "pounds") { 17 | return amount * POUNDS_TO_DOLLARS; 18 | } 19 | 20 | return amount * DOLLARS_TO_POUNDS; 21 | } 22 | 23 | int main() { 24 | // todo: do while 25 | cout << "Choose from the following options (type number to begin):" << endl; 26 | cout << "(1) Pounds to dollars" << endl; 27 | cout << "(2) Dollars to pounds" << endl; 28 | 29 | int choice; 30 | cin >> choice; 31 | 32 | if(!cin) { 33 | cout << "Please type the number of your choice"; 34 | return 1; 35 | } 36 | 37 | string type; 38 | string sign; 39 | string convertedSign; 40 | float amount; 41 | 42 | switch(choice) { 43 | case 1: 44 | cout << "Enter amount in £"; 45 | type = "pounds"; 46 | sign = "£"; 47 | convertedSign = "$"; 48 | break; 49 | 50 | case 2: 51 | cout << "Enter amount in $"; 52 | type = "dollars"; 53 | sign = "$"; 54 | convertedSign = "£"; 55 | break; 56 | 57 | default: 58 | cout << "Please pick an option from the list"; 59 | return 1; 60 | } 61 | 62 | cin >> amount; 63 | if(!cin) { 64 | cout << "Enter a number" << endl; 65 | 66 | return 1; 67 | } 68 | 69 | cout << sign << amount << " is " 70 | << convertedSign << std::fixed << std::setprecision(2) 71 | << convert(amount, type) << endl; 72 | 73 | return 0; 74 | } -------------------------------------------------------------------------------- /18-encryption/encrypt/src/rot13.rs: -------------------------------------------------------------------------------- 1 | pub fn rot13(line: &String) -> String { 2 | let mut converted = String::new(); 3 | 4 | for letter in line.chars() { 5 | if letter.is_alphabetic() { 6 | converted.push(get_char_code(letter)); 7 | } else { 8 | converted.push(letter); 9 | } 10 | } 11 | 12 | converted 13 | } 14 | 15 | // only letters in English alphabet 16 | // just hardcode it :) 17 | fn get_char_code(letter: char) -> char { 18 | match letter { 19 | 'A' => 'N', 20 | 'B' => 'O', 21 | 'C' => 'P', 22 | 'D' => 'Q', 23 | 'E' => 'R', 24 | 'F' => 'S', 25 | 'G' => 'T', 26 | 'H' => 'U', 27 | 'I' => 'V', 28 | 'J' => 'W', 29 | 'K' => 'X', 30 | 'L' => 'Y', 31 | 'M' => 'Z', 32 | 'N' => 'A', 33 | 'O' => 'B', 34 | 'P' => 'C', 35 | 'Q' => 'D', 36 | 'R' => 'E', 37 | 'S' => 'F', 38 | 'T' => 'G', 39 | 'U' => 'H', 40 | 'V' => 'I', 41 | 'W' => 'J', 42 | 'X' => 'K', 43 | 'Y' => 'L', 44 | 'Z' => 'M', 45 | 'a' => 'n', 46 | 'b' => 'o', 47 | 'c' => 'p', 48 | 'd' => 'q', 49 | 'e' => 'r', 50 | 'f' => 's', 51 | 'g' => 't', 52 | 'h' => 'u', 53 | 'i' => 'v', 54 | 'j' => 'w', 55 | 'k' => 'x', 56 | 'l' => 'y', 57 | 'm' => 'z', 58 | 'n' => 'a', 59 | 'o' => 'b', 60 | 'p' => 'c', 61 | 'q' => 'd', 62 | 'r' => 'e', 63 | 's' => 'f', 64 | 't' => 'g', 65 | 'u' => 'h', 66 | 'v' => 'i', 67 | 'w' => 'j', 68 | 'x' => 'k', 69 | 'y' => 'l', 70 | 'z' => 'm', 71 | _ => ' ' 72 | } 73 | } 74 | 75 | #[test] 76 | fn it_converts() { 77 | let input = "Hello World!".to_string(); 78 | let converted = "Uryyb Jbeyq!".to_string(); 79 | assert!(rot13(&input) == "Uryyb Jbeyq!"); 80 | assert!(rot13(&converted) == "Hello World!"); 81 | } -------------------------------------------------------------------------------- /12-circle/circle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include // M_PI, sqrt 3 | 4 | class Circle { 5 | private: 6 | float area; 7 | float radius; 8 | float diameter; 9 | 10 | public: 11 | Circle(float area = 0, float radius = 0, float diameter = 0) : 12 | area{area}, radius{radius}, diameter{diameter} {} 13 | 14 | static Circle from_radius(float radius) { 15 | return Circle(M_PI * (radius * radius), radius, radius * 2); 16 | } 17 | 18 | static Circle from_diameter(float diameter) { 19 | float radius = diameter / 2.0; 20 | 21 | return Circle(M_PI * (radius * radius), radius, diameter); 22 | } 23 | 24 | static Circle from_area(float area) { 25 | float diameter = sqrt(area / M_PI); 26 | 27 | return Circle(area, diameter / 2.0, diameter); 28 | } 29 | 30 | void print() { 31 | std::cout << "Circle(area: " << area 32 | << ", radius: " << radius 33 | << ", diameter: " << diameter << ")" << std::endl; 34 | } 35 | }; 36 | 37 | int main() { 38 | std::cout << "Pick an option: " << std::endl; 39 | std::cout << "1. Area" << std::endl; 40 | std::cout << "2. Radius" << std::endl; 41 | std::cout << "3. Diameter" << std::endl; 42 | 43 | int choice; 44 | std::cin >> choice; 45 | 46 | if(!std::cin) { 47 | std::cout << "Enter a number!" << std::endl; 48 | return 1; 49 | } 50 | 51 | std::cout << "Enter size: "; 52 | int size; 53 | std::cin >> size; 54 | 55 | if(!std::cin) { 56 | std::cout << "Enter a number!" << std::endl; 57 | return 1; 58 | } 59 | 60 | Circle circle; 61 | switch(choice) { 62 | case 1: 63 | circle = Circle::from_area(size); 64 | break; 65 | case 2: 66 | circle = Circle::from_radius(size); 67 | break; 68 | case 3: 69 | circle = Circle::from_diameter(size); 70 | break; 71 | default: 72 | std::cout << "Pick an option from the list!" << std::endl; 73 | return 1; 74 | } 75 | 76 | circle.print(); 77 | 78 | return 0; 79 | } -------------------------------------------------------------------------------- /26-todo/todo/src/store.rs: -------------------------------------------------------------------------------- 1 | use store::Action::{ Visibility }; 2 | use todo::{ Todo, TodoAction, todo_reducer }; 3 | 4 | pub struct Store { 5 | pub state: State, 6 | listeners: Vec, 7 | reducer: fn(&State, Action) -> State 8 | } 9 | 10 | impl Store { 11 | pub fn create_store(reducer: fn(&State, Action) -> State) -> Store { 12 | Store { 13 | state: State::default(), 14 | listeners: Vec::new(), 15 | reducer: reducer 16 | } 17 | } 18 | 19 | pub fn subscribe(&mut self, listener: fn(&State)) { 20 | self.listeners.push(listener); 21 | } 22 | 23 | // fn get_state(&self) -> &State { 24 | // &self.state 25 | // } 26 | 27 | pub fn dispatch(&mut self, action: Action) { 28 | self.state = (self.reducer)(&self.state, action); 29 | for listener in &self.listeners { 30 | listener(&self.state) 31 | } 32 | } 33 | } 34 | 35 | 36 | #[derive(Debug, Clone)] 37 | pub struct State { 38 | pub todos: Vec, 39 | pub filter: VisibilityFilter 40 | } 41 | 42 | impl State { 43 | pub fn default() -> Self { 44 | State { 45 | todos: Vec::new(), 46 | filter: VisibilityFilter::ShowAll 47 | } 48 | } 49 | } 50 | 51 | #[derive(Clone, Debug)] 52 | pub enum VisibilityFilter { 53 | ShowActive, 54 | ShowAll, 55 | ShowCompleted 56 | } 57 | 58 | #[derive(Clone, Debug)] 59 | pub enum Action { 60 | Todos(TodoAction), 61 | Visibility(VisibilityFilter) 62 | } 63 | 64 | pub fn reducer(state: &State, action: Action) -> State { 65 | State { 66 | todos: todo_reducer(&state.todos, &action), 67 | filter: visibility_reducer(&state.filter, &action) 68 | } 69 | } 70 | 71 | fn visibility_reducer(state: &VisibilityFilter, action: &Action) -> VisibilityFilter { 72 | match *action { 73 | Visibility(ref vis_action) => vis_action.clone(), 74 | _ => state.clone() 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /19-primes/cpp/primes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "sieve.h" 6 | 7 | int main() { 8 | std::cout << "Enter a number: "; 9 | 10 | int target; 11 | std::cin >> target; 12 | 13 | if(!std::cin) { 14 | std::cout << "That's no number!" << std::endl; 15 | return 1; 16 | } 17 | 18 | std::vector sieve = createSieve(target); 19 | 20 | std::vector> results; 21 | for(int i = 0; i < target / 2; i++) { 22 | if(sieve[i] == true) { 23 | if(sieve[target - i] == true) { 24 | // emaplce_back adds straight into a pair in vec 25 | results.emplace_back(i, target - i); 26 | } 27 | } 28 | } 29 | 30 | for(auto result : results) { 31 | std::cout << result.first << ", " << result.second << std::endl; 32 | } 33 | 34 | // bit of testing :) 35 | // assert(sieve[2] == true); 36 | // assert(sieve[3] == true); 37 | // assert(sieve[4] == false); 38 | // assert(sieve[5] == true); 39 | // assert(sieve[6] == false); 40 | // assert(sieve[7] == true); 41 | // assert(sieve[8] == false); 42 | // assert(sieve[9] == false); 43 | // assert(sieve[10] == false); 44 | // assert(sieve[11] == true); 45 | // assert(sieve[12] == false); 46 | // assert(sieve[13] == true); 47 | // assert(sieve[14] == false); 48 | // assert(sieve[15] == false); 49 | // assert(sieve[16] == false); 50 | // assert(sieve[17] == true); 51 | // assert(sieve[18] == false); 52 | // assert(sieve[19] == true); 53 | // assert(sieve[20] == false); 54 | // assert(sieve[21] == false); 55 | // assert(sieve[22] == false); 56 | // assert(sieve[23] == true); 57 | // assert(sieve[24] == false); 58 | // assert(sieve[25] == false); 59 | // assert(sieve[26] == false); 60 | // assert(sieve[27] == false); 61 | // assert(sieve[28] == false); 62 | // assert(sieve[29] == true); 63 | // assert(sieve[30] == false); 64 | // assert(sieve[31] == true); 65 | // assert(sieve[32] == false); 66 | 67 | return 0; 68 | } -------------------------------------------------------------------------------- /26-todo/todo/src/todo.rs: -------------------------------------------------------------------------------- 1 | use store::{ Action }; 2 | use store::Action::{ Todos }; 3 | use todo::TodoAction::{ Add, Toggle, Remove }; 4 | 5 | #[derive(Debug, Clone)] 6 | pub struct Todo { 7 | pub id: i16, // unique key 8 | pub description: String, 9 | pub completed: bool, 10 | pub order: i32, // where in the list should it be 11 | pub deleted: bool 12 | } 13 | 14 | impl Todo { 15 | pub fn new(id: i16, description: String, order: i32) -> Self { 16 | Todo { 17 | id: id, 18 | description: description, 19 | completed: false, 20 | order: order, 21 | deleted: false 22 | } 23 | } 24 | } 25 | 26 | #[derive(Clone, Debug)] 27 | pub enum TodoAction { 28 | Add(String), 29 | Toggle(i16), 30 | Remove(i16) 31 | } 32 | 33 | pub fn get_mut_todo(todos: &mut Vec, id: i16) -> Option<&mut Todo> { 34 | todos.iter_mut().find(|todo| todo.id == id) 35 | } 36 | 37 | pub fn todo_reducer(state: &Vec, action: &Action) -> Vec { 38 | let mut new_state: Vec = state.clone(); 39 | 40 | match *action { 41 | Todos(ref todo_action) => match *todo_action { 42 | Add(ref title) => { 43 | let new_id = new_state.len() as i16 + 1; 44 | new_state.push(Todo::new(new_id, title.to_string(), 0)) 45 | }, 46 | Toggle(todo_id) => { 47 | if let Some(todo) = get_mut_todo(&mut new_state, todo_id) { 48 | if todo.completed { 49 | todo.completed = false; 50 | } else { 51 | todo.completed = true; 52 | } 53 | } 54 | }, 55 | Remove(todo_id) => { 56 | if let Some(todo) = get_mut_todo(&mut new_state, todo_id) { 57 | todo.deleted = true; 58 | } 59 | } 60 | }, 61 | // not a todo action 62 | _ => () 63 | } 64 | 65 | new_state 66 | } 67 | -------------------------------------------------------------------------------- /14-calc/calc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include // getline 4 | #include 5 | #include 6 | 7 | // make sure all methods have same signatures so you can add to map 8 | struct Calc { 9 | float divide(int first, int second) { 10 | return (float)first / second; 11 | } 12 | 13 | float mulitply(int first, int second) { 14 | return (float)first * second; 15 | } 16 | 17 | float add(int first, int second) { 18 | return (float)first + second; 19 | } 20 | 21 | float subtract(int first, int second) { 22 | return (float)first - second; 23 | } 24 | }; 25 | 26 | using namespace std; 27 | 28 | int main() { 29 | // map operator to function pointer 30 | std::map map; 31 | map["+"] = &Calc::add; 32 | map["-"] = &Calc::subtract; 33 | map["*"] = &Calc::mulitply; 34 | map["/"] = &Calc::divide; 35 | 36 | std::cout << "Enter a sum, or 'q' to quit" << std::endl; 37 | 38 | while (true) { 39 | string input; 40 | getline(cin, input); 41 | 42 | string operators[] = {"+", "-", "*", "/"}; 43 | 44 | if(input == "q") { 45 | break; 46 | } 47 | 48 | // search for operator in string 49 | // if not in string, returns number greater than string length 50 | // can also use std::string::npos 51 | for(auto op : operators) { 52 | std::size_t found = input.find(op); 53 | 54 | if(found != std::string::npos) { 55 | // split string at operator 56 | // get first and second numbers 57 | auto start = 0; 58 | auto end = found; 59 | 60 | int x = std::stoi(input.substr(start, end - start)); 61 | int y = std::stoi(input.substr(end + op.length(), input.length())); 62 | 63 | Calc calc; 64 | auto func = map.find(op)->second; 65 | 66 | // TODO: check func exists 67 | 68 | // can't use strings in switch 69 | // get string:function pair out of map 70 | // call function 71 | std::cout << (calc.*(func))(x, y) << std::endl; 72 | } 73 | } 74 | } 75 | 76 | return 0; 77 | } -------------------------------------------------------------------------------- /26-todo/todo-web/src/todo.rs: -------------------------------------------------------------------------------- 1 | extern crate rustc_serialize; 2 | 3 | use store::{ Action }; 4 | use store::Action::{ Todos }; 5 | use todo::TodoAction::{ Add, Toggle, Remove }; 6 | 7 | #[derive(Debug, Clone, RustcEncodable, RustcDecodable)] 8 | pub struct Todo { 9 | pub id: i16, // unique key 10 | pub description: String, 11 | pub completed: bool, 12 | pub order: i32, // where in the list should it be 13 | pub deleted: bool 14 | } 15 | 16 | impl Todo { 17 | pub fn new(id: i16, description: String, order: i32) -> Self { 18 | Todo { 19 | id: id, 20 | description: description, 21 | completed: false, 22 | order: order, 23 | deleted: false 24 | } 25 | } 26 | } 27 | 28 | #[derive(Clone, Debug)] 29 | pub enum TodoAction { 30 | Add(String), 31 | Toggle(i16), 32 | Remove(i16) 33 | } 34 | 35 | pub fn get_mut_todo(todos: &mut Vec, id: i16) -> Option<&mut Todo> { 36 | todos.iter_mut().find(|todo| todo.id == id) 37 | } 38 | 39 | pub fn todo_reducer(state: &Vec, action: &Action) -> Vec { 40 | let mut new_state: Vec = state.clone(); 41 | 42 | match *action { 43 | Todos(ref todo_action) => match *todo_action { 44 | Add(ref title) => { 45 | let new_id = new_state.len() as i16 + 1; 46 | new_state.push(Todo::new(new_id, title.to_string(), 0)) 47 | }, 48 | Toggle(todo_id) => { 49 | if let Some(todo) = get_mut_todo(&mut new_state, todo_id) { 50 | if todo.completed { 51 | todo.completed = false; 52 | } else { 53 | todo.completed = true; 54 | } 55 | } 56 | }, 57 | Remove(todo_id) => { 58 | if let Some(todo) = get_mut_todo(&mut new_state, todo_id) { 59 | todo.deleted = true; 60 | } 61 | } 62 | }, 63 | // not a todo action 64 | _ => () 65 | } 66 | 67 | new_state 68 | } 69 | -------------------------------------------------------------------------------- /20-quiz/cpp/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | // https://github.com/nlohmann/json 8 | #include "json.h" 9 | 10 | using json = nlohmann::json; 11 | 12 | struct Question { 13 | std::string question; 14 | std::string answer; 15 | }; 16 | 17 | std::stringstream open_file(std::string filename) { 18 | std::ifstream text(filename); 19 | std::stringstream buffer; 20 | buffer << text.rdbuf(); 21 | 22 | return buffer; 23 | } 24 | 25 | std::vector get_questions(json data) { 26 | std::vector questions; 27 | // for(json::iterator it = data.begin; it != data.end(); it++) { 28 | for(auto entry : data) { 29 | Question q; 30 | q.question = entry["question"]; 31 | q.answer = entry["answer"]; 32 | questions.push_back(q); 33 | } 34 | 35 | return questions; 36 | } 37 | 38 | int main(int argc, char* argv[]) { 39 | // get filename from args 40 | if(argc == 1) { 41 | std::cerr << "Provide a question file" << std::endl; 42 | return 1; 43 | } 44 | 45 | std::string filename = argv[1]; 46 | std::stringstream contents = open_file(filename); 47 | 48 | // convert from JSON 49 | json data = json::parse(contents.str()); 50 | std::vector questions = get_questions(data); 51 | 52 | int score = 0; 53 | for(Question q : questions) { 54 | std::cout << q.question << std::endl; 55 | std::string answer; 56 | std::getline(std::cin, answer); 57 | 58 | if(!std::cin) { 59 | std::cerr << "Enter your answer!" << std::endl; 60 | return 1; 61 | } 62 | 63 | // transform to lowercase - in-place 64 | std::transform(answer.begin(), answer.end(), answer.begin(), ::tolower); 65 | std::transform(q.answer.begin(), q.answer.end(), q.answer.begin(), ::tolower); 66 | 67 | if(answer == q.answer) { 68 | std::cout << "Correct!" << std::endl; 69 | score++; 70 | } else { 71 | std::cout << "Nope. The answer is " << q.answer << std::endl; 72 | } 73 | } 74 | 75 | std::cout << "You scored " << score << " out of " << questions.size() << std::endl; 76 | 77 | 78 | return 0; 79 | } -------------------------------------------------------------------------------- /28-markov/histogram/src/histogram.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::path::Path; 3 | use std::io::{ BufReader, BufRead }; 4 | use std::collections::HashMap; 5 | 6 | use regex::Regex; 7 | 8 | #[derive(Debug)] 9 | pub struct Keyword { 10 | phrase: String, 11 | occurences: u32, 12 | percentage: f32 13 | } 14 | 15 | // mega slow in dev, fast in --release 16 | pub fn process_file(filename: &Path) -> HashMap { 17 | let mut histogram: HashMap = HashMap::new(); 18 | 19 | let file = match File::open(&filename) { 20 | Err(e) => panic!("Error reading file: {:?}", e), 21 | Ok(file) => file 22 | }; 23 | let buffer = BufReader::new(&file); 24 | for line in buffer.lines() { 25 | match line { 26 | Err(e) => println!("Error reading line: {:?}", e), 27 | Ok(line) => append_to_histogram(&line, &mut histogram) 28 | } 29 | } 30 | 31 | histogram 32 | } 33 | 34 | pub fn keyword_occurences(word: &str, histogram: &HashMap, total: &u32) -> Option { 35 | match histogram.get(word) { 36 | Some(value) => { 37 | Some(Keyword { 38 | phrase: word.to_string(), 39 | occurences: *value, 40 | percentage: *value as f32 / *total as f32 41 | }) 42 | }, 43 | None => None 44 | } 45 | } 46 | 47 | pub fn sort_histogram(histogram: &HashMap) -> Vec<(&String, &u32)> { 48 | let mut sorted: Vec<_> = histogram.iter().collect(); 49 | // sort inline 50 | sorted.sort_by(|a, b| b.1.cmp(a.1)); 51 | sorted 52 | } 53 | 54 | pub fn get_total_words(histogram: &HashMap) -> u32 { 55 | // fold === reduce 56 | histogram.iter().fold(0, |acc, words| acc + words.1) 57 | } 58 | 59 | fn append_to_histogram(text: &String, histogram: &mut HashMap) { 60 | for word in strip(&text).split(" ").filter(|s| !s.is_empty()) { 61 | *histogram.entry(word.to_lowercase()).or_insert(0) += 1; 62 | } 63 | } 64 | 65 | fn strip(text: &String) -> String { 66 | let no_punctuation = Regex::new(r"[^a-zA-Z0-9]").unwrap(); 67 | 68 | no_punctuation.replace_all(&text, " ").to_string() 69 | } 70 | -------------------------------------------------------------------------------- /26-todo/todo-web/src/todos.tpl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Todo 6 | 7 | 8 | 14 | 21 | 22 | 23 |
24 |
25 |

Todos

26 |
27 | 28 |
29 |
30 | 31 |
32 |
    33 | {{#each todos}} 34 | {{#unless deleted}} 35 | {{#filter_todo}} 36 |
  • 37 |
    38 | 39 | 40 | 41 |
    42 |
  • 43 | {{/filter_todo}} 44 | {{/unless}} 45 | {{/each}} 46 |
47 |
48 | 49 | 59 |
60 | 61 | 62 | -------------------------------------------------------------------------------- /26-todo/todo-web/src/store.rs: -------------------------------------------------------------------------------- 1 | extern crate rustc_serialize; 2 | 3 | use rustc_serialize::json::{ self, Json, ToJson }; 4 | use store::Action::{ Visibility }; 5 | use todo::{ Todo, TodoAction, todo_reducer }; 6 | 7 | pub struct Store { 8 | pub state: State, 9 | listeners: Vec, 10 | reducer: fn(&State, Action) -> State 11 | } 12 | 13 | impl Store { 14 | pub fn create_store(reducer: fn(&State, Action) -> State) -> Store { 15 | Store { 16 | state: State::default(), 17 | listeners: Vec::new(), 18 | reducer: reducer 19 | } 20 | } 21 | 22 | pub fn subscribe(&mut self, listener: fn(&State)) { 23 | self.listeners.push(listener); 24 | } 25 | 26 | pub fn get_state(&self) -> &State { 27 | &self.state 28 | } 29 | 30 | pub fn dispatch(&mut self, action: Action) { 31 | self.state = (self.reducer)(&self.state, action); 32 | for listener in &self.listeners { 33 | listener(&self.state) 34 | } 35 | } 36 | } 37 | 38 | 39 | #[derive(Debug, Clone, RustcEncodable, RustcDecodable)] 40 | pub struct State { 41 | pub todos: Vec, 42 | pub filter: VisibilityFilter 43 | } 44 | 45 | impl State { 46 | pub fn default() -> Self { 47 | State { 48 | todos: Vec::new(), 49 | filter: VisibilityFilter::ShowAll 50 | } 51 | } 52 | } 53 | 54 | impl ToJson for State { 55 | fn to_json(&self) -> Json { 56 | Json::from_str(&json::encode(&self).unwrap()).unwrap() 57 | } 58 | } 59 | 60 | #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] 61 | pub enum VisibilityFilter { 62 | ShowActive, 63 | ShowAll, 64 | ShowCompleted 65 | } 66 | 67 | #[derive(Clone, Debug)] 68 | pub enum Action { 69 | Todos(TodoAction), 70 | Visibility(VisibilityFilter) 71 | } 72 | 73 | pub fn reducer(state: &State, action: Action) -> State { 74 | State { 75 | todos: todo_reducer(&state.todos, &action), 76 | filter: visibility_reducer(&state.filter, &action) 77 | } 78 | } 79 | 80 | fn visibility_reducer(state: &VisibilityFilter, action: &Action) -> VisibilityFilter { 81 | match *action { 82 | Visibility(ref vis_action) => vis_action.clone(), 83 | _ => state.clone() 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /20-quiz/quiz.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "question": "Cynology is the study of what?", 4 | "answer": "Dogs" 5 | }, 6 | { 7 | "question": "In which country was Henry Kissinger born?", 8 | "answer": "Germany" 9 | }, 10 | { 11 | "question": "Who composed the work 'The Marriage of Figaro'?", 12 | "answer": "Mozart" 13 | }, 14 | { 15 | "question": "Born Eric Arthur Blair in Motihari, Bengal, India, this famous author is better known by what pseudonym?", 16 | "answer": "George Orwell" 17 | }, 18 | { 19 | "question": "In Roman mythology, who was the king of the gods?", 20 | "answer": "Jupiter" 21 | }, 22 | { 23 | "question": "A cow's stomach is divided into how many compartments?", 24 | "answer": "4" 25 | }, 26 | { 27 | "question": "What is the term for cutting vegetables into long thin matchstick like shapes?", 28 | "answer": "Julienne" 29 | }, 30 | { 31 | "question": "Known as 'The Mile High' city, what is the capital city of Colorado", 32 | "answer": "Denver" 33 | }, 34 | { 35 | "question": "In the sitcom Dad's Army Arnold Ridley played which character?", 36 | "answer": "Private Godfrey" 37 | }, 38 | { 39 | "question": "Indira Ghandi International Airport services which city?", 40 | "answer": "Delhi" 41 | }, 42 | { 43 | "question": "Born Leonardo Bonacci in Pisa, Italy, which mathematician identified a sequence where the following number is made by adding the two previous number?", 44 | "answer": "Fibonacci" 45 | }, 46 | { 47 | "question": "Which traditional Royal Navy term refers to a day or shorter period reserved for rest and recovery?", 48 | "answer": "Banyan" 49 | }, 50 | { 51 | "question": "A Pascal is the SI unit for measuring what?", 52 | "answer": "Pressure" 53 | }, 54 | { 55 | "question": "Which nation won the 2014 World Cup?", 56 | "answer": "Germany" 57 | }, 58 | { 59 | "question": "The M55 motorway links the M6 north of Preston to which seaside town?", 60 | "answer": "Blackpool" 61 | }, 62 | { 63 | "question": "Which British city is affectionately known as 'Brizzle'?", 64 | "answer": "Bristol" 65 | }, 66 | { 67 | "question": "In which was the film Grease released to cinemas? a) 1978 b) 1972 c) 1982", 68 | "answer": "1978" 69 | } 70 | ] -------------------------------------------------------------------------------- /11-combo/combo/src/main.rs: -------------------------------------------------------------------------------- 1 | // List all possible combinations of letters in a 4-letter word. 2 | // Eg 'TEST' can be unscrambled as TEST,TETS,TSET,TSTE,TTSE,TTES 3 | 4 | use std::io; 5 | 6 | /// Remove the first letter 7 | /// Find all the permutations of the remaining letters (recursive step) 8 | /// Reinsert the letter that was removed in every possible location. 9 | fn permutations(word: String) -> Vec { 10 | let length = word.len(); 11 | 12 | if length <= 1 { 13 | // need return keyword for early return 14 | // otherwise error: expected () found String 15 | return vec![word]; 16 | } 17 | 18 | // remove first character 19 | let trimmed = word.chars().skip(1).collect(); 20 | 21 | // find all permutations of remaining letters 22 | let perms = permutations(trimmed); 23 | let current_char = word.chars().nth(0).unwrap(); 24 | let mut result = Vec::new(); 25 | 26 | // reinsert first letter in every possible place 27 | for perm in &perms { 28 | for i in 0..&perms.len() + 1 { 29 | let front: String = perm.chars().take(i).collect(); 30 | let rest: String = perm.chars().skip(i).collect(); 31 | result.push(format!("{}{}{}", front, current_char, rest)); 32 | } 33 | } 34 | 35 | 36 | result 37 | } 38 | 39 | fn main() { 40 | // get input 41 | println!("Enter a word (max 6 letters): "); 42 | 43 | let mut input_text = String::new(); 44 | io::stdin() 45 | .read_line(&mut input_text) 46 | .expect("Failed to read input"); 47 | 48 | input_text = input_text.trim().to_string(); 49 | 50 | // check length 51 | let len = input_text.len(); 52 | if len > 6 { 53 | panic!("Input too long!"); 54 | } 55 | 56 | // print number of permutations 57 | let total_perms = permutations(input_text); 58 | 59 | // sort/dedup are in-place 60 | let mut unique_perms = total_perms.clone(); 61 | 62 | // no chaining 63 | unique_perms.sort(); 64 | unique_perms.dedup(); 65 | println!("Permutations: \n{:?}\n", total_perms); 66 | println!("Distinct permutations: \n{:?}\n", unique_perms); 67 | println!("Total permutations: {}", total_perms.len()); 68 | println!("Distinct permutations: {}", unique_perms.len()); 69 | } 70 | 71 | 72 | #[test] 73 | fn find_permutations() { 74 | assert!(permutations("bar".to_string()) == ["bar", "abr", "arb", "bra", "rba", "rab"]); 75 | } -------------------------------------------------------------------------------- /20-quiz/quiz/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rustc_serialize; 2 | 3 | use std::fs::File; 4 | use std::io; 5 | use std::io::{ Read, Result }; 6 | use std::env; 7 | use rustc_serialize::json; 8 | 9 | #[derive(Debug, RustcDecodable)] 10 | struct Question { 11 | question: String, 12 | answer: String 13 | } 14 | 15 | fn check_answer(actual_answer: &String, answer: String) -> bool { 16 | actual_answer.trim().to_lowercase() == answer.trim().to_lowercase() 17 | } 18 | 19 | // returns result since we're using try! 20 | fn open_file(filename: &String) -> Result { 21 | let mut content = String::new(); 22 | let mut file = try!(File::open(filename)); 23 | try!(file.read_to_string(&mut content)); 24 | 25 | Ok(content) 26 | } 27 | 28 | fn get_questions(filename: &String) -> Vec { 29 | let questions = match open_file(filename) { 30 | Err(e) => panic!("Failed to read file: {:?}", e), 31 | Ok(result) => { 32 | let questions: Vec = match json::decode(&result) { 33 | Err(e) => panic!("Error parsing json: {}", e), 34 | Ok(quiz) => quiz 35 | }; 36 | 37 | questions 38 | } 39 | }; 40 | 41 | questions 42 | } 43 | 44 | fn ask_question(question: &Question) -> String { 45 | println!("{}", question.question); 46 | let mut answer = String::new(); 47 | io::stdin() 48 | .read_line(&mut answer) 49 | .expect("Enter your answer!"); 50 | 51 | answer 52 | } 53 | 54 | fn main() { 55 | let args: Vec = env::args().collect(); 56 | 57 | if args.len() < 2 { 58 | println!("Provide a quiz json file!"); 59 | return; 60 | } 61 | 62 | let questions = get_questions(&args[1]); 63 | let mut score = 0; 64 | let total = questions.len(); 65 | 66 | for question in questions { 67 | let answer = ask_question(&question); 68 | match check_answer(&question.answer, answer) { 69 | true => { 70 | println!("Correct!"); 71 | score = score + 1; 72 | }, 73 | false => { 74 | println!("Nope! The answer is {}", question.answer); 75 | } 76 | }; 77 | } 78 | 79 | println!("You scored {} out of {}", score, total); 80 | } 81 | 82 | #[test] 83 | fn it_checks_answers() { 84 | assert!(check_answer(&"Test".to_string(), "Test".to_string()) == true); 85 | assert!(check_answer(&"Test".to_string(), "test".to_string()) == true); 86 | assert!(check_answer(&"Test".to_string(), "test2".to_string()) == false); 87 | } -------------------------------------------------------------------------------- /15-piggy-bank/piggy/src/main.rs: -------------------------------------------------------------------------------- 1 | // Determine how much money is in a piggy bank that contains several 2 | // £2 coins, £1 coins, 50p coins, 20p coins, 10p coins and 3 | // 5p coins. 4 | 5 | use std::io; 6 | use std::io::Write; // stdout.flush 7 | 8 | #[derive(Debug)] 9 | struct Coin { 10 | value: i32, // monetary value in pence 11 | amount: i32 // number of coins 12 | } 13 | 14 | impl Coin { 15 | // &self - this is an instance method 16 | fn total(&self) -> i32 { 17 | self.value * self.amount 18 | } 19 | } 20 | 21 | fn get_input() -> i32 { 22 | let mut input_text = String::new(); 23 | io::stdin() 24 | .read_line(&mut input_text) 25 | .expect("Failed to read input"); 26 | let num: i32 = input_text.trim().parse().ok().expect("That's no number!"); 27 | 28 | num 29 | } 30 | 31 | // print! needs to be flushed to display 32 | fn print_line(text: &str) { 33 | print!("{}", text); 34 | io::stdout().flush().unwrap(); 35 | } 36 | 37 | fn pence_to_pounds(pence: i32) -> String { 38 | format!("£{:.2}", pence as f32 / 100f32) 39 | } 40 | 41 | fn get_total(coins: Vec) -> String { 42 | let mut total: i32 = 0; 43 | 44 | for coin in coins { 45 | total = total + coin.total(); 46 | } 47 | 48 | pence_to_pounds(total) 49 | } 50 | 51 | fn main() { 52 | let mut coins: Vec = Vec::new(); 53 | // create Coin for each, add to vec 54 | // iterate through vec, get total (reduce) 55 | println!("Enter number of coins: "); 56 | print_line("£2: "); 57 | coins.push(Coin { value: 200, amount: get_input() }); 58 | 59 | print_line("£1: "); 60 | coins.push(Coin { value: 100, amount: get_input() }); 61 | 62 | print_line("50p: "); 63 | coins.push(Coin { value: 50, amount: get_input() }); 64 | 65 | print_line("20p: "); 66 | coins.push(Coin { value: 20, amount: get_input() }); 67 | 68 | print_line("10p: "); 69 | coins.push(Coin { value: 10, amount: get_input() }); 70 | 71 | print_line("5p: "); 72 | coins.push(Coin { value: 5, amount: get_input() }); 73 | 74 | println!("\nTotal: {}", get_total(coins)); 75 | } 76 | 77 | // Use the following values to test your programme: 78 | // one £2, 79 | // three £1, 80 | // five 50p coins, 81 | // two 20p coins, 82 | // one 10p coin 83 | // and fifteen 5p coins. 84 | 85 | #[test] 86 | fn test_coins() { 87 | let mut coins: Vec = Vec::new(); 88 | 89 | coins.push(Coin { value: 200, amount: 1 }); 90 | coins.push(Coin { value: 100, amount: 3 }); 91 | coins.push(Coin { value: 50, amount: 5 }); 92 | coins.push(Coin { value: 20, amount: 2 }); 93 | coins.push(Coin { value: 10, amount: 1 }); 94 | coins.push(Coin { value: 5, amount: 15 }); 95 | 96 | assert!(get_total(coins) == "£8.75"); 97 | } -------------------------------------------------------------------------------- /22-matrix/matrix/src/main.rs: -------------------------------------------------------------------------------- 1 | // https://doc.rust-lang.org/std/ops/ 2 | // https://users.rust-lang.org/t/beginner-query-implementing-traits-for-generic-structs/2871/4 3 | extern crate matrix; 4 | extern crate util; 5 | 6 | use std::io; 7 | use std::io::prelude::*; 8 | use matrix::{ Matrix, random_matrix }; 9 | use util::read_number; 10 | 11 | fn get_user_matrix() -> Result, &'static str> { 12 | println!("Enter matrix row by row. Press 'enter' twice to finish"); 13 | 14 | let mut matrix: Vec> = Vec::new(); 15 | let stdin = io::stdin(); 16 | for line in stdin.lock().lines() { 17 | // read line by line 18 | // can't do it in one go - line.unwrap() doesn't live long enough 19 | let tmp = line.unwrap(); 20 | if tmp == "" { 21 | break; 22 | } 23 | 24 | let split_line: Vec<&str> = tmp.split(" ").collect(); 25 | let mut row: Vec = Vec::new(); 26 | for num in split_line { 27 | row.push(num.parse().ok().expect("Enter a number!")); 28 | } 29 | matrix.push(row); 30 | } 31 | 32 | if matrix.len() > 0 { 33 | // if uneven input, new_from_vec just takes len of first row 34 | let created = Matrix::new_from_vec(matrix); 35 | 36 | Ok(created) 37 | } else { 38 | Err("Enter the matrix") 39 | } 40 | 41 | } 42 | 43 | fn main() { 44 | println!("1. Enter matrices manually\n2. Use random matrices"); 45 | let input_type = read_number(); 46 | let mut first: Matrix; 47 | let mut second: Matrix; 48 | 49 | if input_type == 1 { 50 | // read in user matrix 51 | first = match get_user_matrix() { 52 | Err(e) => panic!("{:?}", e), 53 | Ok(matrix) => matrix 54 | }; 55 | 56 | second = match get_user_matrix() { 57 | Err(e) => panic!("{:?}", e), 58 | Ok(matrix) => matrix 59 | }; 60 | } else { 61 | println!("Enter rows:"); 62 | let rows: i32 = read_number(); 63 | 64 | println!("Enter cols:"); 65 | let cols: i32 = read_number(); 66 | 67 | first = random_matrix(rows, cols); 68 | second = random_matrix(rows, cols); 69 | } 70 | 71 | println!("Choose operation:\n1. Add\n2. Subtract,\n3. Multiply,\n4. Scalar multiply,\n5. Transpose"); 72 | let choice = read_number(); 73 | 74 | // clone's fine since we're just printing 75 | match choice { 76 | 1 => println!("{}\n + \n{} \n=\n {}", first.clone(), second.clone(), first + second), 77 | 2 => println!("{}\n - \n{} \n=\n {}", first.clone(), second.clone(), first - second), 78 | 3 => println!("{} \n* \n{}\n =\n {}", first.clone(), second.clone(), first * second), 79 | 4 => println!("{}\n *\n 2\n =\n {}", first.clone(), first.scalar_mul(2)), 80 | 5 => println!("{}", first.transpose()), 81 | _ => println!("Choose from options 1-5") 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /12-circle/circle/src/main.rs: -------------------------------------------------------------------------------- 1 | // Make a programme that allows the user to input either the radius, diameter, or area of the circle. 2 | // The programme should then calculate the other 2 based on the input. 3 | 4 | use std::io; 5 | 6 | #[derive(Debug)] 7 | pub struct Circle { 8 | radius: f64, 9 | diameter: f64, 10 | area: f64 11 | } 12 | 13 | impl Circle { 14 | fn radius(diameter: f64) -> f64 { 15 | diameter / 2f64 16 | } 17 | 18 | fn area(radius: f64) -> f64 { 19 | std::f64::consts::PI * (radius * radius) 20 | } 21 | 22 | fn diameter_from_area(area: f64) -> f64 { 23 | // sqrt(area/pi) = d 24 | (area/std::f64::consts::PI).sqrt() 25 | } 26 | 27 | fn new(radius: f64, diameter: f64, area: f64) -> Circle { 28 | Circle { 29 | radius: radius, 30 | diameter: diameter, 31 | area: area 32 | } 33 | } 34 | 35 | fn new_with_area(area: f64) -> Circle { 36 | // Self:: or Circle:: 37 | // Self = static type 38 | // Circle = explicit type 39 | let diameter = Self::diameter_from_area(area); 40 | let radius = Self::radius(diameter); 41 | 42 | Circle { 43 | radius: radius, 44 | diameter: diameter, 45 | area: area 46 | } 47 | } 48 | 49 | fn new_with_radius(radius: f64) -> Circle { 50 | Circle { 51 | radius: radius, 52 | diameter: 2.0 * radius, 53 | area: Self::area(radius) 54 | } 55 | } 56 | 57 | fn new_with_diameter(diameter: f64) -> Circle { 58 | let radius = Self::radius(diameter); 59 | 60 | Circle { 61 | diameter: diameter, 62 | radius: radius, 63 | area: Self::area(radius) 64 | } 65 | } 66 | } 67 | 68 | fn main() { 69 | let mut input = String::new(); 70 | 71 | println!("Pick an option:"); 72 | println!("1. Area"); 73 | println!("2. Radius"); 74 | println!("3. Diameter"); 75 | 76 | io::stdin() 77 | .read_line(&mut input) 78 | .expect("Failed to read input"); 79 | 80 | let option: f64 = match input.trim().parse() { 81 | Ok(num) => num, 82 | Err(_) => panic!("That's no number!") 83 | }; 84 | 85 | match option { 86 | 1f64 => println!("Enter area:"), 87 | 2f64 => println!("Enter radius:"), 88 | 3f64 => println!("Enter diameter:"), 89 | _ => panic!("Pick one of the options.") 90 | }; 91 | 92 | let mut size_string = String::new(); 93 | io::stdin() 94 | .read_line(&mut size_string) 95 | .expect("Failed to read input"); 96 | 97 | match size_string.trim().parse() { 98 | Ok(num) => { 99 | let circle = match option { 100 | 1f64 => Circle::new_with_area(num), 101 | 2f64 => Circle::new_with_radius(num), 102 | 3f64 => Circle::new_with_diameter(num), 103 | _ => Circle::new(0.0, 0.0, 0.0) 104 | }; 105 | 106 | println!("{:?}", circle); 107 | } 108 | Err(_) => panic!("That's no number") 109 | }; 110 | } 111 | -------------------------------------------------------------------------------- /26-todo/todo-web/src/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] extern crate nickel; 2 | extern crate rustc_serialize; 3 | extern crate handlebars; 4 | 5 | mod todo; 6 | mod store; 7 | mod template; 8 | 9 | // from http://fredrik.anderzon.se/2016/05/10/rust-for-node-developers-part-1-introduction/ 10 | use std::io; 11 | use nickel::{ Nickel, HttpRouter, FormBody }; 12 | // so you don't have to namespace everything 13 | use store::Action::{ Todos, Visibility }; 14 | use store::VisibilityFilter::{ ShowActive, ShowCompleted, ShowAll }; 15 | use store::{ Store, State, reducer }; 16 | use todo::TodoAction::{ Add, Remove, Toggle }; 17 | use todo::{ Todo }; 18 | use template::render; 19 | use std::sync::{ Arc, Mutex }; 20 | 21 | fn main() { 22 | let mut store = Store::create_store(reducer); 23 | store.dispatch(Todos(Add("First thing".to_string()))); 24 | store.dispatch(Todos(Add("Another thing".to_string()))); 25 | let store_container = Arc::new(Mutex::new(store)); 26 | 27 | let mut server = Nickel::new(); 28 | 29 | // create a store which is consumed by thread 30 | let store = store_container.clone(); 31 | server.get("/", middleware! { |_req, res| 32 | let store = store.lock().unwrap(); 33 | return render(res, "./src/todos.tpl", store.get_state()); 34 | }); 35 | 36 | let store = store_container.clone(); 37 | server.get("/:action/:id", middleware! { |req, res| 38 | let mut store = store.lock().unwrap(); 39 | 40 | if let Ok(num) = req.param("id").unwrap().parse::() { 41 | match req.param("action").unwrap() { 42 | "toggle" => store.dispatch(Todos(Toggle(num))), 43 | "remove" => store.dispatch(Todos(Remove(num))), 44 | _ => () 45 | } 46 | } else { 47 | // look for show action 48 | match req.param("action").unwrap() { 49 | "show" => { 50 | match req.param("id").unwrap() { 51 | "all" => store.dispatch(Visibility(ShowAll)), 52 | "active" => store.dispatch(Visibility(ShowActive)), 53 | "completed" => store.dispatch(Visibility(ShowCompleted)), 54 | _ => () 55 | } 56 | } 57 | _ => () 58 | } 59 | } 60 | 61 | return render(res, "./src/todos.tpl", store.get_state()); 62 | }); 63 | 64 | let store = store_container.clone(); 65 | server.post("/*", middleware! { |req, res| 66 | let mut store = store.lock().unwrap(); 67 | let form_body = req.form_body().ok().unwrap(); 68 | if let Some(new_todo) = form_body.get("todo") { 69 | if new_todo.len() > 0 { 70 | store.dispatch(Todos(Add(new_todo.to_string()))); 71 | } 72 | } 73 | return render(res, "./src/todos.tpl", store.get_state()); 74 | }); 75 | 76 | server.listen("0.0.0.0:1234").unwrap(); 77 | } 78 | -------------------------------------------------------------------------------- /30-youtube/youtube/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate reqwest; 2 | extern crate select; 3 | extern crate regex; 4 | extern crate serde_json; 5 | extern crate url; 6 | 7 | use std::io::{ Read }; 8 | use std::collections::HashMap; 9 | use select::document::Document; 10 | use select::predicate::{ Name }; 11 | use regex::Regex; 12 | use serde_json::{ Value, Error }; 13 | use url::percent_encoding::{ percent_decode }; 14 | 15 | fn parse_json(text: &str, start: usize) -> Result { 16 | let end_re = Regex::new(r";ytplayer.load =").unwrap(); 17 | // let mat = re.find(text).unwrap(); 18 | let end_pos = end_re.find(text).unwrap(); 19 | 20 | let start = start + 18; 21 | let end = end_pos.end() - 16; 22 | 23 | let slice = &text[start..end]; 24 | 25 | let parsed: Value = serde_json::from_str(slice)?; 26 | 27 | Ok(parsed) 28 | } 29 | 30 | fn main() { 31 | // let mut res = reqwest::get("https://www.youtube.com/watch?v=yfG94k41MrI").unwrap(); 32 | let mut res = reqwest::get("https://www.youtube.com/watch?v=NntQ86FHcMY").unwrap(); 33 | 34 | let mut content = String::new(); 35 | res.read_to_string(&mut content); 36 | 37 | // let dom = parse_document(RcDom::default(), Default::default()).from_bytes().read_from(&mut content.as_bytes()).unwrap(); 38 | // serialize(&mut io::stdout(), &dom.document, Default::default()); 39 | 40 | let re = Regex::new(r"ytplayer.config").unwrap(); 41 | // let end_re = Regex::new(r";ytplayer.load =").unwrap(); 42 | 43 | let doc = Document::from(content.as_str()); 44 | for node in doc.find(Name("script")) { 45 | // get text 46 | // search text for ytplayer.config 47 | // use that node 48 | // get json data from node 49 | if re.is_match(&node.text().to_string()) { 50 | let text = &node.text(); 51 | let mat = re.find(text).unwrap(); 52 | 53 | match parse_json(&node.text(), mat.start()) { 54 | Ok(parsed) => { 55 | let stream_map: String = parsed["args"]["url_encoded_fmt_stream_map"].to_string(); 56 | let mut videos: Vec> = vec![]; 57 | 58 | let urls: Vec<&str> = stream_map.split(",").collect(); 59 | for url in urls { 60 | let mut video: HashMap<&str, &str> = HashMap::new(); 61 | 62 | let params = url.split("&"); 63 | for param in params { 64 | let attr: Vec<&str> = param.split("=").collect(); 65 | video.insert(attr[0], attr[1]); 66 | } 67 | 68 | videos.push(video); 69 | }; 70 | 71 | // for video in videos { 72 | // println!("{:?}", video); 73 | // } 74 | println!("{:?}", videos[0]); 75 | let url = percent_decode(&videos[0].get("url").unwrap().as_bytes()).decode_utf8().unwrap(); 76 | println!("{:?}", url); 77 | let dl_url = format!("{}&signature={}&keepalive=yes", url, videos[0].get("s").unwrap().to_owned()); 78 | 79 | match reqwest::get(dl_url.as_str()) { 80 | Ok(res) => println!("{:?}", res), 81 | Err(e) => println!("{:?}", e) 82 | } 83 | break; 84 | }, 85 | Err(e) => panic!("Error parsing json: {}", e) 86 | } 87 | 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /28-markov/markov/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate regex; 2 | extern crate rand; 3 | 4 | use std::fs::File; 5 | use std::path::Path; 6 | use std::io::{ BufReader, BufRead }; 7 | use std::collections::HashMap; 8 | use std::env; 9 | 10 | use rand::distributions::{ Range, IndependentSample }; 11 | 12 | #[derive(Debug)] 13 | struct Markov { 14 | prefix: Vec, 15 | dict: HashMap, Vec>, 16 | order: u8 17 | } 18 | 19 | fn create_markov(filename: &Path, order: u8) -> Markov { 20 | let mut markov = Markov { 21 | dict: HashMap::new(), 22 | prefix: Vec::new(), 23 | order: order 24 | }; 25 | 26 | let file = match File::open(&filename) { 27 | Err(e) => panic!("Error reading file: {:?}", e), 28 | Ok(file) => file 29 | }; 30 | 31 | let buffer = BufReader::new(&file); 32 | for line in buffer.lines() { 33 | match line { 34 | Err(e) => println!("Error reading line: {:?}", e), 35 | Ok(line) => { 36 | for word in line.trim().split(" ").filter(|s| !s.is_empty()) { 37 | process_word(word, &mut markov); 38 | } 39 | } 40 | } 41 | } 42 | 43 | markov 44 | } 45 | 46 | fn process_word(word: &str, markov: &mut Markov) { 47 | if markov.prefix.len() < markov.order as usize { 48 | markov.prefix.push(word.to_string()); 49 | } else { 50 | let ref mut entry = *markov.dict.entry(markov.prefix.clone()).or_insert(Vec::new()); 51 | entry.push(word.to_string()); 52 | markov.prefix.remove(0); 53 | markov.prefix.push(word.to_string()) 54 | } 55 | } 56 | 57 | fn get_random_text(markov: &Markov, length: u8) -> String { 58 | let mut rng = rand::thread_rng(); 59 | let max = Range::new(0, markov.dict.len()); 60 | let index = max.ind_sample(&mut rng); 61 | 62 | let mut key: Vec = markov.dict.keys().collect::>()[index as usize].clone(); 63 | let mut sentence = String::new(); 64 | 65 | for word in &key { 66 | sentence += word.as_str(); 67 | sentence += " "; 68 | } 69 | 70 | for _ in 0..length { 71 | match markov.dict.get(&key) { 72 | None => println!("Error getting from dict: {:?} {:?}", key, markov.dict.get(&key)), 73 | Some(suffix) => { 74 | let between = Range::new(0, suffix.len()); 75 | let num = between.ind_sample(&mut rng); 76 | let word = suffix[num as usize].as_str(); 77 | 78 | sentence += word; 79 | sentence += " "; 80 | 81 | key.remove(0); 82 | key.push(word.to_string()); 83 | } 84 | }; 85 | } 86 | 87 | sentence 88 | } 89 | 90 | fn main() { 91 | let args: Vec = env::args().collect(); 92 | 93 | if args.len() < 2 { 94 | println!("Enter a file name"); 95 | } else { 96 | let ref filename = args[1]; 97 | let mut sentence_length = 200; 98 | let mut order: u8 = 2; 99 | 100 | if args.len() == 3 { 101 | sentence_length = args[2].parse().expect("Enter a number"); 102 | } 103 | 104 | if args.len() == 4 { 105 | order = args[3].parse().expect("Enter a number"); 106 | } 107 | 108 | // TODO: file, input or url 109 | let markov = create_markov(&Path::new(filename), order); 110 | println!("{}", get_random_text(&markov, sentence_length)); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /26-todo/todo/src/main.rs: -------------------------------------------------------------------------------- 1 | mod todo; 2 | mod store; 3 | 4 | // from http://fredrik.anderzon.se/2016/05/10/rust-for-node-developers-part-1-introduction/ 5 | use std::io; 6 | // so you don't have to namespace everything 7 | use store::Action::{ Todos, Visibility }; 8 | use store::VisibilityFilter::{ ShowActive, ShowCompleted, ShowAll }; 9 | use store::{ Store, State, reducer }; 10 | use todo::TodoAction::{ Add, Remove, Toggle }; 11 | use todo::{ Todo }; 12 | 13 | 14 | fn print_todo(todo: &Todo) { 15 | let completed = if todo.completed { "✔" } else { " " }; 16 | println!("[{}] {}. {}", completed, todo.id, todo.description); 17 | } 18 | 19 | fn print_todos(state: &State) { 20 | let visibility = &state.filter; 21 | 22 | println!("\nTodo list\n==================="); 23 | println!("Filter: {:?}", visibility); 24 | for todo in &state.todos { 25 | if !todo.deleted { 26 | match *visibility { 27 | ShowAll => print_todo(&todo), 28 | ShowCompleted => if todo.completed { 29 | print_todo(&todo) 30 | }, 31 | ShowActive => if !todo.completed { 32 | print_todo(&todo) 33 | } 34 | } 35 | } 36 | } 37 | 38 | if state.todos.len() as i16 == 0 { 39 | println!("(No items to display)"); 40 | } 41 | println!("\n"); 42 | } 43 | 44 | fn invalid_command(command: &str) { 45 | println!("Invalid command {}", command); 46 | } 47 | 48 | fn show_help() { 49 | println!("Commands:"); 50 | println!(" help: show this message"); 51 | println!(" add [text]: add a todo item with text"); 52 | println!(" toggle [id]: toggle selected item completed state"); 53 | println!(" list [all|active|completed]: filter items"); 54 | println!(" remove [id]: delete item") 55 | } 56 | 57 | fn main() { 58 | let mut store = Store::create_store(reducer); 59 | store.subscribe(print_todos); 60 | show_help(); 61 | print_todos(&store.state); 62 | 63 | loop { 64 | let mut command = String::new(); 65 | io::stdin() 66 | .read_line(&mut command) 67 | .expect("Failed to read input"); 68 | 69 | let command_parts: Vec<&str> = command.split_whitespace().collect(); 70 | 71 | match command_parts.len() { 72 | 0 => invalid_command(&command), 73 | _ => match command_parts[0] { 74 | "add" => store.dispatch(Todos(Add(command_parts[1..].join(" ").to_string() ))), 75 | "remove" => if let Ok(num) = command_parts[1].parse::() { 76 | store.dispatch(Todos(Remove(num))); 77 | }, 78 | "toggle" => if let Ok(num) = command_parts[1].parse::() { 79 | store.dispatch(Todos(Toggle(num))); 80 | }, 81 | "list" => { 82 | if command_parts.len() > 1 { 83 | match command_parts[1] { 84 | "all" => store.dispatch(Visibility(ShowAll)), 85 | "active" => store.dispatch(Visibility(ShowActive)), 86 | "completed" => store.dispatch(Visibility(ShowCompleted)), 87 | _ => invalid_command(&command) 88 | } 89 | } else { 90 | store.dispatch(Visibility(ShowAll)) 91 | } 92 | }, 93 | "help" => show_help(), 94 | _ => invalid_command(&command) 95 | } 96 | } 97 | } 98 | 99 | } 100 | -------------------------------------------------------------------------------- /29-noughts-and-crosses/noughts-and-crosses/src/store.rs: -------------------------------------------------------------------------------- 1 | //! Contains game state and the store, and related reducer functions 2 | 3 | use board::{ Board, Pieces }; 4 | 5 | /// The store - all game data is saved here and is read-only 6 | /// The only way to change this data is through a reducer function 7 | pub struct Store { 8 | pub state: State, 9 | reducer: fn(&State, Action) -> State 10 | } 11 | 12 | impl Store { 13 | pub fn create_store(reducer: fn(&State, Action) -> State) -> Store { 14 | Store { 15 | state: State::default(), 16 | reducer: reducer 17 | } 18 | } 19 | 20 | /// Trigger an update on the store 21 | pub fn dispatch(&mut self, action: Action) { 22 | self.state = (self.reducer)(&self.state, action); 23 | } 24 | } 25 | 26 | #[derive(Clone, PartialEq, Debug)] 27 | pub enum GameStatus { 28 | Playing, 29 | Won, 30 | Lost, 31 | Draw 32 | } 33 | 34 | // Current state of the game 35 | /// - board: all pieces 36 | /// - status: is the game in progress or has the player won or lost 37 | /// - winner: the token of the winning player 38 | #[derive(Clone)] 39 | pub struct State { 40 | pub board: Board, 41 | pub status: GameStatus, 42 | pub winner: Pieces 43 | } 44 | 45 | impl State { 46 | pub fn default() -> Self { 47 | State { 48 | board: Board::new(), 49 | status: GameStatus::Playing, 50 | winner: Pieces::Empty 51 | } 52 | } 53 | } 54 | 55 | /// Actions which can be dispatched to updated the state 56 | #[derive(Clone)] 57 | pub enum Action { 58 | BoardUpdate(BoardAction), 59 | Status(StatusAction), 60 | Winner(WinnerAction) 61 | } 62 | 63 | /// Reducers take a slice of state data and an action, then return a new state slice 64 | /// with updated data 65 | pub fn reducer(state: &State, action: Action) -> State { 66 | State { 67 | board: board_reducer(&state.board, &action), 68 | status: status_reducer(&state.status, &action), 69 | winner: winner_reducer(&state.winner, &action) 70 | } 71 | } 72 | 73 | /// Board actions and reducer just add pieces to the board 74 | #[derive(Clone)] 75 | pub enum BoardAction { 76 | Update(u8, u8, Pieces) 77 | } 78 | 79 | fn board_reducer(state: &Board, action: &Action) -> Board { 80 | let mut new_board: Board = state.clone(); 81 | 82 | match *action { 83 | Action::BoardUpdate(ref board_action) => match *board_action { 84 | BoardAction::Update(x, y, ref token) => { 85 | new_board.update(x, y, token); 86 | }, 87 | }, 88 | _ => () 89 | } 90 | 91 | new_board 92 | } 93 | 94 | /// Game action/reducer changes the status (is game in progress or not) 95 | #[derive(Clone)] 96 | pub enum StatusAction { 97 | Update(GameStatus) 98 | } 99 | 100 | fn status_reducer(state: &GameStatus, action: &Action) -> GameStatus { 101 | let mut new_status: GameStatus = state.clone(); 102 | 103 | match *action { 104 | Action::Status(ref status_action) => match *status_action { 105 | StatusAction::Update(ref status) => { 106 | new_status = status.clone(); 107 | } 108 | }, 109 | _ => () 110 | } 111 | 112 | new_status 113 | } 114 | 115 | /// Winner action/reducer contains the token of the winning player 116 | #[derive(Clone)] 117 | pub enum WinnerAction { 118 | Update(Pieces) 119 | } 120 | 121 | fn winner_reducer(winner: &Pieces, action: &Action) -> Pieces { 122 | let mut new_winner: Pieces = winner.clone(); 123 | 124 | match *action { 125 | Action::Winner(ref winner_action) => match *winner_action { 126 | WinnerAction::Update(ref token) => { 127 | new_winner = token.clone(); 128 | } 129 | }, 130 | _ => () 131 | } 132 | 133 | new_winner 134 | } 135 | -------------------------------------------------------------------------------- /19-primes/primes/src/main.rs: -------------------------------------------------------------------------------- 1 | // Write a programme which will print all the pairs of prime numbers 2 | // whose sum equals the number entered by the user. 3 | 4 | use std::io; 5 | 6 | // http://stackoverflow.com/a/1801446/345078 7 | fn is_prime(n: u64) -> bool { 8 | if n < 4 { 9 | return true; 10 | } 11 | 12 | if n % 2 == 0 { 13 | return false; 14 | } 15 | 16 | if n % 3 == 0 { 17 | return false; 18 | } 19 | 20 | // every prime takes the form 6k +/- 1 21 | let mut i = 5; 22 | let mut w = 2; 23 | 24 | while i * i <= n { 25 | if n % i == 0 { 26 | return false; 27 | } 28 | 29 | i = i + w; 30 | w = 6 - w; 31 | } 32 | 33 | true 34 | } 35 | 36 | fn create_sieve(limit: u64) -> Vec { 37 | // sieve of eratosthenes 38 | // create list from 2..limit 39 | // let p = 2 (smallest prime) 40 | // enumerate multiples of p up to limit ie 2p, 3p, 4p... and mark as not prime 41 | // p = first number not marked; if none then return list 42 | 43 | // vec with default vals 44 | let mut x = vec![true; (limit + 1) as usize]; 45 | x[0] = false; 46 | x[1] = false; 47 | let len = x.len(); 48 | 49 | for i in 2..len { 50 | if x[i as usize] == true { 51 | let step = i; 52 | 53 | // start at square instead of 2p (will have already been checked) 54 | let mut n = i * i; 55 | while n < len { 56 | x[n as usize] = false; 57 | 58 | n = n + step; 59 | } 60 | 61 | // this would be handy D: 62 | // for n in (i*i)..limit.step_by(i) { 63 | // x[n as usize] = false; 64 | // } 65 | } 66 | } 67 | 68 | x 69 | } 70 | 71 | fn main() { 72 | let mut input = String::new(); 73 | println!("Enter a number:"); 74 | 75 | io::stdin() 76 | .read_line(&mut input) 77 | .expect("Failed to read input"); 78 | 79 | let target: u64 = input.trim().parse().expect("That's no number!"); 80 | let mut results: Vec<(u64, u64)> = Vec::new(); 81 | 82 | // two methods: 1. walk through list of numbers to halfway 83 | // and check if they're prime 84 | for i in 2..target / 2 { 85 | if is_prime(i) { 86 | if is_prime(target - i) {; 87 | results.push((i, target - i)); 88 | } 89 | } 90 | } 91 | println!("{:?}", results); 92 | 93 | let mut sieve_results: Vec<(u64, u64)> = Vec::new(); 94 | // 2. make a sieve of primes and iterate through 95 | let sieve = create_sieve(target); 96 | for i in 1..target / 2 { 97 | if sieve[i as usize] == true { 98 | if sieve[(target - i) as usize] == true { 99 | sieve_results.push((i, target - i)); 100 | } 101 | } 102 | } 103 | println!("{:?}", sieve_results); 104 | 105 | 106 | assert!(results == sieve_results); 107 | } 108 | 109 | #[test] 110 | fn test_sieve() { 111 | let sieve = create_sieve(32); 112 | 113 | assert!(sieve[2] == true); 114 | assert!(sieve[3] == true); 115 | assert!(sieve[4] == false); 116 | assert!(sieve[5] == true); 117 | assert!(sieve[6] == false); 118 | assert!(sieve[7] == true); 119 | assert!(sieve[8] == false); 120 | assert!(sieve[9] == false); 121 | assert!(sieve[10] == false); 122 | assert!(sieve[11] == true); 123 | assert!(sieve[12] == false); 124 | assert!(sieve[13] == true); 125 | assert!(sieve[14] == false); 126 | assert!(sieve[15] == false); 127 | assert!(sieve[16] == false); 128 | assert!(sieve[17] == true); 129 | assert!(sieve[18] == false); 130 | assert!(sieve[19] == true); 131 | assert!(sieve[20] == false); 132 | assert!(sieve[21] == false); 133 | assert!(sieve[22] == false); 134 | assert!(sieve[23] == true); 135 | assert!(sieve[24] == false); 136 | assert!(sieve[25] == false); 137 | assert!(sieve[26] == false); 138 | assert!(sieve[27] == false); 139 | assert!(sieve[28] == false); 140 | assert!(sieve[29] == true); 141 | assert!(sieve[30] == false); 142 | assert!(sieve[31] == true); 143 | assert!(sieve[32] == false); 144 | } 145 | 146 | #[test] 147 | fn test_prime() { 148 | assert!(is_prime(2) == true); 149 | assert!(is_prime(3) == true); 150 | assert!(is_prime(4) == false); 151 | assert!(is_prime(8) == false); 152 | assert!(is_prime(11) == true); 153 | assert!(is_prime(13) == true); 154 | assert!(is_prime(14) == false); 155 | assert!(is_prime(20) == false); 156 | assert!(is_prime(29) == true); 157 | } -------------------------------------------------------------------------------- /29-noughts-and-crosses/noughts-and-crosses/src/board.rs: -------------------------------------------------------------------------------- 1 | //! Board layout and logic 2 | 3 | use std::fmt::{ Display, Formatter, Result }; 4 | 5 | /// The states for a place on the board 6 | #[derive(PartialEq, Clone, Debug)] 7 | pub enum Pieces { 8 | Player, 9 | AI, 10 | Empty 11 | } 12 | 13 | impl Display for Pieces { 14 | fn fmt(&self, f: &mut Formatter) -> Result { 15 | match self { 16 | &Pieces::Player => try!(write!(f, "x")), 17 | &Pieces::AI => try!(write!(f, "o")), 18 | &Pieces::Empty => try!(write!(f, ".")) 19 | }; 20 | 21 | Ok(()) 22 | } 23 | } 24 | 25 | /// The board 26 | #[derive(Clone)] 27 | pub struct Board { 28 | pub board: Vec> 29 | } 30 | 31 | impl Board { 32 | pub fn new() -> Self { 33 | Board { 34 | board: vec![ 35 | vec![Pieces::Empty, Pieces::Empty, Pieces::Empty], 36 | vec![Pieces::Empty, Pieces::Empty, Pieces::Empty], 37 | vec![Pieces::Empty, Pieces::Empty, Pieces::Empty] 38 | ] 39 | } 40 | } 41 | 42 | /// Add a piece to the board 43 | pub fn update(&mut self, x: u8, y: u8, token: &Pieces) { 44 | if self.can_place(x, y) { 45 | self.board[x as usize][y as usize] = token.clone(); 46 | } 47 | } 48 | 49 | /// Checks that there are still empty spaces on the board 50 | pub fn has_space(&self) -> bool { 51 | let mut space = false; 52 | for row in &self.board { 53 | if row.contains(&Pieces::Empty) { 54 | space = true; 55 | break; 56 | } 57 | }; 58 | 59 | space 60 | } 61 | 62 | 63 | /// Checks particular co-ord on the board is available to play 64 | pub fn can_place(&self, x: u8, y: u8) -> bool { 65 | self.board[x as usize][y as usize] == Pieces::Empty 66 | } 67 | 68 | /// Check if any line has all the same pieces 69 | /// Since it's only a small board we don't need to check every square for neighbours 70 | /// just top, bottom, left, right and two diagonal rows 71 | pub fn check_neighbours(&self) -> Pieces { 72 | let mut token = Pieces::Empty; 73 | 74 | if self.check_top() { 75 | token = self.board[0][0].clone(); 76 | } else if self.check_centre() { 77 | token = self.board[1][1].clone(); 78 | } else if self.check_left() { 79 | token = self.board[1][0].clone(); 80 | } else if self.check_right() { 81 | token = self.board[1][2].clone(); 82 | } else if self.check_bottom() { 83 | token = self.board[2][1].clone(); 84 | } 85 | 86 | token 87 | } 88 | 89 | fn check_top(&self) -> bool { 90 | self.board[0][0] != Pieces::Empty && (self.board[0][0] == self.board[0][2] && self.board[0][0] == self.board[0][1]) 91 | } 92 | 93 | fn check_centre(&self) -> bool { 94 | let vert = self.board[1][1] != Pieces::Empty && (self.board[1][1] == self.board[0][1] && self.board[1][1] == self.board[2][1]); 95 | let horz = self.board[1][1] != Pieces::Empty && (self.board[1][1] == self.board[1][0] && self.board[1][1] == self.board[1][2]); 96 | let right_diag = self.board[1][1] != Pieces::Empty && (self.board[1][1] == self.board[0][0] && self.board[1][1] == self.board[2][2]); 97 | let left_diag = self.board[1][1] != Pieces::Empty && (self.board[1][1] == self.board[0][2] && self.board[1][1] == self.board[2][0]); 98 | 99 | vert || horz || right_diag || left_diag 100 | } 101 | 102 | fn check_left(&self) -> bool { 103 | self.board[1][0] != Pieces::Empty && self.board[1][0] == self.board[0][0] && self.board[1][0] == self.board[2][0] 104 | } 105 | 106 | fn check_right(&self) -> bool { 107 | self.board[1][2] != Pieces::Empty && self.board[1][2] == self.board[0][2] && self.board[1][2] == self.board[2][2] 108 | } 109 | 110 | fn check_bottom(&self) -> bool { 111 | self.board[2][1] != Pieces::Empty && self.board[2][1] == self.board[2][0] && self.board[2][1] == self.board[2][2] 112 | } 113 | } 114 | 115 | impl Display for Board { 116 | fn fmt(&self, f: &mut Formatter) -> Result { 117 | let row_names = vec!['a', 'b', 'c']; 118 | 119 | try!(write!(f, " ")); 120 | for col in 0..self.board[0].len() { 121 | try!(write!(f, " {} ", col + 1)); 122 | } 123 | 124 | try!(write!(f, "\n")); 125 | 126 | for row in 0..self.board.len() { 127 | try!(write!(f, "{} ", row_names[row])); 128 | 129 | for col in 0..self.board[row].len() { 130 | try!(write!(f, " {} ", self.board[row as usize][col as usize])); 131 | } 132 | try!(write!(f, "\n")); 133 | } 134 | 135 | Ok(()) 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /29-noughts-and-crosses/noughts-and-crosses/src/main.rs: -------------------------------------------------------------------------------- 1 | //! # Noughts and Crosses 2 | //! 3 | //! A noughts and crosses game for the command line 4 | //! Based on Redux principles - one (immutable) store for game state 5 | //! all changes to state are requested via reducer functions which 6 | //! return a new state with the changes applied. 7 | 8 | extern crate rand; 9 | 10 | mod board; 11 | mod store; 12 | mod ai; 13 | 14 | use std::io; 15 | use rand::Rng; 16 | 17 | use board::{ Pieces }; 18 | use store::{ Store, State, GameStatus, BoardAction, WinnerAction, StatusAction, reducer }; 19 | use store::Action::{ BoardUpdate, Winner, Status }; 20 | 21 | /// Sets the winner in game state, and updates status to not be 'playing' 22 | fn winner(store: &mut Store, token: Pieces) { 23 | store.dispatch(Winner(WinnerAction::Update(token.clone()))); 24 | 25 | if token == Pieces::Player { 26 | store.dispatch(Status(StatusAction::Update(GameStatus::Won))); 27 | } else { 28 | store.dispatch(Status(StatusAction::Update(GameStatus::Lost))); 29 | } 30 | } 31 | 32 | /// Put a piece on the board at position 33 | /// then check to see if anyone has won 34 | fn place_piece(pos: (u8, u8), mut store: &mut Store, token: Pieces) { 35 | store.dispatch(BoardUpdate(BoardAction::Update(pos.0, pos.1 - 1, token))); 36 | 37 | print_board(&store.state); 38 | 39 | // does this need to be a match? 40 | let token: Pieces = store.state.board.check_neighbours(); 41 | match token { 42 | Pieces::Empty => (), 43 | _ => winner(&mut store, token) 44 | }; 45 | } 46 | 47 | /// print out the current state of the board 48 | fn print_board(state: &State) { 49 | println!("{}", state.board); 50 | } 51 | 52 | /// Show the winner 53 | fn print_winner(state: &State) { 54 | println!("Game over! {:?}", state.status); 55 | } 56 | 57 | /// Main part of the game loop 58 | /// - take in player input and parse 59 | /// - attempt to place a piece if valid 60 | /// - try to trigger the AI to place a piece 61 | fn take_turn(mut store: &mut Store) { 62 | // get input 63 | println!("Enter position: "); 64 | let mut command = String::new(); 65 | io::stdin().read_line(&mut command) 66 | .expect("Failed to read input"); 67 | 68 | // expect input to be in format "a1" etc 69 | match command.trim().len() { 70 | 2 => { 71 | // split into chars, remove any empty pieces 72 | let position: Vec<&str> = command.trim().split("").filter(|s| !s.is_empty()).collect(); 73 | 74 | match position[1].parse::() { 75 | Ok(y) => { 76 | let x: u8 = match position[0] { 77 | "b" => 1, 78 | "c" => 2, 79 | _ => 0 80 | }; 81 | 82 | if y > 0 && y < 4 { 83 | place_piece((x, y), &mut store, Pieces::Player) 84 | } else { 85 | println!("Try choosing somewhere on the board"); 86 | } 87 | }, 88 | Err(_) => println!("Make sure you enter a position on the board (eg a1)") 89 | } 90 | }, 91 | _ => println!("I'm sorry, I don't understand {}", command) 92 | } 93 | 94 | // TODO: don't move ai until player has made a valid move 95 | if store.state.board.has_space() { 96 | ai::place(&mut store); 97 | } else { 98 | store.dispatch(Status(StatusAction::Update(GameStatus::Draw))); 99 | } 100 | } 101 | 102 | /// Start the game loop 103 | fn main() { 104 | let mut store = Store::create_store(reducer); 105 | store.dispatch(Status(StatusAction::Update(GameStatus::Playing))); 106 | 107 | print_board(&store.state); 108 | 109 | // let the ai go first sometimes 110 | if rand::thread_rng().gen_range(0, 2) == 1 { 111 | ai::place(&mut store); 112 | } 113 | 114 | loop { 115 | if store.state.status == GameStatus::Playing { 116 | take_turn(&mut store); 117 | } else { 118 | break; 119 | } 120 | } 121 | 122 | print_winner(&store.state); 123 | } 124 | 125 | #[cfg(test)] 126 | mod tests { 127 | use board::{ Pieces }; 128 | use store::{ Store, GameStatus, StatusAction, reducer }; 129 | use store::Action::{ Status }; 130 | 131 | #[test] 132 | fn can_place() { 133 | let mut store = Store::create_store(reducer); 134 | store.dispatch(Status(StatusAction::Update(GameStatus::Playing))); 135 | 136 | assert!(store.state.board.board[0][0] == Pieces::Empty); 137 | 138 | super::place_piece((0, 1), &mut store, Pieces::Player); 139 | assert!(store.state.board.board[0][0] == Pieces::Player); 140 | 141 | super::place_piece((1, 1), &mut store, Pieces::AI); 142 | assert!(store.state.board.board[1][0] == Pieces::AI); 143 | } 144 | 145 | #[test] 146 | fn cant_overwrite() { 147 | let mut store = Store::create_store(reducer); 148 | store.dispatch(Status(StatusAction::Update(GameStatus::Playing))); 149 | assert!(store.state.board.board[0][0] == Pieces::Empty); 150 | 151 | super::place_piece((0, 1), &mut store, Pieces::Player); 152 | assert!(store.state.board.board[0][0] == Pieces::Player); 153 | 154 | super::place_piece((0, 1), &mut store, Pieces::AI); 155 | assert!(store.state.board.board[0][0] == Pieces::Player); 156 | } 157 | 158 | #[test] 159 | fn can_win() { 160 | let mut store = Store::create_store(reducer); 161 | store.dispatch(Status(StatusAction::Update(GameStatus::Playing))); 162 | assert!(store.state.board.board[0][0] == Pieces::Empty); 163 | 164 | super::place_piece((0, 1), &mut store, Pieces::Player); 165 | super::place_piece((0, 2), &mut store, Pieces::Player); 166 | super::place_piece((0, 3), &mut store, Pieces::Player); 167 | assert!(store.state.status == GameStatus::Won); 168 | assert!(store.state.winner == Pieces::Player); 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /21-html/deas.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Don't Expect Anything Sensible 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 21 | 24 | 25 |
26 | 27 |

Don't Expect
Anything Sensible

28 |
29 | 30 |
31 |
32 |

An independent games studio based in Bristol. To receive updates and alpha invitations, sign up below.

33 | 34 |
35 |
36 |
37 | 38 |
39 | 40 | 41 | 42 |
43 |
44 | 45 | 46 |
47 | 48 |
49 |
50 |
51 |
52 | 53 | 60 | 61 | 62 | Play the alpha of our latest game here 63 | Play our infinite runner game 64 | 65 | 66 | 70 | 71 |
72 | 73 |
74 |

75 | Get in touch. 76 | Background images via Gratisography. 77 |

78 | 79 |

Don't Expect Anything Sensible Ltd is a company registered in England and Wales, registered number 09278114. Registered address: Unit 11 Hove Business Centre, Fonthill Road, Hove, East Sussex, BN3 6HA UK.

80 |
81 | 82 | 83 | 84 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | # Small projects to learn C++ and Rust. 2 | 3 | List from http://www.cplusplus.com/forum/beginner/3473/ 4 | 5 | ## Beginner 6 | 7 | 1. [x] Write a programme which finds the factorial of a number entered by the user. (check for all conditions). 8 | 2. [x] Develop a programme to convert currency X to currency Y and vice versa. 9 | 3. [x] Write a programme that prints out a triangle from largest to smallest; user inputs the largest number. Eg: 10 | 11 | ``` 12 | ***** 13 | **** 14 | *** 15 | ** 16 | * 17 | ``` 18 | 19 | 4. [x] Write a programme that prints out a triangle from smallest to largest; user inputs bottom number. Eg: 20 | 21 | ``` 22 | * 23 | ** 24 | *** 25 | **** 26 | ****** 27 | ``` 28 | 29 | 5. [x] Print out a triangle from smallest to largest, skipping even rows. User inputs largest number, eg: 30 | 31 | ``` 32 | * 33 | *** 34 | ***** 35 | ******* 36 | ``` 37 | 38 | 6. [x] Develop a programme that uses a randomly generated number to select 1 of 3 (or more) functions to show the user. 39 | 7. [x] Guessing game. ask the user to guess a number between 1 and a 100. If you guessed correctly, it will say you win. If you're too high or too low it will also let you know. 40 | 8. [x] Create a programme which generates Fibonacci series til a number 'n', where 'n' is entered by the user. Eg if the user enters 10 then the output would be: `1 1 2 3 5 8` 41 | 9. [x] Given a string, determine how many of the characters are vowels and how many are consonants. Terminate the string when the input character encountered is non-alphabetic. 42 | 10. [x] Find the Fifth root of the sum of the squares of the first 100 ODD numbers only. 43 | 11. [x] List all possible combinations of letters in a 4-letter word. Eg 'TEST' can be unscrambled as TEST, TETS, TSET, TSTE, TTSE, TTES, etc. 44 | 12. [x] Make a programme that allows the user to input either the radius, diameter, or area of the circle. The programme should then calculate the other 2 based on the input. 45 | 13. [x] Read a line of text and write it out backwards using a recursive function. 46 | 14. [x] Write a programme to simulate a simple calculator. It should accept two numbers from the user along with the required operation to be performed. Addition, subtraction, division and multiplication are the basic operations that should be implemented. Feel free to implement other operations. Bonus points for splitting the calculation functions into a separate module. 47 | 15. [x] Determine how much money is in a piggy bank that contains several £2 coins, £1 coins, 50p coins, 20p coins, 10p coins and 5p coins. Use the following values to test your programme: one £2, three £1, five 50p coins, two 20p coins, one 10p coin and fifteen 5p coins. 48 | 16. [x] Create a simple palindrome checker programme. The programme should allow the user to enter a string and check whether the given string is a palindrome or not. Only digits and alphabets should be considered while checking for palindromes - any other characters are to be ignored. 49 | 17. [x] Write a programme that allows you to input students' midterm, final and homework scores, and calculate a weighted score. Use the following weights: 20% midterm, 40% final, 40% median homework. 50 | 51 | ## Intermediate 52 | 53 | 18. [x] Simple file encryption (using something simple like ROT13). 54 | 19. [x] Write a programme which will print all the pairs of prime numbers whose sum equals the number entered by the user. Eg 10 = 5 + 5, 7 + 3; 12 = 11 + 1, 5 + 7 55 | 20. [x] Write a quiz which retrieves a question and answer from a file. Allow the user to take the quiz, count points total and show score. 56 | 21. [x] Read XHTML, remove the tags, then print out the remaining text. 57 | 22. [x] Write a programme which performs addition, subtraction, multiplication of matrices. The dimensions of both the matrices would be specified by the user (dynamic memory allocation required). Use of structure or a class to define the matrix would be a good idea. 58 | 23. [ ] Write a programme which will perform the job of moving the file from one location to another. The source and destination path will be entered by the user. Perform the required error checking and handle the exceptions accordingly. 59 | 24. [ ] Create a sophisticated linked list class. You should be able to insert and delete nodes anywhere in the list, and the linked list should be (doubly linked)[https://en.wikipedia.org/wiki/Doubly_linked_list]. 60 | 25. [ ] Create a programme that implements a database. The fields are hard-coded, and the data is saved in a binary file. Although this isn't really flexibility, you aren't relying on any external libraries or functions. 61 | 26. [x] Create a command-line todo list. Users should be able to add, complete and delete items. Bonus: use a database (eg SQLite) to persist todo items between programme runs. 62 | 63 | ## Expert 64 | 65 | - [ ] Write a programme which acted like a personal planner. A user can input an event, note things to-do on a certain date. 66 | 28. [x] Make a Markov chain generator. Read text from a source, create a histogram and allow different prefix lengths. See [Think Python](http://greenteapress.com/thinkpython2/html/thinkpython2014.html#sec159) for info. 67 | 29. [x] Noughts and crosses game. 68 | 30. [ ] Create a Youtube video downloader (actually really difficult cos Youtube tries to block everything) 69 | - [ ] Write a phone/address book programme, with persistent data. The users should be able to add/delete/change the data. 70 | - [ ] Write a simple payroll programme, that would include pay rates, and hours work for employees. 71 | - [ ] Write a card game, eg blackjack 72 | - [ ] Create a chess game. 73 | - [ ] Create a binary tree which has search and sorting functions. 74 | - [ ] Create a Quine, (a programme that prints out its own source code). 75 | - [ ] [C++] Implement your own `strstr`. 76 | - [ ] [C++] Implement your own version of the Standard Template Library. 77 | - [ ] [Make a pokedex](http://codereview.stackexchange.com/questions/135293/basic-pokedex-in-c) - use a database, enums for types/gender etc 78 | - [ ] Video format converter, eg .mov to .mp4 (ie frontend to ffmpeg) 79 | - [ ] URL shortener service 80 | 81 | ## Graphics 82 | 83 | - [ ] Write a programme to draw a rectangle, ellipse, square, circle, point and line based on user input. 84 | - [ ] Create a paint programme. It should be possible to switch between different tools (circle, rectangle, eraser etc) using pre-defined key strokes. 85 | - [ ] Plot a simple x-y graph for a hardcoded function (e.g. y=cos(x)). It should be possible to zoom in on any part of the graph. 86 | - [ ] Write a programme to plot a graph of given equation of form y=f(x) and a range for x as command line arguments. (e.g. my_graph_plotter -eq="y=x*x" -xmin=-10, -xmax=10) (PS: more to do with equation solving than graphics) 87 | - [ ] Write the classic brick break-out game (Arkanoid/Breakout) 88 | 89 | fuzzy search (levenstein) 90 | gui 91 | generative art 92 | 93 | Good resources for Rust: 94 | - https://github.com/kud1ing/awesome-rust 95 | - https://github.com/ctjhoa/rust-learning 96 | - https://github.com/cis198-2016s 97 | - http://fredrik.anderzon.se/2016/05/10/rust-for-node-developers-part-1-introduction/ 98 | - http://www.arewewebyet.org/#getting-started 99 | - http://cglab.ca/~abeinges/blah/too-many-lists/book/ 100 | - https://www.reddit.com/r/rust/comments/5d4h8l/school_vacation_starts_tomorrow_i_want_to_know/da1zdiz/ 101 | -------------------------------------------------------------------------------- /22-matrix/matrix/matrix/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | 3 | use std::fmt::{ Display, Result, Formatter }; 4 | use std::ops::{ Add, Sub, Mul }; 5 | use rand::Rng; 6 | 7 | #[derive(Debug, Clone)] 8 | pub struct Matrix { 9 | rows: i32, 10 | cols: i32, 11 | matrix: Vec> 12 | } 13 | 14 | impl Matrix where T: Copy + Default { 15 | pub fn new(rows: i32, cols: i32, val: T) -> Self { 16 | let mut _rows: Vec> = Vec::new(); 17 | 18 | for _ in 0..rows { 19 | let _row = vec![val; cols as usize]; 20 | _rows.push(_row); 21 | } 22 | 23 | Matrix { rows: rows, cols: cols, matrix: _rows } 24 | } 25 | 26 | pub fn new_from_vec(data: Vec>) -> Self { 27 | let rows = data.len() as i32; 28 | let cols = data[0].len() as i32; 29 | 30 | Matrix { rows: rows, cols: cols, matrix: data } 31 | } 32 | 33 | pub fn scalar_mul(self, multiplier: T) -> Self where T: Mul + Copy + Default { 34 | let mut new_matrix = Matrix::new(self.rows, self.cols, Default::default()); 35 | 36 | for i in 0..self.rows { 37 | let row = i as usize; 38 | 39 | for j in 0..self.cols { 40 | let col = j as usize; 41 | 42 | new_matrix.matrix[row][col] = self.matrix[row][col] * multiplier; 43 | } 44 | } 45 | 46 | new_matrix 47 | } 48 | 49 | pub fn transpose(self) -> Self { 50 | let mut new_matrix = Matrix::new(self.cols, self.rows, Default::default()); 51 | for i in 0..self.rows { 52 | let row = i as usize; 53 | 54 | for j in 0..self.cols { 55 | let col = j as usize; 56 | 57 | new_matrix.matrix[col][row] = self.matrix[row][col]; 58 | } 59 | } 60 | 61 | new_matrix 62 | } 63 | } 64 | 65 | // Make sure generic type T implements Add (so you can add them together) 66 | // Copy so we can copy self.rows/self.cols to new matrix 67 | // and Default, so we can use that to fill the matrix 68 | // ensures the T implementation returns a T 69 | impl Add for Matrix where T: Add + Copy + Default { 70 | type Output = Matrix; 71 | 72 | fn add(self, other: Matrix) -> Matrix { 73 | let mut new_matrix = Matrix::new(self.rows, self.cols, Default::default()); 74 | 75 | for i in 0..self.rows { 76 | let row = i as usize; 77 | for j in 0..self.cols { 78 | let col = j as usize; 79 | new_matrix.matrix[row][col] = self.matrix[row][col] + other.matrix[row][col]; 80 | } 81 | } 82 | 83 | new_matrix 84 | } 85 | } 86 | 87 | impl Sub for Matrix where T: Sub + Copy + Default { 88 | type Output = Matrix; 89 | 90 | fn sub(self, other: Matrix) -> Matrix { 91 | let mut new_matrix: Matrix = Matrix::new(self.rows, self.cols, Default::default()); 92 | 93 | for i in 0..self.rows { 94 | let row = i as usize; 95 | 96 | for j in 0..self.cols { 97 | let col = j as usize; 98 | 99 | new_matrix.matrix[row][col] = self.matrix[row][col] - other.matrix[row][col]; 100 | } 101 | } 102 | 103 | new_matrix 104 | } 105 | } 106 | 107 | impl Mul for Matrix where T: Mul + Copy + Default + Add { 108 | type Output = Matrix; 109 | 110 | // this is dot product 111 | fn mul(self, other: Matrix) -> Matrix { 112 | // TODO: add a check for other.rows and self.cols (currently panics) 113 | // other.rows must eq self.cols 114 | // size = self.rows x other.cols 115 | 116 | // http://www.freemathhelp.com/matrix-multiplication.html 117 | let mut new_matrix: Matrix = Matrix::new(self.rows, other.cols, Default::default()); 118 | 119 | for i in 0..self.rows { 120 | for j in 0..other.cols { 121 | let mut total: T = Default::default(); 122 | for k in 0..other.rows { 123 | total = total + self.matrix[i as usize][k as usize] * other.matrix[k as usize][j as usize]; 124 | } 125 | // each number in self.row * each number in other.col 126 | new_matrix.matrix[i as usize][j as usize] = total; 127 | } 128 | } 129 | 130 | new_matrix 131 | } 132 | } 133 | 134 | impl Display for Matrix where T: Display { 135 | fn fmt(&self, f: &mut Formatter) -> Result { 136 | for row in 0..self.rows { 137 | for col in 0..self.cols { 138 | try!(write!(f, "{} ", self.matrix[row as usize][col as usize])); 139 | } 140 | try!(write!(f, "\n")); 141 | } 142 | 143 | Ok(()) 144 | } 145 | } 146 | 147 | pub fn random_matrix(rows: i32, cols: i32) -> Matrix { 148 | let mut _rows: Vec> = Vec::new(); 149 | 150 | for _ in 0..rows { 151 | let mut _row: Vec = Vec::new(); 152 | 153 | for _ in 0..cols { 154 | let num: i32 = rand::thread_rng().gen_range(-20, 20); 155 | _row.push(num); 156 | } 157 | 158 | _rows.push(_row); 159 | } 160 | 161 | Matrix { rows: rows, cols: cols, matrix: _rows } 162 | } 163 | 164 | #[cfg(test)] 165 | mod test { 166 | use super::{ Matrix, random_matrix }; 167 | 168 | #[test] 169 | fn create() { 170 | let first = Matrix::new(2, 2, 2); 171 | let matrix = vec![vec![2, 2], vec![2, 2]]; 172 | 173 | assert_eq!(first.rows, 2); 174 | assert_eq!(first.cols, 2); 175 | assert_eq!(first.matrix, matrix); 176 | 177 | let mut second = Matrix::new(2, 4, 1); 178 | let second_matrix = vec![vec![1, 1, 1, 1], vec![1, 1, 1, 1]]; 179 | 180 | assert_eq!(second.rows, 2); 181 | assert_eq!(second.cols, 4); 182 | assert_eq!(second.matrix, second_matrix); 183 | 184 | second.matrix[1][1] = 5; 185 | let changed_matrix = vec![vec![1, 1, 1, 1], vec![1, 5, 1, 1]]; 186 | assert_eq!(second.matrix, changed_matrix); 187 | 188 | let ran = random_matrix(2, 5); 189 | assert_eq!(ran.rows, 2); 190 | assert_eq!(ran.cols, 5); 191 | 192 | let third_matrix = vec![ 193 | vec![13, 9, 7, 15], 194 | vec![8, 7, 4, 6], 195 | vec![6, 4, 0, 3] 196 | ]; 197 | let third = Matrix::new_from_vec(vec![ 198 | vec![13, 9, 7, 15], 199 | vec![8, 7, 4, 6], 200 | vec![6, 4, 0, 3] 201 | ]); 202 | assert_eq!(third.rows, 3); 203 | assert_eq!(third.cols, 4); 204 | assert_eq!(third.matrix, third_matrix); 205 | } 206 | 207 | #[test] 208 | fn add() { 209 | let first = Matrix::new(3, 3, 1); 210 | let second = Matrix::new(3, 3, 2); 211 | let third = first + second; 212 | let matrix = vec![vec![3, 3, 3], vec![3, 3, 3], vec![3, 3, 3]]; 213 | 214 | assert_eq!(third.rows, 3); 215 | assert_eq!(third.cols, 3); 216 | assert_eq!(third.matrix, matrix); 217 | } 218 | 219 | #[test] 220 | fn sub() { 221 | let first = Matrix::new(3, 3, 1); 222 | let second = Matrix::new(3, 3, 2); 223 | let matrix = vec![vec![-1, -1, -1], vec![-1, -1, -1], vec![-1, -1, -1]]; 224 | let third = first - second; 225 | 226 | assert_eq!(third.rows, 3); 227 | assert_eq!(third.cols, 3); 228 | assert_eq!(third.matrix, matrix); 229 | } 230 | 231 | #[test] 232 | fn mul() { 233 | let first = Matrix::new(3, 3, 2); 234 | let second = Matrix::new(3, 3, 3); 235 | let third = first * second; 236 | let matrix = vec![vec![18, 18, 18], vec![18, 18, 18], vec![18, 18, 18]]; 237 | 238 | assert_eq!(third.matrix, matrix); 239 | 240 | let mut fifth = Matrix::new(2, 2, 5); 241 | fifth.matrix[0][0] = 1; 242 | fifth.matrix[0][1] = 6; 243 | fifth.matrix[1][0] = 3; 244 | fifth.matrix[1][1] = 8; 245 | 246 | let mut sixth = Matrix::new(2, 2, 8); 247 | sixth.matrix[0][0] = 2; 248 | sixth.matrix[0][1] = 2; 249 | sixth.matrix[1][0] = 9; 250 | sixth.matrix[1][1] = 7; 251 | 252 | let second_matrix = vec![vec![56, 44], vec![78, 62]]; 253 | assert_eq!((fifth * sixth).matrix, second_matrix); 254 | 255 | let mut this_one = Matrix::new(2, 3, 1); 256 | this_one.matrix[0][1] = 2; 257 | this_one.matrix[0][2] = 3; 258 | this_one.matrix[1][0] = 4; 259 | this_one.matrix[1][1] = 5; 260 | this_one.matrix[1][2] = 6; 261 | 262 | let mut another = Matrix::new(3, 1, 9); 263 | another.matrix[1][0] = 8; 264 | another.matrix[2][0] = 7; 265 | 266 | let third_matrix = vec![vec![46], vec![118]]; 267 | assert_eq!((this_one * another).matrix, third_matrix); 268 | 269 | // [3 4 2] x [13 9 7 15 = [83 63 37 75] (83 = 3x13 + 4x8 + 2x6) 270 | // 8 7 4 6 271 | // 6 4 0 3] 272 | let first_dot = Matrix::new_from_vec(vec![ 273 | vec![3, 4, 2] 274 | ]); 275 | let second_dot = Matrix::new_from_vec(vec![ 276 | vec![13, 9, 7, 15], 277 | vec![8, 7, 4, 6], 278 | vec![6, 4, 0, 3] 279 | ]); 280 | let merged = vec![vec![83, 63, 37, 75]]; 281 | 282 | assert_eq!((first_dot * second_dot).matrix, merged); 283 | } 284 | 285 | #[test] 286 | fn scalar_mul() { 287 | let first = Matrix::new(3, 3, 2); 288 | let second = first.scalar_mul(3); 289 | let matrix = vec![vec![6, 6, 6], vec![6, 6, 6], vec![6, 6, 6]]; 290 | 291 | assert_eq!(second.matrix, matrix); 292 | 293 | let third = Matrix::new(4, 2, 3.0); 294 | let fourth = third.scalar_mul(0.5); 295 | let second_matrix = vec![vec![1.5, 1.5], vec![1.5, 1.5], vec![1.5, 1.5], vec![1.5, 1.5]]; 296 | 297 | assert_eq!(fourth.matrix, second_matrix); 298 | } 299 | 300 | #[test] 301 | fn transpose() { 302 | let first = Matrix::new_from_vec(vec![ 303 | vec![1, 2, 3], 304 | vec![4, 5, 6] 305 | ]); 306 | 307 | let second = Matrix::new_from_vec(vec![ 308 | vec![1, 4], 309 | vec![2, 5], 310 | vec![3, 6] 311 | ]); 312 | 313 | assert_eq!((first.transpose()).matrix, second.matrix); 314 | } 315 | } -------------------------------------------------------------------------------- /18-encryption/py/secret.txt: -------------------------------------------------------------------------------- 1 | Nyvpr jnf ortvaavat gb trg irel gverq bs fvggvat ol ure fvfgre ba gur 2 | onax, naq bs univat abguvat gb qb: bapr be gjvpr fur unq crrcrq vagb gur 3 | obbx ure fvfgre jnf ernqvat, ohg vg unq ab cvpgherf be pbairefngvbaf va 4 | vg, 'naq jung vf gur hfr bs n obbx,' gubhtug Nyvpr 'jvgubhg cvpgherf be 5 | pbairefngvbaf?' 6 | 7 | Fb fur jnf pbafvqrevat va ure bja zvaq (nf jryy nf fur pbhyq, sbe gur 8 | ubg qnl znqr ure srry irel fyrrcl naq fghcvq), jurgure gur cyrnfher 9 | bs znxvat n qnvfl-punva jbhyq or jbegu gur gebhoyr bs trggvat hc naq 10 | cvpxvat gur qnvfvrf, jura fhqqrayl n Juvgr Enoovg jvgu cvax rlrf ena 11 | pybfr ol ure. 12 | 13 | Gurer jnf abguvat fb IREL erznexnoyr va gung; abe qvq Nyvpr guvax vg fb 14 | IREL zhpu bhg bs gur jnl gb urne gur Enoovg fnl gb vgfrys, 'Bu qrne! 15 | Bu qrne! V funyy or yngr!' (jura fur gubhtug vg bire nsgrejneqf, vg 16 | bppheerq gb ure gung fur bhtug gb unir jbaqrerq ng guvf, ohg ng gur gvzr 17 | vg nyy frrzrq dhvgr angheny); ohg jura gur Enoovg npghnyyl GBBX N JNGPU 18 | BHG BS VGF JNVFGPBNG-CBPXRG, naq ybbxrq ng vg, naq gura uheevrq ba, 19 | Nyvpr fgnegrq gb ure srrg, sbe vg synfurq npebff ure zvaq gung fur unq 20 | arire orsber frra n enoovg jvgu rvgure n jnvfgpbng-cbpxrg, be n jngpu 21 | gb gnxr bhg bs vg, naq oheavat jvgu phevbfvgl, fur ena npebff gur svryq 22 | nsgre vg, naq sbeghangryl jnf whfg va gvzr gb frr vg cbc qbja n ynetr 23 | enoovg-ubyr haqre gur urqtr. 24 | 25 | Va nabgure zbzrag qbja jrag Nyvpr nsgre vg, arire bapr pbafvqrevat ubj 26 | va gur jbeyq fur jnf gb trg bhg ntnva. 27 | 28 | Gur enoovg-ubyr jrag fgenvtug ba yvxr n ghaary sbe fbzr jnl, naq gura 29 | qvccrq fhqqrayl qbja, fb fhqqrayl gung Nyvpr unq abg n zbzrag gb guvax 30 | nobhg fgbccvat urefrys orsber fur sbhaq urefrys snyyvat qbja n irel qrrc 31 | jryy. 32 | 33 | Rvgure gur jryy jnf irel qrrc, be fur sryy irel fybjyl, sbe fur unq 34 | cyragl bs gvzr nf fur jrag qbja gb ybbx nobhg ure naq gb jbaqre jung jnf 35 | tbvat gb unccra arkg. Svefg, fur gevrq gb ybbx qbja naq znxr bhg jung 36 | fur jnf pbzvat gb, ohg vg jnf gbb qnex gb frr nalguvat; gura fur 37 | ybbxrq ng gur fvqrf bs gur jryy, naq abgvprq gung gurl jrer svyyrq jvgu 38 | phcobneqf naq obbx-furyirf; urer naq gurer fur fnj zncf naq cvpgherf 39 | uhat hcba crtf. Fur gbbx qbja n wne sebz bar bs gur furyirf nf 40 | fur cnffrq; vg jnf ynoryyrq 'BENATR ZNEZNYNQR', ohg gb ure terng 41 | qvfnccbvagzrag vg jnf rzcgl: fur qvq abg yvxr gb qebc gur wne sbe srne 42 | bs xvyyvat fbzrobql, fb znantrq gb chg vg vagb bar bs gur phcobneqf nf 43 | fur sryy cnfg vg. 44 | 45 | 'Jryy!' gubhtug Nyvpr gb urefrys, 'nsgre fhpu n snyy nf guvf, V funyy 46 | guvax abguvat bs ghzoyvat qbja fgnvef! Ubj oenir gurl'yy nyy guvax zr ng 47 | ubzr! Jul, V jbhyqa'g fnl nalguvat nobhg vg, rira vs V sryy bss gur gbc 48 | bs gur ubhfr!' (Juvpu jnf irel yvxryl gehr.) 49 | 50 | Qbja, qbja, qbja. Jbhyq gur snyy ARIRE pbzr gb na raq! 'V jbaqre ubj 51 | znal zvyrf V'ir snyyra ol guvf gvzr?' fur fnvq nybhq. 'V zhfg or trggvat 52 | fbzrjurer arne gur prager bs gur rnegu. Yrg zr frr: gung jbhyq or sbhe 53 | gubhfnaq zvyrf qbja, V guvax' (sbe, lbh frr, Nyvpr unq yrneag frireny 54 | guvatf bs guvf fbeg va ure yrffbaf va gur fpubbyebbz, naq gubhtu guvf 55 | jnf abg n IREL tbbq bccbeghavgl sbe fubjvat bss ure xabjyrqtr, nf gurer 56 | jnf ab bar gb yvfgra gb ure, fgvyy vg jnf tbbq cenpgvpr gb fnl vg bire) 57 | 'lrf, gung'f nobhg gur evtug qvfgnaprohg gura V jbaqre jung Yngvghqr 58 | be Ybatvghqr V'ir tbg gb?' (Nyvpr unq ab vqrn jung Yngvghqr jnf, be 59 | Ybatvghqr rvgure, ohg gubhtug gurl jrer avpr tenaq jbeqf gb fnl.) 60 | 61 | Cerfragyl fur ortna ntnva. 'V jbaqre vs V funyy snyy evtug GUEBHTU gur 62 | rnegu! Ubj shaal vg'yy frrz gb pbzr bhg nzbat gur crbcyr gung jnyx jvgu 63 | gurve urnqf qbjajneq! Gur Nagvcnguvrf, V guvax' (fur jnf engure tynq 64 | gurer JNF ab bar yvfgravat, guvf gvzr, nf vg qvqa'g fbhaq ng nyy gur 65 | evtug jbeq) 'ohg V funyy unir gb nfx gurz jung gur anzr bs gur pbhagel 66 | vf, lbh xabj. Cyrnfr, Zn'nz, vf guvf Arj Mrnynaq be Nhfgenyvn?' (naq 67 | fur gevrq gb phegfrl nf fur fcbxr - snapl PHEGFRLVAT nf lbh'er snyyvat 68 | guebhtu gur nve! Qb lbh guvax lbh pbhyq znantr vg?) 'Naq jung na 69 | vtabenag yvggyr tvey fur'yy guvax zr sbe nfxvat! Ab, vg'yy arire qb gb 70 | nfx: creuncf V funyy frr vg jevggra hc fbzrjurer.' 71 | 72 | Qbja, qbja, qbja. Gurer jnf abguvat ryfr gb qb, fb Nyvpr fbba ortna 73 | gnyxvat ntnva. 'Qvanu'yy zvff zr irel zhpu gb-avtug, V fubhyq guvax!' 74 | (Qvanu jnf gur png.) 'V ubcr gurl'yy erzrzore ure fnhpre bs zvyx ng 75 | grn-gvzr. Qvanu zl qrne! V jvfu lbh jrer qbja urer jvgu zr! Gurer ner ab 76 | zvpr va gur nve, V'z nsenvq, ohg lbh zvtug pngpu n ong, naq gung'f irel 77 | yvxr n zbhfr, lbh xabj. Ohg qb pngf rng ongf, V jbaqre?' Naq urer Nyvpr 78 | ortna gb trg engure fyrrcl, naq jrag ba fnlvat gb urefrys, va n qernzl 79 | fbeg bs jnl, 'Qb pngf rng ongf? Qb pngf rng ongf?' naq fbzrgvzrf, 'Qb 80 | ongf rng pngf?' sbe, lbh frr, nf fur pbhyqa'g nafjre rvgure dhrfgvba, 81 | vg qvqa'g zhpu znggre juvpu jnl fur chg vg. Fur sryg gung fur jnf qbmvat 82 | bss, naq unq whfg ortha gb qernz gung fur jnf jnyxvat unaq va unaq jvgu 83 | Qvanu, naq fnlvat gb ure irel rnearfgyl, 'Abj, Qvanu, gryy zr gur gehgu: 84 | qvq lbh rire rng n ong?' jura fhqqrayl, guhzc! guhzc! qbja fur pnzr hcba 85 | n urnc bs fgvpxf naq qel yrnirf, naq gur snyy jnf bire. 86 | 87 | Nyvpr jnf abg n ovg uheg, naq fur whzcrq hc ba gb ure srrg va n zbzrag: 88 | fur ybbxrq hc, ohg vg jnf nyy qnex bireurnq; orsber ure jnf nabgure 89 | ybat cnffntr, naq gur Juvgr Enoovg jnf fgvyy va fvtug, uheelvat qbja vg. 90 | Gurer jnf abg n zbzrag gb or ybfg: njnl jrag Nyvpr yvxr gur jvaq, naq 91 | jnf whfg va gvzr gb urne vg fnl, nf vg ghearq n pbeare, 'Bu zl rnef 92 | naq juvfxref, ubj yngr vg'f trggvat!' Fur jnf pybfr oruvaq vg jura fur 93 | ghearq gur pbeare, ohg gur Enoovg jnf ab ybatre gb or frra: fur sbhaq 94 | urefrys va n ybat, ybj unyy, juvpu jnf yvg hc ol n ebj bs ynzcf unatvat 95 | sebz gur ebbs. 96 | 97 | Gurer jrer qbbef nyy ebhaq gur unyy, ohg gurl jrer nyy ybpxrq; naq jura 98 | Nyvpr unq orra nyy gur jnl qbja bar fvqr naq hc gur bgure, gelvat rirel 99 | qbbe, fur jnyxrq fnqyl qbja gur zvqqyr, jbaqrevat ubj fur jnf rire gb 100 | trg bhg ntnva. 101 | 102 | Fhqqrayl fur pnzr hcba n yvggyr guerr-yrttrq gnoyr, nyy znqr bs fbyvq 103 | tynff; gurer jnf abguvat ba vg rkprcg n gval tbyqra xrl, naq Nyvpr'f 104 | svefg gubhtug jnf gung vg zvtug orybat gb bar bs gur qbbef bs gur unyy; 105 | ohg, nynf! rvgure gur ybpxf jrer gbb ynetr, be gur xrl jnf gbb fznyy, 106 | ohg ng nal engr vg jbhyq abg bcra nal bs gurz. Ubjrire, ba gur frpbaq 107 | gvzr ebhaq, fur pnzr hcba n ybj phegnva fur unq abg abgvprq orsber, naq 108 | oruvaq vg jnf n yvggyr qbbe nobhg svsgrra vapurf uvtu: fur gevrq gur 109 | yvggyr tbyqra xrl va gur ybpx, naq gb ure terng qryvtug vg svggrq! 110 | 111 | Nyvpr bcrarq gur qbbe naq sbhaq gung vg yrq vagb n fznyy cnffntr, abg 112 | zhpu ynetre guna n eng-ubyr: fur xaryg qbja naq ybbxrq nybat gur cnffntr 113 | vagb gur ybiryvrfg tneqra lbh rire fnj. Ubj fur ybatrq gb trg bhg bs 114 | gung qnex unyy, naq jnaqre nobhg nzbat gubfr orqf bs oevtug sybjref naq 115 | gubfr pbby sbhagnvaf, ohg fur pbhyq abg rira trg ure urnq guebhtu gur 116 | qbbejnl; 'naq rira vs zl urnq jbhyq tb guebhtu,' gubhtug cbbe Nyvpr, 'vg 117 | jbhyq or bs irel yvggyr hfr jvgubhg zl fubhyqref. Bu, ubj V jvfu V pbhyq 118 | fuhg hc yvxr n gryrfpbcr! V guvax V pbhyq, vs V bayl xarj ubj gb ortva.' 119 | Sbe, lbh frr, fb znal bhg-bs-gur-jnl guvatf unq unccrarq yngryl, 120 | gung Nyvpr unq ortha gb guvax gung irel srj guvatf vaqrrq jrer ernyyl 121 | vzcbffvoyr. 122 | 123 | Gurer frrzrq gb or ab hfr va jnvgvat ol gur yvggyr qbbe, fb fur jrag 124 | onpx gb gur gnoyr, unys ubcvat fur zvtug svaq nabgure xrl ba vg, be ng 125 | nal engr n obbx bs ehyrf sbe fuhggvat crbcyr hc yvxr gryrfpbcrf: guvf 126 | gvzr fur sbhaq n yvggyr obggyr ba vg, ('juvpu pregnvayl jnf abg urer 127 | orsber,' fnvq Nyvpr,) naq ebhaq gur arpx bs gur obggyr jnf n cncre 128 | ynory, jvgu gur jbeqf 'QEVAX ZR' ornhgvshyyl cevagrq ba vg va ynetr 129 | yrggref. 130 | 131 | Vg jnf nyy irel jryy gb fnl 'Qevax zr,' ohg gur jvfr yvggyr Nyvpr jnf 132 | abg tbvat gb qb GUNG va n uheel. 'Ab, V'yy ybbx svefg,' fur fnvq, 'naq 133 | frr jurgure vg'f znexrq "cbvfba" be abg'; sbe fur unq ernq frireny avpr 134 | yvggyr uvfgbevrf nobhg puvyqera jub unq tbg oheag, naq rngra hc ol jvyq 135 | ornfgf naq bgure hacyrnfnag guvatf, nyy orpnhfr gurl JBHYQ abg erzrzore 136 | gur fvzcyr ehyrf gurve sevraqf unq gnhtug gurz: fhpu nf, gung n erq-ubg 137 | cbxre jvyy ohea lbh vs lbh ubyq vg gbb ybat; naq gung vs lbh phg lbhe 138 | svatre IREL qrrcyl jvgu n xavsr, vg hfhnyyl oyrrqf; naq fur unq arire 139 | sbetbggra gung, vs lbh qevax zhpu sebz n obggyr znexrq 'cbvfba,' vg vf 140 | nyzbfg pregnva gb qvfnterr jvgu lbh, fbbare be yngre. 141 | 142 | Ubjrire, guvf obggyr jnf ABG znexrq 'cbvfba,' fb Nyvpr iragherq gb gnfgr 143 | vg, naq svaqvat vg irel avpr, (vg unq, va snpg, n fbeg bs zvkrq synibhe 144 | bs pureel-gneg, phfgneq, cvar-nccyr, ebnfg ghexrl, gbssrr, naq ubg 145 | ohggrerq gbnfg,) fur irel fbba svavfurq vg bss. 146 | 147 | 'Jung n phevbhf srryvat!' fnvq Nyvpr; 'V zhfg or fuhggvat hc yvxr n 148 | gryrfpbcr.' 149 | 150 | Naq fb vg jnf vaqrrq: fur jnf abj bayl gra vapurf uvtu, naq ure snpr 151 | oevtugrarq hc ng gur gubhtug gung fur jnf abj gur evtug fvmr sbe tbvat 152 | guebhtu gur yvggyr qbbe vagb gung ybiryl tneqra. Svefg, ubjrire, fur 153 | jnvgrq sbe n srj zvahgrf gb frr vs fur jnf tbvat gb fuevax nal shegure: 154 | fur sryg n yvggyr areibhf nobhg guvf; 'sbe vg zvtug raq, lbh xabj,' fnvq 155 | Nyvpr gb urefrys, 'va zl tbvat bhg nygbtrgure, yvxr n pnaqyr. V jbaqre 156 | jung V fubhyq or yvxr gura?' Naq fur gevrq gb snapl jung gur synzr bs n 157 | pnaqyr vf yvxr nsgre gur pnaqyr vf oybja bhg, sbe fur pbhyq abg erzrzore 158 | rire univat frra fhpu n guvat. 159 | 160 | Nsgre n juvyr, svaqvat gung abguvat zber unccrarq, fur qrpvqrq ba tbvat 161 | vagb gur tneqra ng bapr; ohg, nynf sbe cbbe Nyvpr! jura fur tbg gb gur 162 | qbbe, fur sbhaq fur unq sbetbggra gur yvggyr tbyqra xrl, naq jura fur 163 | jrag onpx gb gur gnoyr sbe vg, fur sbhaq fur pbhyq abg cbffvoyl ernpu 164 | vg: fur pbhyq frr vg dhvgr cynvayl guebhtu gur tynff, naq fur gevrq ure 165 | orfg gb pyvzo hc bar bs gur yrtf bs gur gnoyr, ohg vg jnf gbb fyvccrel; 166 | naq jura fur unq gverq urefrys bhg jvgu gelvat, gur cbbe yvggyr guvat 167 | fng qbja naq pevrq. 168 | 169 | 'Pbzr, gurer'f ab hfr va pelvat yvxr gung!' fnvq Nyvpr gb urefrys, 170 | engure funecyl; 'V nqivfr lbh gb yrnir bss guvf zvahgr!' Fur trarenyyl 171 | tnir urefrys irel tbbq nqivpr, (gubhtu fur irel fryqbz sbyybjrq vg), 172 | naq fbzrgvzrf fur fpbyqrq urefrys fb frireryl nf gb oevat grnef vagb 173 | ure rlrf; naq bapr fur erzrzorerq gelvat gb obk ure bja rnef sbe univat 174 | purngrq urefrys va n tnzr bs pebdhrg fur jnf cynlvat ntnvafg urefrys, 175 | sbe guvf phevbhf puvyq jnf irel sbaq bs cergraqvat gb or gjb crbcyr. 176 | 'Ohg vg'f ab hfr abj,' gubhtug cbbe Nyvpr, 'gb cergraq gb or gjb crbcyr! 177 | Jul, gurer'f uneqyl rabhtu bs zr yrsg gb znxr BAR erfcrpgnoyr crefba!' 178 | 179 | Fbba ure rlr sryy ba n yvggyr tynff obk gung jnf ylvat haqre gur gnoyr: 180 | fur bcrarq vg, naq sbhaq va vg n irel fznyy pnxr, ba juvpu gur jbeqf 181 | 'RNG ZR' jrer ornhgvshyyl znexrq va pheenagf. 'Jryy, V'yy rng vg,' fnvq 182 | Nyvpr, 'naq vs vg znxrf zr tebj ynetre, V pna ernpu gur xrl; naq vs vg 183 | znxrf zr tebj fznyyre, V pna perrc haqre gur qbbe; fb rvgure jnl V'yy 184 | trg vagb gur tneqra, naq V qba'g pner juvpu unccraf!' 185 | 186 | Fur ngr n yvggyr ovg, naq fnvq nakvbhfyl gb urefrys, 'Juvpu jnl? Juvpu 187 | jnl?', ubyqvat ure unaq ba gur gbc bs ure urnq gb srry juvpu jnl vg jnf 188 | tebjvat, naq fur jnf dhvgr fhecevfrq gb svaq gung fur erznvarq gur fnzr 189 | fvmr: gb or fher, guvf trarenyyl unccraf jura bar rngf pnxr, ohg Nyvpr 190 | unq tbg fb zhpu vagb gur jnl bs rkcrpgvat abguvat ohg bhg-bs-gur-jnl 191 | guvatf gb unccra, gung vg frrzrq dhvgr qhyy naq fghcvq sbe yvsr gb tb ba 192 | va gur pbzzba jnl. 193 | 194 | Fb fur frg gb jbex, naq irel fbba svavfurq bss gur pnxr. 195 | -------------------------------------------------------------------------------- /18-encryption/cpp/secret.txt: -------------------------------------------------------------------------------- 1 | Nyvpr jnf ortvaavat gb trg irel gverq bs fvggvat ol ure fvfgre ba gur 2 | onax, naq bs univat abguvat gb qb: bapr be gjvpr fur unq crrcrq vagb gur 3 | obbx ure fvfgre jnf ernqvat, ohg vg unq ab cvpgherf be pbairefngvbaf va 4 | vg, 'naq jung vf gur hfr bs n obbx,' gubhtug Nyvpr 'jvgubhg cvpgherf be 5 | pbairefngvbaf?' 6 | 7 | Fb fur jnf pbafvqrevat va ure bja zvaq (nf jryy nf fur pbhyq, sbe gur 8 | ubg qnl znqr ure srry irel fyrrcl naq fghcvq), jurgure gur cyrnfher 9 | bs znxvat n qnvfl-punva jbhyq or jbegu gur gebhoyr bs trggvat hc naq 10 | cvpxvat gur qnvfvrf, jura fhqqrayl n Juvgr Enoovg jvgu cvax rlrf ena 11 | pybfr ol ure. 12 | 13 | Gurer jnf abguvat fb IREL erznexnoyr va gung; abe qvq Nyvpr guvax vg fb 14 | IREL zhpu bhg bs gur jnl gb urne gur Enoovg fnl gb vgfrys, 'Bu qrne! 15 | Bu qrne! V funyy or yngr!' (jura fur gubhtug vg bire nsgrejneqf, vg 16 | bppheerq gb ure gung fur bhtug gb unir jbaqrerq ng guvf, ohg ng gur gvzr 17 | vg nyy frrzrq dhvgr angheny); ohg jura gur Enoovg npghnyyl GBBX N JNGPU 18 | BHG BS VGF JNVFGPBNG-CBPXRG, naq ybbxrq ng vg, naq gura uheevrq ba, 19 | Nyvpr fgnegrq gb ure srrg, sbe vg synfurq npebff ure zvaq gung fur unq 20 | arire orsber frra n enoovg jvgu rvgure n jnvfgpbng-cbpxrg, be n jngpu 21 | gb gnxr bhg bs vg, naq oheavat jvgu phevbfvgl, fur ena npebff gur svryq 22 | nsgre vg, naq sbeghangryl jnf whfg va gvzr gb frr vg cbc qbja n ynetr 23 | enoovg-ubyr haqre gur urqtr. 24 | 25 | Va nabgure zbzrag qbja jrag Nyvpr nsgre vg, arire bapr pbafvqrevat ubj 26 | va gur jbeyq fur jnf gb trg bhg ntnva. 27 | 28 | Gur enoovg-ubyr jrag fgenvtug ba yvxr n ghaary sbe fbzr jnl, naq gura 29 | qvccrq fhqqrayl qbja, fb fhqqrayl gung Nyvpr unq abg n zbzrag gb guvax 30 | nobhg fgbccvat urefrys orsber fur sbhaq urefrys snyyvat qbja n irel qrrc 31 | jryy. 32 | 33 | Rvgure gur jryy jnf irel qrrc, be fur sryy irel fybjyl, sbe fur unq 34 | cyragl bs gvzr nf fur jrag qbja gb ybbx nobhg ure naq gb jbaqre jung jnf 35 | tbvat gb unccra arkg. Svefg, fur gevrq gb ybbx qbja naq znxr bhg jung 36 | fur jnf pbzvat gb, ohg vg jnf gbb qnex gb frr nalguvat; gura fur 37 | ybbxrq ng gur fvqrf bs gur jryy, naq abgvprq gung gurl jrer svyyrq jvgu 38 | phcobneqf naq obbx-furyirf; urer naq gurer fur fnj zncf naq cvpgherf 39 | uhat hcba crtf. Fur gbbx qbja n wne sebz bar bs gur furyirf nf 40 | fur cnffrq; vg jnf ynoryyrq 'BENATR ZNEZNYNQR', ohg gb ure terng 41 | qvfnccbvagzrag vg jnf rzcgl: fur qvq abg yvxr gb qebc gur wne sbe srne 42 | bs xvyyvat fbzrobql, fb znantrq gb chg vg vagb bar bs gur phcobneqf nf 43 | fur sryy cnfg vg. 44 | 45 | 'Jryy!' gubhtug Nyvpr gb urefrys, 'nsgre fhpu n snyy nf guvf, V funyy 46 | guvax abguvat bs ghzoyvat qbja fgnvef! Ubj oenir gurl'yy nyy guvax zr ng 47 | ubzr! Jul, V jbhyqa'g fnl nalguvat nobhg vg, rira vs V sryy bss gur gbc 48 | bs gur ubhfr!' (Juvpu jnf irel yvxryl gehr.) 49 | 50 | Qbja, qbja, qbja. Jbhyq gur snyy ARIRE pbzr gb na raq! 'V jbaqre ubj 51 | znal zvyrf V'ir snyyra ol guvf gvzr?' fur fnvq nybhq. 'V zhfg or trggvat 52 | fbzrjurer arne gur prager bs gur rnegu. Yrg zr frr: gung jbhyq or sbhe 53 | gubhfnaq zvyrf qbja, V guvax' (sbe, lbh frr, Nyvpr unq yrneag frireny 54 | guvatf bs guvf fbeg va ure yrffbaf va gur fpubbyebbz, naq gubhtu guvf 55 | jnf abg n IREL tbbq bccbeghavgl sbe fubjvat bss ure xabjyrqtr, nf gurer 56 | jnf ab bar gb yvfgra gb ure, fgvyy vg jnf tbbq cenpgvpr gb fnl vg bire) 57 | 'lrf, gung'f nobhg gur evtug qvfgnaprohg gura V jbaqre jung Yngvghqr 58 | be Ybatvghqr V'ir tbg gb?' (Nyvpr unq ab vqrn jung Yngvghqr jnf, be 59 | Ybatvghqr rvgure, ohg gubhtug gurl jrer avpr tenaq jbeqf gb fnl.) 60 | 61 | Cerfragyl fur ortna ntnva. 'V jbaqre vs V funyy snyy evtug GUEBHTU gur 62 | rnegu! Ubj shaal vg'yy frrz gb pbzr bhg nzbat gur crbcyr gung jnyx jvgu 63 | gurve urnqf qbjajneq! Gur Nagvcnguvrf, V guvax' (fur jnf engure tynq 64 | gurer JNF ab bar yvfgravat, guvf gvzr, nf vg qvqa'g fbhaq ng nyy gur 65 | evtug jbeq) 'ohg V funyy unir gb nfx gurz jung gur anzr bs gur pbhagel 66 | vf, lbh xabj. Cyrnfr, Zn'nz, vf guvf Arj Mrnynaq be Nhfgenyvn?' (naq 67 | fur gevrq gb phegfrl nf fur fcbxr - snapl PHEGFRLVAT nf lbh'er snyyvat 68 | guebhtu gur nve! Qb lbh guvax lbh pbhyq znantr vg?) 'Naq jung na 69 | vtabenag yvggyr tvey fur'yy guvax zr sbe nfxvat! Ab, vg'yy arire qb gb 70 | nfx: creuncf V funyy frr vg jevggra hc fbzrjurer.' 71 | 72 | Qbja, qbja, qbja. Gurer jnf abguvat ryfr gb qb, fb Nyvpr fbba ortna 73 | gnyxvat ntnva. 'Qvanu'yy zvff zr irel zhpu gb-avtug, V fubhyq guvax!' 74 | (Qvanu jnf gur png.) 'V ubcr gurl'yy erzrzore ure fnhpre bs zvyx ng 75 | grn-gvzr. Qvanu zl qrne! V jvfu lbh jrer qbja urer jvgu zr! Gurer ner ab 76 | zvpr va gur nve, V'z nsenvq, ohg lbh zvtug pngpu n ong, naq gung'f irel 77 | yvxr n zbhfr, lbh xabj. Ohg qb pngf rng ongf, V jbaqre?' Naq urer Nyvpr 78 | ortna gb trg engure fyrrcl, naq jrag ba fnlvat gb urefrys, va n qernzl 79 | fbeg bs jnl, 'Qb pngf rng ongf? Qb pngf rng ongf?' naq fbzrgvzrf, 'Qb 80 | ongf rng pngf?' sbe, lbh frr, nf fur pbhyqa'g nafjre rvgure dhrfgvba, 81 | vg qvqa'g zhpu znggre juvpu jnl fur chg vg. Fur sryg gung fur jnf qbmvat 82 | bss, naq unq whfg ortha gb qernz gung fur jnf jnyxvat unaq va unaq jvgu 83 | Qvanu, naq fnlvat gb ure irel rnearfgyl, 'Abj, Qvanu, gryy zr gur gehgu: 84 | qvq lbh rire rng n ong?' jura fhqqrayl, guhzc! guhzc! qbja fur pnzr hcba 85 | n urnc bs fgvpxf naq qel yrnirf, naq gur snyy jnf bire. 86 | 87 | Nyvpr jnf abg n ovg uheg, naq fur whzcrq hc ba gb ure srrg va n zbzrag: 88 | fur ybbxrq hc, ohg vg jnf nyy qnex bireurnq; orsber ure jnf nabgure 89 | ybat cnffntr, naq gur Juvgr Enoovg jnf fgvyy va fvtug, uheelvat qbja vg. 90 | Gurer jnf abg n zbzrag gb or ybfg: njnl jrag Nyvpr yvxr gur jvaq, naq 91 | jnf whfg va gvzr gb urne vg fnl, nf vg ghearq n pbeare, 'Bu zl rnef 92 | naq juvfxref, ubj yngr vg'f trggvat!' Fur jnf pybfr oruvaq vg jura fur 93 | ghearq gur pbeare, ohg gur Enoovg jnf ab ybatre gb or frra: fur sbhaq 94 | urefrys va n ybat, ybj unyy, juvpu jnf yvg hc ol n ebj bs ynzcf unatvat 95 | sebz gur ebbs. 96 | 97 | Gurer jrer qbbef nyy ebhaq gur unyy, ohg gurl jrer nyy ybpxrq; naq jura 98 | Nyvpr unq orra nyy gur jnl qbja bar fvqr naq hc gur bgure, gelvat rirel 99 | qbbe, fur jnyxrq fnqyl qbja gur zvqqyr, jbaqrevat ubj fur jnf rire gb 100 | trg bhg ntnva. 101 | 102 | Fhqqrayl fur pnzr hcba n yvggyr guerr-yrttrq gnoyr, nyy znqr bs fbyvq 103 | tynff; gurer jnf abguvat ba vg rkprcg n gval tbyqra xrl, naq Nyvpr'f 104 | svefg gubhtug jnf gung vg zvtug orybat gb bar bs gur qbbef bs gur unyy; 105 | ohg, nynf! rvgure gur ybpxf jrer gbb ynetr, be gur xrl jnf gbb fznyy, 106 | ohg ng nal engr vg jbhyq abg bcra nal bs gurz. Ubjrire, ba gur frpbaq 107 | gvzr ebhaq, fur pnzr hcba n ybj phegnva fur unq abg abgvprq orsber, naq 108 | oruvaq vg jnf n yvggyr qbbe nobhg svsgrra vapurf uvtu: fur gevrq gur 109 | yvggyr tbyqra xrl va gur ybpx, naq gb ure terng qryvtug vg svggrq! 110 | 111 | Nyvpr bcrarq gur qbbe naq sbhaq gung vg yrq vagb n fznyy cnffntr, abg 112 | zhpu ynetre guna n eng-ubyr: fur xaryg qbja naq ybbxrq nybat gur cnffntr 113 | vagb gur ybiryvrfg tneqra lbh rire fnj. Ubj fur ybatrq gb trg bhg bs 114 | gung qnex unyy, naq jnaqre nobhg nzbat gubfr orqf bs oevtug sybjref naq 115 | gubfr pbby sbhagnvaf, ohg fur pbhyq abg rira trg ure urnq guebhtu gur 116 | qbbejnl; 'naq rira vs zl urnq jbhyq tb guebhtu,' gubhtug cbbe Nyvpr, 'vg 117 | jbhyq or bs irel yvggyr hfr jvgubhg zl fubhyqref. Bu, ubj V jvfu V pbhyq 118 | fuhg hc yvxr n gryrfpbcr! V guvax V pbhyq, vs V bayl xarj ubj gb ortva.' 119 | Sbe, lbh frr, fb znal bhg-bs-gur-jnl guvatf unq unccrarq yngryl, 120 | gung Nyvpr unq ortha gb guvax gung irel srj guvatf vaqrrq jrer ernyyl 121 | vzcbffvoyr. 122 | 123 | Gurer frrzrq gb or ab hfr va jnvgvat ol gur yvggyr qbbe, fb fur jrag 124 | onpx gb gur gnoyr, unys ubcvat fur zvtug svaq nabgure xrl ba vg, be ng 125 | nal engr n obbx bs ehyrf sbe fuhggvat crbcyr hc yvxr gryrfpbcrf: guvf 126 | gvzr fur sbhaq n yvggyr obggyr ba vg, ('juvpu pregnvayl jnf abg urer 127 | orsber,' fnvq Nyvpr,) naq ebhaq gur arpx bs gur obggyr jnf n cncre 128 | ynory, jvgu gur jbeqf 'QEVAX ZR' ornhgvshyyl cevagrq ba vg va ynetr 129 | yrggref. 130 | 131 | Vg jnf nyy irel jryy gb fnl 'Qevax zr,' ohg gur jvfr yvggyr Nyvpr jnf 132 | abg tbvat gb qb GUNG va n uheel. 'Ab, V'yy ybbx svefg,' fur fnvq, 'naq 133 | frr jurgure vg'f znexrq "cbvfba" be abg'; sbe fur unq ernq frireny avpr 134 | yvggyr uvfgbevrf nobhg puvyqera jub unq tbg oheag, naq rngra hc ol jvyq 135 | ornfgf naq bgure hacyrnfnag guvatf, nyy orpnhfr gurl JBHYQ abg erzrzore 136 | gur fvzcyr ehyrf gurve sevraqf unq gnhtug gurz: fhpu nf, gung n erq-ubg 137 | cbxre jvyy ohea lbh vs lbh ubyq vg gbb ybat; naq gung vs lbh phg lbhe 138 | svatre IREL qrrcyl jvgu n xavsr, vg hfhnyyl oyrrqf; naq fur unq arire 139 | sbetbggra gung, vs lbh qevax zhpu sebz n obggyr znexrq 'cbvfba,' vg vf 140 | nyzbfg pregnva gb qvfnterr jvgu lbh, fbbare be yngre. 141 | 142 | Ubjrire, guvf obggyr jnf ABG znexrq 'cbvfba,' fb Nyvpr iragherq gb gnfgr 143 | vg, naq svaqvat vg irel avpr, (vg unq, va snpg, n fbeg bs zvkrq synibhe 144 | bs pureel-gneg, phfgneq, cvar-nccyr, ebnfg ghexrl, gbssrr, naq ubg 145 | ohggrerq gbnfg,) fur irel fbba svavfurq vg bss. 146 | 147 | 'Jung n phevbhf srryvat!' fnvq Nyvpr; 'V zhfg or fuhggvat hc yvxr n 148 | gryrfpbcr.' 149 | 150 | Naq fb vg jnf vaqrrq: fur jnf abj bayl gra vapurf uvtu, naq ure snpr 151 | oevtugrarq hc ng gur gubhtug gung fur jnf abj gur evtug fvmr sbe tbvat 152 | guebhtu gur yvggyr qbbe vagb gung ybiryl tneqra. Svefg, ubjrire, fur 153 | jnvgrq sbe n srj zvahgrf gb frr vs fur jnf tbvat gb fuevax nal shegure: 154 | fur sryg n yvggyr areibhf nobhg guvf; 'sbe vg zvtug raq, lbh xabj,' fnvq 155 | Nyvpr gb urefrys, 'va zl tbvat bhg nygbtrgure, yvxr n pnaqyr. V jbaqre 156 | jung V fubhyq or yvxr gura?' Naq fur gevrq gb snapl jung gur synzr bs n 157 | pnaqyr vf yvxr nsgre gur pnaqyr vf oybja bhg, sbe fur pbhyq abg erzrzore 158 | rire univat frra fhpu n guvat. 159 | 160 | Nsgre n juvyr, svaqvat gung abguvat zber unccrarq, fur qrpvqrq ba tbvat 161 | vagb gur tneqra ng bapr; ohg, nynf sbe cbbe Nyvpr! jura fur tbg gb gur 162 | qbbe, fur sbhaq fur unq sbetbggra gur yvggyr tbyqra xrl, naq jura fur 163 | jrag onpx gb gur gnoyr sbe vg, fur sbhaq fur pbhyq abg cbffvoyl ernpu 164 | vg: fur pbhyq frr vg dhvgr cynvayl guebhtu gur tynff, naq fur gevrq ure 165 | orfg gb pyvzo hc bar bs gur yrtf bs gur gnoyr, ohg vg jnf gbb fyvccrel; 166 | naq jura fur unq gverq urefrys bhg jvgu gelvat, gur cbbe yvggyr guvat 167 | fng qbja naq pevrq. 168 | 169 | 'Pbzr, gurer'f ab hfr va pelvat yvxr gung!' fnvq Nyvpr gb urefrys, 170 | engure funecyl; 'V nqivfr lbh gb yrnir bss guvf zvahgr!' Fur trarenyyl 171 | tnir urefrys irel tbbq nqivpr, (gubhtu fur irel fryqbz sbyybjrq vg), 172 | naq fbzrgvzrf fur fpbyqrq urefrys fb frireryl nf gb oevat grnef vagb 173 | ure rlrf; naq bapr fur erzrzorerq gelvat gb obk ure bja rnef sbe univat 174 | purngrq urefrys va n tnzr bs pebdhrg fur jnf cynlvat ntnvafg urefrys, 175 | sbe guvf phevbhf puvyq jnf irel sbaq bs cergraqvat gb or gjb crbcyr. 176 | 'Ohg vg'f ab hfr abj,' gubhtug cbbe Nyvpr, 'gb cergraq gb or gjb crbcyr! 177 | Jul, gurer'f uneqyl rabhtu bs zr yrsg gb znxr BAR erfcrpgnoyr crefba!' 178 | 179 | Fbba ure rlr sryy ba n yvggyr tynff obk gung jnf ylvat haqre gur gnoyr: 180 | fur bcrarq vg, naq sbhaq va vg n irel fznyy pnxr, ba juvpu gur jbeqf 181 | 'RNG ZR' jrer ornhgvshyyl znexrq va pheenagf. 'Jryy, V'yy rng vg,' fnvq 182 | Nyvpr, 'naq vs vg znxrf zr tebj ynetre, V pna ernpu gur xrl; naq vs vg 183 | znxrf zr tebj fznyyre, V pna perrc haqre gur qbbe; fb rvgure jnl V'yy 184 | trg vagb gur tneqra, naq V qba'g pner juvpu unccraf!' 185 | 186 | Fur ngr n yvggyr ovg, naq fnvq nakvbhfyl gb urefrys, 'Juvpu jnl? Juvpu 187 | jnl?', ubyqvat ure unaq ba gur gbc bs ure urnq gb srry juvpu jnl vg jnf 188 | tebjvat, naq fur jnf dhvgr fhecevfrq gb svaq gung fur erznvarq gur fnzr 189 | fvmr: gb or fher, guvf trarenyyl unccraf jura bar rngf pnxr, ohg Nyvpr 190 | unq tbg fb zhpu vagb gur jnl bs rkcrpgvat abguvat ohg bhg-bs-gur-jnl 191 | guvatf gb unccra, gung vg frrzrq dhvgr qhyy naq fghcvq sbe yvsr gb tb ba 192 | va gur pbzzba jnl. 193 | 194 | Fb fur frg gb jbex, naq irel fbba svavfurq bss gur pnxr. 195 | -------------------------------------------------------------------------------- /18-encryption/encrypt/secret.txt: -------------------------------------------------------------------------------- 1 | Nyvpr jnf ortvaavat gb trg irel gverq bs fvggvat ol ure fvfgre ba gur 2 | onax, naq bs univat abguvat gb qb: bapr be gjvpr fur unq crrcrq vagb gur 3 | obbx ure fvfgre jnf ernqvat, ohg vg unq ab cvpgherf be pbairefngvbaf va 4 | vg, 'naq jung vf gur hfr bs n obbx,' gubhtug Nyvpr 'jvgubhg cvpgherf be 5 | pbairefngvbaf?' 6 | 7 | Fb fur jnf pbafvqrevat va ure bja zvaq (nf jryy nf fur pbhyq, sbe gur 8 | ubg qnl znqr ure srry irel fyrrcl naq fghcvq), jurgure gur cyrnfher 9 | bs znxvat n qnvfl-punva jbhyq or jbegu gur gebhoyr bs trggvat hc naq 10 | cvpxvat gur qnvfvrf, jura fhqqrayl n Juvgr Enoovg jvgu cvax rlrf ena 11 | pybfr ol ure. 12 | 13 | Gurer jnf abguvat fb IREL erznexnoyr va gung; abe qvq Nyvpr guvax vg fb 14 | IREL zhpu bhg bs gur jnl gb urne gur Enoovg fnl gb vgfrys, 'Bu qrne! 15 | Bu qrne! V funyy or yngr!' (jura fur gubhtug vg bire nsgrejneqf, vg 16 | bppheerq gb ure gung fur bhtug gb unir jbaqrerq ng guvf, ohg ng gur gvzr 17 | vg nyy frrzrq dhvgr angheny); ohg jura gur Enoovg npghnyyl GBBX N JNGPU 18 | BHG BS VGF JNVFGPBNG-CBPXRG, naq ybbxrq ng vg, naq gura uheevrq ba, 19 | Nyvpr fgnegrq gb ure srrg, sbe vg synfurq npebff ure zvaq gung fur unq 20 | arire orsber frra n enoovg jvgu rvgure n jnvfgpbng-cbpxrg, be n jngpu 21 | gb gnxr bhg bs vg, naq oheavat jvgu phevbfvgl, fur ena npebff gur svryq 22 | nsgre vg, naq sbeghangryl jnf whfg va gvzr gb frr vg cbc qbja n ynetr 23 | enoovg-ubyr haqre gur urqtr. 24 | 25 | Va nabgure zbzrag qbja jrag Nyvpr nsgre vg, arire bapr pbafvqrevat ubj 26 | va gur jbeyq fur jnf gb trg bhg ntnva. 27 | 28 | Gur enoovg-ubyr jrag fgenvtug ba yvxr n ghaary sbe fbzr jnl, naq gura 29 | qvccrq fhqqrayl qbja, fb fhqqrayl gung Nyvpr unq abg n zbzrag gb guvax 30 | nobhg fgbccvat urefrys orsber fur sbhaq urefrys snyyvat qbja n irel qrrc 31 | jryy. 32 | 33 | Rvgure gur jryy jnf irel qrrc, be fur sryy irel fybjyl, sbe fur unq 34 | cyragl bs gvzr nf fur jrag qbja gb ybbx nobhg ure naq gb jbaqre jung jnf 35 | tbvat gb unccra arkg. Svefg, fur gevrq gb ybbx qbja naq znxr bhg jung 36 | fur jnf pbzvat gb, ohg vg jnf gbb qnex gb frr nalguvat; gura fur 37 | ybbxrq ng gur fvqrf bs gur jryy, naq abgvprq gung gurl jrer svyyrq jvgu 38 | phcobneqf naq obbx-furyirf; urer naq gurer fur fnj zncf naq cvpgherf 39 | uhat hcba crtf. Fur gbbx qbja n wne sebz bar bs gur furyirf nf 40 | fur cnffrq; vg jnf ynoryyrq 'BENATR ZNEZNYNQR', ohg gb ure terng 41 | qvfnccbvagzrag vg jnf rzcgl: fur qvq abg yvxr gb qebc gur wne sbe srne 42 | bs xvyyvat fbzrobql, fb znantrq gb chg vg vagb bar bs gur phcobneqf nf 43 | fur sryy cnfg vg. 44 | 45 | 'Jryy!' gubhtug Nyvpr gb urefrys, 'nsgre fhpu n snyy nf guvf, V funyy 46 | guvax abguvat bs ghzoyvat qbja fgnvef! Ubj oenir gurl'yy nyy guvax zr ng 47 | ubzr! Jul, V jbhyqa'g fnl nalguvat nobhg vg, rira vs V sryy bss gur gbc 48 | bs gur ubhfr!' (Juvpu jnf irel yvxryl gehr.) 49 | 50 | Qbja, qbja, qbja. Jbhyq gur snyy ARIRE pbzr gb na raq! 'V jbaqre ubj 51 | znal zvyrf V'ir snyyra ol guvf gvzr?' fur fnvq nybhq. 'V zhfg or trggvat 52 | fbzrjurer arne gur prager bs gur rnegu. Yrg zr frr: gung jbhyq or sbhe 53 | gubhfnaq zvyrf qbja, V guvax' (sbe, lbh frr, Nyvpr unq yrneag frireny 54 | guvatf bs guvf fbeg va ure yrffbaf va gur fpubbyebbz, naq gubhtu guvf 55 | jnf abg n IREL tbbq bccbeghavgl sbe fubjvat bss ure xabjyrqtr, nf gurer 56 | jnf ab bar gb yvfgra gb ure, fgvyy vg jnf tbbq cenpgvpr gb fnl vg bire) 57 | 'lrf, gung'f nobhg gur evtug qvfgnaprohg gura V jbaqre jung Yngvghqr 58 | be Ybatvghqr V'ir tbg gb?' (Nyvpr unq ab vqrn jung Yngvghqr jnf, be 59 | Ybatvghqr rvgure, ohg gubhtug gurl jrer avpr tenaq jbeqf gb fnl.) 60 | 61 | Cerfragyl fur ortna ntnva. 'V jbaqre vs V funyy snyy evtug GUEBHTU gur 62 | rnegu! Ubj shaal vg'yy frrz gb pbzr bhg nzbat gur crbcyr gung jnyx jvgu 63 | gurve urnqf qbjajneq! Gur Nagvcnguvrf, V guvax' (fur jnf engure tynq 64 | gurer JNF ab bar yvfgravat, guvf gvzr, nf vg qvqa'g fbhaq ng nyy gur 65 | evtug jbeq) 'ohg V funyy unir gb nfx gurz jung gur anzr bs gur pbhagel 66 | vf, lbh xabj. Cyrnfr, Zn'nz, vf guvf Arj Mrnynaq be Nhfgenyvn?' (naq 67 | fur gevrq gb phegfrl nf fur fcbxr - snapl PHEGFRLVAT nf lbh'er snyyvat 68 | guebhtu gur nve! Qb lbh guvax lbh pbhyq znantr vg?) 'Naq jung na 69 | vtabenag yvggyr tvey fur'yy guvax zr sbe nfxvat! Ab, vg'yy arire qb gb 70 | nfx: creuncf V funyy frr vg jevggra hc fbzrjurer.' 71 | 72 | Qbja, qbja, qbja. Gurer jnf abguvat ryfr gb qb, fb Nyvpr fbba ortna 73 | gnyxvat ntnva. 'Qvanu'yy zvff zr irel zhpu gb-avtug, V fubhyq guvax!' 74 | (Qvanu jnf gur png.) 'V ubcr gurl'yy erzrzore ure fnhpre bs zvyx ng 75 | grn-gvzr. Qvanu zl qrne! V jvfu lbh jrer qbja urer jvgu zr! Gurer ner ab 76 | zvpr va gur nve, V'z nsenvq, ohg lbh zvtug pngpu n ong, naq gung'f irel 77 | yvxr n zbhfr, lbh xabj. Ohg qb pngf rng ongf, V jbaqre?' Naq urer Nyvpr 78 | ortna gb trg engure fyrrcl, naq jrag ba fnlvat gb urefrys, va n qernzl 79 | fbeg bs jnl, 'Qb pngf rng ongf? Qb pngf rng ongf?' naq fbzrgvzrf, 'Qb 80 | ongf rng pngf?' sbe, lbh frr, nf fur pbhyqa'g nafjre rvgure dhrfgvba, 81 | vg qvqa'g zhpu znggre juvpu jnl fur chg vg. Fur sryg gung fur jnf qbmvat 82 | bss, naq unq whfg ortha gb qernz gung fur jnf jnyxvat unaq va unaq jvgu 83 | Qvanu, naq fnlvat gb ure irel rnearfgyl, 'Abj, Qvanu, gryy zr gur gehgu: 84 | qvq lbh rire rng n ong?' jura fhqqrayl, guhzc! guhzc! qbja fur pnzr hcba 85 | n urnc bs fgvpxf naq qel yrnirf, naq gur snyy jnf bire. 86 | 87 | Nyvpr jnf abg n ovg uheg, naq fur whzcrq hc ba gb ure srrg va n zbzrag: 88 | fur ybbxrq hc, ohg vg jnf nyy qnex bireurnq; orsber ure jnf nabgure 89 | ybat cnffntr, naq gur Juvgr Enoovg jnf fgvyy va fvtug, uheelvat qbja vg. 90 | Gurer jnf abg n zbzrag gb or ybfg: njnl jrag Nyvpr yvxr gur jvaq, naq 91 | jnf whfg va gvzr gb urne vg fnl, nf vg ghearq n pbeare, 'Bu zl rnef 92 | naq juvfxref, ubj yngr vg'f trggvat!' Fur jnf pybfr oruvaq vg jura fur 93 | ghearq gur pbeare, ohg gur Enoovg jnf ab ybatre gb or frra: fur sbhaq 94 | urefrys va n ybat, ybj unyy, juvpu jnf yvg hc ol n ebj bs ynzcf unatvat 95 | sebz gur ebbs. 96 | 97 | Gurer jrer qbbef nyy ebhaq gur unyy, ohg gurl jrer nyy ybpxrq; naq jura 98 | Nyvpr unq orra nyy gur jnl qbja bar fvqr naq hc gur bgure, gelvat rirel 99 | qbbe, fur jnyxrq fnqyl qbja gur zvqqyr, jbaqrevat ubj fur jnf rire gb 100 | trg bhg ntnva. 101 | 102 | Fhqqrayl fur pnzr hcba n yvggyr guerr-yrttrq gnoyr, nyy znqr bs fbyvq 103 | tynff; gurer jnf abguvat ba vg rkprcg n gval tbyqra xrl, naq Nyvpr'f 104 | svefg gubhtug jnf gung vg zvtug orybat gb bar bs gur qbbef bs gur unyy; 105 | ohg, nynf! rvgure gur ybpxf jrer gbb ynetr, be gur xrl jnf gbb fznyy, 106 | ohg ng nal engr vg jbhyq abg bcra nal bs gurz. Ubjrire, ba gur frpbaq 107 | gvzr ebhaq, fur pnzr hcba n ybj phegnva fur unq abg abgvprq orsber, naq 108 | oruvaq vg jnf n yvggyr qbbe nobhg svsgrra vapurf uvtu: fur gevrq gur 109 | yvggyr tbyqra xrl va gur ybpx, naq gb ure terng qryvtug vg svggrq! 110 | 111 | Nyvpr bcrarq gur qbbe naq sbhaq gung vg yrq vagb n fznyy cnffntr, abg 112 | zhpu ynetre guna n eng-ubyr: fur xaryg qbja naq ybbxrq nybat gur cnffntr 113 | vagb gur ybiryvrfg tneqra lbh rire fnj. Ubj fur ybatrq gb trg bhg bs 114 | gung qnex unyy, naq jnaqre nobhg nzbat gubfr orqf bs oevtug sybjref naq 115 | gubfr pbby sbhagnvaf, ohg fur pbhyq abg rira trg ure urnq guebhtu gur 116 | qbbejnl; 'naq rira vs zl urnq jbhyq tb guebhtu,' gubhtug cbbe Nyvpr, 'vg 117 | jbhyq or bs irel yvggyr hfr jvgubhg zl fubhyqref. Bu, ubj V jvfu V pbhyq 118 | fuhg hc yvxr n gryrfpbcr! V guvax V pbhyq, vs V bayl xarj ubj gb ortva.' 119 | Sbe, lbh frr, fb znal bhg-bs-gur-jnl guvatf unq unccrarq yngryl, 120 | gung Nyvpr unq ortha gb guvax gung irel srj guvatf vaqrrq jrer ernyyl 121 | vzcbffvoyr. 122 | 123 | Gurer frrzrq gb or ab hfr va jnvgvat ol gur yvggyr qbbe, fb fur jrag 124 | onpx gb gur gnoyr, unys ubcvat fur zvtug svaq nabgure xrl ba vg, be ng 125 | nal engr n obbx bs ehyrf sbe fuhggvat crbcyr hc yvxr gryrfpbcrf: guvf 126 | gvzr fur sbhaq n yvggyr obggyr ba vg, ('juvpu pregnvayl jnf abg urer 127 | orsber,' fnvq Nyvpr,) naq ebhaq gur arpx bs gur obggyr jnf n cncre 128 | ynory, jvgu gur jbeqf 'QEVAX ZR' ornhgvshyyl cevagrq ba vg va ynetr 129 | yrggref. 130 | 131 | Vg jnf nyy irel jryy gb fnl 'Qevax zr,' ohg gur jvfr yvggyr Nyvpr jnf 132 | abg tbvat gb qb GUNG va n uheel. 'Ab, V'yy ybbx svefg,' fur fnvq, 'naq 133 | frr jurgure vg'f znexrq "cbvfba" be abg'; sbe fur unq ernq frireny avpr 134 | yvggyr uvfgbevrf nobhg puvyqera jub unq tbg oheag, naq rngra hc ol jvyq 135 | ornfgf naq bgure hacyrnfnag guvatf, nyy orpnhfr gurl JBHYQ abg erzrzore 136 | gur fvzcyr ehyrf gurve sevraqf unq gnhtug gurz: fhpu nf, gung n erq-ubg 137 | cbxre jvyy ohea lbh vs lbh ubyq vg gbb ybat; naq gung vs lbh phg lbhe 138 | svatre IREL qrrcyl jvgu n xavsr, vg hfhnyyl oyrrqf; naq fur unq arire 139 | sbetbggra gung, vs lbh qevax zhpu sebz n obggyr znexrq 'cbvfba,' vg vf 140 | nyzbfg pregnva gb qvfnterr jvgu lbh, fbbare be yngre. 141 | 142 | Ubjrire, guvf obggyr jnf ABG znexrq 'cbvfba,' fb Nyvpr iragherq gb gnfgr 143 | vg, naq svaqvat vg irel avpr, (vg unq, va snpg, n fbeg bs zvkrq synibhe 144 | bs pureel-gneg, phfgneq, cvar-nccyr, ebnfg ghexrl, gbssrr, naq ubg 145 | ohggrerq gbnfg,) fur irel fbba svavfurq vg bss. 146 | 147 | 'Jung n phevbhf srryvat!' fnvq Nyvpr; 'V zhfg or fuhggvat hc yvxr n 148 | gryrfpbcr.' 149 | 150 | Naq fb vg jnf vaqrrq: fur jnf abj bayl gra vapurf uvtu, naq ure snpr 151 | oevtugrarq hc ng gur gubhtug gung fur jnf abj gur evtug fvmr sbe tbvat 152 | guebhtu gur yvggyr qbbe vagb gung ybiryl tneqra. Svefg, ubjrire, fur 153 | jnvgrq sbe n srj zvahgrf gb frr vs fur jnf tbvat gb fuevax nal shegure: 154 | fur sryg n yvggyr areibhf nobhg guvf; 'sbe vg zvtug raq, lbh xabj,' fnvq 155 | Nyvpr gb urefrys, 'va zl tbvat bhg nygbtrgure, yvxr n pnaqyr. V jbaqre 156 | jung V fubhyq or yvxr gura?' Naq fur gevrq gb snapl jung gur synzr bs n 157 | pnaqyr vf yvxr nsgre gur pnaqyr vf oybja bhg, sbe fur pbhyq abg erzrzore 158 | rire univat frra fhpu n guvat. 159 | 160 | Nsgre n juvyr, svaqvat gung abguvat zber unccrarq, fur qrpvqrq ba tbvat 161 | vagb gur tneqra ng bapr; ohg, nynf sbe cbbe Nyvpr! jura fur tbg gb gur 162 | qbbe, fur sbhaq fur unq sbetbggra gur yvggyr tbyqra xrl, naq jura fur 163 | jrag onpx gb gur gnoyr sbe vg, fur sbhaq fur pbhyq abg cbffvoyl ernpu 164 | vg: fur pbhyq frr vg dhvgr cynvayl guebhtu gur tynff, naq fur gevrq ure 165 | orfg gb pyvzo hc bar bs gur yrtf bs gur gnoyr, ohg vg jnf gbb fyvccrel; 166 | naq jura fur unq gverq urefrys bhg jvgu gelvat, gur cbbe yvggyr guvat 167 | fng qbja naq pevrq. 168 | 169 | 'Pbzr, gurer'f ab hfr va pelvat yvxr gung!' fnvq Nyvpr gb urefrys, 170 | engure funecyl; 'V nqivfr lbh gb yrnir bss guvf zvahgr!' Fur trarenyyl 171 | tnir urefrys irel tbbq nqivpr, (gubhtu fur irel fryqbz sbyybjrq vg), 172 | naq fbzrgvzrf fur fpbyqrq urefrys fb frireryl nf gb oevat grnef vagb 173 | ure rlrf; naq bapr fur erzrzorerq gelvat gb obk ure bja rnef sbe univat 174 | purngrq urefrys va n tnzr bs pebdhrg fur jnf cynlvat ntnvafg urefrys, 175 | sbe guvf phevbhf puvyq jnf irel sbaq bs cergraqvat gb or gjb crbcyr. 176 | 'Ohg vg'f ab hfr abj,' gubhtug cbbe Nyvpr, 'gb cergraq gb or gjb crbcyr! 177 | Jul, gurer'f uneqyl rabhtu bs zr yrsg gb znxr BAR erfcrpgnoyr crefba!' 178 | 179 | Fbba ure rlr sryy ba n yvggyr tynff obk gung jnf ylvat haqre gur gnoyr: 180 | fur bcrarq vg, naq sbhaq va vg n irel fznyy pnxr, ba juvpu gur jbeqf 181 | 'RNG ZR' jrer ornhgvshyyl znexrq va pheenagf. 'Jryy, V'yy rng vg,' fnvq 182 | Nyvpr, 'naq vs vg znxrf zr tebj ynetre, V pna ernpu gur xrl; naq vs vg 183 | znxrf zr tebj fznyyre, V pna perrc haqre gur qbbe; fb rvgure jnl V'yy 184 | trg vagb gur tneqra, naq V qba'g pner juvpu unccraf!' 185 | 186 | Fur ngr n yvggyr ovg, naq fnvq nakvbhfyl gb urefrys, 'Juvpu jnl? Juvpu 187 | jnl?', ubyqvat ure unaq ba gur gbc bs ure urnq gb srry juvpu jnl vg jnf 188 | tebjvat, naq fur jnf dhvgr fhecevfrq gb svaq gung fur erznvarq gur fnzr 189 | fvmr: gb or fher, guvf trarenyyl unccraf jura bar rngf pnxr, ohg Nyvpr 190 | unq tbg fb zhpu vagb gur jnl bs rkcrpgvat abguvat ohg bhg-bs-gur-jnl 191 | guvatf gb unccra, gung vg frrzrq dhvgr qhyy naq fghcvq sbe yvsr gb tb ba 192 | va gur pbzzba jnl. 193 | 194 | Fb fur frg gb jbex, naq irel fbba svavfurq bss gur pnxr. 195 | --------------------------------------------------------------------------------