Problem 8: ruby rewrite
This commit is contained in:
parent
a3e0177f4e
commit
f9aced1a77
6 changed files with 110 additions and 179 deletions
7
problems/8-string-to-integer/Cargo.lock
generated
7
problems/8-string-to-integer/Cargo.lock
generated
|
@ -1,7 +0,0 @@
|
||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "string-to-integer"
|
|
||||||
version = "0.1.0"
|
|
|
@ -1,8 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "string-to-integer"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
55
problems/8-string-to-integer/main.rb
Normal file
55
problems/8-string-to-integer/main.rb
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
def my_atoi(s)
|
||||||
|
res = 0
|
||||||
|
sign = 1
|
||||||
|
sign_was_scanned = false
|
||||||
|
digit_was_scanned = false
|
||||||
|
|
||||||
|
i32_min = -2_147_483_648
|
||||||
|
i32_max = 2_147_483_647
|
||||||
|
|
||||||
|
s.each_char do |c|
|
||||||
|
if c >= '0' && c <= '9'
|
||||||
|
digit_was_scanned = true
|
||||||
|
conv = c.ord - '0'.ord
|
||||||
|
|
||||||
|
# Add new digit
|
||||||
|
res = res * 10 + conv * sign
|
||||||
|
|
||||||
|
# Test overflow
|
||||||
|
return i32_max if sign > 0 && res > i32_max
|
||||||
|
return i32_min if sign < 0 && res < i32_min
|
||||||
|
|
||||||
|
|
||||||
|
# First '-'
|
||||||
|
elsif c == '-' && sign_was_scanned == false && digit_was_scanned == false
|
||||||
|
sign_was_scanned = true
|
||||||
|
sign *= -1
|
||||||
|
|
||||||
|
# First '+'
|
||||||
|
elsif c == '+' && sign_was_scanned == false && digit_was_scanned == false
|
||||||
|
sign_was_scanned = true
|
||||||
|
|
||||||
|
# Repeated '-' or '-' after number
|
||||||
|
elsif c == '-'
|
||||||
|
return res
|
||||||
|
|
||||||
|
# Repeated '+' or '+' after number
|
||||||
|
elsif c == '+'
|
||||||
|
return res
|
||||||
|
|
||||||
|
# Letters before number
|
||||||
|
elsif c != '+' && c != ' ' && digit_was_scanned == false
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Space after sign
|
||||||
|
elsif c == ' ' && sign_was_scanned
|
||||||
|
return res
|
||||||
|
|
||||||
|
# Letters after number
|
||||||
|
elsif digit_was_scanned == true
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
res
|
||||||
|
end
|
|
@ -1,148 +0,0 @@
|
||||||
use std::convert::TryInto;
|
|
||||||
|
|
||||||
pub struct Solution{}
|
|
||||||
|
|
||||||
impl Solution {
|
|
||||||
pub fn my_atoi(s: String) -> i32 {
|
|
||||||
let mut res: i32 = 0;
|
|
||||||
let mut sign: i32 = 1;
|
|
||||||
let mut sign_was_scanned = false;
|
|
||||||
let mut digit_was_scanned = false;
|
|
||||||
|
|
||||||
for c in s.chars() {
|
|
||||||
if c >= '0' && c <= '9' {
|
|
||||||
digit_was_scanned = true;
|
|
||||||
let conv: i32 = c.to_digit(10).unwrap().try_into().unwrap();
|
|
||||||
// Test overflow
|
|
||||||
if sign > 0 && res > (i32::MAX - conv * sign) / 10 {
|
|
||||||
return i32::MAX;
|
|
||||||
}
|
|
||||||
if sign < 0 && res < (i32::MIN - conv * sign) / 10 {
|
|
||||||
return i32::MIN;
|
|
||||||
}
|
|
||||||
// Add new digit
|
|
||||||
res = res * 10 + conv * sign;
|
|
||||||
}
|
|
||||||
// First '-'
|
|
||||||
else if c == '-' && sign_was_scanned == false && digit_was_scanned == false {
|
|
||||||
sign_was_scanned = true;
|
|
||||||
sign *= -1;
|
|
||||||
}
|
|
||||||
// Repeated '-' or '-' after number
|
|
||||||
else if c == '-' {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
// First '+'
|
|
||||||
else if c == '+' && sign_was_scanned == false && digit_was_scanned == false {
|
|
||||||
sign_was_scanned = true;
|
|
||||||
}
|
|
||||||
// Repeated '+' or '+' after number
|
|
||||||
else if c == '+' {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
// Letters before number
|
|
||||||
else if c != '+' && c != ' ' && digit_was_scanned == false {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
// Space after sign
|
|
||||||
else if c == ' ' && sign_was_scanned {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
// Letters after number
|
|
||||||
else if digit_was_scanned == true {
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_simple_string() {
|
|
||||||
let input = String::from("42");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 42);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_spaces() {
|
|
||||||
let input = String::from(" -42");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, -42);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_words() {
|
|
||||||
let input = String::from("4193 with words");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 4193);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_zeros() {
|
|
||||||
let input = String::from("0032");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 32);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_max_int() {
|
|
||||||
let input = String::from("21474242483648");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, i32::MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_min_int() {
|
|
||||||
let input = String::from("-2424147483649");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, i32::MIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_invalid_string() {
|
|
||||||
let input = String::from("words and 987");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_garbage_after_number() {
|
|
||||||
let input = String::from("3.14159");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_multiple_signs() {
|
|
||||||
let input = String::from("+-12");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_sign_after_number() {
|
|
||||||
let input = String::from("00000-42a1234");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_minus_after_negative_number() {
|
|
||||||
let input = String::from("-5-");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, -5);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_space_after_sign() {
|
|
||||||
let input = String::from(" + 413");
|
|
||||||
let result = Solution::my_atoi(input);
|
|
||||||
assert_eq!(result, 0);
|
|
||||||
}
|
|
||||||
}
|
|
52
problems/8-string-to-integer/test.rb
Normal file
52
problems/8-string-to-integer/test.rb
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
require_relative 'main'
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
class TestStringToInt < Test::Unit::TestCase
|
||||||
|
def test_simple_string
|
||||||
|
assert_equal(42, my_atoi('42'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_spaces
|
||||||
|
assert_equal(-42, my_atoi(' -42'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_words_after_number
|
||||||
|
assert_equal(4193, my_atoi('4193 with words'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_zeros
|
||||||
|
assert_equal(32, my_atoi('0032'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_max_int
|
||||||
|
assert_equal(2_147_483_647, my_atoi('2147483648'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_min_int
|
||||||
|
assert_equal(-2_147_483_648, my_atoi('-2147483649'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_invalid_string
|
||||||
|
assert_equal(0, my_atoi('words and 987'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_garbage_after_number
|
||||||
|
assert_equal(3, my_atoi('3.14748'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_multiple_signs
|
||||||
|
assert_equal(0, my_atoi('+-12'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_sign_after_number
|
||||||
|
assert_equal(0, my_atoi('00000-42a1234'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_minus_after_negative_number
|
||||||
|
assert_equal(-5, my_atoi('-5-'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_space_after_sign
|
||||||
|
assert_equal(0, my_atoi(' + 413'))
|
||||||
|
end
|
||||||
|
end
|
19
readme.md
19
readme.md
|
@ -1,18 +1,11 @@
|
||||||
# Leetcode
|
# Rubycode
|
||||||
|
|
||||||
|
Solutions of leetcode problems in Ruby.
|
||||||
|
|
||||||
- [My profile](https://leetcode.com/ordinary-dev/)
|
- [My profile](https://leetcode.com/ordinary-dev/)
|
||||||
|
|
||||||
## How to run solutions
|
## How to run solutions
|
||||||
|
|
||||||
For programs written in Rust:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd problems/random-problem
|
|
||||||
cargo test
|
|
||||||
```
|
|
||||||
|
|
||||||
For programs written in Ruby:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd problems/random-problem
|
cd problems/random-problem
|
||||||
ruby test.rb
|
ruby test.rb
|
||||||
|
@ -20,11 +13,5 @@ ruby test.rb
|
||||||
|
|
||||||
## Solution structure
|
## Solution structure
|
||||||
|
|
||||||
For programs written in Rust:
|
|
||||||
|
|
||||||
- `src/lib.rs` - solution and tests
|
|
||||||
|
|
||||||
For programs written in Ruby:
|
|
||||||
|
|
||||||
- `main.rb` - the solution itself
|
- `main.rb` - the solution itself
|
||||||
- `test.rb` - tests
|
- `test.rb` - tests
|
||||||
|
|
Loading…
Reference in a new issue