Problem 8: ruby rewrite

This commit is contained in:
Ivan R. 2022-12-03 12:19:24 +05:00
parent a3e0177f4e
commit f9aced1a77
No known key found for this signature in database
GPG key ID: 56C7BAAE859B302C
6 changed files with 110 additions and 179 deletions

View file

@ -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"

View file

@ -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]

View 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

View file

@ -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);
}
}

View 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

View file

@ -1,18 +1,11 @@
# Leetcode
# Rubycode
Solutions of leetcode problems in Ruby.
- [My profile](https://leetcode.com/ordinary-dev/)
## How to run solutions
For programs written in Rust:
```bash
cd problems/random-problem
cargo test
```
For programs written in Ruby:
```bash
cd problems/random-problem
ruby test.rb
@ -20,11 +13,5 @@ ruby test.rb
## Solution structure
For programs written in Rust:
- `src/lib.rs` - solution and tests
For programs written in Ruby:
- `main.rb` - the solution itself
- `test.rb` - tests